[dolfin] 01/01: New upstream version 2017.2.0.post0

Drew Parsons dparsons at moszumanska.debian.org
Sun Jan 21 15:00:11 UTC 2018


This is an automated email from the git hooks/post-receive script.

dparsons pushed a commit to annotated tag upstream/2017.2.0.post0
in repository dolfin.

commit 3907d051b624b67ce53ce54b4d7cb946f9f0173c
Author: Drew Parsons <dparsons at debian.org>
Date:   Sun Jan 21 19:30:41 2018 +0800

    New upstream version 2017.2.0.post0
---
 .circleci/config.yml                               |    32 +-
 CMakeLists.txt                                     |    54 +-
 ChangeLog.rst                                      |    13 +
 bench/fem/jit/python/bench_fem_jit_python          |     2 +-
 cmake/modules/FindGMP.cmake                        |    19 +
 cmake/modules/FindMPFR.cmake                       |    83 +
 cmake/templates/dolfin.conf.in                     |     3 -
 demo/CMakeLists.txt                                |     2 +-
 demo/documented/bcs/python/demo_bcs.py             |     2 +-
 demo/documented/biharmonic/cpp/Biharmonic.ufl.rst  |     2 +-
 .../biharmonic/python/demo_biharmonic.py.rst       |     2 +-
 .../documented/cahn-hilliard/cpp/documentation.rst |     3 +-
 demo/documented/cahn-hilliard/cpp/main.cpp         |     4 +-
 .../cahn-hilliard/python/demo_cahn-hilliard.py.rst |     2 +-
 demo/documented/neumann-poisson/cpp/main.cpp       |     3 +-
 .../python/demo_neumann-poisson.py.rst             |     6 +-
 demo/documented/poisson/cpp/main.cpp.rst           |     3 +-
 demo/documented/stokes-iterative/cpp/main.cpp      |     3 +-
 .../python/demo_stokes-iterative.py.rst            |     6 +-
 .../python/demo_subdomains-poisson.py              |     4 +-
 .../subdomains-poisson/python/documentation.rst    |    21 +-
 .../python/demo_tensor-weighted-poisson.py         |    15 +-
 .../python/demo_advection-diffusion.py             |     2 +-
 .../auto-adaptive-navier-stokes/cpp/main.cpp       |     4 +-
 .../buckling-tao/python/demo_buckling-tao.py       |     2 +-
 .../python/demo_collision-detection.py             |     2 +-
 .../curl-curl/python/demo_curl-curl.py             |     2 +-
 .../cpp/AdvectionDiffusion.ufl                     |     2 +-
 .../python/demo_dg-advection-diffusion.py          |     2 +-
 demo/undocumented/dg-poisson/cpp/Poisson.ufl       |     2 +-
 demo/undocumented/dg-poisson/cpp/main.cpp          |     2 +-
 .../dg-poisson/python/demo_dg-poisson.py           |     4 +-
 demo/undocumented/elasticity/cpp/main.cpp          |     4 +-
 .../elasticity/python/demo_elasticity.py           |     2 +-
 .../ghost-mesh/python/demo_ghost-mesh.py           |     2 +-
 demo/undocumented/lift-drag/cpp/main.cpp           |     2 +-
 .../lift-drag/python/demo_lift-drag.py             |     2 +-
 demo/undocumented/multimesh-3d/cpp/CMakeLists.txt  |    38 +
 .../multimesh-3d/cpp/MultiMeshH10Norm.ufl          |    20 +
 .../multimesh-3d/cpp/MultiMeshL2Norm.ufl           |    20 +
 .../cpp/MultiMeshPoisson.ufl                       |     9 +-
 demo/undocumented/multimesh-3d/cpp/main.cpp        |   224 +
 .../multimesh-poisson/cpp/MultiMeshPoisson.ufl     |    10 +-
 .../undocumented/multimesh-poisson/cpp/P1.ufl      |    24 +-
 demo/undocumented/multimesh-poisson/cpp/main.cpp   |    51 +-
 .../python/demo_multimesh-poisson.py               |    53 +-
 demo/undocumented/multimesh-quadrature/cpp/README  |     2 +
 .../propeller_2d_coarse.xml.gz                     |   Bin
 .../propeller_2d_fine.xml.gz                       |   Bin
 .../python/demo_multimesh-quadrature.py            |   147 +
 .../multimesh-stokes/cpp/MultiMeshStokes.ufl       |    10 +-
 demo/undocumented/multimesh-stokes/cpp/Stokes.ufl  |    52 -
 demo/undocumented/multimesh-stokes/cpp/main.cpp    |    42 +-
 demo/undocumented/multimesh-stokes/cpp/reference.h |    49 -
 .../python/demo_multimesh-stokes.py                |    52 +-
 .../multimesh/python/demo_multimesh.py             |   138 -
 .../python/demo_multistage-solver.py               |     2 +-
 .../python/demo_overlapping-regions.py             |     2 +-
 demo/undocumented/parallel-refinement/cpp/main.cpp |    16 +-
 .../python/demo_parallel-refinement.py             |     8 +-
 .../point-integral/python/demo_point-integral.py   |     2 +-
 .../refinement/python/demo_refinement.py           |     2 +-
 doc/source/conf.py                                 |     4 +-
 dolfin/CMakeLists.txt                              |    10 +
 dolfin/common/Variable.h                           |     2 +-
 dolfin/fem/AssemblerBase.cpp                       |    62 +-
 dolfin/fem/DirichletBC.cpp                         |     2 +-
 dolfin/fem/DiscreteOperators.cpp                   |     4 +-
 dolfin/fem/DofMap.h                                |     2 +-
 dolfin/fem/DofMapBuilder.cpp                       |     8 +-
 dolfin/fem/DofMapBuilder.h                         |     1 +
 dolfin/fem/MultiMeshAssembler.cpp                  |   219 +-
 dolfin/fem/MultiMeshAssembler.h                    |     3 +
 dolfin/fem/MultiMeshDirichletBC.cpp                |    47 +
 dolfin/fem/MultiMeshDirichletBC.h                  |    18 +-
 dolfin/fem/MultiMeshDofMap.cpp                     |    47 +
 dolfin/fem/MultiMeshDofMap.h                       |     6 +
 dolfin/fem/MultiMeshForm.cpp                       |    28 +
 dolfin/fem/MultiMeshForm.h                         |    18 +
 dolfin/fem/PETScDMCollection.cpp                   |     1 +
 dolfin/fem/PETScDMCollection.h                     |     2 +-
 dolfin/fem/UFC.h                                   |     7 +-
 dolfin/fem/fem_utils.cpp                           |     1 +
 dolfin/function/Function.cpp                       |     9 +-
 dolfin/function/FunctionAssigner.cpp               |     1 +
 dolfin/function/FunctionSpace.h                    |     3 +-
 dolfin/function/MultiMeshCoefficientAssigner.cpp   |     7 +-
 dolfin/function/MultiMeshCoefficientAssigner.h     |     2 +-
 dolfin/function/MultiMeshFunction.cpp              |   165 +-
 dolfin/function/MultiMeshFunction.h                |    62 +
 dolfin/function/MultiMeshFunctionSpace.cpp         |    33 +-
 dolfin/function/MultiMeshFunctionSpace.h           |     7 +-
 dolfin/generation/BoxMesh.cpp                      |    90 +-
 dolfin/generation/BoxMesh.h                        |    29 +-
 dolfin/generation/CMakeLists.txt                   |     4 -
 dolfin/generation/IntervalMesh.cpp                 |     2 +-
 dolfin/generation/RectangleMesh.cpp                |    77 +-
 dolfin/generation/RectangleMesh.h                  |    42 +-
 dolfin/generation/SphericalShellMesh.cpp           |     2 +-
 dolfin/generation/UnitCubeMesh.h                   |    32 +-
 dolfin/generation/UnitDiscMesh.cpp                 |     2 +-
 dolfin/generation/UnitHexMesh.cpp                  |   111 -
 dolfin/generation/UnitHexMesh.h                    |    56 -
 dolfin/generation/UnitQuadMesh.cpp                 |    96 -
 dolfin/generation/UnitQuadMesh.h                   |    59 -
 dolfin/generation/UnitSquareMesh.h                 |    39 +-
 dolfin/generation/UnitTetrahedronMesh.cpp          |     2 +-
 dolfin/generation/UnitTriangleMesh.cpp             |     2 +-
 dolfin/generation/dolfin_generation.h              |     2 -
 dolfin/geometry/BoundingBoxTree2D.h                |     6 +-
 dolfin/geometry/CGALExactArithmetic.h              |  1152 ++
 dolfin/geometry/CMakeLists.txt                     |    17 +-
 dolfin/geometry/CollisionDetection.cpp             |  1158 --
 dolfin/geometry/CollisionDetection.h               |   296 -
 dolfin/geometry/CollisionPredicates.cpp            |  1053 ++
 dolfin/geometry/CollisionPredicates.h              |   316 +
 dolfin/geometry/ConvexTriangulation.cpp            |   603 +
 dolfin/geometry/ConvexTriangulation.h              |    84 +
 dolfin/geometry/GenericBoundingBoxTree.cpp         |    14 +-
 dolfin/geometry/GeometryDebugging.cpp              |   151 +
 dolfin/geometry/GeometryDebugging.h                |    83 +
 dolfin/geometry/GeometryPredicates.cpp             |   214 +
 dolfin/geometry/GeometryPredicates.h               |    70 +
 dolfin/geometry/GeometryTools.h                    |   120 +
 dolfin/geometry/IntersectionConstruction.cpp       |   862 ++
 dolfin/geometry/IntersectionConstruction.h         |   292 +
 dolfin/geometry/IntersectionTriangulation.cpp      |  1365 ---
 dolfin/geometry/IntersectionTriangulation.h        |   214 -
 dolfin/geometry/Point.h                            |    10 +-
 dolfin/geometry/SimplexQuadrature.cpp              |  3944 ++++++-
 dolfin/geometry/SimplexQuadrature.h                |   237 +-
 dolfin/geometry/dolfin_geometry.h                  |     1 +
 dolfin/geometry/intersect.cpp                      |    12 +-
 dolfin/geometry/predicates.cpp                     |  2372 ++++
 dolfin/geometry/predicates.h                       |    59 +
 dolfin/io/HDF5File.cpp                             |    18 +-
 dolfin/io/HDF5Utility.cpp                          |     4 +-
 dolfin/io/VTKWriter.cpp                            |    12 +-
 dolfin/io/X3DFile.cpp                              |     4 +-
 dolfin/io/XDMFFile.cpp                             |    43 +-
 dolfin/io/XMLMesh.cpp                              |     6 +-
 dolfin/la/EigenVector.cpp                          |    12 +-
 dolfin/la/GenericMatrix.cpp                        |     4 +-
 dolfin/la/GenericMatrix.h                          |     5 +-
 dolfin/la/PETScObject.h                            |     1 +
 dolfin/la/SLEPcEigenSolver.cpp                     |    41 +-
 dolfin/la/SLEPcEigenSolver.h                       |     3 -
 dolfin/log/Logger.cpp                              |    17 +-
 dolfin/log/Logger.h                                |     5 +-
 dolfin/log/log.cpp                                 |     5 +
 dolfin/log/log.h                                   |     3 +
 dolfin/mesh/BoundaryComputation.cpp                |     6 +-
 dolfin/mesh/CMakeLists.txt                         |     1 +
 dolfin/{geometry/intersect.cpp => mesh/Cell.cpp}   |    32 +-
 dolfin/mesh/Cell.h                                 |    33 +-
 dolfin/mesh/CellType.cpp                           |    46 +-
 dolfin/mesh/CellType.h                             |    17 +-
 dolfin/mesh/DistributedMeshTools.cpp               |     4 +-
 dolfin/mesh/DynamicMeshEditor.cpp                  |     8 +-
 dolfin/mesh/Edge.h                                 |    12 +-
 dolfin/mesh/Face.h                                 |    12 +-
 dolfin/mesh/Facet.h                                |    12 +-
 dolfin/mesh/HexahedronCell.cpp                     |    14 -
 dolfin/mesh/HexahedronCell.h                       |    17 +-
 dolfin/mesh/IntervalCell.cpp                       |    19 +-
 dolfin/mesh/IntervalCell.h                         |    20 +-
 dolfin/mesh/LocalMeshData.cpp                      |     2 +-
 dolfin/mesh/Mesh.cpp                               |     9 +-
 dolfin/mesh/Mesh.h                                 |    27 +-
 dolfin/mesh/MeshColoring.cpp                       |     6 +-
 dolfin/mesh/MeshColoring.h                         |     4 +-
 dolfin/mesh/MeshEditor.cpp                         |    42 +-
 dolfin/mesh/MeshEditor.h                           |    18 -
 dolfin/mesh/MeshFunction.h                         |     8 +-
 dolfin/mesh/MeshHierarchy.cpp                      |    10 +-
 dolfin/mesh/MeshQuality.cpp                        |    10 +-
 dolfin/mesh/MeshQuality.h                          |     4 +-
 dolfin/mesh/MeshRenumbering.cpp                    |     8 +-
 dolfin/mesh/MeshTopology.cpp                       |     5 +-
 dolfin/mesh/MeshTopology.h                         |     4 +-
 dolfin/mesh/MeshTransformation.cpp                 |    18 +-
 dolfin/mesh/MeshTransformation.h                   |    13 +-
 dolfin/mesh/MultiMesh.cpp                          |  1495 ++-
 dolfin/mesh/MultiMesh.h                            |   202 +-
 dolfin/mesh/PointCell.cpp                          |    19 +-
 dolfin/mesh/PointCell.h                            |    19 +-
 dolfin/mesh/QuadrilateralCell.cpp                  |    14 -
 dolfin/mesh/QuadrilateralCell.h                    |    17 +-
 dolfin/mesh/TetrahedronCell.cpp                    |    19 +-
 dolfin/mesh/TetrahedronCell.h                      |    20 +-
 dolfin/mesh/TopologyComputation.cpp                |     4 +-
 dolfin/mesh/TriangleCell.cpp                       |    19 +-
 dolfin/mesh/TriangleCell.h                         |    18 +-
 dolfin/mesh/Vertex.h                               |    12 +-
 dolfin/refinement/BisectionRefinement1D.cpp        |     2 +-
 dolfin/refinement/LocalMeshCoarsening.cpp          |    12 +-
 dolfin/refinement/ParallelRefinement.cpp           |    14 +-
 dolfin/refinement/ParallelRefinement.h             |     8 +-
 dolfin/refinement/RegularCutRefinement.cpp         |     3 +-
 dolfin/refinement/refine.cpp                       |    22 +-
 dolfin/refinement/refine.h                         |     2 +-
 dolfin/swig/la/post.i                              |    13 +-
 dolfin/swig/mesh/post.i                            |    42 +
 dolfin/swig/mesh/pre.i                             |    91 +
 dolfin/swig/shared_ptr_classes.i                   |     1 +
 dolfin/swig/typemaps/std_map.i                     |    27 +
 dolfin/swig/typemaps/std_vector.i                  |    22 +-
 python/CMakeLists.txt                              |    36 +-
 python/cmake/FindPETSc4py.cmake                    |   112 +
 python/doc/Makefile                                |    20 +
 python/doc/source/api.rst                          |    21 +-
 python/dolfin/__init__.py                          |    58 +-
 python/dolfin/common/plotting.py                   |    26 +-
 python/dolfin/common/timer.py                      |     6 +-
 python/dolfin/fem/adaptivesolving.py               |    12 +-
 python/dolfin/fem/assembling.py                    |     6 +-
 python/dolfin/fem/form.py                          |     5 +-
 python/dolfin/fem/formmanipulations.py             |    24 +-
 python/dolfin/fem/norms.py                         |    55 +-
 python/dolfin/fem/problem.py                       |    95 +
 python/dolfin/fem/projection.py                    |    13 +-
 python/dolfin/fem/solvers.py                       |    50 +
 python/dolfin/fem/solving.py                       |   147 +-
 python/dolfin/function/argument.py                 |    13 +-
 python/dolfin/function/constant.py                 |     2 +
 python/dolfin/function/expression.py               |    90 +-
 python/dolfin/function/function.py                 |    61 +-
 python/dolfin/function/functionspace.py            |    37 +-
 python/dolfin/function/jit.py                      |     9 +-
 python/dolfin/function/specialfunctions.py         |    91 +-
 python/dolfin/jit/__init__.py                      |     2 +-
 python/dolfin/jit/jit.py                           |    99 +-
 python/dolfin/jit/pybind11jit.py                   |    46 +-
 python/dolfin/la/__init__.py                       |    50 +-
 python/dolfin/la/solver.py                         |    72 +
 python/dolfin/mesh/__init__.py                     |     3 +
 python/dolfin/mesh/ale.py                          |    38 +-
 python/dolfin/mesh/meshfunction.py                 |    59 +-
 python/dolfin/mesh/subdomain.py                    |    29 +-
 python/dolfin/mesh/svgtools.py                     |    32 +-
 python/dolfin/multistage/__init__.py               |     8 +-
 python/dolfin/multistage/factorize.py              |    18 +-
 python/dolfin/multistage/multistagescheme.py       |   203 +-
 python/dolfin/multistage/multistagesolvers.py      |     1 +
 python/dolfin/multistage/rushlarsenschemes.py      |    74 +-
 python/dolfin/parameter/__init__.py                |    13 +-
 python/dolfin_utils/meshconvert/meshconvert.py     |     2 +-
 python/dolfin_utils/test/fixtures.py               |    80 +-
 python/setup.cfg                                   |     2 +
 python/setup.py                                    |    10 +-
 .../intersect.cpp => python/src/MPICommWrapper.cpp |    32 +-
 .../PETScObject.h => python/src/MPICommWrapper.h   |    45 +-
 python/src/adaptivity.cpp                          |     8 +-
 python/src/ale.cpp                                 |     2 -
 python/src/casters.h                               |     3 +-
 python/src/common.cpp                              |   165 +-
 python/src/dolfin.cpp                              |     4 +-
 python/src/fem.cpp                                 |    46 +-
 python/src/function.cpp                            |    29 +-
 python/src/generation.cpp                          |   101 +-
 python/src/geometry.cpp                            |    31 +-
 python/src/io.cpp                                  |    23 +-
 python/src/la.cpp                                  |   339 +-
 python/src/log.cpp                                 |    23 +-
 python/src/mesh.cpp                                |   112 +-
 python/src/mpi_casters.h                           |   170 +-
 python/src/multistage.cpp                          |     4 +-
 python/src/nls.cpp                                 |    22 +-
 python/src/parameter.cpp                           |    21 +-
 python/src/petsc_casters.h                         |   147 +-
 scripts/dolfin-order/mesh0.xml.gz                  |   Bin 312 -> 0 bytes
 scripts/dolfin-order/mesh1.xml.gz                  |   Bin 247 -> 0 bytes
 scripts/dolfin-plot/mesh.xml.gz                    |   Bin 20894 -> 0 bytes
 shippable.yml                                      |    22 -
 site-packages/dolfin/common/plotting.py            |    11 +-
 .../dolfin/compilemodules/compilemodule.py         |     2 +-
 site-packages/dolfin/fem/assembling.py             |    16 +-
 site-packages/dolfin/fem/form.py                   |     2 +
 site-packages/dolfin/fem/interpolation.py          |    22 +-
 site-packages/dolfin/fem/norms.py                  |   109 +-
 .../dolfin/functions/multimeshfunction.py          |    67 +-
 site-packages/dolfin/functions/specialfunctions.py |    89 +-
 site-packages/dolfin_utils/meshconvert/abaqus.py   |     2 +-
 .../dolfin_utils/meshconvert/meshconvert.py        |     7 +-
 site-packages/dolfin_utils/test/fixtures.py        |    26 +-
 test/README                                        |    11 -
 test/regression/test.py                            |     2 +
 test/unit/CMakeLists.txt                           |    32 -
 test/unit/README                                   |     3 -
 test/unit/cpp/CMakeLists.txt                       |   116 +-
 test/unit/cpp/catch/catch.hpp                      | 11545 +++++++++++++++++++
 test/unit/cpp/common/SubSystemsManager.cpp         |    29 +-
 test/unit/cpp/function/Expression.cpp              |    99 +-
 test/unit/cpp/geometry/ConvexTriangulation.cpp     |   287 +
 test/unit/cpp/io/XMLMeshData.cpp                   |    80 +-
 test/unit/cpp/io/XMLMeshValueCollection.cpp        |    23 +-
 test/unit/cpp/la/LinearOperator.cpp                |   111 +-
 test/unit/cpp/la/Vector.cpp                        |   257 +-
 test/unit/cpp/main.cpp                             |     2 +
 test/unit/cpp/mesh/Mesh.cpp                        |   427 +-
 test/unit/cpp/mesh/MeshColoring.cpp                |    70 +-
 test/unit/cpp/mesh/MeshFunction.cpp                |    93 +-
 test/unit/cpp/mesh/MeshValueCollection.cpp         |   245 +-
 test/unit/cpp/mesh/MultiMesh.cpp                   |    91 +
 test/unit/cpp/multimesh/MultiMesh.cpp              |   307 -
 test/unit/cpp/parameter/Parameters.cpp             |    56 +-
 test/unit/pytest.ini                               |     3 +
 test/unit/python/adaptivity/test_error_control.py  |     2 -
 test/unit/python/adaptivity/test_time_series.py    |     2 -
 test/unit/python/ale/test_harmonic_smoothing.py    |     6 +-
 test/unit/python/common/test_mpi.py                |    52 +
 test/unit/python/fem/test_assembler.py             |    19 +-
 test/unit/python/fem/test_dirichlet_bc.py          |    16 +-
 test/unit/python/fem/test_discrete_operators.py    |     6 +-
 test/unit/python/fem/test_dofmap.py                |   138 +-
 test/unit/python/fem/test_dp_assemble.py           |    16 +-
 test/unit/python/fem/test_finite_element.py        |    10 +-
 test/unit/python/fem/test_form.py                  |    14 +-
 .../fem/test_interior_facet_integral_sides.py      |     4 +-
 test/unit/python/fem/test_local_assembler.py       |     2 -
 test/unit/python/fem/test_local_solver.py          |     4 +-
 test/unit/python/fem/test_manifolds.py             |     2 -
 test/unit/python/fem/test_petsc_transfer_matrix.py |     2 -
 test/unit/python/fem/test_point_source.py          |     8 +-
 test/unit/python/fem/test_solving.py               |     2 -
 .../python/fem/test_symbolic_geometry_assembly.py  |   343 +-
 test/unit/python/fem/test_system_assembler.py      |    18 +-
 test/unit/python/fem/test_variational_problem.py   |     8 +-
 test/unit/python/function/test_constant.py         |    16 +-
 .../function/test_constrained_function_space.py    |     2 -
 test/unit/python/function/test_expression.py       |    12 +-
 test/unit/python/function/test_function.py         |    27 +-
 .../unit/python/function/test_function_assigner.py |    40 +-
 test/unit/python/function/test_function_space.py   |    28 +-
 .../python/function/test_lagrange_interpolator.py  |     2 -
 .../function/test_nonmatching_interpolation.py     |     2 -
 .../unit/python/function/test_special_functions.py |     2 -
 .../unit/python/geometry/test_bounding_box_tree.py |    11 +-
 .../python/geometry/test_collision_detection.py    |   244 +-
 .../geometry/test_collision_segment_segment.py     |   137 +
 test/unit/python/geometry/test_coordinates.py      |     2 -
 test/unit/python/geometry/test_geometry_issues.py  |   163 +
 test/unit/python/geometry/test_intersection.py     |     8 +-
 .../geometry/test_intersection_construction.py     |   323 +
 .../geometry/test_intersection_triangulation.py    |   174 -
 test/unit/python/geometry/test_point.py            |    11 +-
 test/unit/python/graph/test_graph_build.py         |     2 -
 test/unit/python/io/test_HDF5.py                   |    12 +-
 test/unit/python/io/test_HDF5_attribute.py         |     2 -
 test/unit/python/io/test_HDF5_series.py            |     4 +-
 test/unit/python/io/test_SVG.py                    |     2 -
 test/unit/python/io/test_X3D.py                    |    10 +-
 test/unit/python/io/test_XDMF.py                   |    84 +-
 test/unit/python/io/test_XDMF_cell_output.py       |     2 +-
 test/unit/python/io/test_XMLFunction.py            |     3 +-
 test/unit/python/io/test_XML_mesh.py               |     2 -
 test/unit/python/io/test_XML_mesh_function.py      |     2 -
 .../python/io/test_XML_mesh_value_collection.py    |     2 -
 test/unit/python/io/test_XML_table.py              |     2 -
 test/unit/python/io/test_XML_vector.py             |     2 -
 test/unit/python/io/test_vtk.py                    |    27 +-
 test/unit/python/jit/test_jit.py                   |   162 +-
 test/unit/python/la/test_krylov_solver.py          |     2 -
 test/unit/python/la/test_la_basic.py               |    14 +-
 test/unit/python/la/test_linear_operator.py        |     8 +-
 test/unit/python/la/test_lu_solver.py              |     7 +-
 test/unit/python/la/test_matrix.py                 |    64 +-
 test/unit/python/la/test_mg_solver.py              |     5 +-
 test/unit/python/la/test_nullspace.py              |     2 -
 test/unit/python/la/test_petsc4py.py               |    97 +
 test/unit/python/la/test_scalar.py                 |     2 -
 test/unit/python/la/test_slepc_solver.py           |    15 +-
 test/unit/python/la/test_solve.py                  |     2 -
 test/unit/python/la/test_tensor_layout.py          |     2 -
 test/unit/python/la/test_vector.py                 |    35 +-
 .../{mesh/test_mesh_data.py => log/test_log.py}    |    24 +-
 test/unit/python/math/test_math.py                 |     2 -
 test/unit/python/mesh/test_boundary_mesh.py        |     8 +-
 test/unit/python/mesh/test_cell.py                 |     6 +-
 test/unit/python/mesh/test_edge.py                 |     2 -
 test/unit/python/mesh/test_face.py                 |     2 -
 .../mesh/{test_mesh_data.py => test_facet.py}      |    26 +-
 test/unit/python/mesh/test_ghost_mesh.py           |     2 -
 .../unit/python/mesh/test_manifold_point_search.py |     7 +-
 test/unit/python/mesh/test_mesh.py                 |   119 +-
 test/unit/python/mesh/test_mesh_coloring.py        |     0
 test/unit/python/mesh/test_mesh_data.py            |     2 -
 test/unit/python/mesh/test_mesh_editor.py          |     2 -
 test/unit/python/mesh/test_mesh_function.py        |    18 +-
 test/unit/python/mesh/test_mesh_iterator.py        |     2 -
 test/unit/python/mesh/test_mesh_markers.py         |     2 -
 test/unit/python/mesh/test_mesh_quality.py         |     2 -
 test/unit/python/mesh/test_mesh_transformation.py  |     2 -
 .../unit/python/mesh/test_mesh_value_collection.py |    10 +-
 .../python/mesh/test_multi_mesh_integration.py     |   113 -
 .../mesh/test_periodic_boundary_computation.py     |     2 -
 test/unit/python/mesh/test_sub_domain.py           |    32 +-
 test/unit/python/mesh/test_sub_mesh.py             |     6 +-
 .../unit/python/meshconvert/test_mesh_converter.py |     8 +-
 test/unit/python/multimesh/test_compression.py     |   103 +
 test/unit/python/multimesh/test_interface_area.py  |   139 +
 test/unit/python/multimesh/test_multimesh.py       |    58 +-
 .../python/multimesh/test_multimesh_cell_types.py  |    94 +
 .../multimesh/test_multimesh_coefficients.py       |   113 +
 .../test_multimesh_initialization.py}              |    41 +-
 .../unit/python/multimesh/test_multimesh_issues.py |    69 +
 test/unit/python/multimesh/test_multimesh_solve.py |   125 +
 test/unit/python/multimesh/test_volume.py          |   206 +
 test/unit/python/multistage/test_RK_solver.py      |     8 +-
 .../multistage/test_point_integral_solver.py       |     2 -
 test/unit/python/nls/test_PETScSNES_solver.py      |     2 -
 test/unit/python/nls/test_PETScTAOSolver.py        |     2 -
 .../python/nls/test_TAO_linear_bound_solver.py     |     2 -
 .../test_solve_result_against_reference.py         |     5 +-
 test/unit/python/parameter/test_parameters.py      |     4 +-
 .../test_assembly_derivatives.py                   |     2 -
 .../ufl-jit-assemble-chain/test_form_operations.py |     2 -
 417 files changed, 32479 insertions(+), 8938 deletions(-)

diff --git a/.circleci/config.yml b/.circleci/config.yml
index 22e6af1..a9a3b68 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -11,26 +11,22 @@ jobs:
       - checkout
       - run:
           name: Install/update dependencies  # Install with sudo as tests not run as superuser in circleci/python
-          command: |
-            sudo pip3 install pytest six --upgrade
-      - run:
-          name: Install FIAT
-          command: pip3 install git+https://bitbucket.org/fenics-project/fiat.git@master
-      - run:
-          name: Install UFL
-          command: pip3 install git+https://bitbucket.org/fenics-project/ufl.git@master
+          command: sudo pip3 install pytest pytest-xdist six flake8 --upgrade
       - run:
-          name: Install Dijitso
-          command: pip3 install git+https://bitbucket.org/fenics-project/dijitso.git@master
-      - run:
-          name: Install Instant
-          command: pip3 install git+https://bitbucket.org/fenics-project/instant.git@master
+          name: Install FEniCS dependencies
+          command: |
+            if [ "${CIRCLE_BRANCH}" == "next" ] ; then export DEP_BRANCH_NAME="next" ; else export DEP_BRANCH_NAME="master" ; fi
+            pip3 install git+https://bitbucket.org/fenics-project/fiat.git@"${DEP_BRANCH_NAME}"
+            pip3 install git+https://bitbucket.org/fenics-project/ufl.git@"${DEP_BRANCH_NAME}"
+            pip3 install git+https://bitbucket.org/fenics-project/dijitso.git@"${DEP_BRANCH_NAME}"
+            pip3 install git+https://bitbucket.org/fenics-project/instant.git@"${DEP_BRANCH_NAME}"
+            pip3 install git+https://bitbucket.org/fenics-project/ffc.git@"${DEP_BRANCH_NAME}"
       - run:
-          name: Install FFC
-          command: pip3 install git+https://bitbucket.org/fenics-project/ffc.git@master
+          name: Flake8 checks on pybind11 Python code
+          command: python3 -m flake8 python/dolfin
       - run:
           name: Configure DOLFIN
-          command: mkdir -p build && cd build && cmake .. -DCMAKE_BUILD_TYPE=Debug -DDOLFIN_ENABLE_TESTING=ON
+          command: mkdir -p build && cd build && cmake .. -DCMAKE_BUILD_TYPE=Developer -DDOLFIN_ENABLE_TESTING=ON
       - run:
           name: Build DOLFIN and install
           command: cd build && make install -j2
@@ -39,7 +35,7 @@ jobs:
           command: cd build && make run_unittests_cpp
       - run:
           name: Run Python unit tests (SWIG, serial)
-          command: source /usr/local/share/dolfin/dolfin.conf && python3 -m pytest test/unit/python/
+          command: source /usr/local/share/dolfin/dolfin.conf && python3 -m pytest -n 2 test/unit/python/
       - run:
           name: Run Python unit tests (SWIG, MPI)
           command: source /usr/local/share/dolfin/dolfin.conf && mpirun -n 3 python3 -m pytest test/unit/python/
@@ -65,7 +61,7 @@ jobs:
             pip3 -v install . --user
       - run:
           name: Run unit tests (pybind11, serial)
-          command: python3 -m pytest test/unit/python/
+          command: python3 -m pytest -n 2 test/unit/python/
       - run:
           name: Run unit tests (pybind11, MPI parallel)
           command: mpirun -n 3 python3 -m pytest test/unit/python/
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4e18344..a744382 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,7 +7,7 @@ cmake_minimum_required(VERSION 3.5)
 # Set project name and version number
 
 project(DOLFIN)
-set(DOLFIN_VERSION_RELEASE 0)
+set(DOLFIN_VERSION_RELEASE 1)
 set(DOLFIN_VERSION_MAJOR "2017")
 set(DOLFIN_VERSION_MINOR "2")
 set(DOLFIN_VERSION_MICRO "0")
@@ -85,11 +85,11 @@ option(DOLFIN_DEPRECATION_ERROR "Turn deprecation warnings into errors." OFF)
 option(DOLFIN_ENABLE_BENCHMARKS "Enable benchmark programs." OFF)
 option(DOLFIN_ENABLE_CODE_COVERAGE "Enable code coverage." OFF)
 option(DOLFIN_ENABLE_DOCS "Enable generation of documentation." ON)
-option(DOLFIN_ENABLE_GTEST "Enable C++ unit tests with Google Test if DOLFIN_ENABLE_TESTING is true (requires Internet connection to download Google Test when first configured)." ON)
 option(DOLFIN_ENABLE_TESTING "Enable testing." OFF)
 option(DOLFIN_IGNORE_PETSC4PY_VERSION "Ignore version of PETSc4py." OFF)
 option(DOLFIN_SKIP_BUILD_TESTS "Skip build tests for testing usability of dependency packages." OFF)
 option(DOLFIN_WITH_LIBRARY_VERSION "Build with library version information." ON)
+option(DOLFIN_ENABLE_GEOMETRY_DEBUGGING "Enable geometry debugging (developers only; requires libcgal-dev and libcgal-qt5-dev)." OFF)
 
 add_feature_info(BUILD_SHARED_LIBS BUILD_SHARED_LIBS "Build DOLFIN with shared libraries.")
 add_feature_info(CMAKE_USE_RELATIVE_PATHS CMAKE_USE_RELATIVE_PATHS "Use relative paths in makefiles and projects.")
@@ -97,12 +97,12 @@ add_feature_info(DOLFIN_AUTO_DETECT_MPI DOLFIN_AUTO_DETECT_MPI "Detect MPI autom
 add_feature_info(DOLFIN_ENABLE_CODE_COVERAGE DOLFIN_ENABLE_CODE_COVERAGE "Enable code coverage.")
 add_feature_info(DOLFIN_WITH_LIBRARY_VERSION DOLFIN_WITH_LIBRARY_VERSION "Build with library version information.")
 add_feature_info(DOLFIN_ENABLE_TESTING DOLFIN_ENABLE_TESTING "Enable testing.")
-add_feature_info(DOLFIN_ENABLE_GTEST DOLFIN_ENABLE_GTEST "Enable C++ unit tests with Google Test if DOLFIN_ENABLE_TESTING is true (requires Internet connection to download Google Test when first configured).")
 add_feature_info(DOLFIN_ENABLE_BENCHMARKS DOLFIN_ENABLE_BENCHMARKS "Enable benchmark programs.")
 add_feature_info(DOLFIN_ENABLE_DOCS DOLFIN_ENABLE_DOCS "Enable generation of documentation.")
 add_feature_info(DOLFIN_SKIP_BUILD_TESTS DOLFIN_SKIP_BUILD_TESTS "Skip build tests for testing usability of dependency packages.")
 add_feature_info(DOLFIN_DEPRECATION_ERROR DOLFIN_DEPRECATION_ERROR "Turn deprecation warnings into errors.")
 add_feature_info(DOLFIN_IGNORE_PETSC4PY_VERSION DOLFIN_IGNORE_PETSC4PY_VERSION "Ignore version of PETSc4py.")
+add_feature_info(DOLFIN_ENABLE_GEOMETRY_DEBUGGING DOLFIN_ENABLE_GEOMETRY_DEBUGGING "Enable geometry debugging.")
 
 # Add shared library paths so shared libs in non-system paths are found
 option(CMAKE_INSTALL_RPATH_USE_LINK_PATH "Add paths to linker search and installed rpath." ON)
@@ -283,7 +283,7 @@ set_package_properties(Boost PROPERTIES TYPE REQUIRED
   URL "http://www.boost.org")
 
 # Check for required package Eigen3
-find_package(Eigen3 3.2.8 REQUIRED)
+find_package(Eigen3 3.2.90 REQUIRED)
 set_package_properties(Eigen3 PROPERTIES TYPE REQUIRED
   DESCRIPTION "Lightweight C++ template library for linear algebra"
   URL "http://eigen.tuxfamily.org")
@@ -294,6 +294,7 @@ set_package_properties(Eigen3 PROPERTIES TYPE REQUIRED
 # Note: Check for Python interpreter even when Python is disabled
 #       because it is used to get the installation path for
 #       dolfin_utils
+
 if (DOLFIN_USE_PYTHON3)
   find_package(PythonInterp 3)
 else()
@@ -479,7 +480,10 @@ if (DOLFIN_ENABLE_HDF5)
   if (NOT DEFINED ENV{HDF5_ROOT})
     set(ENV{HDF5_ROOT} "$ENV{HDF5_DIR}")
   endif()
-  set(HDF5_PREFER_PARALLEL TRUE)
+  set(HDF5_PREFER_PARALLEL FALSE)
+  if (DOLFIN_ENABLE_MPI)
+    set(HDF5_PREFER_PARALLEL TRUE)
+  endif()
   find_package(HDF5 COMPONENTS C)
   set_package_properties(HDF5 PROPERTIES TYPE OPTIONAL
     DESCRIPTION "Hierarchical Data Format 5 (HDF5)"
@@ -579,6 +583,23 @@ if (DOLFIN_ENABLE_DOCS AND PYTHON_FOUND)
     PURPOSE "Needed to build documentation")
 endif()
 
+# Check for geometry debugging
+if (DOLFIN_ENABLE_GEOMETRY_DEBUGGING)
+  message(STATUS "Enabling geometry debugging")
+  find_package(CGAL REQUIRED)
+  find_package(GMP REQUIRED)
+  find_package(MPFR REQUIRED)
+  if (NOT CGAL_FOUND)
+    message(FATAL_ERROR "Unable to find package CGAL required for DOLFIN_ENABLE_GEOMETRY_DEBUGGING")
+  endif()
+  if (NOT GMP_FOUND)
+    message(FATAL_ERROR "Unable to find package GMP required for DOLFIN_ENABLE_GEOMETRY_DEBUGGING")
+  endif()
+  if (NOT MPFR_FOUND)
+    message(FATAL_ERROR "Unable to find package MPFR required for DOLFIN_ENABLE_GEOMETRY_DEBUGGING")
+  endif()
+endif()
+
 #------------------------------------------------------------------------------
 # Print summary of found and not found optional packages
 
@@ -962,24 +983,13 @@ endif()
 
 if (DOLFIN_ENABLE_TESTING)
 
-  # Google Test needs to be downloaded and compiled by CMake, so we
-  # handle it as a special case.
-  if (DOLFIN_ENABLE_GTEST)
-    # Add sub directory to build GoogleTest
-    add_subdirectory(test/unit)
-
-    # Add target "unittests_cpp", but do not add to default target
-    add_subdirectory(test/unit/cpp EXCLUDE_FROM_ALL)
+  # Add target "unittests_cpp", but do not add to default target
+  add_subdirectory(test/unit/cpp EXCLUDE_FROM_ALL)
 
-    # Add target "run_unittests_cpp" for running only C++ unit tests
-    add_custom_target(run_unittests_cpp
-      COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test/unit/cpp/unittests_cpp
-      DEPENDS copy_data_test_demo unittests_cpp)
-  else()
-    # Add dummy targets for C++ unit tests
-    add_custom_target(unittests_cpp)
-    add_custom_target(run_unittests_cpp)
-  endif()
+  # Add target "run_unittests_cpp" for running only C++ unit tests
+  add_custom_target(run_unittests_cpp
+    COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test/unit/cpp/unittests_cpp
+    DEPENDS copy_data_test_demo unittests_cpp)
 
   # FIXME: remove this buildbot updated to call unittests_cpp
   # Add alias for unittests_cpp
diff --git a/ChangeLog.rst b/ChangeLog.rst
index 0cf576d..9c88be7 100644
--- a/ChangeLog.rst
+++ b/ChangeLog.rst
@@ -4,6 +4,12 @@ Change log
 2017.2.0 (2017-09-25)
 ---------------------
 
+- Remove ``UnitQuadMesh`` and ``UnitHexMesh``. Now use ``UnitSquareMesh`` and
+  ``UnitCubeMesh`` with cell type qualifiers.
+- Remove ``MeshEditor::open`` without cell type. Now you must explicitly
+  specify CellType when opening a ``Mesh`` with ``MeshEditor``.
+- Rename ``Mesh::size_global`` to ``Mesh::num_entities_global``.
+- Remove ``Mesh::size``. Use ``Mesh::num_entities`` instead.
 - Improved mesh topology computation performance.
 - Remove excessive calls to MPI init. It may now be necessary in some
   cases to explicitly intialise MPI.
@@ -38,6 +44,13 @@ Change log
   elements.
 - Updates for some demos and tests to show usage of quadrilateral and
   hexahedral meshes.
+- Deprecate ``CellSize`` (equivalent to ``2*Circumradius``)
+  in favour of new ``CellDiameter``; add ``MinCellEdgeLength``
+  and ``MaxCellEdgeLength``
+- Deprecate subclassing of ``Expression`` in Python; new Python class
+  ``UserExpression`` introduced for user overloads
+- Deprecate ``VertexFunction``, ``EdgeFunction``, ``FaceFunction``,
+  ``FacetFunction``, ``CellFunction``; use ``MeshFunction`` instead
 
 
 2017.1.0 (2017-05-09)
diff --git a/bench/fem/jit/python/bench_fem_jit_python b/bench/fem/jit/python/bench_fem_jit_python
index 7e94bf6..a411c81 100755
--- a/bench/fem/jit/python/bench_fem_jit_python
+++ b/bench/fem/jit/python/bench_fem_jit_python
@@ -50,7 +50,7 @@ p1 = Function(Q)
 W  = Function(DGv)
 nu = Constant(0.1)
 k  = Constant(0.1)
-h  = CellSize(mesh)
+h  = 2*Circumradius(mesh)
 d1 = h
 d2 = 2.0*h
 
diff --git a/cmake/modules/FindGMP.cmake b/cmake/modules/FindGMP.cmake
new file mode 100644
index 0000000..820f402
--- /dev/null
+++ b/cmake/modules/FindGMP.cmake
@@ -0,0 +1,19 @@
+# Try to find the GMP librairies
+# GMP_FOUND - system has GMP lib
+# GMP_INCLUDE_DIR - the GMP include directory
+# GMP_LIBRARIES - Libraries needed to use GMP
+
+if (GMP_INCLUDE_DIR AND GMP_LIBRARIES)
+		# Already in cache, be silent
+		set(GMP_FIND_QUIETLY TRUE)
+endif (GMP_INCLUDE_DIR AND GMP_LIBRARIES)
+
+find_path(GMP_INCLUDE_DIR NAMES gmp.h )
+find_library(GMP_LIBRARIES NAMES gmp libgmp )
+find_library(GMPXX_LIBRARIES NAMES gmpxx libgmpxx )
+MESSAGE(STATUS "GMP libs: " ${GMP_LIBRARIES} " " ${GMPXX_LIBRARIES} )
+
+include(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(GMP DEFAULT_MSG GMP_INCLUDE_DIR GMP_LIBRARIES)
+
+mark_as_advanced(GMP_INCLUDE_DIR GMP_LIBRARIES)
diff --git a/cmake/modules/FindMPFR.cmake b/cmake/modules/FindMPFR.cmake
new file mode 100644
index 0000000..094aa2d
--- /dev/null
+++ b/cmake/modules/FindMPFR.cmake
@@ -0,0 +1,83 @@
+# Try to find the MPFR library
+# See http://www.mpfr.org/
+#
+# This module supports requiring a minimum version, e.g. you can do
+#   find_package(MPFR 2.3.0)
+# to require version 2.3.0 to newer of MPFR.
+#
+# Once done this will define
+#
+#  MPFR_FOUND - system has MPFR lib with correct version
+#  MPFR_INCLUDES - the MPFR include directory
+#  MPFR_LIBRARIES - the MPFR library
+#  MPFR_VERSION - MPFR version
+
+# Copyright (c) 2006, 2007 Montel Laurent, <montel at kde.org>
+# Copyright (c) 2008, 2009 Gael Guennebaud, <g.gael at free.fr>
+# Copyright (c) 2010 Jitse Niesen, <jitse at maths.leeds.ac.uk>
+# Redistribution and use is allowed according to the terms of the BSD license.
+
+# Set MPFR_INCLUDES
+
+find_path(MPFR_INCLUDES
+  NAMES
+  mpfr.h
+  PATHS
+  $ENV{GMPDIR}
+  ${INCLUDE_INSTALL_DIR}
+)
+
+# Set MPFR_FIND_VERSION to 1.0.0 if no minimum version is specified
+
+if(NOT MPFR_FIND_VERSION)
+  if(NOT MPFR_FIND_VERSION_MAJOR)
+    set(MPFR_FIND_VERSION_MAJOR 1)
+  endif(NOT MPFR_FIND_VERSION_MAJOR)
+  if(NOT MPFR_FIND_VERSION_MINOR)
+    set(MPFR_FIND_VERSION_MINOR 0)
+  endif(NOT MPFR_FIND_VERSION_MINOR)
+  if(NOT MPFR_FIND_VERSION_PATCH)
+    set(MPFR_FIND_VERSION_PATCH 0)
+  endif(NOT MPFR_FIND_VERSION_PATCH)
+
+  set(MPFR_FIND_VERSION "${MPFR_FIND_VERSION_MAJOR}.${MPFR_FIND_VERSION_MINOR}.${MPFR_FIND_VERSION_PATCH}")
+endif(NOT MPFR_FIND_VERSION)
+
+
+if(MPFR_INCLUDES)
+
+  # Set MPFR_VERSION
+
+  file(READ "${MPFR_INCLUDES}/mpfr.h" _mpfr_version_header)
+
+  string(REGEX MATCH "define[ \t]+MPFR_VERSION_MAJOR[ \t]+([0-9]+)" _mpfr_major_version_match "${_mpfr_version_header}")
+  set(MPFR_MAJOR_VERSION "${CMAKE_MATCH_1}")
+  string(REGEX MATCH "define[ \t]+MPFR_VERSION_MINOR[ \t]+([0-9]+)" _mpfr_minor_version_match "${_mpfr_version_header}")
+  set(MPFR_MINOR_VERSION "${CMAKE_MATCH_1}")
+  string(REGEX MATCH "define[ \t]+MPFR_VERSION_PATCHLEVEL[ \t]+([0-9]+)" _mpfr_patchlevel_version_match "${_mpfr_version_header}")
+  set(MPFR_PATCHLEVEL_VERSION "${CMAKE_MATCH_1}")
+
+  set(MPFR_VERSION ${MPFR_MAJOR_VERSION}.${MPFR_MINOR_VERSION}.${MPFR_PATCHLEVEL_VERSION})
+
+  # Check whether found version exceeds minimum version
+
+  if(${MPFR_VERSION} VERSION_LESS ${MPFR_FIND_VERSION})
+    set(MPFR_VERSION_OK FALSE)
+    message(STATUS "MPFR version ${MPFR_VERSION} found in ${MPFR_INCLUDES}, "
+                   "but at least version ${MPFR_FIND_VERSION} is required")
+  else(${MPFR_VERSION} VERSION_LESS ${MPFR_FIND_VERSION})
+    set(MPFR_VERSION_OK TRUE)
+  endif(${MPFR_VERSION} VERSION_LESS ${MPFR_FIND_VERSION})
+
+endif(MPFR_INCLUDES)
+
+# Set MPFR_LIBRARIES
+
+find_library(MPFR_LIBRARIES mpfr PATHS $ENV{GMPDIR} ${LIB_INSTALL_DIR})
+
+# Epilogue
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(MPFR DEFAULT_MSG
+                                  MPFR_INCLUDES MPFR_LIBRARIES MPFR_VERSION_OK)
+mark_as_advanced(MPFR_INCLUDES MPFR_LIBRARIES)
diff --git a/cmake/templates/dolfin.conf.in b/cmake/templates/dolfin.conf.in
index da5d33f..2e5be4f 100644
--- a/cmake/templates/dolfin.conf.in
+++ b/cmake/templates/dolfin.conf.in
@@ -7,8 +7,5 @@ export PKG_CONFIG_PATH=@CMAKE_INSTALL_PREFIX@/@DOLFIN_PKGCONFIG_DIR@:$PKG_CONFIG
 export PYTHONPATH=@DOLFIN_INSTALL_PYTHON_MODULE_DIR@:@DOLFIN_INSTALL_PYTHON_PURE_MODULE_DIR@:$PYTHONPATH
 export MANPATH=@CMAKE_INSTALL_PREFIX@/@DOLFIN_MAN_DIR@:$MANPATH
 
-# Helper to find VTK if not installed in a system path
-export @OS_LIBRARY_PATH_NAME@=@VTK_INSTALL_PREFIX@/lib:$@OS_LIBRARY_PATH_NAME@
-
 # Special Mac variables
 export DYLD_FRAMEWORK_PATH=/opt/local/Library/Frameworks:$DYLD_FRAMEWORK_PATH
diff --git a/demo/CMakeLists.txt b/demo/CMakeLists.txt
index 44fa7cd..c2b41af 100644
--- a/demo/CMakeLists.txt
+++ b/demo/CMakeLists.txt
@@ -67,8 +67,8 @@ if (DOLFIN_FOUND)
   add_subdirectory(undocumented/mesh-quality/cpp)
   #add_subdirectory(undocumented/mixed-poisson-sphere/cpp)
   #add_subdirectory(undocumented/mplot/cpp)
-  #add_subdirectory(undocumented/multimesh/cpp)
   add_subdirectory(undocumented/multimesh-poisson/cpp)
+  #add_subdirectory(undocumented/multimesh-quadrature/cpp)
   add_subdirectory(undocumented/multimesh-stokes/cpp)
   add_subdirectory(undocumented/meshfunction-refinement/cpp)
   #add_subdirectory(undocumented/multistage-solver/cpp)
diff --git a/demo/documented/bcs/python/demo_bcs.py b/demo/documented/bcs/python/demo_bcs.py
index f36be4a..6485199 100644
--- a/demo/documented/bcs/python/demo_bcs.py
+++ b/demo/documented/bcs/python/demo_bcs.py
@@ -46,7 +46,7 @@ u2 = Constant(2.0)
 u3 = Constant(3.0)
 
 if has_pybind11():
-    markers = FacetFunction("size_t", mesh, 9999)
+    markers = MeshFunction("size_t", mesh, mesh.topology().dim()-1, 9999)
     for (f, v) in mesh.domains().markers(mesh.topology().dim()-1).items():
         markers[f] = v
 
diff --git a/demo/documented/biharmonic/cpp/Biharmonic.ufl.rst b/demo/documented/biharmonic/cpp/Biharmonic.ufl.rst
index 13b69d8..8033eb3 100644
--- a/demo/documented/biharmonic/cpp/Biharmonic.ufl.rst
+++ b/demo/documented/biharmonic/cpp/Biharmonic.ufl.rst
@@ -24,7 +24,7 @@ regenerating the code. ::
 
    # Normal component, mesh size and right-hand side
    n  = FacetNormal(triangle)
-   h = 2.0*Circumradius(triangle)
+   h = CellDiameter(triangle)
    h_avg = (h('+') + h('-'))/2
 
    # Parameters
diff --git a/demo/documented/biharmonic/python/demo_biharmonic.py.rst b/demo/documented/biharmonic/python/demo_biharmonic.py.rst
index fe1e836..96d589b 100644
--- a/demo/documented/biharmonic/python/demo_biharmonic.py.rst
+++ b/demo/documented/biharmonic/python/demo_biharmonic.py.rst
@@ -157,7 +157,7 @@ the penalty parameter ``alpha``. The penalty parameters is made a
 can be changed without needing to regenerate code. ::
 
     # Define normal component, mesh size and right-hand side
-    h = CellSize(mesh)
+    h = CellDiameter(mesh)
     h_avg = (h('+') + h('-'))/2.0
     n = FacetNormal(mesh)
     f = Source(degree=2)
diff --git a/demo/documented/cahn-hilliard/cpp/documentation.rst b/demo/documented/cahn-hilliard/cpp/documentation.rst
index fb1db3f..6f23b69 100644
--- a/demo/documented/cahn-hilliard/cpp/documentation.rst
+++ b/demo/documented/cahn-hilliard/cpp/documentation.rst
@@ -313,7 +313,8 @@ A mesh is then created with 97 (96 + 1) vertices in each direction:
 .. code-block:: c++
 
     // Mesh
-    auto mesh = std::make_shared<Mesh>(UnitQuadMesh::create(96, 96));
+    auto mesh = std::make_shared<Mesh>(
+      UnitSquareMesh::create({{96, 96}}, CellType::Type::quadrilateral));
 
 A set of constants (required for the assembling of the forms) and two
 scalars (to be used in the time stepping) are then declared:
diff --git a/demo/documented/cahn-hilliard/cpp/main.cpp b/demo/documented/cahn-hilliard/cpp/main.cpp
index c21605a..afa1156 100644
--- a/demo/documented/cahn-hilliard/cpp/main.cpp
+++ b/demo/documented/cahn-hilliard/cpp/main.cpp
@@ -78,7 +78,9 @@ int main(int argc, char* argv[])
   dolfin::init(argc, argv);
 
   // Mesh
-  auto mesh = std::make_shared<Mesh>(UnitQuadMesh::create(96, 96));
+  auto mesh = std::make_shared<Mesh>(
+    UnitSquareMesh::create({{96, 96}}, CellType::Type::quadrilateral));
+
 
   // Create function space and forms, depending on spatial dimension
   // of the mesh
diff --git a/demo/documented/cahn-hilliard/python/demo_cahn-hilliard.py.rst b/demo/documented/cahn-hilliard/python/demo_cahn-hilliard.py.rst
index 8a1fba7..9a816fe 100644
--- a/demo/documented/cahn-hilliard/python/demo_cahn-hilliard.py.rst
+++ b/demo/documented/cahn-hilliard/python/demo_cahn-hilliard.py.rst
@@ -195,7 +195,7 @@ created, and on this mesh a :py:class:`FunctionSpace
 a pair of linear Lagrangian elements. ::
 
     # Create mesh and build function space
-    mesh = UnitQuadMesh.create(96, 96)
+    mesh = UnitSquareMesh.create(96, 96, CellType.Type_quadrilateral)
     P1 = FiniteElement("Lagrange", mesh.ufl_cell(), 1)
     ME = FunctionSpace(mesh, P1*P1)
 
diff --git a/demo/documented/neumann-poisson/cpp/main.cpp b/demo/documented/neumann-poisson/cpp/main.cpp
index fd3646d..c7360ef 100644
--- a/demo/documented/neumann-poisson/cpp/main.cpp
+++ b/demo/documented/neumann-poisson/cpp/main.cpp
@@ -70,7 +70,8 @@ class Flux : public Expression
 int main()
 {
   // Create mesh and function space
-  auto mesh = std::make_shared<Mesh>(UnitQuadMesh::create(64, 64));
+  auto mesh = std::make_shared<Mesh>(
+    UnitSquareMesh::create({{64, 64}}, CellType::Type::quadrilateral));
   auto V = std::make_shared<Poisson::FunctionSpace>(mesh);
 
   // Define variational problem
diff --git a/demo/documented/neumann-poisson/python/demo_neumann-poisson.py.rst b/demo/documented/neumann-poisson/python/demo_neumann-poisson.py.rst
index 1d81973..560577c 100644
--- a/demo/documented/neumann-poisson/python/demo_neumann-poisson.py.rst
+++ b/demo/documented/neumann-poisson/python/demo_neumann-poisson.py.rst
@@ -22,12 +22,12 @@ First, the :py:mod:`dolfin` module is imported: ::
     from dolfin import *
 
 We proceed by defining a mesh of the domain.  We use a built-in mesh
-provided by the class :py:class:`UnitQuadMesh
-<dolfin.cpp.UnitQuadMesh>`.  In order to create a mesh consisting of
+provided by the class :py:class:`UnitSquareMesh
+<dolfin.cpp.UnitSquareMesh>`.  In order to create a mesh consisting of
 :math:`64 \times 64` squares, we do as follows: ::
 
     # Create mesh
-    mesh = UnitQuadMesh.create(64, 64)
+    mesh = UnitSquareMesh.create(64, 64, CellType.Type_quadrilateral)
 
 Next, we need to define the function space. ::
 
diff --git a/demo/documented/poisson/cpp/main.cpp.rst b/demo/documented/poisson/cpp/main.cpp.rst
index 90e3de9..daf1828 100644
--- a/demo/documented/poisson/cpp/main.cpp.rst
+++ b/demo/documented/poisson/cpp/main.cpp.rst
@@ -144,7 +144,8 @@ the form file) defined relative to this mesh, we do as follows
    int main()
    {
      // Create mesh and function space
-     auto mesh = std::make_shared<Mesh>(UnitSquareMesh::create({{32, 32}}));
+     auto mesh = std::make_shared<Mesh>(
+       UnitSquareMesh::create({{32, 32}}, CellType::Type::triangle));
      auto V = std::make_shared<Poisson::FunctionSpace>(mesh);
 
 Now, the Dirichlet boundary condition (:math:`u = 0`) can be created
diff --git a/demo/documented/stokes-iterative/cpp/main.cpp b/demo/documented/stokes-iterative/cpp/main.cpp
index de336b0..69d1fec 100644
--- a/demo/documented/stokes-iterative/cpp/main.cpp
+++ b/demo/documented/stokes-iterative/cpp/main.cpp
@@ -100,7 +100,8 @@ int main()
   }
 
   // Create mesh
-  auto mesh = std::make_shared<Mesh>(UnitHexMesh::create(16, 16, 16));
+  auto mesh = std::make_shared<Mesh>(
+    UnitCubeMesh::create({{16, 16, 16}}, CellType::Type::hexahedron));
 
   // Create function space and subspaces
   auto W = std::make_shared<Stokes::FunctionSpace>(mesh);
diff --git a/demo/documented/stokes-iterative/python/demo_stokes-iterative.py.rst b/demo/documented/stokes-iterative/python/demo_stokes-iterative.py.rst
index f908f45..8e208e4 100644
--- a/demo/documented/stokes-iterative/python/demo_stokes-iterative.py.rst
+++ b/demo/documented/stokes-iterative/python/demo_stokes-iterative.py.rst
@@ -57,8 +57,8 @@ If not available, costly QMR method is choosen. ::
              "Krylov subspace method. Terminating.")
         exit()
 
-Next, we define the mesh (a :py:class:`UnitHexMesh
-<dolfin.cpp.UnitHexMesh>`) and a mixed finite element ``TH``.
+Next, we define the mesh (a :py:class:`UnitCubeMesh
+<dolfin.cpp.UnitCubeMesh>`) and a mixed finite element ``TH``.
 Then we build a :py:class:`FunctionSpace
 <dolfin.functions.functionspace.FunctionSpace>` on this element.
 (This mixed finite element space is known as the
@@ -66,7 +66,7 @@ Taylor--Hood elements and is a stable, standard element pair for the
 Stokes equations.) ::
 
     # Load mesh
-    mesh = UnitHexMesh.create(16, 16, 16)
+    mesh = UnitCubeMesh.create(16, 16, 16, CellType.Type_hexahedron)
 
     # Build function space
     P2 = VectorElement("Lagrange", mesh.ufl_cell(), 2)
diff --git a/demo/documented/subdomains-poisson/python/demo_subdomains-poisson.py b/demo/documented/subdomains-poisson/python/demo_subdomains-poisson.py
index a4c6600..965d622 100644
--- a/demo/documented/subdomains-poisson/python/demo_subdomains-poisson.py
+++ b/demo/documented/subdomains-poisson/python/demo_subdomains-poisson.py
@@ -56,12 +56,12 @@ obstacle = Obstacle()
 mesh = UnitSquareMesh(64, 64)
 
 # Initialize mesh function for interior domains
-domains = CellFunction("size_t", mesh)
+domains = MeshFunction("size_t", mesh, mesh.topology().dim())
 domains.set_all(0)
 obstacle.mark(domains, 1)
 
 # Initialize mesh function for boundary domains
-boundaries = FacetFunction("size_t", mesh)
+boundaries = MeshFunction("size_t", mesh, mesh.topology().dim()-1)
 boundaries.set_all(0)
 left.mark(boundaries, 1)
 top.mark(boundaries, 2)
diff --git a/demo/documented/subdomains-poisson/python/documentation.rst b/demo/documented/subdomains-poisson/python/documentation.rst
index 85d8341..dca72a7 100644
--- a/demo/documented/subdomains-poisson/python/documentation.rst
+++ b/demo/documented/subdomains-poisson/python/documentation.rst
@@ -84,16 +84,8 @@ We next define a mesh of the domain:
 
 The above subdomains are defined with the sole purpose of populating
 mesh functions. (For more complicated geometries, the mesh functions
-would typically be provided by other means.) The classes
-:py:class:`CellFunction <dolfin.cpp.CellFunction>` and
-:py:class:`FacetFunction <dolfin.cpp.FacetFunction>` are specialized
-versions of the more general :py:class:`MeshFunction
-<dolfin.cpp.MeshFunction>`. :py:class:`CellFunction
-<dolfin.cpp.CellFunction>` represents a function with a value for each
-cell of a mesh, while :py:class:`FacetFunction
-<dolfin.cpp.FacetFunction>` represents a function with a value for
-each facet. We define a :py:class:`CellFunction
-<dolfin.cpp.CellFunction>` to indicate which cells that correspond to
+would typically be provided by other means.) We define a :py:class:`MeshFunction
+<dolfin.cpp.MeshFunction>` over the mesh cells to indicate which cells that correspond to
 the different interior subregions :math:`\Omega_0` and
 :math:`\Omega_1`. Those in the interior rectangle will be tagged by
 `1`, while the remainder is tagged by `0`. We can set all the values
@@ -108,20 +100,21 @@ value):
 .. code-block:: python
 
     # Initialize mesh function for interior domains
-    domains = CellFunction("size_t", mesh)
+    domains = MeshFunction("size_t", mesh, mesh.topology().dim())
     domains.set_all(0)
     obstacle.mark(domains, 1)
 
 
-We can do the same for the boundaries using a :py:class:`FacetFunction
-<dolfin.cpp.FacetFunction>`. We first tag all the edges by ``0``, then
+We can do the same for the boundaries using a :py:class:`MeshFunction
+<dolfin.cpp.MeshFunction>` defined ove the topological dimension `
+mesh.topology().dim()-1`. We first tag all the edges by ``0``, then
 the edges on the left by ``1``, on the top by ``2``, on the right by
 ``3`` and on the bottom by ``4``:
 
 .. code-block:: python
 
     # Initialize mesh function for boundary domains
-    boundaries = FacetFunction("size_t", mesh)
+    boundaries = MeshFunction("size_t", mesh, mesh.topology().dim()-1)
     boundaries.set_all(0)
     left.mark(boundaries, 1)
     top.mark(boundaries, 2)
diff --git a/demo/documented/tensor-weighted-poisson/python/demo_tensor-weighted-poisson.py b/demo/documented/tensor-weighted-poisson/python/demo_tensor-weighted-poisson.py
index e343edd..cb50dfa 100644
--- a/demo/documented/tensor-weighted-poisson/python/demo_tensor-weighted-poisson.py
+++ b/demo/documented/tensor-weighted-poisson/python/demo_tensor-weighted-poisson.py
@@ -104,7 +104,7 @@ public:
 PYBIND11_MODULE(SIGNATURE, m)
 {
   py::class_<Conductivity, std::shared_ptr<Conductivity>, dolfin::Expression>
-    (m, "Conductivity", py::dynamic_attr())
+    (m, "Conductivity")
     .def(py::init<>())
     .def_readwrite("c00", &Conductivity::c00)
     .def_readwrite("c01", &Conductivity::c01)
@@ -112,16 +112,9 @@ PYBIND11_MODULE(SIGNATURE, m)
 }
 
 """
-    class UserConductivity(UserExpression):
-        def value_shape(self):
-            return (3,)
-
-    c = UserConductivity(degree=0)
-    cc = compile_cpp_code(conductivity_code).Conductivity()
-    cc.c00 = c00
-    cc.c01 = c01
-    cc.c11 = c11
-    c._cpp_object = cc
+
+    c = CompiledExpression(compile_cpp_code(conductivity_code).Conductivity(),
+                           c00=c00, c01=c01, c11=c11, degree=0)
 
 else:
     conductivity_code = """
diff --git a/demo/undocumented/advection-diffusion/python/demo_advection-diffusion.py b/demo/undocumented/advection-diffusion/python/demo_advection-diffusion.py
index 1779548..d80ef50 100644
--- a/demo/undocumented/advection-diffusion/python/demo_advection-diffusion.py
+++ b/demo/undocumented/advection-diffusion/python/demo_advection-diffusion.py
@@ -37,7 +37,7 @@ def boundary_value(n):
 # Load mesh and subdomains
 mesh = Mesh("../dolfin_fine.xml.gz")
 sub_domains = MeshFunction("size_t", mesh, "../dolfin_fine_subdomains.xml.gz");
-h = CellSize(mesh)
+h = CellDiameter(mesh)
 
 # Create FunctionSpaces
 Q = FunctionSpace(mesh, "CG", 1)
diff --git a/demo/undocumented/auto-adaptive-navier-stokes/cpp/main.cpp b/demo/undocumented/auto-adaptive-navier-stokes/cpp/main.cpp
index 77559ef..ca44a1c 100644
--- a/demo/undocumented/auto-adaptive-navier-stokes/cpp/main.cpp
+++ b/demo/undocumented/auto-adaptive-navier-stokes/cpp/main.cpp
@@ -68,7 +68,7 @@ int main()
   // Define boundary condition
   auto u0 = std::make_shared<Constant>(0.0, 0.0);
   Noslip noslip;
-  auto noslip_markers = std::make_shared<FacetFunction<std::size_t>>(mesh, 1);
+  auto noslip_markers = std::make_shared<MeshFunction<std::size_t>>(mesh, mesh->topology().dim()-1, 1);
   noslip.mark(*noslip_markers, 0);
   auto W0 = W->sub(0);
   auto bc = std::make_shared<DirichletBC>(W0, u0, noslip_markers, 0);
@@ -90,7 +90,7 @@ int main()
   auto M = std::make_shared<AdaptiveNavierStokes::GoalFunctional>(mesh);
   M->w = w;
   Outflow outflow;
-  auto outflow_markers = std::make_shared<FacetFunction<std::size_t>>(mesh, 1);
+  auto outflow_markers = std::make_shared<MeshFunction<std::size_t>>(mesh, mesh->topology().dim()-1, 1);
   outflow.mark(*outflow_markers, 0);
   M->ds = outflow_markers;
 
diff --git a/demo/undocumented/buckling-tao/python/demo_buckling-tao.py b/demo/undocumented/buckling-tao/python/demo_buckling-tao.py
index deb124c..13fd16b 100644
--- a/demo/undocumented/buckling-tao/python/demo_buckling-tao.py
+++ b/demo/undocumented/buckling-tao/python/demo_buckling-tao.py
@@ -74,7 +74,7 @@ class Left(SubDomain):
 class Right(SubDomain):
     def inside(self, x, on_boundary):
         return on_boundary and near(x[0], 10)
-boundaries = FacetFunction("size_t", mesh)
+boundaries = MeshFunction("size_t", mesh, mesh.topology().dim()-1)
 boundaries.set_all(0)
 left = Left()
 left.mark(boundaries, 1)
diff --git a/demo/undocumented/collision-detection/python/demo_collision-detection.py b/demo/undocumented/collision-detection/python/demo_collision-detection.py
index 535f28a..6d6a2c0 100644
--- a/demo/undocumented/collision-detection/python/demo_collision-detection.py
+++ b/demo/undocumented/collision-detection/python/demo_collision-detection.py
@@ -40,7 +40,7 @@ mesh_B.translate(Point(x_B, y_B))
 mesh_C.translate(Point(x_C, y_C))
 
 # Create mesh function for plotting
-f = CellFunction("size_t", mesh_A)
+f = MeshFunction("size_t", mesh_A, mesh_A.topology().dim())
 
 # Build bounding box trees for background mesh
 tree_A = BoundingBoxTree()
diff --git a/demo/undocumented/curl-curl/python/demo_curl-curl.py b/demo/undocumented/curl-curl/python/demo_curl-curl.py
index 34f68a1..c8ace04 100644
--- a/demo/undocumented/curl-curl/python/demo_curl-curl.py
+++ b/demo/undocumented/curl-curl/python/demo_curl-curl.py
@@ -60,7 +60,7 @@ if not has_petsc4py():
     exit()
 
 # Import petsc4py and check that HYPRE bindings are available
-from petsc4py import *
+from petsc4py import PETSc
 try:
     getattr(PETSc.PC, 'getHYPREType')
 except AttributeError:
diff --git a/demo/undocumented/dg-advection-diffusion/cpp/AdvectionDiffusion.ufl b/demo/undocumented/dg-advection-diffusion/cpp/AdvectionDiffusion.ufl
index 9e5c996..ba67f5d 100644
--- a/demo/undocumented/dg-advection-diffusion/cpp/AdvectionDiffusion.ufl
+++ b/demo/undocumented/dg-advection-diffusion/cpp/AdvectionDiffusion.ufl
@@ -32,7 +32,7 @@ v   = TestFunction(scalar)
 
 u = Coefficient(vector)
 f = Coefficient(scalar)
-h = 2.0*Circumradius(cell)
+h = CellDiameter(cell)
 h_avg = (h('+') + h('-'))/2
 n = FacetNormal(cell)
 
diff --git a/demo/undocumented/dg-advection-diffusion/python/demo_dg-advection-diffusion.py b/demo/undocumented/dg-advection-diffusion/python/demo_dg-advection-diffusion.py
index 082154f..747dda3 100644
--- a/demo/undocumented/dg-advection-diffusion/python/demo_dg-advection-diffusion.py
+++ b/demo/undocumented/dg-advection-diffusion/python/demo_dg-advection-diffusion.py
@@ -61,7 +61,7 @@ alpha = Constant(5.0)
 
 # Mesh-related functions
 n = FacetNormal(mesh)
-h = CellSize(mesh)
+h = CellDiameter(mesh)
 h_avg = (h('+') + h('-'))/2
 
 # ( dot(v, n) + |dot(v, n)| )/2.0
diff --git a/demo/undocumented/dg-poisson/cpp/Poisson.ufl b/demo/undocumented/dg-poisson/cpp/Poisson.ufl
index 9a9fb4d..fc48abc 100644
--- a/demo/undocumented/dg-poisson/cpp/Poisson.ufl
+++ b/demo/undocumented/dg-poisson/cpp/Poisson.ufl
@@ -34,7 +34,7 @@ u0 = Coefficient(element)
 g  = Coefficient(element)
 
 # Normal component, cell size and right-hand side
-h = 2.0*Circumradius(triangle)
+h = CellDiameter(triangle)
 h_avg = (h('+') + h('-'))/2
 n = FacetNormal(triangle)
 
diff --git a/demo/undocumented/dg-poisson/cpp/main.cpp b/demo/undocumented/dg-poisson/cpp/main.cpp
index c3ad1f9..ef7ecf3 100644
--- a/demo/undocumented/dg-poisson/cpp/main.cpp
+++ b/demo/undocumented/dg-poisson/cpp/main.cpp
@@ -105,7 +105,7 @@ int main()
   NeumannBoundary neumann_boundary;
   DirichletBoundary dirichlet_boundary;
 
-  auto boundaries = std::make_shared<FacetFunction<std::size_t>>(mesh, 0);
+  auto boundaries = std::make_shared<MeshFunction<std::size_t>>(mesh, mesh->topology().dim()-1, 0);
   neumann_boundary.mark(*boundaries, 2);
   dirichlet_boundary.mark(*boundaries, 1);
 
diff --git a/demo/undocumented/dg-poisson/python/demo_dg-poisson.py b/demo/undocumented/dg-poisson/python/demo_dg-poisson.py
index 8b4a65c..9061577 100644
--- a/demo/undocumented/dg-poisson/python/demo_dg-poisson.py
+++ b/demo/undocumented/dg-poisson/python/demo_dg-poisson.py
@@ -62,7 +62,7 @@ v = TestFunction(V)
 
 # Define normal vector and mesh size
 n = FacetNormal(mesh)
-h = CellSize(mesh)
+h = CellDiameter(mesh)
 h_avg = (h('+') + h('-'))/2
 
 # Define the source term f, Dirichlet term u0 and Neumann term g
@@ -71,7 +71,7 @@ u0 = Expression('x[0] + 0.25*sin(2*pi*x[1])', degree=2)
 g = Expression('(x[1] - 0.5)*(x[1] - 0.5)', degree=2)
 
 # Mark facets of the mesh
-boundaries = FacetFunction('size_t', mesh, 0)
+boundaries = MeshFunction('size_t', mesh, mesh.topology().dim()-1, 0)
 NeumanBoundary().mark(boundaries, 2)
 DirichletBoundary().mark(boundaries, 1)
 
diff --git a/demo/undocumented/elasticity/cpp/main.cpp b/demo/undocumented/elasticity/cpp/main.cpp
index e0dec0d..6af2c3d 100644
--- a/demo/undocumented/elasticity/cpp/main.cpp
+++ b/demo/undocumented/elasticity/cpp/main.cpp
@@ -195,8 +195,8 @@ int main()
   // Save colored mesh paritions in VTK format if running in parallel
   if (dolfin::MPI::size(mesh->mpi_comm()) > 1)
   {
-    CellFunction<std::size_t>
-      partitions(mesh, dolfin::MPI::rank(mesh->mpi_comm()));
+    MeshFunction<std::size_t>
+      partitions(mesh, mesh->topology().dim(), dolfin::MPI::rank(mesh->mpi_comm()));
     File file("partitions.pvd");
     file << partitions;
   }
diff --git a/demo/undocumented/elasticity/python/demo_elasticity.py b/demo/undocumented/elasticity/python/demo_elasticity.py
index 387a1a2..586e4a8 100644
--- a/demo/undocumented/elasticity/python/demo_elasticity.py
+++ b/demo/undocumented/elasticity/python/demo_elasticity.py
@@ -143,7 +143,7 @@ File("elasticity.pvd", "compressed") << u
 
 # Save colored mesh partitions in VTK format if running in parallel
 if MPI.size(mesh.mpi_comm()) > 1:
-    File("partitions.pvd") << CellFunction("size_t", mesh, \
+    File("partitions.pvd") << MeshFunction("size_t", mesh, mesh.topology().dim(), \
                                            MPI.rank(mesh.mpi_comm()))
 
 # Project and write stress field to post-processing file
diff --git a/demo/undocumented/ghost-mesh/python/demo_ghost-mesh.py b/demo/undocumented/ghost-mesh/python/demo_ghost-mesh.py
index 2037896..3d42614 100755
--- a/demo/undocumented/ghost-mesh/python/demo_ghost-mesh.py
+++ b/demo/undocumented/ghost-mesh/python/demo_ghost-mesh.py
@@ -142,7 +142,7 @@ for note in verts_note:
 for note in facet_note:
     plt.text(note[0], note[1], note[2], size=8, verticalalignment='center', backgroundcolor=note[3])
 
-# Q = FacetFunction("double", mesh)
+# Q = MeshFunction("double", mesh, mesh.topology().dim()-1)
 
 # # Save solution in XDMF format if available
 # xdmf = XDMFFile(mesh.mpi_comm(), "Q.xdmf")
diff --git a/demo/undocumented/lift-drag/cpp/main.cpp b/demo/undocumented/lift-drag/cpp/main.cpp
index d271037..bc97dc6 100644
--- a/demo/undocumented/lift-drag/cpp/main.cpp
+++ b/demo/undocumented/lift-drag/cpp/main.cpp
@@ -57,7 +57,7 @@ int main()
   auto p = std::make_shared<Function>(Vp, "../dolfin_fine_pressure.xml.gz");
 
   // Mark 'fish'
-  auto markers = std::make_shared<FacetFunction<std::size_t>>(mesh, 1);
+  auto markers = std::make_shared<MeshFunction<std::size_t>>(mesh, mesh->topology().dim()-1, 1);
   Fish fish;
   fish.mark(*markers, 1);
 
diff --git a/demo/undocumented/lift-drag/python/demo_lift-drag.py b/demo/undocumented/lift-drag/python/demo_lift-drag.py
index 1f60c55..aa9781d 100644
--- a/demo/undocumented/lift-drag/python/demo_lift-drag.py
+++ b/demo/undocumented/lift-drag/python/demo_lift-drag.py
@@ -48,7 +48,7 @@ class Fish(SubDomain):
         return x[0] > DOLFIN_EPS and x[0] < (1.0 - DOLFIN_EPS) and \
                x[1] > DOLFIN_EPS and x[1] < (1.0 - DOLFIN_EPS)
 
-markers = FacetFunction("size_t", mesh, 1)
+markers = MeshFunction("size_t", mesh, mesh.topology().dim()-1, 1)
 Fish().mark(markers, 1);
 
 # Define functionals for drag and lift
diff --git a/demo/undocumented/multimesh-3d/cpp/CMakeLists.txt b/demo/undocumented/multimesh-3d/cpp/CMakeLists.txt
new file mode 100644
index 0000000..7b0c84a
--- /dev/null
+++ b/demo/undocumented/multimesh-3d/cpp/CMakeLists.txt
@@ -0,0 +1,38 @@
+# This file is automatically generated by running
+#
+#     cmake/scripts/generate-cmakefiles
+#
+# Require CMake 3.5
+cmake_minimum_required(VERSION 3.5)
+
+set(PROJECT_NAME demo_multimesh-3d)
+project(${PROJECT_NAME})
+
+# Set CMake behavior
+cmake_policy(SET CMP0004 NEW)
+
+# Get DOLFIN configuration data (DOLFINConfig.cmake must be in
+# DOLFIN_CMAKE_CONFIG_PATH)
+find_package(DOLFIN REQUIRED)
+
+include(${DOLFIN_USE_FILE})
+
+# Default build type (can be overridden by user)
+if (NOT CMAKE_BUILD_TYPE)
+  set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
+      "Choose the type of build, options are: Debug MinSizeRel Release RelWithDebInfo." FORCE)
+endif()
+
+# Do not throw error for 'multi-line comments' (these are typical in
+# rst which includes LaTeX)
+include(CheckCXXCompilerFlag)
+CHECK_CXX_COMPILER_FLAG("-Wno-comment" HAVE_NO_MULTLINE)
+if (HAVE_NO_MULTLINE)
+  set(CMAKE_CXX_FLAGS "-Wno-comment ${CMAKE_CXX_FLAGS}")
+endif()
+
+# Executable
+add_executable(${PROJECT_NAME} main.cpp)
+
+# Target libraries
+target_link_libraries(${PROJECT_NAME} dolfin)
diff --git a/demo/undocumented/multimesh-3d/cpp/MultiMeshH10Norm.ufl b/demo/undocumented/multimesh-3d/cpp/MultiMeshH10Norm.ufl
new file mode 100644
index 0000000..64ae712
--- /dev/null
+++ b/demo/undocumented/multimesh-3d/cpp/MultiMeshH10Norm.ufl
@@ -0,0 +1,20 @@
+#from L2Norm import *
+
+#M = l2norm(triangle)
+
+from ufl import *
+
+ORDER = 1
+
+domain = triangle
+
+# Define element and FE solution
+P1 = FiniteElement("Lagrange", domain, ORDER)
+uh = Coefficient(P1)
+
+# Exact solution
+P3 = FiniteElement("Lagrange", domain, ORDER + 2)
+u = Coefficient(P3)
+
+# Squared L2 norm of error
+M = inner(grad(u - uh), grad(u - uh))*dX
diff --git a/demo/undocumented/multimesh-3d/cpp/MultiMeshL2Norm.ufl b/demo/undocumented/multimesh-3d/cpp/MultiMeshL2Norm.ufl
new file mode 100644
index 0000000..a726277
--- /dev/null
+++ b/demo/undocumented/multimesh-3d/cpp/MultiMeshL2Norm.ufl
@@ -0,0 +1,20 @@
+#from L2Norm import *
+
+#M = l2norm(triangle)
+
+from ufl import *
+
+ORDER = 1
+
+domain = triangle
+
+# Define element and FE solution
+P1 = FiniteElement("Lagrange", domain, ORDER)
+uh = Coefficient(P1)
+
+# Exact solution
+Px = FiniteElement("Lagrange", domain, ORDER + 2)
+u = Coefficient(Px)
+
+# Squared L2 norm of error
+M = inner(u - uh, u - uh)*dX
diff --git a/demo/undocumented/multimesh-poisson/cpp/MultiMeshPoisson.ufl b/demo/undocumented/multimesh-3d/cpp/MultiMeshPoisson.ufl
similarity index 90%
copy from demo/undocumented/multimesh-poisson/cpp/MultiMeshPoisson.ufl
copy to demo/undocumented/multimesh-3d/cpp/MultiMeshPoisson.ufl
index b7a06fe..e97d6f2 100644
--- a/demo/undocumented/multimesh-poisson/cpp/MultiMeshPoisson.ufl
+++ b/demo/undocumented/multimesh-3d/cpp/MultiMeshPoisson.ufl
@@ -16,7 +16,7 @@
 # along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 #
 # First added:  2013-06-26
-# Last changed: 2015-10-16
+# Last changed: 2017-08-23
 #
 # The bilinear form a(u, v) and linear form L(v) for a multimesh
 # formulation of Poisson's equation.
@@ -24,7 +24,8 @@
 # Compile this form with FFC: ffc -l dolfin MultiMeshPoisson.ufl.
 
 # Define element
-element = FiniteElement("Lagrange", triangle, 1)
+simplex = tetrahedron
+element = FiniteElement("Lagrange", simplex, 1)
 
 # Define trial and test functions and right-hand side
 u = TrialFunction(element)
@@ -32,8 +33,8 @@ v = TestFunction(element)
 f = Coefficient(element)
 
 # Define facet normal and mesh size
-n = FacetNormal(triangle)
-h = 2.0*Circumradius(triangle)
+n = FacetNormal(simplex)
+h = 2.0*Circumradius(simplex)
 h = (h('+') + h('-')) / 2
 
 # Parameters
diff --git a/demo/undocumented/multimesh-3d/cpp/main.cpp b/demo/undocumented/multimesh-3d/cpp/main.cpp
new file mode 100644
index 0000000..d59e20f
--- /dev/null
+++ b/demo/undocumented/multimesh-3d/cpp/main.cpp
@@ -0,0 +1,224 @@
+// Copyright (C) 2017 August Johansson
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN 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 Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added:  2013-08-24
+// Last changed: 2017-08-30
+//
+// This demo program solves Poisson's equation on a domain defined by
+// three overlapping and non-matching meshes. The solution is computed
+// on a sequence of rotating meshes to test the multimesh
+// functionality.
+
+#include <cmath>
+#include <fstream>
+#include <dolfin.h>
+#include "MultiMeshPoisson.h"
+#include "MultiMeshL2Norm.h"
+#include "MultiMeshH10Norm.h"
+
+using namespace dolfin;
+
+class Arguments
+{
+public:
+  std::size_t N = 1;
+  std::size_t Nx = 10;
+
+  std::string print() const
+  {
+    std::stringstream ss;
+    ss << "N" << N<<"_"
+       << "Nx" << Nx;
+    return ss.str();
+  }
+
+  void parse(int argc, char** argv)
+  {
+    std::size_t c = 1;
+
+    if (argc > c)
+    {
+      this->N = atoi(argv[c]);
+      c++;
+      if (argc > c)
+	this->Nx = atoi(argv[c]);
+    }
+  }
+};
+
+
+// Sub domain for Dirichlet boundary condition
+class DirichletBoundary : public SubDomain
+{
+  bool inside(const Array<double>& x, bool on_boundary) const
+  {
+    return on_boundary;
+  }
+};
+
+class ExactSolution : public Expression
+{
+  void eval(Array<double>& values, const Array<double>& x) const
+  {
+    values[0] = sin(DOLFIN_PI*x[0])*sin(DOLFIN_PI*x[1])*sin(DOLFIN_PI*x[2]);
+  }
+};
+
+class Source : public Expression
+{
+  void eval(Array<double>& values, const Array<double>& x) const
+  {
+    values[0] = 3.0*DOLFIN_PI*DOLFIN_PI*sin(DOLFIN_PI*x[0])*sin(DOLFIN_PI*x[1])*sin(DOLFIN_PI*x[2]);
+  }
+};
+
+void build_multimesh(std::size_t N,
+		     std::size_t Nx,
+		     std::shared_ptr<MultiMesh> multimesh,
+		     double& exact_volume)
+{
+  // Background mesh
+  auto mesh_0 = std::make_shared<UnitCubeMesh>(Nx, Nx, Nx);
+  multimesh->add(mesh_0);
+  exact_volume = 1.;
+
+  // Initialize random generator (dolfin built-in)
+  dolfin::seed(1);
+
+  for (std::size_t i = 1; i < N; ++i)
+  {
+    // Create domain range
+    double x_a = dolfin::rand();
+    double x_b = dolfin::rand();
+
+    if (x_a > x_b)
+      std::swap(x_a, x_b);
+    double y_a = dolfin::rand();
+    double y_b = dolfin::rand();
+    if (y_a > y_b)
+      std::swap(y_a, y_b);
+
+    double z_a = dolfin::rand();
+    double z_b = dolfin::rand();
+    if (z_a > z_b)
+      std::swap(z_a, z_b);
+
+    // std::cout << i << ": " << x_a<<' '<<y_a<<' ' << z_a << ", " << x_b<<' '<<y_b << ' ' << z_b <<std::endl;
+
+    // Find number of elements
+    const std::size_t Nx_part = (std::size_t)std::max(std::abs(x_a - x_b)*Nx, 1.);
+    const std::size_t Ny_part = (std::size_t)std::max(std::abs(y_a - y_b)*Nx, 1.);
+    const std::size_t Nz_part = (std::size_t)std::max(std::abs(z_a - z_b)*Nx, 1.);
+
+    // Create mesh
+    auto mesh_i = std::make_shared<BoxMesh>(Point(x_a, y_a, z_a),
+					    Point(x_b, y_b, z_b),
+					    Nx_part, Ny_part, Nz_part);
+    multimesh->add(mesh_i);
+  }
+
+  // Build
+  multimesh->build();
+}
+
+template<class TFunctional>
+double compute_error(const std::shared_ptr<MultiMeshFunctionSpace> V,
+		     const std::shared_ptr<MultiMeshFunction> u_h,
+		     const std::shared_ptr<Expression> u)
+{
+  std::cout << "Compute error" << std::endl;
+
+  auto M = std::make_shared<MultiMeshForm>(V);
+
+  for (std::size_t i = 0; i < V->multimesh()->num_parts(); ++i)
+  {
+    auto M_i = std::make_shared<TFunctional>(V->multimesh()->part(i));
+    const bool deepcopy = true;
+    M_i->uh = std::make_shared<const Function>(*u_h->part(i, deepcopy));
+    M_i->u = u;
+    M->add(M_i);
+  }
+
+  M->build();
+
+  auto assembler = std::make_shared<MultiMeshAssembler>();
+  auto m = std::make_shared<Scalar>();
+  assembler->assemble(*m, *M);
+
+  dolfin_assert(m->get_scalar_value() > 0.);
+  return std::sqrt(m->get_scalar_value());
+}
+
+void solve(const std::shared_ptr<MultiMesh> multimesh)
+{
+  // Create function space
+  auto V = std::make_shared<MultiMeshPoisson::MultiMeshFunctionSpace>(multimesh);
+
+  // Create forms
+  auto a = std::make_shared<MultiMeshPoisson::MultiMeshBilinearForm>(V, V);
+  auto L = std::make_shared<MultiMeshPoisson::MultiMeshLinearForm>(V);
+
+  // Attach source
+  auto f = std::make_shared<Source>();
+  L->f = f;
+
+  // Assemble linear system
+  auto A = std::make_shared<Matrix>();
+  auto b = std::make_shared<Vector>();
+  assemble_multimesh(*A, *a);
+  assemble_multimesh(*b, *L);
+
+  // Apply boundary condition
+  auto zero = std::make_shared<Constant>(0.0);
+  auto boundary = std::make_shared<DirichletBoundary>();
+  auto bc = std::make_shared<MultiMeshDirichletBC>(V, zero, boundary);
+  bc->apply(*A, *b);
+
+  // Compute solution
+  auto uh = std::make_shared<MultiMeshFunction>(V);
+  std::cout << "Solve" << std::endl;
+  solve(*A, *uh->vector(), *b, "cg");
+
+  // Compute errors
+  auto exact_solution = std::make_shared<ExactSolution>();
+  const double L2error = compute_error<MultiMeshL2Norm::Functional>(V, uh, exact_solution);
+  const double H10error = compute_error<MultiMeshH10Norm::Functional>(V, uh, exact_solution);
+  std::cout << L2error << ' ' << H10error << std::endl;
+}
+
+
+int main(int argc, char* argv[])
+{
+  Arguments args;
+  args.parse(argc, argv);
+
+  auto multimesh = std::make_shared<MultiMesh>();
+  double exact_volume;
+  build_multimesh(args.N, args.Nx, multimesh, exact_volume);
+
+  const double volume = multimesh->compute_volume();
+  const double volume_error = std::abs(volume - exact_volume);
+  dolfin::cout << "volume error " << volume_error << dolfin::endl;
+
+  if (volume_error > DOLFIN_EPS_LARGE)
+  {
+    dolfin::cout << "  large error" << dolfin::endl;
+  }
+
+  solve(multimesh);
+
+}
diff --git a/demo/undocumented/multimesh-poisson/cpp/MultiMeshPoisson.ufl b/demo/undocumented/multimesh-poisson/cpp/MultiMeshPoisson.ufl
index b7a06fe..032638d 100644
--- a/demo/undocumented/multimesh-poisson/cpp/MultiMeshPoisson.ufl
+++ b/demo/undocumented/multimesh-poisson/cpp/MultiMeshPoisson.ufl
@@ -16,7 +16,7 @@
 # along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 #
 # First added:  2013-06-26
-# Last changed: 2015-10-16
+# Last changed: 2015-11-28
 #
 # The bilinear form a(u, v) and linear form L(v) for a multimesh
 # formulation of Poisson's equation.
@@ -37,15 +37,15 @@ h = 2.0*Circumradius(triangle)
 h = (h('+') + h('-')) / 2
 
 # Parameters
-alpha = 4.0
-beta = 4.0
+alpha = 10.0
+beta = 1.0
 
 # Define bilinear form
 a = dot(grad(u), grad(v))*dX \
   - dot(avg(grad(u)), jump(v, n))*dI \
   - dot(avg(grad(v)), jump(u, n))*dI \
-  + alpha/h*jump(u)*jump(v)*dI \
-  + beta*dot(jump(grad(u)), jump(grad(v)))*dO
+  + alpha/h * jump(u)*jump(v)*dI \
+  + beta/h**2 * dot(jump(u), jump(v))*dO
 
 # Define linear form
 L = f*v*dX
diff --git a/test/unit/python/mesh/test_mesh_data.py b/demo/undocumented/multimesh-poisson/cpp/P1.ufl
old mode 100755
new mode 100644
similarity index 68%
copy from test/unit/python/mesh/test_mesh_data.py
copy to demo/undocumented/multimesh-poisson/cpp/P1.ufl
index 7145ef4..9d92788
--- a/test/unit/python/mesh/test_mesh_data.py
+++ b/demo/undocumented/multimesh-poisson/cpp/P1.ufl
@@ -1,8 +1,4 @@
-#!/usr/bin/env py.test
-
-"Unit tests for the MeshData class"
-
-# Copyright (C) 2011 Anders Logg
+# Copyright (C) 2009 Garth N. Wells
 #
 # This file is part of DOLFIN.
 #
@@ -19,15 +15,13 @@
 # You should have received a copy of the GNU Lesser General Public License
 # along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 #
-# First added:  2011-08-22
-# Last changed: 2011-08-22
-
-import pytest
-from dolfin import *
-
+# First added:  2009-06-18
+# Last changed: 
+#
+# The bilinear form a(v, u) and linear form L(v) for
+# projection onto piecewise quadratics.
+#
+# Compile this form with FFC: ffc -l dolfin P1.ufl
 
-def test_meshfunction():
-    "Test input/output"
+element = FiniteElement("Lagrange", triangle, 1)
 
-    mesh = UnitCubeMesh(3, 3, 3)
-    f = mesh.data().create_array("foo", 3)
diff --git a/demo/undocumented/multimesh-poisson/cpp/main.cpp b/demo/undocumented/multimesh-poisson/cpp/main.cpp
index 1f77e0d..3c85406 100644
--- a/demo/undocumented/multimesh-poisson/cpp/main.cpp
+++ b/demo/undocumented/multimesh-poisson/cpp/main.cpp
@@ -30,15 +30,6 @@
 using namespace dolfin;
 using std::make_shared;
 
-// Source term (right-hand side)
-class Source : public Expression
-{
-  void eval(Array<double>& values, const Array<double>& x) const
-  {
-    values[0] = 1.0;
-  }
-};
-
 // Sub domain for Dirichlet boundary condition
 class DirichletBoundary : public SubDomain
 {
@@ -49,10 +40,9 @@ class DirichletBoundary : public SubDomain
 };
 
 // Compute solution for given mesh configuration
-void solve_poisson(double t,
-                   double x1, double y1,
-                   double x2, double y2,
-                   File& u0_file, File& u1_file, File& u2_file)
+std::shared_ptr<MultiMeshFunction> solve_poisson(double t,
+                                                 double x1, double y1,
+                                                 double x2, double y2)
 {
   // Create meshes
   double r = 0.5;
@@ -77,7 +67,7 @@ void solve_poisson(double t,
   auto L = make_shared<MultiMeshPoisson::MultiMeshLinearForm>(V);
 
   // Attach coefficients
-  auto f = make_shared<Source>();
+  auto f = make_shared<Constant>(1);
   L->f = f;
 
   // Assemble linear system
@@ -92,14 +82,14 @@ void solve_poisson(double t,
   auto bc = make_shared<MultiMeshDirichletBC>(V, zero, boundary);
   bc->apply(*A, *b);
 
+  // Lock inactive dofs
+  V->lock_inactive_dofs(*A, *b);
+
   // Compute solution
   auto u = make_shared<MultiMeshFunction>(V);
   solve(*A, *u->vector(), *b);
 
-  // Save to file
-  u0_file << *u->part(0);
-  u1_file << *u->part(1);
-  u2_file << *u->part(2);
+  return u;
 }
 
 int main(int argc, char* argv[])
@@ -111,14 +101,14 @@ int main(int argc, char* argv[])
   }
 
   // Parameters
-  const double T = 40.0;
-  const std::size_t N = 400;
+  const double T = 10.0;
+  const std::size_t N = 100;
   const double dt = T / N;
 
-  // Files for storing solution
-  File u0_file("u0.pvd");
-  File u1_file("u1.pvd");
-  File u2_file("u2.pvd");
+  // Create files for output
+  XDMFFile f0("output/u0.xdmf");
+  XDMFFile f1("output/u1.xdmf");
+  XDMFFile f2("output/u2.xdmf");
 
   // Iterate over configurations
   for (std::size_t n = 0; n < N; n++)
@@ -133,9 +123,18 @@ int main(int argc, char* argv[])
     const double y2 = sin(t)*cos(2*t);
 
     // Compute solution
-    solve_poisson(t, x1, y1, x2, y2,
-                  u0_file, u1_file, u2_file);
+    std::shared_ptr<MultiMeshFunction> u = solve_poisson(t, x1, y1, x2, y2);
+
+    // Save to file
+    f0.write(*u->part(0), t);
+    f1.write(*u->part(1), t);
+    f2.write(*u->part(2), t);
   }
 
+  // Close files
+  f0.close();
+  f1.close();
+  f2.close();
+
   return 0;
 }
diff --git a/demo/undocumented/multimesh-poisson/python/demo_multimesh-poisson.py b/demo/undocumented/multimesh-poisson/python/demo_multimesh-poisson.py
index 238f958..ee79125 100644
--- a/demo/undocumented/multimesh-poisson/python/demo_multimesh-poisson.py
+++ b/demo/undocumented/multimesh-poisson/python/demo_multimesh-poisson.py
@@ -24,7 +24,6 @@
 # functionality.
 
 from dolfin import *
-import matplotlib.pyplot as plt
 
 if has_pybind11():
     print("Not supported in pybind11")
@@ -34,8 +33,7 @@ class DirichletBoundary(SubDomain):
     def inside(self, x, on_boundary):
         return on_boundary
 
-def solve_poisson(t, x1, y1, x2, y2, plot_solution,
-                  u0_file, u1_file, u2_file):
+def solve_poisson(t, x1, y1, x2, y2):
     "Compute solution for given mesh configuration"
 
     # Create meshes
@@ -67,15 +65,15 @@ def solve_poisson(t, x1, y1, x2, y2, plot_solution,
     h = (h('+') + h('-')) / 2
 
     # Set parameters
-    alpha = 4.0
-    beta = 4.0
+    alpha = 10.0
+    beta = 1.0
 
     # Define bilinear form
     a = dot(grad(u), grad(v))*dX \
       - dot(avg(grad(u)), jump(v, n))*dI \
       - dot(avg(grad(v)), jump(u, n))*dI \
-      + alpha/h*jump(u)*jump(v)*dI \
-      + beta*dot(jump(grad(u)), jump(grad(v)))*dO
+      + alpha/h * jump(u)*jump(v)*dI \
+      + beta/h**2 * dot(jump(u), jump(v))*dO
 
     # Define linear form
     L = f*v*dX
@@ -90,36 +88,28 @@ def solve_poisson(t, x1, y1, x2, y2, plot_solution,
     bc = MultiMeshDirichletBC(V, zero, boundary)
     bc.apply(A, b)
 
+    # Lock inactive dofs
+    V.lock_inactive_dofs(A, b)
+
     # Compute solution
     u = MultiMeshFunction(V)
     solve(A, u.vector(), b)
 
-    # Save to file
-    u0_file << u.part(0)
-    u1_file << u.part(1)
-    u2_file << u.part(2)
-
-    # Plot solution (last time)
-    #if plot_solution:
-    #    plt.figure(); plot(V.multimesh())
-    #    plt.figure(); plot(u.part(0), title="u_0")
-    #    plt.figure(); plot(u.part(1), title="u_1")
-    #    plt.figure(); plot(u.part(2), title="u_2")
-    #    plt.show()
+    return u
 
 if MPI.size(mpi_comm_world()) > 1:
     info("Sorry, this demo does not (yet) run in parallel.")
     exit(0)
 
 # Parameters
-T = 40.0
-N = 400
+T = 10.0
+N = 100
 dt = T / N
 
-# Files for storing solution
-u0_file = File("u0.pvd")
-u1_file = File("u1.pvd")
-u2_file = File("u2.pvd")
+# Create files for output
+f0 = XDMFFile("output/u0.xdmf")
+f1 = XDMFFile("output/u1.xdmf")
+f2 = XDMFFile("output/u2.xdmf")
 
 # Iterate over configurations
 for n in range(N):
@@ -133,5 +123,14 @@ for n in range(N):
     y2 = sin(t)*cos(2*t)
 
     # Compute solution
-    solve_poisson(t, x1, y1, x2, y2, n == N - 1,
-                  u0_file, u1_file, u2_file)
+    u = solve_poisson(t, x1, y1, x2, y2)
+
+    # Save to file
+    f0.write(u.part(0), t)
+    f1.write(u.part(1), t)
+    f2.write(u.part(2), t)
+
+# Close files
+f0.close()
+f1.close()
+f2.close()
diff --git a/demo/undocumented/multimesh-quadrature/cpp/README b/demo/undocumented/multimesh-quadrature/cpp/README
new file mode 100644
index 0000000..2cf893f
--- /dev/null
+++ b/demo/undocumented/multimesh-quadrature/cpp/README
@@ -0,0 +1,2 @@
+This demo does not have a C++ version since the demo relies heavily
+on plotting via Matplotlib.
diff --git a/demo/undocumented/multimesh/propeller_2d_coarse.xml.gz b/demo/undocumented/multimesh-quadrature/propeller_2d_coarse.xml.gz
similarity index 100%
rename from demo/undocumented/multimesh/propeller_2d_coarse.xml.gz
rename to demo/undocumented/multimesh-quadrature/propeller_2d_coarse.xml.gz
diff --git a/demo/undocumented/multimesh/propeller_2d_fine.xml.gz b/demo/undocumented/multimesh-quadrature/propeller_2d_fine.xml.gz
similarity index 100%
rename from demo/undocumented/multimesh/propeller_2d_fine.xml.gz
rename to demo/undocumented/multimesh-quadrature/propeller_2d_fine.xml.gz
diff --git a/demo/undocumented/multimesh-quadrature/python/demo_multimesh-quadrature.py b/demo/undocumented/multimesh-quadrature/python/demo_multimesh-quadrature.py
new file mode 100644
index 0000000..c1805be
--- /dev/null
+++ b/demo/undocumented/multimesh-quadrature/python/demo_multimesh-quadrature.py
@@ -0,0 +1,147 @@
+# Copyright (C) 2014-2017 Anders Logg
+#
+# This file is part of DOLFIN.
+#
+# DOLFIN is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# DOLFIN 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+#
+# First added:  2014-04-07
+# Last changed: 2017-05-17
+#
+# This demo program illustrates multimesh quadrature on a pair
+# of overlapping meshes using red dots to mark positive quadature
+# weights and black dots to mark negative quadature weights.
+#
+# To create movies from the generated PNG files, enter the output
+# directory and run the following commmands:
+# 
+# ffmpeg -i multimesh_quadrature_%04d.png multimesh_quadrature.mp4
+# ffmpeg -i multimesh_quadrature_%04d.png multimesh_quadrature_compressed.mp4
+
+from dolfin import *
+import os
+
+# Don't plot when DOLFIN_NOPLOT is set
+plot = os.environ.get("DOLFIN_NOPLOT") is None
+if plot:
+    import pylab as pl
+
+# Colors for plotting
+red    = "#ff3c00"
+green  = "#59ce55"
+yellow = "#fff0aa"
+blue   = "#b4d8e7"
+white  = "#ffffff"
+black  = "#000000"
+
+def plot_triangle(c, mesh, color=None, alpha_fill=None, alpha_line=None):
+    if not plot: return
+    cell = Cell(mesh, c)
+    xy = cell.get_vertex_coordinates()
+    x = [xy[0], xy[2], xy[4]]
+    y = [xy[1], xy[3], xy[5]]
+    if not color is None: pl.fill(x, y, color=color, alpha=alpha_fill)
+    pl.plot(x + [x[0]], y + [y[0]], color='k', alpha=alpha_line)
+
+def plot_point_red(x, y):
+    if not plot: return
+    pl.plot(x, y, '.', markersize=5, color=red)
+
+def plot_point_black(x, y):
+    if not plot: return
+    pl.plot(x, y, '.', markersize=2, color=black)
+
+def clear_plot():
+    if not plot: return
+    pl.clf()
+
+def save_plot(frame, compress):
+    if not plot: return
+    if not os.path.isdir("output"): os.makedirs("output")
+    pl.axis("equal")
+    pl.axis("off")
+    c = "_compressed" if compress else ""
+    pl.savefig("output/multimesh_quadrature%s_%.4d.png" % (c, frame), dpi=300)
+
+def show_plot():
+    if not plot: return
+    pl.show()
+
+# Parameters
+N = 8
+dv = 5
+R = 0.6
+num_frames = 3
+
+# Uncomment to generate a longer movie
+#num_frames = 360
+
+# Iterate over quadrature compression on/off
+for compress in [True, False]:
+	print("Compression:", compress)
+
+	# Create and load meshes
+	mesh = RectangleMesh(Point(-R, -R), Point(R, R), N, N)
+	propeller = Mesh("../propeller_2d_coarse.xml.gz")
+
+	# Iterate over frames (rotations of the propeller)
+	for frame in range(num_frames):
+	    print("Frame %d out of %d..." % (frame + 1, num_frames))
+
+	    # Rotate propeller
+	    propeller.rotate(dv)
+
+	    # Build multimesh
+	    multimesh = MultiMesh()
+	    multimesh.parameters["compress_volume_quadrature"] = compress
+	    multimesh.add(mesh)
+	    multimesh.add(propeller)
+	    multimesh.build()
+
+	    # Extract data
+	    cut_cells = multimesh.cut_cells(0)
+	    uncut_cells = multimesh.uncut_cells(0)
+	    covered_cells = multimesh.covered_cells(0)
+
+	    # Clear plot
+	    clear_plot()
+
+	    # Plot cells in background mesh
+	    for c in cut_cells:
+	        plot_triangle(c, mesh, yellow)
+	    for c in uncut_cells:
+	        plot_triangle(c, mesh, blue)
+	    for c in covered_cells:
+	        plot_triangle(c, mesh, white, alpha_line=0.1)
+
+	    # Plot propeller mesh
+	    for c in range(propeller.num_cells()):
+	        plot_triangle(c, propeller, color=white, alpha_fill=0.25)
+
+	    # Plot quadrature points
+	    for c in cut_cells:
+	        points, weights = multimesh.quadrature_rules_cut_cells(0, c)
+	        for i in range(len(weights)):
+	            w = weights[i]
+	            x = points[2*i]
+	            y = points[2*i + 1]
+	            if w > 0:
+	                plot_point_red(x, y)
+	            else:
+	                plot_point_black(x, y)
+
+	    # Save plot
+	    save_plot(frame, compress)
+
+# Show last frame
+show_plot()
diff --git a/demo/undocumented/multimesh-stokes/cpp/MultiMeshStokes.ufl b/demo/undocumented/multimesh-stokes/cpp/MultiMeshStokes.ufl
index 30cf049..88b297a 100644
--- a/demo/undocumented/multimesh-stokes/cpp/MultiMeshStokes.ufl
+++ b/demo/undocumented/multimesh-stokes/cpp/MultiMeshStokes.ufl
@@ -38,7 +38,8 @@ n = FacetNormal(triangle)
 h = 2.0*Circumradius(triangle)
 
 # Parameters
-alpha = 4.0
+alpha = 20.0
+beta = 5
 
 def tensor_jump(v, n):
     return outer(v('+'), n('+')) + outer(v('-'), n('-'))
@@ -55,8 +56,9 @@ def b_h(v, q):
 def l_h(v, q, f):
     return inner(f, v)*dX
 
-def s_O(v, w):
-    return inner(jump(grad(v)), jump(grad(w)))*dO
+def s_O(v, q, w, r):
+    return (beta/avg(h)**2) * inner(jump(v), jump(w))*dO \
+        +  beta * inner(jump(q), jump(r))*dO
 
 def s_C(v, q, w, r):
     return h*h*inner(-div(grad(v)) + grad(q), -div(grad(w)) - grad(r))*dC
@@ -65,7 +67,7 @@ def l_C(v, q, f):
     return h*h*inner(f, -div(grad(v)) - grad(q))*dC
 
 # Define bilinear form
-a = a_h(u, v) + b_h(v, p) + b_h(u, q) + s_O(u, v) + s_C(u, p, v, q)
+a = a_h(u, v) + b_h(v, p) + b_h(u, q) + s_O(u, p, v, q) + s_C(u, p, v, q)
 
 # Define linear form
 L  = l_h(v, q, f) + l_C(v, q, f)
diff --git a/demo/undocumented/multimesh-stokes/cpp/Stokes.ufl b/demo/undocumented/multimesh-stokes/cpp/Stokes.ufl
deleted file mode 100644
index d903702..0000000
--- a/demo/undocumented/multimesh-stokes/cpp/Stokes.ufl
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright (C) 2014 Anders Logg
-#
-# This file is part of DOLFIN.
-#
-# DOLFIN is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# DOLFIN 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
-#
-# First added:  2014-06-10
-# Last changed: 2014-06-11
-#
-# The bilinear form a(u, v) and linear form L(v) for a standard
-# formulation of the Stokes equations.
-#
-# Compile this form with FFC: ffc -l dolfin Stokes.ufl.
-
-# Define element
-P2 = VectorElement("Lagrange", triangle, 2)
-P1 = FiniteElement("Lagrange", triangle, 1)
-TH = P2 * P1
-
-# Define trial and test functions and right-hand side
-(u, p) = TrialFunctions(TH)
-(v, q) = TestFunctions(TH)
-f = Coefficient(P2)
-
-# Define facet normal
-n = FacetNormal(triangle)
-
-def tensor_jump(v, n):
-    return outer(v('+'), n('+')) + outer(v('-'), n('-'))
-
-def a_h(v, w):
-    return inner(grad(v), grad(w))*dx
-
-def b_h(v, q):
-    return -div(v)*q*dx
-
-# Bilinear form
-a = a_h(u, v) + b_h(v, p) + b_h(u, q)
-
-# Linear form
-L = dot(f, v)*dx
diff --git a/demo/undocumented/multimesh-stokes/cpp/main.cpp b/demo/undocumented/multimesh-stokes/cpp/main.cpp
index b266631..e8d40e4 100644
--- a/demo/undocumented/multimesh-stokes/cpp/main.cpp
+++ b/demo/undocumented/multimesh-stokes/cpp/main.cpp
@@ -16,7 +16,7 @@
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 //
 // First added:  2014-06-10
-// Last changed: 2016-03-02
+// Last changed: 2017-09-28
 //
 // This demo program solves the Stokes equations on a domain defined
 // by three overlapping and non-matching meshes.
@@ -130,31 +130,23 @@ int main(int argc, char* argv[])
   bc1->apply(*A, *b);
   bc2->apply(*A, *b);
 
+  // Remove inactive dofs
+  V->lock_inactive_dofs(*A, *b);
+
   // Compute solution
-  MultiMeshFunction w(W);
-  solve(*A, *w.vector(), *b);
-
-  // Extract solution components
-  Function& u0 = (*w.part(0))[0];
-  Function& u1 = (*w.part(1))[0];
-  Function& u2 = (*w.part(2))[0];
-  Function& p0 = (*w.part(0))[1];
-  Function& p1 = (*w.part(1))[1];
-  Function& p2 = (*w.part(2))[1];
-
-  // Save to file
-  File u0_file("u0.pvd");
-  File u1_file("u1.pvd");
-  File u2_file("u2.pvd");
-  File p0_file("p0.pvd");
-  File p1_file("p1.pvd");
-  File p2_file("p2.pvd");
-  u0_file << u0;
-  u1_file << u1;
-  u2_file << u2;
-  p0_file << p0;
-  p1_file << p1;
-  p2_file << p2;
+  auto w = make_shared<MultiMeshFunction>(W);
+  solve(*A, *w->vector(), *b);
+
+  // Save solution parts and components to file
+  for (int part = 0; part < 3; part++)
+  {
+    XDMFFile ufile("output/u" + std::to_string(part) + ".xdmf");
+    XDMFFile pfile("output/p" + std::to_string(part) + ".xdmf");
+    ufile.write((*w->part(part))[0]);
+    pfile.write((*w->part(part))[1]);
+    ufile.close();
+    pfile.close();
+  }
 
   return 0;
 }
diff --git a/demo/undocumented/multimesh-stokes/cpp/reference.h b/demo/undocumented/multimesh-stokes/cpp/reference.h
deleted file mode 100644
index b82b5e7..0000000
--- a/demo/undocumented/multimesh-stokes/cpp/reference.h
+++ /dev/null
@@ -1,49 +0,0 @@
-#include "Stokes.h"
-
-void run_reference()
-{
-  info("Running reference case");
-
-  // Read mesh and sub domain markers
-  UnitSquareMesh mesh(16, 16);
-
-  // Create function space and subspaces
-  Stokes::FunctionSpace W(mesh);
-  SubSpace W0(W, 0);
-  SubSpace W1(W, 1);
-
-  // Create boundary values
-  Constant noslip_value(0, 0);
-  InflowValue inflow_value;
-  Constant outflow_value(0);
-
-  // Create subdomains for boundary conditions
-  NoslipBoundary noslip_boundary;
-  InflowBoundary inflow_boundary;
-  OutflowBoundary outflow_boundary;
-
-  // No-slip boundary condition for velocity
-  DirichletBC bc0(W0, noslip_value, noslip_boundary);
-
-  // Inflow boundary condition for velocity
-  DirichletBC bc1(W0, inflow_value, inflow_boundary);
-
-  // Boundary condition for pressure at outflow
-  DirichletBC bc2(W1, outflow_value, outflow_boundary);
-
-  // Collect boundary conditions
-  std::vector<const DirichletBC*> bcs;
-  bcs.push_back(&bc0); bcs.push_back(&bc1); bcs.push_back(&bc2);
-
-  // Define variational problem
-  Constant f(0.0, 0.0);
-  Stokes::BilinearForm a(W, W);
-  Stokes::LinearForm L(W);
-  L.f = f;
-
-  // Compute solution
-  Function w(W);
-  solve(a == L, w, bcs);
-  Function u = w[0];
-  Function p = w[1];
-}
diff --git a/demo/undocumented/multimesh-stokes/python/demo_multimesh-stokes.py b/demo/undocumented/multimesh-stokes/python/demo_multimesh-stokes.py
index 129b785..83e2f67 100644
--- a/demo/undocumented/multimesh-stokes/python/demo_multimesh-stokes.py
+++ b/demo/undocumented/multimesh-stokes/python/demo_multimesh-stokes.py
@@ -16,13 +16,12 @@
 # along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 #
 # First added:  2015-11-11
-# Last changed: 2015-11-24
+# Last changed: 2017-05-25
 #
 # This demo program solves the Stokes equations on a domain defined
 # by three overlapping and non-matching meshes.
 
 from dolfin import *
-import matplotlib.pyplot as plt
 
 if has_pybind11():
     print("Not supported in pybind11")
@@ -56,8 +55,6 @@ multimesh.add(mesh_1)
 multimesh.add(mesh_2)
 multimesh.build()
 
-# FIXME: Tensor algebra not supported for multimesh function spaces
-
 # Create function space
 P2 = VectorElement("Lagrange", triangle, 2)
 P1 = FiniteElement("Lagrange", triangle, 1)
@@ -78,7 +75,8 @@ n = FacetNormal(multimesh)
 h = 2.0*Circumradius(multimesh)
 
 # Parameters
-alpha = 4.0
+alpha = 20.0
+beta = 5.0
 
 def tensor_jump(v, n):
     return outer(v('+'), n('+')) + outer(v('-'), n('-'))
@@ -95,8 +93,9 @@ def b_h(v, q):
 def l_h(v, q, f):
     return inner(f, v)*dX
 
-def s_O(v, w):
-    return inner(jump(grad(v)), jump(grad(w)))*dO
+def s_O(v, q, w, r):
+    return (beta/avg(h)**2) * inner(jump(v), jump(w))*dO \
+        +  beta * inner(jump(q), jump(r))*dO
 
 def s_C(v, q, w, r):
     return h*h*inner(-div(grad(v)) + grad(q), -div(grad(w)) - grad(r))*dC
@@ -105,7 +104,7 @@ def l_C(v, q, f):
     return h*h*inner(f, -div(grad(v)) - grad(q))*dC
 
 # Define bilinear form
-a = a_h(u, v) + b_h(v, p) + b_h(u, q) + s_O(u, v) + s_C(u, p, v, q)
+a = a_h(u, v) + b_h(v, p) + b_h(u, q) + s_O(u, p, v, q) + s_C(u, p, v, q)
 
 # Define linear form
 L  = l_h(v, q, f) + l_C(v, q, f)
@@ -137,36 +136,17 @@ bc2 = MultiMeshDirichletBC(Q, outflow_value, outflow_boundary)
 bc0.apply(A, b)
 bc1.apply(A, b)
 bc2.apply(A, b)
+W.lock_inactive_dofs(A, b)
 
 # Compute solution
 w = MultiMeshFunction(W)
 solve(A, w.vector(), b)
 
-# FIXME: w.part(i).split() not working for extracted parts
-# FIXME: since they are only dolfin::Functions
-
-# Extract solution components
-u0 = w.part(0).sub(0)
-u1 = w.part(1).sub(0)
-u2 = w.part(2).sub(0)
-p0 = w.part(0).sub(1)
-p1 = w.part(1).sub(1)
-p2 = w.part(2).sub(1)
-
-# Save to file
-File("u0.pvd") << u0
-File("u1.pvd") << u1
-File("u2.pvd") << u2
-File("p0.pvd") << p0
-File("p1.pvd") << p1
-File("p2.pvd") << p2
-
-# Plot solution
-#plt.figure(); plot(W.multimesh())
-#plt.figure(); plot(u0, title="u_0")
-#plt.figure(); plot(u1, title="u_1")
-#plt.figure(); plot(u2, title="u_2")
-#plt.figure(); plot(p0, title="p_0")
-#plt.figure(); plot(p1, title="p_1")
-#plt.figure(); plot(p2, title="p_2")
-#plt.show()
+# Save solution parts and components to file
+for part in range(3):
+    ufile = XDMFFile("output/u%d.xdmf" % part)
+    pfile = XDMFFile("output/p%d.xdmf" % part)
+    ufile.write(w.part(part).sub(0))
+    pfile.write(w.part(part).sub(1))
+    ufile.close()
+    pfile.close()
diff --git a/demo/undocumented/multimesh/python/demo_multimesh.py b/demo/undocumented/multimesh/python/demo_multimesh.py
deleted file mode 100644
index 528cdb5..0000000
--- a/demo/undocumented/multimesh/python/demo_multimesh.py
+++ /dev/null
@@ -1,138 +0,0 @@
-# Copyright (C) 2014-2015 Anders Logg
-#
-# This file is part of DOLFIN.
-#
-# DOLFIN is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# DOLFIN 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
-#
-# First added:  2014-04-07
-# Last changed: 2015-06-15
-
-from __future__ import print_function
-from dolfin import *
-import os
-
-print("Multi-mesh plotting requires updating")
-exit(0)
-
-# Don't plot when DOLFIN_NOPLOT is set
-plot = os.environ.get("DOLFIN_NOPLOT") is None
-if plot:
-    import pylab as pl
-
-# Colors for plotting
-red    = "#ff3c00"
-green  = "#59ce55"
-yellow = "#fff0aa"
-blue   = "#b4d8e7"
-white  = "#ffffff"
-black  = "#000000"
-
-def plot_triangle(c, mesh, color=None, alpha_fill=None, alpha_line=None):
-    if not plot: return
-    cell = Cell(mesh, c)
-    xy = cell.get_vertex_coordinates()
-    x = [xy[0], xy[2], xy[4]]
-    y = [xy[1], xy[3], xy[5]]
-    if not color is None: pl.fill(x, y, color=color, alpha=alpha_fill)
-    pl.plot(x + [x[0]], y + [y[0]], color='k', alpha=alpha_line)
-
-def plot_point_red(x, y):
-    if not plot: return
-    pl.plot(x, y, '.', markersize=5, color=red)
-
-def plot_point_black(x, y):
-    if not plot: return
-    pl.plot(x, y, '.', markersize=2, color=black)
-
-def clear_plot():
-    if not plot: return
-    pl.clf()
-
-def save_plot(frame):
-    if not plot: return
-    pl.axis("equal")
-    pl.axis("off")
-    pl.savefig("multimesh_propeller_%.4d.png" % frame, dpi=300)
-
-def show_plot():
-    if not plot: return
-    pl.show()
-
-# Parameters
-N  = 20
-dv = 5
-R  = 0.6
-num_frames = 3
-
-# Uncomment to generate a longer movie
-#num_frames = 360
-
-# Create and load meshes
-mesh = RectangleMesh(Point(-R, -R), Point(R, R), N, N)
-propeller = Mesh("../propeller_2d_coarse.xml.gz")
-
-# Iterate over rotations
-for frame in range(num_frames):
-
-    print("Frame %d out of %d..." % (frame + 1, num_frames))
-
-    # Rotate propeller
-    propeller.rotate(dv)
-
-    # Build multimesh
-    multimesh = MultiMesh()
-    multimesh.add(mesh)
-    multimesh.add(propeller)
-    multimesh.build()
-
-    # Extract data
-    cut_cells = multimesh.cut_cells(0)
-    uncut_cells = multimesh.uncut_cells(0)
-    covered_cells = multimesh.covered_cells(0)
-
-    # Clear plot
-    clear_plot()
-
-    # Plot cells in background mesh
-    for c in cut_cells:
-        plot_triangle(c, mesh, yellow)
-    for c in uncut_cells:
-        plot_triangle(c, mesh, blue)
-    for c in covered_cells:
-        plot_triangle(c, mesh, white, alpha_line=0.1)
-
-    # Plot propeller mesh
-    for c in range(propeller.num_cells()):
-        plot_triangle(c, propeller, color=white, alpha_fill=0.25)
-
-    # Plot quadrature points
-    for c in cut_cells:
-        points, weights = multimesh.quadrature_rule_cut_cell(0, c)
-        for i in range(len(weights)):
-            w = weights[i]
-            x = points[2*i]
-            y = points[2*i + 1]
-            if w > 0:
-                plot_point_red(x, y)
-            else:
-                plot_point_black(x, y)
-
-    # Save plot
-    save_plot(frame)
-
-# Show last frame
-show_plot()
-
-# Generate movie using
-#ffmpeg -r 25 -b 1800 -i multimesh_propeller_%04d.png multimesh_propeller.mp4
diff --git a/demo/undocumented/multistage-solver/python/demo_multistage-solver.py b/demo/undocumented/multistage-solver/python/demo_multistage-solver.py
index 9c93a43..c9738cc 100644
--- a/demo/undocumented/multistage-solver/python/demo_multistage-solver.py
+++ b/demo/undocumented/multistage-solver/python/demo_multistage-solver.py
@@ -43,7 +43,7 @@ exit(0)
 # Load mesh and subdomains
 mesh = Mesh("../dolfin_fine.xml.gz")
 sub_domains = MeshFunction("size_t", mesh, "../dolfin_fine_subdomains.xml.gz");
-h = CellSize(mesh)
+h = CellDiameter(mesh)
 
 # Create FunctionSpaces
 Q = FunctionSpace(mesh, "CG", 1)
diff --git a/demo/undocumented/overlapping-regions/python/demo_overlapping-regions.py b/demo/undocumented/overlapping-regions/python/demo_overlapping-regions.py
index a86e9f6..669055e 100644
--- a/demo/undocumented/overlapping-regions/python/demo_overlapping-regions.py
+++ b/demo/undocumented/overlapping-regions/python/demo_overlapping-regions.py
@@ -41,7 +41,7 @@ class Right(SubDomain):
 
 # Define mesh and subdomains
 mesh = UnitSquareMesh(64, 64)
-domains = CellFunction("size_t", mesh)
+domains = MeshFunction("size_t", mesh, mesh.topology().dim())
 domains.set_all(0)
 Left().mark(domains, 1)
 Mid().mark(domains, 2)
diff --git a/demo/undocumented/parallel-refinement/cpp/main.cpp b/demo/undocumented/parallel-refinement/cpp/main.cpp
index 9672943..c6fab1a 100644
--- a/demo/undocumented/parallel-refinement/cpp/main.cpp
+++ b/demo/undocumented/parallel-refinement/cpp/main.cpp
@@ -28,31 +28,31 @@ int main()
   auto mesh = std::make_shared<UnitSquareMesh>(20, 20);
 
   // Create MeshFunction to hold cell process rank
-  CellFunction<std::size_t>
-    processes0(mesh, dolfin::MPI::rank(mesh->mpi_comm()));
+  MeshFunction<std::size_t>
+    processes0(mesh, mesh->topology().dim(), dolfin::MPI::rank(mesh->mpi_comm()));
 
   // Output cell distribution to VTK file
   File file("processes.pvd");
   file << processes0;
 
   // Mark all cells on process 0 for refinement
-  const CellFunction<bool>
-    marker(mesh, (dolfin::MPI::rank(mesh->mpi_comm()) == 0));
+  const MeshFunction<bool>
+    marker(mesh, mesh->topology().dim(), (dolfin::MPI::rank(mesh->mpi_comm()) == 0));
 
   // Refine mesh, but keep all new cells on parent process
   auto mesh0 = std::make_shared<Mesh>(refine(*mesh, marker, false));
 
   // Create MeshFunction to hold cell process rank
-  const CellFunction<std::size_t>
-    processes1(mesh0, dolfin::MPI::rank(mesh->mpi_comm()));
+  const MeshFunction<std::size_t>
+    processes1(mesh0, mesh->topology().dim(), dolfin::MPI::rank(mesh->mpi_comm()));
   file << processes1;
 
   // Refine mesh, but this time repartition the mesh after refinement
   auto mesh1 = std::make_shared<Mesh>(refine(*mesh, marker, false));
 
   // Create MeshFunction to hold cell process rank
-  CellFunction<std::size_t>
-    processes2(mesh1, dolfin::MPI::rank(mesh->mpi_comm()));
+  MeshFunction<std::size_t>
+    processes2(mesh1, mesh->topology().dim(), dolfin::MPI::rank(mesh->mpi_comm()));
   file << processes2;
 
   return 0;
diff --git a/demo/undocumented/parallel-refinement/python/demo_parallel-refinement.py b/demo/undocumented/parallel-refinement/python/demo_parallel-refinement.py
index 06602ba..e2bad2d 100644
--- a/demo/undocumented/parallel-refinement/python/demo_parallel-refinement.py
+++ b/demo/undocumented/parallel-refinement/python/demo_parallel-refinement.py
@@ -24,25 +24,25 @@ from dolfin import *
 mesh = UnitSquareMesh(20, 20)
 
 # Create MeshFunction to hold cell process rank
-processes = CellFunction('size_t', mesh, MPI.rank(mesh.mpi_comm()))
+processes = MeshFunction('size_t', mesh, mesh.topology().dim(), MPI.rank(mesh.mpi_comm()))
 
 # Output cell distribution to VTK file
 file = File("processes.pvd")
 file << processes
 
 # Mark all cells on process 0 for refinement
-marker = CellFunction('bool', mesh, (MPI.rank(mesh.mpi_comm()) == 0))
+marker = MeshFunction('bool', mesh, mesh.topology().dim(), (MPI.rank(mesh.mpi_comm()) == 0))
 
 # Refine mesh, but keep all news cells on parent process
 mesh0 = refine(mesh, marker, False)
 
 # Create MeshFunction to hold cell process rank for refined mesh
-processes1 = CellFunction('size_t', mesh0, MPI.rank(mesh.mpi_comm()))
+processes1 = MeshFunction('size_t', mesh0, mesh0.topology().dim(), MPI.rank(mesh.mpi_comm()))
 file << processes1
 
 # Refine mesh, but this time repartition the mesh after refinement
 mesh1 = refine(mesh, marker, True)
 
 # Create MeshFunction to hold cell process rank for refined mesh
-processes2 = CellFunction('size_t', mesh1, MPI.rank(mesh.mpi_comm()))
+processes2 = MeshFunction('size_t', mesh1, mesh1.topology().dim(), MPI.rank(mesh.mpi_comm()))
 file << processes2
diff --git a/demo/undocumented/point-integral/python/demo_point-integral.py b/demo/undocumented/point-integral/python/demo_point-integral.py
index 0c59f53..aa0f4ea 100644
--- a/demo/undocumented/point-integral/python/demo_point-integral.py
+++ b/demo/undocumented/point-integral/python/demo_point-integral.py
@@ -50,7 +50,7 @@ def center_func(x):
            0.45 <= x[1] and x[1] <= 0.55 and near(x[0], 0.5)
 
 # Define domain for point integral
-center_domain = VertexFunction("size_t", mesh, 0)
+center_domain = MeshFunction("size_t", mesh, 0, 0)
 center = AutoSubDomain(center_func)
 center.mark(center_domain, 1)
 dPP = dP(subdomain_data=center_domain)
diff --git a/demo/undocumented/refinement/python/demo_refinement.py b/demo/undocumented/refinement/python/demo_refinement.py
index 446faef..22b861d 100644
--- a/demo/undocumented/refinement/python/demo_refinement.py
+++ b/demo/undocumented/refinement/python/demo_refinement.py
@@ -56,7 +56,7 @@ for i in range(5):
     print("marking for refinement")
 
     # Mark cells for refinement
-    cell_markers = CellFunction("bool", mesh)
+    cell_markers = MeshFunction("bool", mesh, mesh.topology().dim())
     for c in cells(mesh):
         if c.midpoint().distance(p) < 0.1:
             cell_markers[c] = True
diff --git a/doc/source/conf.py b/doc/source/conf.py
index 621853d..0eea0a4 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -119,9 +119,9 @@ author = u'FEniCS Project'
 # built documents.
 #
 # The short X.Y version.
-version = u'2017.2.0.dev0'
+version = u'2017.2.0'
 # The full version, including alpha/beta/rc tags.
-release = u'2017.2.0.dev0'
+release = u'2017.2.0'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff --git a/dolfin/CMakeLists.txt b/dolfin/CMakeLists.txt
index db92c91..c0f875b 100644
--- a/dolfin/CMakeLists.txt
+++ b/dolfin/CMakeLists.txt
@@ -217,6 +217,16 @@ if (DOLFIN_ENABLE_MPI AND MPI_CXX_FOUND)
   target_include_directories(dolfin SYSTEM PUBLIC ${MPI_CXX_INCLUDE_PATH})
 endif()
 
+if (DOLFIN_ENABLE_GEOMETRY_DEBUGGING AND GMP_FOUND AND MPFR_FOUND AND CGAL_FOUND) 
+  message(STATUS "Appending link flags for geometry debugging")
+  target_compile_definitions(dolfin PUBLIC "-DDOLFIN_ENABLE_GEOMETRY_DEBUGGING")
+  target_include_directories(dolfin PRIVATE ${CGAL_INCLUDE_DIRS})
+  target_include_directories(dolfin PRIVATE ${GMP_INCLUDE_DIRS})
+  target_include_directories(dolfin PRIVATE ${MPFR_INCLUDE_DIRS})
+  target_link_libraries(dolfin PRIVATE ${GMP_LIBRARIES})
+  target_link_libraries(dolfin PRIVATE ${MPFR_LIBRARIES})
+endif()
+
 #------------------------------------------------------------------------------
 # Set compiler flags, include directories and library dependencies
 
diff --git a/dolfin/common/Variable.h b/dolfin/common/Variable.h
index 25c0a8c..a4129e3 100644
--- a/dolfin/common/Variable.h
+++ b/dolfin/common/Variable.h
@@ -55,7 +55,7 @@ namespace dolfin
     void rename(const std::string name, const std::string label);
 
     /// Return name
-    std::string name()  const;
+    std::string name() const;
 
     /// Return label (description)
     std::string label() const;
diff --git a/dolfin/fem/AssemblerBase.cpp b/dolfin/fem/AssemblerBase.cpp
index 75d9d7a..92accd3 100644
--- a/dolfin/fem/AssemblerBase.cpp
+++ b/dolfin/fem/AssemblerBase.cpp
@@ -294,60 +294,20 @@ You might have forgotten to specify the value dimension correctly in an Expressi
                  "Mesh geometry degree does not match degree of coordinate element in form");
   }
 
-  switch (mesh.type().cell_type())
-  {
-  case CellType::interval:
-    if (coordinate_element->cell_shape() != ufc::shape::interval)
-    {
-      dolfin_error("AssemblerBase.cpp",
-                   "assemble form",
-                   "Mesh cell type (intervals) does not match cell type of form");
-    }
-    break;
-  case CellType::triangle:
-    if (coordinate_element->cell_shape() != ufc::shape::triangle)
-    {
-      dolfin_error("AssemblerBase.cpp",
-                   "assemble form",
-                   "Mesh cell type (triangles) does not match cell type of form");
-    }
-    break;
-  case CellType::tetrahedron:
-    if (coordinate_element->cell_shape() != ufc::shape::tetrahedron)
-    {
-      dolfin_error("AssemblerBase.cpp",
-                   "assemble form",
-                   "Mesh cell type (tetrahedra) does not match cell type of form");
-    }
-    break;
-  case CellType::quadrilateral:
-    if (coordinate_element->cell_shape() != ufc::shape::quadrilateral)
-    {
-      dolfin_error("AssemblerBase.cpp",
-                   "assemble form",
-                   "Mesh cell type (quadrilateral) does not match cell type of form");
-    }
-    break;
-  case CellType::hexahedron:
-    if (coordinate_element->cell_shape() != ufc::shape::hexahedron)
-    {
-      dolfin_error("AssemblerBase.cpp",
-                   "assemble form",
-                   "Mesh cell type (hexahedron) does not match cell type of form");
-    }
-    break;
-  default:
-    dolfin_error("AssemblerBase.cpp",
-                 "assemble form",
-                 "Mesh cell type is unknown!");
-  }
-
-  // Check that the mesh is ordered
-  if (!mesh.ordered())
+  std::map<CellType::Type, ufc::shape> dolfin_to_ufc_shapes
+    = { {CellType::Type::interval, ufc::shape::interval},
+        {CellType::Type::triangle, ufc::shape::triangle},
+        {CellType::Type::tetrahedron, ufc::shape::tetrahedron},
+        {CellType::Type::quadrilateral, ufc::shape::quadrilateral},
+        {CellType::Type::hexahedron, ufc::shape::hexahedron} };
+
+  auto cell_type_pair = dolfin_to_ufc_shapes.find(mesh.type().cell_type());
+  dolfin_assert(cell_type_pair != dolfin_to_ufc_shapes.end());
+  if (coordinate_element->cell_shape() != cell_type_pair->second)
   {
     dolfin_error("AssemblerBase.cpp",
                  "assemble form",
-                 "Mesh is not correctly ordered. Consider calling mesh.order()");
+                 "Mesh cell type does not match cell type of UFC form");
   }
 }
 //-----------------------------------------------------------------------------
diff --git a/dolfin/fem/DirichletBC.cpp b/dolfin/fem/DirichletBC.cpp
index 31c9f31..3f254aa 100644
--- a/dolfin/fem/DirichletBC.cpp
+++ b/dolfin/fem/DirichletBC.cpp
@@ -641,7 +641,7 @@ void DirichletBC::init_from_sub_domain(std::shared_ptr<const SubDomain>
   // all facet as subdomain 1
   const std::size_t dim = mesh->topology().dim();
   _function_space->mesh()->init(dim - 1);
-  FacetFunction<std::size_t> sub_domains(mesh, 1);
+  MeshFunction<std::size_t> sub_domains(mesh, dim - 1, 1);
 
   // Set geometric dimension (needed for SWIG interface)
   sub_domain->_geometric_dimension = mesh->geometry().dim();
diff --git a/dolfin/fem/DiscreteOperators.cpp b/dolfin/fem/DiscreteOperators.cpp
index de6eb1c..56dc503 100644
--- a/dolfin/fem/DiscreteOperators.cpp
+++ b/dolfin/fem/DiscreteOperators.cpp
@@ -54,7 +54,7 @@ DiscreteOperators::build_gradient(const FunctionSpace& V0,
 
   // Check that V0 is a (lowest-order) edge basis
   mesh.init(1);
-  if (V0.dim() != mesh.size_global(1))
+  if (V0.dim() != mesh.num_entities_global(1))
   {
     dolfin_error("DiscreteGradient.cpp",
                  "compute discrete gradient operator",
@@ -62,7 +62,7 @@ DiscreteOperators::build_gradient(const FunctionSpace& V0,
   }
 
   // Check that V1 is a linear nodal basis
-  if (V1.dim() != mesh.size_global(0))
+  if (V1.dim() != mesh.num_entities_global(0))
   {
     dolfin_error("DiscreteGradient.cpp",
                  "compute discrete gradient operator",
diff --git a/dolfin/fem/DofMap.h b/dolfin/fem/DofMap.h
index 3f399c8..da87c67 100644
--- a/dolfin/fem/DofMap.h
+++ b/dolfin/fem/DofMap.h
@@ -104,7 +104,7 @@ namespace dolfin
     { return _is_view; }
 
     /// Return the dimension of the global finite element function
-    /// space
+    /// space. Use index_map()->size() to get the local dimension.
     ///
     /// *Returns*
     ///     std::size_t
diff --git a/dolfin/fem/DofMapBuilder.cpp b/dolfin/fem/DofMapBuilder.cpp
index a534fd5..0c20ab1 100644
--- a/dolfin/fem/DofMapBuilder.cpp
+++ b/dolfin/fem/DofMapBuilder.cpp
@@ -1077,7 +1077,7 @@ std::shared_ptr<const ufc::dofmap> DofMapBuilder::build_ufc_node_graph(
       mesh.init(d);
       DistributedMeshTools::number_entities(mesh, d);
       num_mesh_entities_local[d]  = mesh.num_entities(d);
-      num_mesh_entities_global_unconstrained[d] = mesh.size_global(d);
+      num_mesh_entities_global_unconstrained[d] = mesh.num_entities_global(d);
     }
   }
 
@@ -1181,8 +1181,8 @@ DofMapBuilder::build_ufc_node_graph_constrained(
   for (std::size_t d = 0; d <= D; ++d)
     needs_entities[d] = ufc_dofmap->needs_mesh_entities(d);
 
-  // Generate and number required mesh entities (local & global, and
-  // constrained global)
+  // Generate and number required mesh entities (local & global, and constrained
+  // global)
   std::vector<std::size_t> num_mesh_entities_local(D + 1, 0);
   std::vector<std::size_t> num_mesh_entities_global_unconstrained(D + 1, 0);
   std::vector<bool> required_mesh_entities(D + 1, false);
@@ -1194,7 +1194,7 @@ DofMapBuilder::build_ufc_node_graph_constrained(
       mesh.init(d);
       DistributedMeshTools::number_entities(mesh, d);
       num_mesh_entities_local[d]  = mesh.num_entities(d);
-      num_mesh_entities_global_unconstrained[d] = mesh.size_global(d);
+      num_mesh_entities_global_unconstrained[d] = mesh.num_entities_global(d);
     }
   }
 
diff --git a/dolfin/fem/DofMapBuilder.h b/dolfin/fem/DofMapBuilder.h
index 7a2e8fd..4fc0811 100644
--- a/dolfin/fem/DofMapBuilder.h
+++ b/dolfin/fem/DofMapBuilder.h
@@ -43,6 +43,7 @@ namespace dolfin
   class IndexMap;
   class SubDomain;
   class UFC;
+  class Cell;
 
   /// Builds a DofMap on a Mesh
 
diff --git a/dolfin/fem/MultiMeshAssembler.cpp b/dolfin/fem/MultiMeshAssembler.cpp
index 5272e4e..ff17215 100644
--- a/dolfin/fem/MultiMeshAssembler.cpp
+++ b/dolfin/fem/MultiMeshAssembler.cpp
@@ -27,7 +27,10 @@
 #include <dolfin/log/log.h>
 #include <dolfin/mesh/Cell.h>
 #include <dolfin/mesh/Mesh.h>
+#include <dolfin/mesh/Facet.h>
 #include <dolfin/mesh/MultiMesh.h>
+#include <dolfin/function/MultiMeshFunction.h>
+#include <dolfin/function/FunctionSpace.h>
 
 #include "SparsityPatternBuilder.h"
 #include "UFC.h"
@@ -60,6 +63,9 @@ void MultiMeshAssembler::assemble(GenericTensor& A, const MultiMeshForm& a)
   // Assemble over uncut cells
   _assemble_uncut_cells(A, a);
 
+  // Assemble over exterior facets
+  _assemble_uncut_exterior_facets(A, a);
+
   // Assemble over cut cells
   _assemble_cut_cells(A, a);
 
@@ -73,13 +79,107 @@ void MultiMeshAssembler::assemble(GenericTensor& A, const MultiMeshForm& a)
   if (finalize_tensor)
     A.apply("add");
 
-  // Lock any remaining inactive dofs
-  if (A.rank() == 2)
-    static_cast<GenericMatrix&>(A).ident_zeros();
-
   end();
 }
 //-----------------------------------------------------------------------------
+void MultiMeshAssembler::_assemble_uncut_exterior_facets(GenericTensor& A,
+                                                         const MultiMeshForm& a)
+{
+  // FIXME: This implementation assumes that there is one background mesh
+  // that contains the entire exterior facet. 
+
+  // Get form rank
+  const std::size_t form_rank = a.rank();
+
+  // Extract multimesh
+  std::shared_ptr<const MultiMesh> multimesh = a.multimesh();
+
+  // Collect pointers to dof maps
+  std::vector<const MultiMeshDofMap*> dofmaps;
+  for (std::size_t i = 0; i < form_rank; i++)
+    dofmaps.push_back(a.function_space(i)->dofmap().get());
+
+  // Vector to hold dof map for a cell
+  std::vector<ArrayView<const dolfin::la_index>> dofs(form_rank);
+
+  // Initialize variables that will be reused throughout assembly
+  ufc::cell ufc_cell;
+  std::vector<double> coordinate_dofs;
+
+  // Assembly exterior uncut facets on mesh 0, the background mesh
+  int part = 0;
+
+  log(PROGRESS, "Assembling multimesh form over uncut facets on part %d.", part);
+
+  // Get form for current part
+  const Form& a_part = *a.part(part);
+
+  // Create data structure for local assembly data
+  UFC ufc_part(a_part);
+
+  // Extract mesh
+  dolfin_assert(a_part.mesh());
+  const Mesh& mesh_part = *(a_part.mesh());
+
+  // FIXME: Handle subdomains
+
+  // Exterior facet integral
+  const ufc::exterior_facet_integral* integral = ufc_part.default_exterior_facet_integral.get();
+
+  // Skip if we don't have a facet integral
+  if (!integral) return;
+
+  // Iterate over uncut cells
+  for (FacetIterator facet(mesh_part); !facet.end(); ++facet)
+  {
+
+    // Only consider exterior facets
+    if (!facet->exterior())
+    {
+      continue;
+    }
+
+    const std::size_t D = mesh_part.topology().dim();
+
+    // Get mesh cell to which mesh facet belongs (pick first, there is
+    // only one)
+    dolfin_assert(facet->num_entities(D) == 1);
+    Cell mesh_cell(mesh_part, facet->entities(D)[0]);
+
+    // Check that cell is not a ghost
+    dolfin_assert(!mesh_cell.is_ghost());
+
+    // Get local index of facet with respect to the cell
+    const std::size_t local_facet = mesh_cell.index(*facet);
+
+    // Update UFC cell
+    mesh_cell.get_cell_data(ufc_cell, local_facet);
+    mesh_cell.get_coordinate_dofs(coordinate_dofs);
+
+    // Update UFC object
+    ufc_part.update(mesh_cell, coordinate_dofs, ufc_cell,
+               integral->enabled_coefficients());
+
+    // Get local-to-global dof maps for cell
+    for (std::size_t i = 0; i < form_rank; ++i)
+    {
+      const auto dofmap = a.function_space(i)->dofmap()->part(part);
+      const auto dmap = dofmap->cell_dofs(mesh_cell.index());
+      dofs[i] = ArrayView<const dolfin::la_index>(dmap.size(), dmap.data());
+    }
+
+    // Tabulate cell tensor
+    integral->tabulate_tensor(ufc_part.A.data(),
+                              ufc_part.w(),
+                              coordinate_dofs.data(),
+                              local_facet,
+                              ufc_cell.orientation);
+
+    // Add entries to global tensor
+    A.add(ufc_part.A.data(), dofs);
+  }
+}
+//-----------------------------------------------------------------------------
 void MultiMeshAssembler::_assemble_uncut_cells(GenericTensor& A,
                                                const MultiMeshForm& a)
 {
@@ -204,7 +304,7 @@ void MultiMeshAssembler::_assemble_cut_cells(GenericTensor& A,
 
     // Get cut cells and quadrature rules
     const std::vector<unsigned int>& cut_cells = multimesh->cut_cells(part);
-    const auto& quadrature_rules = multimesh->quadrature_rule_cut_cells(part);
+    const auto& quadrature_rules = multimesh->quadrature_rules_cut_cells(part);
 
     // Iterate over cut cells
     for (auto it = cut_cells.begin(); it != cut_cells.end(); ++it)
@@ -283,6 +383,21 @@ void MultiMeshAssembler::_assemble_interface(GenericTensor& A,
   // Get form rank
   const std::size_t form_rank = a.rank();
 
+  // Get multimesh coefficients
+  // These are updated in within this assembly loop
+  std::map<std::size_t, std::shared_ptr<const MultiMeshFunction> >
+    multimesh_coefficients = a.multimesh_coefficients();
+
+  // Identify the coefficents that are not MultiMeshFunction
+  // These will be updated by UFC
+  // It is assumed that the coefficents are the same for all parts
+  std::vector<bool> ufc_enabled_coefficients;
+  for (std::size_t i = 0; i < a.part(0)->coefficients().size(); i++)
+  {
+    bool ufc_update = multimesh_coefficients.find(i) == multimesh_coefficients.end();
+    ufc_enabled_coefficients.push_back(ufc_update);
+  }
+
   // Collect pointers to dof maps
   std::vector<const MultiMeshDofMap*> dofmaps;
   for (std::size_t i = 0; i < form_rank; i++)
@@ -321,7 +436,7 @@ void MultiMeshAssembler::_assemble_interface(GenericTensor& A,
     if (!integral) continue;
 
     // Get quadrature rules
-    const auto& quadrature_rules = multimesh->quadrature_rule_interface(part);
+    const auto& quadrature_rules = multimesh->quadrature_rules_interface(part);
 
     // Get collision map
     const auto& cmap = multimesh->collision_map_cut_cells(part);
@@ -363,38 +478,56 @@ void MultiMeshAssembler::_assemble_interface(GenericTensor& A,
           continue;
 
         // Create aliases for cells to simplify notation
-        const Cell& cell_0 = cut_cell;
+        const std::size_t& part_1 = cutting_part;
+        const std::size_t& part_0 = part;
         const Cell& cell_1 = cutting_cell;
+        const Cell& cell_0 = cut_cell;
 
         // Update to current pair of cells
+        // Let UFC update the coefficients that are not MultiMeshFunction
         cell_0.get_cell_data(ufc_cell[0], 0);
         cell_1.get_cell_data(ufc_cell[1], 0);
         cell_0.get_coordinate_dofs(coordinate_dofs[0]);
         cell_1.get_coordinate_dofs(coordinate_dofs[1]);
         ufc_part.update(cell_0, coordinate_dofs[0], ufc_cell[0],
-                        cell_1, coordinate_dofs[1], ufc_cell[1]);
+                        cell_1, coordinate_dofs[1], ufc_cell[1],
+                        ufc_enabled_coefficients);
+
+        // Manually update multimesh coefficients
+        for (auto it : multimesh_coefficients)
+        {
+          std::size_t coefficient_number = it.first;
+          std::shared_ptr<const MultiMeshFunction> coefficient = it.second;
+          double** macro_w = ufc_part.macro_w();
+          const FiniteElement& element = *coefficient->function_space()->part(part_0)->element();
+          std::size_t offset = element.space_dimension();
+
+          double * w_0 = macro_w[coefficient_number];
+          double * w_1 = macro_w[coefficient_number] + offset;
+
+          coefficient->restrict(w_0, element,
+                                part_0, cell_0, coordinate_dofs[0].data(), ufc_cell[0]);
+          coefficient->restrict(w_1, element,
+                                part_1, cell_1, coordinate_dofs[1].data(), ufc_cell[1]);
+        }
 
         // Collect vertex coordinates
         macro_coordinate_dofs.resize(coordinate_dofs[0].size() +
                                      coordinate_dofs[0].size());
-        std::copy(coordinate_dofs[0].begin(),
-                  coordinate_dofs[0].end(),
+        std::copy(coordinate_dofs[0].begin(), coordinate_dofs[0].end(),
                   macro_coordinate_dofs.begin());
-        std::copy(coordinate_dofs[1].begin(),
-                  coordinate_dofs[1].end(),
-                  macro_coordinate_dofs.begin()
-                  + coordinate_dofs[0].size());
+        std::copy(coordinate_dofs[1].begin(), coordinate_dofs[1].end(),
+                  macro_coordinate_dofs.begin() + coordinate_dofs[0].size());
 
         // Tabulate dofs for each dimension on macro element
         for (std::size_t i = 0; i < form_rank; i++)
         {
           // Get dofs for cut mesh
-          const auto dofmap_0 = a.function_space(i)->dofmap()->part(part);
+          const auto dofmap_0 = a.function_space(i)->dofmap()->part(part_0);
           const auto dofs_0 = dofmap_0->cell_dofs(cell_0.index());
 
           // Get dofs for cutting mesh
-          const auto dofmap_1
-            = a.function_space(i)->dofmap()->part(cutting_part);
+          const auto dofmap_1 = a.function_space(i)->dofmap()->part(part_1);
           const auto dofs_1 = dofmap_1->cell_dofs(cell_1.index());
 
           // Create space in macro dof vector
@@ -454,6 +587,21 @@ void MultiMeshAssembler::_assemble_overlap(GenericTensor& A,
   // Get form rank
   const std::size_t form_rank = a.rank();
 
+  // Get multimesh coefficients
+  // These are updated in this assembly loop
+  std::map<std::size_t, std::shared_ptr<const MultiMeshFunction> >
+    multimesh_coefficients = a.multimesh_coefficients();
+
+  // Identify the coefficients that are not MultiMeshFunction
+  // These will be updated by UFC
+  // It is assumed that the coefficents are the same for all parts
+  std::vector<bool> ufc_enabled_coefficients;
+  for (std::size_t i = 0; i < a.part(0)->coefficients().size(); i++)
+  {
+    bool ufc_update = multimesh_coefficients.find(i) == multimesh_coefficients.end();
+    ufc_enabled_coefficients.push_back(ufc_update);
+  }
+
   // Collect pointers to dof maps
   std::vector<const MultiMeshDofMap*> dofmaps;
   for (std::size_t i = 0; i < form_rank; i++)
@@ -491,7 +639,7 @@ void MultiMeshAssembler::_assemble_overlap(GenericTensor& A,
     if (!integral) continue;
 
     // Get quadrature rules
-    const auto& quadrature_rules = multimesh->quadrature_rule_overlap(part);
+    const auto& quadrature_rules = multimesh->quadrature_rules_overlap(part);
 
     // Get collision map
     const auto& cmap = multimesh->collision_map_cut_cells(part);
@@ -529,37 +677,56 @@ void MultiMeshAssembler::_assemble_overlap(GenericTensor& A,
           continue;
 
         // Create aliases for cells to simplify notation
-        const Cell& cell_0 = cut_cell;
+        const std::size_t& part_1 = cutting_part;
+        const std::size_t& part_0 = part;
         const Cell& cell_1 = cutting_cell;
+        const Cell& cell_0 = cut_cell;
 
         // Update to current pair of cells
+        // Let UFC update the coefficients that are not MultiMeshFunction
         cell_0.get_cell_data(ufc_cell[0], 0);
         cell_1.get_cell_data(ufc_cell[1], 0);
         cell_0.get_coordinate_dofs(coordinate_dofs[0]);
         cell_1.get_coordinate_dofs(coordinate_dofs[1]);
         ufc_part.update(cell_0, coordinate_dofs[0], ufc_cell[0],
-                        cell_1, coordinate_dofs[1], ufc_cell[1]);
+                        cell_1, coordinate_dofs[1], ufc_cell[1],
+                        ufc_enabled_coefficients);
 
+        // Manually update multimesh coefficients
+        for (auto it : multimesh_coefficients)
+        {
+          std::size_t coefficient_number = it.first;
+          std::shared_ptr<const MultiMeshFunction> coefficient = it.second;
+          double** macro_w = ufc_part.macro_w();
+          const FiniteElement& element = *coefficient->function_space()->part(part_0)->element();
+          std::size_t offset = element.space_dimension();
+
+          double * w_0 = macro_w[coefficient_number];
+          double * w_1 = macro_w[coefficient_number] + offset;
+
+          coefficient->restrict(w_0, element,
+                                part_0, cell_0, coordinate_dofs[0].data(), ufc_cell[0]);
+          coefficient->restrict(w_1, element,
+                                part_1, cell_1, coordinate_dofs[1].data(), ufc_cell[1]);
+        }
 
         // Collect vertex coordinates
         macro_coordinate_dofs.resize(coordinate_dofs[0].size() +
                                      coordinate_dofs[0].size());
-        std::copy(coordinate_dofs[0].begin(),
-                  coordinate_dofs[0].end(),
+        std::copy(coordinate_dofs[0].begin(), coordinate_dofs[0].end(),
                   macro_coordinate_dofs.begin());
-        std::copy(coordinate_dofs[1].begin(),
-                  coordinate_dofs[1].end(),
+        std::copy(coordinate_dofs[1].begin(), coordinate_dofs[1].end(),
                   macro_coordinate_dofs.begin() + coordinate_dofs[0].size());
 
         // Tabulate dofs for each dimension on macro element
         for (std::size_t i = 0; i < form_rank; i++)
         {
           // Get dofs for cut mesh
-          const auto dofmap_0 = a.function_space(i)->dofmap()->part(part);
+          const auto dofmap_0 = a.function_space(i)->dofmap()->part(part_0);
           const auto dofs_0 = dofmap_0->cell_dofs(cell_0.index());
 
           // Get dofs for cutting mesh
-          const auto dofmap_1 = a.function_space(i)->dofmap()->part(cutting_part);
+          const auto dofmap_1 = a.function_space(i)->dofmap()->part(part_1);
           const auto dofs_1 = dofmap_1->cell_dofs(cell_1.index());
 
           // Create space in macro dof vector
diff --git a/dolfin/fem/MultiMeshAssembler.h b/dolfin/fem/MultiMeshAssembler.h
index a2e296c..ea2ac9d 100644
--- a/dolfin/fem/MultiMeshAssembler.h
+++ b/dolfin/fem/MultiMeshAssembler.h
@@ -65,6 +65,9 @@ namespace dolfin
     // Assemble over cut cells
     void _assemble_cut_cells(GenericTensor& A, const MultiMeshForm& a);
 
+    // Assemble over uncut exterior facets
+    void _assemble_uncut_exterior_facets(GenericTensor& A, const MultiMeshForm& a);
+
     // Assemble over interface
     void _assemble_interface(GenericTensor& A, const MultiMeshForm& a);
 
diff --git a/dolfin/fem/MultiMeshDirichletBC.cpp b/dolfin/fem/MultiMeshDirichletBC.cpp
index abc5460..b24db82 100644
--- a/dolfin/fem/MultiMeshDirichletBC.cpp
+++ b/dolfin/fem/MultiMeshDirichletBC.cpp
@@ -96,6 +96,15 @@ MultiMeshDirichletBC::MultiMeshDirichletBC(std::shared_ptr<const MultiMeshFuncti
   _bcs.push_back(bc);
 }
 //-----------------------------------------------------------------------------
+MultiMeshDirichletBC::MultiMeshDirichletBC(const MultiMeshDirichletBC& bc)
+{
+  *this = bc;
+
+  // Iterate over boundary conditions and call the copy constructor
+  for (std::size_t part = 0; part < _bcs.size(); part++)
+    _bcs[part] = std::make_shared<DirichletBC>(*_bcs[part]);
+}
+//-----------------------------------------------------------------------------
 MultiMeshDirichletBC::~MultiMeshDirichletBC()
 {
   // Do nothing
@@ -245,6 +254,44 @@ void MultiMeshDirichletBC::apply(GenericMatrix& A,
   }
 }
 //-----------------------------------------------------------------------------
+void MultiMeshDirichletBC::zero(GenericMatrix& A) const
+{
+  // Check whether we have a list of boundary conditions, one for each
+  // part, or if we have a single boundary condition for a single
+  // part.
+
+  if (_sub_domain)
+  {
+    // Iterate over boundary conditions
+    for (std::size_t part = 0; part < _bcs.size(); part++)
+    {
+      // Set current part for subdomain wrapper
+      dolfin_assert(_sub_domain);
+      _sub_domain->set_current_part(part);
+
+      // Apply boundary condition for current part
+      _bcs[part]->zero(A);
+    }
+  }
+  else
+  {
+    dolfin_assert(_bcs.size() == 1);
+
+    // Apply the single boundary condition
+    _bcs[0]->zero(A);
+  }
+}
+//-----------------------------------------------------------------------------
+void MultiMeshDirichletBC::homogenize()
+{
+  // Iterate over boundary conditions
+  for (std::size_t part = 0; part < _bcs.size(); part++)
+  {
+    // Homogenize boundary condition
+    _bcs[part]->homogenize();
+  }
+}
+//-----------------------------------------------------------------------------
 MultiMeshDirichletBC::MultiMeshSubDomain::MultiMeshSubDomain
 (std::shared_ptr<const SubDomain> sub_domain,
  std::shared_ptr<const MultiMesh> multimesh,
diff --git a/dolfin/fem/MultiMeshDirichletBC.h b/dolfin/fem/MultiMeshDirichletBC.h
index 0cb6d36..8a3b636 100644
--- a/dolfin/fem/MultiMeshDirichletBC.h
+++ b/dolfin/fem/MultiMeshDirichletBC.h
@@ -89,6 +89,13 @@ namespace dolfin
                          std::size_t part,
                          std::string method="topological");
 
+    /// Copy constructor. Either cached DOF data are copied.
+    ///
+    /// *Arguments*
+    ///     bc (_MultiMeshDirichletBC_)
+    ///         The object to be copied.
+    MultiMeshDirichletBC(const MultiMeshDirichletBC& bc);
+
     /// Destructor
     ~MultiMeshDirichletBC();
 
@@ -134,6 +141,15 @@ namespace dolfin
                GenericVector& b,
                const GenericVector& x) const;
 
+    /// Zero the rows in a matrix A corresponding to boundary dofs
+    ///
+    /// @param     A (_GenericMatrix_)
+    ///         The matrix to zero rows in.
+    void zero(GenericMatrix& A) const;
+
+    /// Set value to 0.0
+    void homogenize();
+
   private:
 
     // Subclass of SubDomain wrapping user-defined subdomain
@@ -172,7 +188,7 @@ namespace dolfin
     };
 
     // List of boundary conditions for parts
-    std::vector<std::shared_ptr<const DirichletBC>> _bcs;
+    std::vector<std::shared_ptr<DirichletBC>> _bcs;
 
     // Wrapper of user-defined subdomain
     mutable std::shared_ptr<MultiMeshSubDomain> _sub_domain;
diff --git a/dolfin/fem/MultiMeshDofMap.cpp b/dolfin/fem/MultiMeshDofMap.cpp
index 154ebd8..a78e5fd 100644
--- a/dolfin/fem/MultiMeshDofMap.cpp
+++ b/dolfin/fem/MultiMeshDofMap.cpp
@@ -20,6 +20,7 @@
 
 #include <dolfin/common/types.h>
 #include <dolfin/common/NoDeleter.h>
+#include <dolfin/common/ArrayView.h>
 #include <dolfin/mesh/Cell.h>
 #include <dolfin/function/FunctionSpace.h>
 #include <dolfin/function/MultiMeshFunctionSpace.h>
@@ -158,3 +159,49 @@ std::string MultiMeshDofMap::str(bool verbose) const
   return s.str();
 }
 //-----------------------------------------------------------------------------
+std::vector<dolfin::la_index>
+MultiMeshDofMap::inactive_dofs(const MultiMesh &multimesh, std::size_t part) const
+{
+  std::shared_ptr<const GenericDofMap> dofmap_part = this->part(part);
+
+  // Get all dofs on covered cells
+  std::vector<unsigned int> covered_cells = multimesh.covered_cells(part);
+
+  std::vector<dolfin::la_index> covered_dofs;
+  covered_dofs.reserve(dofmap_part->max_element_dofs() * covered_cells.size());
+  for (unsigned int cell : covered_cells)
+  {
+    const auto dmap = dofmap_part->cell_dofs(cell);
+    const auto local_dofs = ArrayView<const dolfin::la_index>(dmap.size(), dmap.data());
+    std::copy(local_dofs.begin(), local_dofs.end(), std::back_inserter(covered_dofs));
+  }
+  // Sort and remove duplicates
+  std::sort(covered_dofs.begin(), covered_dofs.end());
+  covered_dofs.erase(std::unique(covered_dofs.begin(), covered_dofs.end()),
+                      covered_dofs.end());
+
+  // Get all dofs on cut cells
+  std::vector<unsigned int> cut_cells = multimesh.cut_cells(part);
+
+  std::vector<dolfin::la_index> cut_cell_dofs;
+  cut_cell_dofs.reserve(dofmap_part->max_element_dofs() * cut_cells.size());
+  for (unsigned int cell : cut_cells)
+  {
+    const auto dmap = dofmap_part->cell_dofs(cell);
+    const auto local_dofs = ArrayView<const dolfin::la_index>(dmap.size(), dmap.data());    
+    std::copy(local_dofs.begin(), local_dofs.end(), std::back_inserter(cut_cell_dofs));
+  }
+  
+  // Sort and remove duplicates
+  std::sort(cut_cell_dofs.begin(), cut_cell_dofs.end());
+  cut_cell_dofs.erase(std::unique(cut_cell_dofs.begin(), cut_cell_dofs.end()),
+                      cut_cell_dofs.end());
+
+  // Remove cut cell dofs from covered dofs
+  std::vector<dolfin::la_index> _inactive_dofs;
+  std::set_difference(covered_dofs.begin(), covered_dofs.end(),
+                      cut_cell_dofs.begin(), cut_cell_dofs.end(),
+                      std::inserter(_inactive_dofs, _inactive_dofs.begin()));
+  return _inactive_dofs;
+}
+//-----------------------------------------------------------------------------
diff --git a/dolfin/fem/MultiMeshDofMap.h b/dolfin/fem/MultiMeshDofMap.h
index df70302..7519d7f 100644
--- a/dolfin/fem/MultiMeshDofMap.h
+++ b/dolfin/fem/MultiMeshDofMap.h
@@ -22,12 +22,14 @@
 #define __MULTI_MESH_DOF_MAP_H
 
 #include "GenericDofMap.h"
+#include <dolfin/mesh/MultiMesh.h>
 
 namespace dolfin
 {
 
   // Forward declarations
   class MultiMeshFunctionSpace;
+  class MultiMesh;
 
   /// This class handles the mapping of degrees of freedom for MultiMesh
   /// function spaces.
@@ -91,6 +93,10 @@ namespace dolfin
     /// Return informal string representation (pretty-print)
     std::string str(bool verbose) const;
 
+    /// Return inactive dofs
+    std::vector<dolfin::la_index> inactive_dofs(const MultiMesh &multimesh,
+                                                std::size_t part_id) const;
+
   private:
 
     // Index Map containing total global dimension (sum of parts)
diff --git a/dolfin/fem/MultiMeshForm.cpp b/dolfin/fem/MultiMeshForm.cpp
index aec8891..fe2964e 100644
--- a/dolfin/fem/MultiMeshForm.cpp
+++ b/dolfin/fem/MultiMeshForm.cpp
@@ -149,3 +149,31 @@ void MultiMeshForm::clear()
   _forms.clear();
 }
 //-----------------------------------------------------------------------------
+void MultiMeshForm::set_multimesh_coefficient(std::size_t i,
+                                              std::shared_ptr<const MultiMeshFunction> coefficient)
+{
+  dolfin_assert(coefficient);
+  _multimesh_coefficients[i] = coefficient;
+}
+//-----------------------------------------------------------------------------
+std::map<std::size_t, std::shared_ptr<const MultiMeshFunction>>
+  MultiMeshForm::multimesh_coefficients() const
+{
+  return _multimesh_coefficients;
+}
+//-----------------------------------------------------------------------------
+std::shared_ptr<const MultiMeshFunction>
+  MultiMeshForm::multimesh_coefficient(std::size_t i) const
+{
+  dolfin_assert(i < _multimesh_coefficients.size());
+  return _multimesh_coefficients.at(i);
+}
+//-----------------------------------------------------------------------------
+std::vector<std::size_t> MultiMeshForm::multimesh_coefficient_keys() const
+{
+  std::vector<size_t> keys;
+  for (auto it = _multimesh_coefficients.begin(); it != _multimesh_coefficients.end(); it++)
+    keys.push_back(it->first);
+  return keys;
+}
+//-----------------------------------------------------------------------------
diff --git a/dolfin/fem/MultiMeshForm.h b/dolfin/fem/MultiMeshForm.h
index 97aceca..2508bba 100644
--- a/dolfin/fem/MultiMeshForm.h
+++ b/dolfin/fem/MultiMeshForm.h
@@ -29,6 +29,7 @@ namespace dolfin
 
   // Forward declarations
   class MultiMeshFunctionSpace;
+  class MultiMeshFunction;
   class MultiMesh;
   class Form;
 
@@ -103,6 +104,19 @@ namespace dolfin
     /// Clear MultiMesh form
     void clear();
 
+    /// Set MultiMeshCoeeficient
+    void set_multimesh_coefficient(std::size_t i,
+                                   std::shared_ptr<const MultiMeshFunction> coefficient);
+
+    /// Get all MultiMesh Coefficients
+    std::map<std::size_t, std::shared_ptr<const MultiMeshFunction>> multimesh_coefficients() const;
+
+    /// Get one multimesh coefficient
+    std::shared_ptr<const MultiMeshFunction> multimesh_coefficient(std::size_t i) const;
+
+    /// Get multimesh coefficient keys
+    std::vector<std::size_t> multimesh_coefficient_keys() const;
+
   private:
 
     // The rank of the form
@@ -117,6 +131,10 @@ namespace dolfin
     // List of forms (one for each part)
     std::vector<std::shared_ptr<const Form>> _forms;
 
+    // Map of MultiMesh coefficents
+    std::map<std::size_t, std::shared_ptr<const MultiMeshFunction>> _multimesh_coefficients;
+
+
   };
 
 }
diff --git a/dolfin/fem/PETScDMCollection.cpp b/dolfin/fem/PETScDMCollection.cpp
index 67009df..191a0fb 100644
--- a/dolfin/fem/PETScDMCollection.cpp
+++ b/dolfin/fem/PETScDMCollection.cpp
@@ -24,6 +24,7 @@
 #include <dolfin/la/PETScMatrix.h>
 #include <dolfin/la/PETScVector.h>
 #include <dolfin/geometry/BoundingBoxTree.h>
+#include <dolfin/function/Function.h>
 #include <dolfin/fem/FiniteElement.h>
 #include <dolfin/fem/GenericDofMap.h>
 #include <dolfin/common/RangedIndexSet.h>
diff --git a/dolfin/fem/PETScDMCollection.h b/dolfin/fem/PETScDMCollection.h
index a98d20a..325700a 100644
--- a/dolfin/fem/PETScDMCollection.h
+++ b/dolfin/fem/PETScDMCollection.h
@@ -40,7 +40,7 @@ namespace dolfin
   ///
   /// Warning: This classs is highly experimental and will change
 
-  class PETScDMCollection
+  class PETScDMCollection : public PETScObject
   {
   public:
 
diff --git a/dolfin/fem/UFC.h b/dolfin/fem/UFC.h
index ce8dc42..79351dc 100644
--- a/dolfin/fem/UFC.h
+++ b/dolfin/fem/UFC.h
@@ -97,7 +97,7 @@ namespace dolfin
 
     /// Pointer to coefficient data. Used to support UFC
     /// interface. None const version
-    double* * w()
+    double** w()
     { return w_pointer.data(); }
 
     /// Pointer to macro element coefficient data. Used to support UFC
@@ -105,6 +105,11 @@ namespace dolfin
     const double* const * macro_w() const
     { return macro_w_pointer.data(); }
 
+    /// Pointer to macro element coefficient data. Used to support UFC
+    /// interface. Non-const version.
+    double** macro_w()
+    { return macro_w_pointer.data(); }
+
   private:
 
     // Finite elements for coefficients
diff --git a/dolfin/fem/fem_utils.cpp b/dolfin/fem/fem_utils.cpp
index ad9e2bf..6ba9962 100644
--- a/dolfin/fem/fem_utils.cpp
+++ b/dolfin/fem/fem_utils.cpp
@@ -18,6 +18,7 @@
 #include <dolfin/common/ArrayView.h>
 #include <dolfin/fem/GenericDofMap.h>
 #include <dolfin/function/FunctionSpace.h>
+#include <dolfin/function/Function.h>
 #include <dolfin/mesh/Mesh.h>
 #include <dolfin/mesh/Vertex.h>
 #include <dolfin/mesh/MeshEntityIterator.h>
diff --git a/dolfin/function/Function.cpp b/dolfin/function/Function.cpp
index 1702dad..950b5da 100644
--- a/dolfin/function/Function.cpp
+++ b/dolfin/function/Function.cpp
@@ -295,8 +295,13 @@ void Function::eval(Array<double>& values, const Array<double>& x) const
   // If not found, use the closest cell
   if (id == std::numeric_limits<unsigned int>::max())
   {
-    if (_allow_extrapolation)
-      id = mesh.bounding_box_tree()->compute_closest_entity(point).first;
+    // Check if the closest cell is within DOLFIN_EPS. This we can
+    // allow without _allow_extrapolation
+    std::pair<unsigned int, double> close
+      = mesh.bounding_box_tree()->compute_closest_entity(point);
+
+    if (_allow_extrapolation or close.second < DOLFIN_EPS)
+      id = close.first;
     else
     {
       dolfin_error("Function.cpp",
diff --git a/dolfin/function/FunctionAssigner.cpp b/dolfin/function/FunctionAssigner.cpp
index be51656..d8b569d 100644
--- a/dolfin/function/FunctionAssigner.cpp
+++ b/dolfin/function/FunctionAssigner.cpp
@@ -23,6 +23,7 @@
 #include <dolfin/common/types.h>
 #include <dolfin/fem/GenericDofMap.h>
 #include <dolfin/function/FunctionSpace.h>
+#include <dolfin/function/Function.h>
 #include <dolfin/la/GenericVector.h>
 #include <dolfin/log/log.h>
 #include <dolfin/mesh/Cell.h>
diff --git a/dolfin/function/FunctionSpace.h b/dolfin/function/FunctionSpace.h
index ee040a5..313d5ff 100644
--- a/dolfin/function/FunctionSpace.h
+++ b/dolfin/function/FunctionSpace.h
@@ -149,7 +149,8 @@ namespace dolfin
     ///         The dofmap.
     std::shared_ptr<const GenericDofMap> dofmap() const;
 
-    /// Return dimension of function space
+    /// Return global dimension of the function space.
+    /// Equivalent to dofmap()->global_dimension()
     ///
     /// *Returns*
     ///     std::size_t
diff --git a/dolfin/function/MultiMeshCoefficientAssigner.cpp b/dolfin/function/MultiMeshCoefficientAssigner.cpp
index 5711558..996ea07 100644
--- a/dolfin/function/MultiMeshCoefficientAssigner.cpp
+++ b/dolfin/function/MultiMeshCoefficientAssigner.cpp
@@ -54,13 +54,16 @@ void MultiMeshCoefficientAssigner::operator=
 }
 //-----------------------------------------------------------------------------
 void MultiMeshCoefficientAssigner::operator=
-(const MultiMeshFunction& coefficient)
+(std::shared_ptr<const MultiMeshFunction> coefficient)
 {
+  dolfin_assert(coefficient);
   // Assign to all parts of form
   for (std::size_t part = 0; part < _form.num_parts(); part++)
   {
     Form& a = const_cast<Form&>(*_form.part(part));
-    a.set_coefficient(_number, coefficient.part(part));
+    a.set_coefficient(_number, coefficient->part(part));
   }
+  // Assign to multimesh form
+  _form.set_multimesh_coefficient(_number, coefficient);
 }
 //-----------------------------------------------------------------------------
diff --git a/dolfin/function/MultiMeshCoefficientAssigner.h b/dolfin/function/MultiMeshCoefficientAssigner.h
index 5187820..8455e29 100644
--- a/dolfin/function/MultiMeshCoefficientAssigner.h
+++ b/dolfin/function/MultiMeshCoefficientAssigner.h
@@ -59,7 +59,7 @@ namespace dolfin
     void operator= (std::shared_ptr<const GenericFunction> coefficient);
 
     /// Assign coefficient from MultiMeshFunction
-    void operator= (const MultiMeshFunction& coefficient);
+    void operator= (std::shared_ptr<const MultiMeshFunction> coefficient);
 
   private:
 
diff --git a/dolfin/function/MultiMeshFunction.cpp b/dolfin/function/MultiMeshFunction.cpp
index 83fd420..cdbafde 100644
--- a/dolfin/function/MultiMeshFunction.cpp
+++ b/dolfin/function/MultiMeshFunction.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2013-2016 Anders Logg
+// Copyright (C) 2013-2017 Anders Logg
 //
 // This file is part of DOLFIN.
 //
@@ -16,12 +16,13 @@
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 //
 // First added:  2013-09-25
-// Last changed: 2016-03-02
+// Last changed: 2017-10-09
 
 #include <dolfin/common/NoDeleter.h>
 #include <dolfin/la/GenericVector.h>
 #include <dolfin/la/DefaultFactory.h>
 #include <dolfin/fem/MultiMeshDofMap.h>
+#include <dolfin/geometry/BoundingBoxTree.h>
 #include "Function.h"
 #include "FunctionSpace.h"
 #include "MultiMeshFunctionSpace.h"
@@ -43,7 +44,7 @@ MultiMeshFunction::MultiMeshFunction(std::shared_ptr<const MultiMeshFunctionSpac
 }
 //-----------------------------------------------------------------------------
 MultiMeshFunction::MultiMeshFunction(std::shared_ptr<const MultiMeshFunctionSpace> V,
-                   std::shared_ptr<GenericVector> x)
+				     std::shared_ptr<GenericVector> x)
   : _function_space(V), _vector(x)
 {
   // We do not check for a subspace since this constructor is used for
@@ -74,13 +75,78 @@ std::shared_ptr<const Function> MultiMeshFunction::part(std::size_t i) const
   // Get view of function space for part
   std::shared_ptr<const FunctionSpace> V = _function_space->view(i);
 
-  // Insert into cache and return reference
-  std::shared_ptr<const Function> ui(new Function(V, _vector));
+  // Create and rename function for part
+  std::shared_ptr<Function> ui(new Function(V, _vector));
+  ui->rename(name(), label());
+
+  // Insert into cache
   _function_parts[i] = ui;
 
   return _function_parts.find(i)->second;
 }
 //-----------------------------------------------------------------------------
+void MultiMeshFunction::assign_part(std::size_t part, const Function& v)
+{
+  // Replace old values with new ones
+  std::size_t start_idx = 0;
+  for (std::size_t j = 0; j < part; ++j)
+    start_idx += _function_space->part(j)->dim();
+
+  const std::size_t N = v.vector()->size();
+
+  std::vector<double> buffer(N);
+  std::vector<la_index> indices(N);
+
+  // Get from [0,N)
+  std::iota(indices.begin(), indices.end(), 0);
+  v.vector()->get_local(buffer.data(), N, indices.data());
+
+  // set [start_idx, N+start_idx)
+  std::iota(indices.begin(), indices.end(), start_idx);
+  _vector->set_local(buffer.data(), N, indices.data());
+
+  // for (dolfin::la_index i = 0; i < (v.vector()->size()); ++i)
+  //     _vector->setitem(start_idx+i, v.vector()->getitem(i));
+}
+//-----------------------------------------------------------------------------
+std::shared_ptr<const Function> MultiMeshFunction::part(std::size_t i,
+							bool deepcopy) const
+{
+  if (not deepcopy)
+    return part(i);
+
+  assert(i < _function_space->num_parts());
+
+  // Create output function
+  std::shared_ptr<const FunctionSpace> V = _function_space->part(i);
+  std::shared_ptr<Function> ui(new Function(V));
+
+  // Finding the relevant part of the global vector
+  std::size_t start_idx = 0;
+  for (std::size_t j = 0; j < i; ++j)
+  {
+    start_idx += _function_space->part(j)->dim();
+  }
+
+  const std::size_t N = ui->vector()->size();
+  std::vector<double> buffer(N);
+  std::vector<dolfin::la_index> indices(N);
+
+  // Get [start_idx, N+start_idx)
+  std::iota(indices.begin(), indices.end(), start_idx);
+  _vector->get_local(buffer.data(), N, indices.data());
+
+  // set [0, N)
+  std::iota(indices.begin(), indices.end(), 0);
+  ui->vector()->set_local(buffer.data(), N, indices.data());
+
+  // // Copy values into output function
+  // for (dolfin::la_index i = 0; i < (ui->vector()->size()); ++i)
+  //     ui->vector()->setitem(i, _vector->getitem(start_idx+i));
+
+  return ui;
+}
+//-----------------------------------------------------------------------------
 std::shared_ptr<GenericVector> MultiMeshFunction::vector()
 {
   dolfin_assert(_vector);
@@ -146,8 +212,95 @@ void MultiMeshFunction::init_vector()
   _vector->zero();
 }
 //-----------------------------------------------------------------------------
+void MultiMeshFunction::restrict(double* w, const FiniteElement& element,
+                                 std::size_t part,
+                                 const Cell& dolfin_cell,
+                                 const double* coordinate_dofs,
+                                 const ufc::cell& ufc_cell) const
+{
+  dolfin_assert(w);
+  dolfin_assert(_function_space);
+  dolfin_assert(_function_space->dofmap());
+  dolfin_assert(part < _function_space->num_parts());
+
+  // Check if we are restricting to an element of this function space
+  if (_function_space->part(part)->has_element(element)
+      && _function_space->part(part)->has_cell(dolfin_cell))
+  {
+    // Get dofmap for cell
+    const GenericDofMap& dofmap = *_function_space->dofmap()->part(part);
+    const auto dofs = dofmap.cell_dofs(dolfin_cell.index());
+
+    // Note: We should have dofmap.max_element_dofs() == dofs.size() here.
+    // Pick values from vector(s)
+    _vector->get_local(w, dofs.size(), dofs.data());
+  }
+  else
+  {
+    // Restrict as UFC function (by calling eval)
+    restrict_as_ufc_function(w, element, part, dolfin_cell,
+                             coordinate_dofs, ufc_cell);
+  }
+}
+//-----------------------------------------------------------------------------
+void MultiMeshFunction::eval(Array<double>& values,
+			     const Array<double>& x,
+			     std::size_t part,
+			     const ufc::cell& ufc_cell) const
+{
+  dolfin_assert(_function_space);
+  dolfin_assert(_function_space->multimesh());
+  const Mesh& mesh = *_function_space->multimesh()->part(part);
+
+  // Check if UFC cell comes from mesh, otherwise
+  // find the cell which contains the point
+  dolfin_assert(ufc_cell.mesh_identifier >= 0);
+  if (ufc_cell.mesh_identifier == (int) mesh.id())
+  {
+    const Cell cell(mesh, ufc_cell.index);
+    this->part(part)->eval(values, x, cell, ufc_cell);
+  }
+  else
+    this->part(part)->eval(values, x);
+}
+//-----------------------------------------------------------------------------
+void MultiMeshFunction::eval(Array<double>& values,
+			     const Array<double>& x) const
+{
+  dolfin_assert(_function_space);
+  dolfin_assert(_function_space->multimesh());
+  const MultiMesh& multimesh = *_function_space->multimesh();
+
+  // Iterate over meshes from top to bottom
+  for (std::size_t j = 0; j < multimesh.num_parts(); j++)
+  {
+    std::size_t part = multimesh.num_parts() - 1 - j;
+
+    // Stop if we reached the bottom part (layer) or found layer containing point
+    if (part == 0 or multimesh.part(part)->bounding_box_tree()->collides_entity(Point(x)))
+    {
+      this->part(part)->eval(values, x);
+      break;
+    }
+  }
+}
+//-----------------------------------------------------------------------------
+void MultiMeshFunction::restrict_as_ufc_function(double* w,
+						 const FiniteElement& element,
+						 std::size_t part,
+						 const Cell& dolfin_cell,
+						 const double* coordinate_dofs,
+						 const ufc::cell& ufc_cell) const
+{
+  dolfin_assert(w);
+
+  // Evaluate dofs to get the expansion coefficients
+  element.evaluate_dofs(w, *this->part(part), coordinate_dofs, ufc_cell.orientation,
+                        ufc_cell);
+}
+//-----------------------------------------------------------------------------
 void MultiMeshFunction::compute_ghost_indices(std::pair<std::size_t, std::size_t> range,
-                                          std::vector<la_index>& ghost_indices) const
+					      std::vector<la_index>& ghost_indices) const
 {
   // NOTE: Well, don't implement me! Rather rewrite init_vector().
   //       See Function::init_vector().
diff --git a/dolfin/function/MultiMeshFunction.h b/dolfin/function/MultiMeshFunction.h
index 9c9de40..eea6ab6 100644
--- a/dolfin/function/MultiMeshFunction.h
+++ b/dolfin/function/MultiMeshFunction.h
@@ -33,6 +33,7 @@ namespace dolfin
   class GenericVector;
   class Function;
   class MultiMeshFunction;
+  class FiniteElement;
 
   /// This class represents a function on a cut and composite finite
   /// element function space (MultiMesh) defined on one or more possibly
@@ -68,6 +69,15 @@ namespace dolfin
     /// Destructor
     virtual ~MultiMeshFunction();
 
+    /// Assign Function to part of a mesh
+    ///
+    /// *Arguments*
+    ///     a (int)
+    ///         Part mesh assigned to
+    ///     V (_Function_)
+    ///         The vector
+    void assign_part(std::size_t a, const Function& v);
+
     /// Return function (part) number i
     ///
     /// *Returns*
@@ -75,6 +85,14 @@ namespace dolfin
     ///         Function (part) number i
     std::shared_ptr<const Function> part(std::size_t i) const;
 
+    /// Return a (deepcopy) function (part) number i
+    ///
+    /// *Returns*
+    ///     _Function_
+    ///         Function (part) number i
+    ///         bool deepcopy flag
+    std::shared_ptr<const Function> part(std::size_t i, bool deepcopy) const;
+    
     /// Return vector of expansion coefficients (non-const version)
     ///
     /// *Returns*
@@ -99,6 +117,50 @@ namespace dolfin
       return _function_space;
     }
 
+    /// Restrict function to local cell in given part (compute expansion coefficients w)
+    ///
+    /// *Arguments*
+    ///     w (list of doubles)
+    ///         Expansion coefficients.
+    ///     element (_FiniteElement_)
+    ///         The element.
+    ///     part (std::size_t)
+    ///         The mesh part
+    ///     dolfin_cell (_Cell_)
+    ///         The cell.
+    ///     ufc_cell (ufc::cell).
+    ///         The ufc::cell.
+    void restrict(double* w,
+                          const FiniteElement& element,
+                          std::size_t part,
+                          const Cell& dolfin_cell,
+                          const double* coordinate_dofs,
+                          const ufc::cell& ufc_cell) const;
+
+    /// Evaluate at given point in given cell in given part
+    ///
+    /// *Arguments*
+    ///     values (_Array_ <double>)
+    ///         The values at the point.
+    ///     x (_Array_ <double>)
+    ///         The coordinates of the point.
+    ///     cell (ufc::cell)
+    ///         The cell which contains the given point.
+    void eval(Array<double>& values, const Array<double>& x,
+                      std::size_t part,
+                      const ufc::cell& cell) const;
+
+    /// Evaluate at a given point
+    void eval(Array<double>& values, const Array<double>& x) const;
+
+    /// Restrict as UFC function (by calling eval)
+    void restrict_as_ufc_function(double* w,
+                                  const FiniteElement& element,
+                                  std::size_t part,
+                                  const Cell& dolfin_cell,
+                                  const double* coordinate_dofs,
+                                  const ufc::cell& ufc_cell) const;
+
   private:
 
     // Initialize vector
diff --git a/dolfin/function/MultiMeshFunctionSpace.cpp b/dolfin/function/MultiMeshFunctionSpace.cpp
index de2e2e6..2ca3082 100644
--- a/dolfin/function/MultiMeshFunctionSpace.cpp
+++ b/dolfin/function/MultiMeshFunctionSpace.cpp
@@ -26,6 +26,9 @@
 #include <dolfin/geometry/BoundingBoxTree.h>
 #include <dolfin/geometry/SimplexQuadrature.h>
 #include <dolfin/fem/MultiMeshDofMap.h>
+#include <dolfin/la/GenericMatrix.h>
+#include <dolfin/la/GenericVector.h>
+
 #include "FunctionSpace.h"
 #include "MultiMeshFunctionSpace.h"
 
@@ -36,7 +39,13 @@ MultiMeshFunctionSpace::MultiMeshFunctionSpace(std::shared_ptr<const MultiMesh>
   : _multimesh(multimesh),
     _dofmap(new MultiMeshDofMap())
 {
-  // Do nothing
+  // Check that multimesh has been built
+  if (!multimesh->is_built())
+  {
+    dolfin_error("MultiMeshFunctionSpace.cpp",
+		 "create multimesh function space",
+		 "Multimesh has not been built; did you forget to call multimesh.build()?");
+  }
 }
 //-----------------------------------------------------------------------------
 MultiMeshFunctionSpace::~MultiMeshFunctionSpace()
@@ -157,3 +166,25 @@ void MultiMeshFunctionSpace::_build_views()
   }
 }
 //-----------------------------------------------------------------------------
+void MultiMeshFunctionSpace::lock_inactive_dofs(GenericMatrix &A, GenericVector &b) const
+{
+  // Iterate over parts
+  for (std::size_t part = 0; part < num_parts(); part++)
+  {
+    // Get inactive dofs
+    std::vector<dolfin::la_index> inactive_dofs_on_part =
+      dofmap()->inactive_dofs(*multimesh(), part);
+
+    // Zero rows of A and put 1 on the diagonal
+    A.ident(inactive_dofs_on_part.size(), &inactive_dofs_on_part[0]);
+
+    // Zero entries in b
+    double zero = 0;
+    for (auto dof : inactive_dofs_on_part)
+    {
+      b.set(&zero, 1, &dof);
+    }
+    //std::vector<const double> zeroes(inactive_dofs_on_part.size());
+    //b.set(&zeroes[0], inactive_dofs_on_part.size(), &inactive_dofs_on_part[0]);
+  }
+}
diff --git a/dolfin/function/MultiMeshFunctionSpace.h b/dolfin/function/MultiMeshFunctionSpace.h
index cb6e820..c7a6a44 100644
--- a/dolfin/function/MultiMeshFunctionSpace.h
+++ b/dolfin/function/MultiMeshFunctionSpace.h
@@ -16,7 +16,7 @@
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 //
 // First added:  2013-08-05
-// Last changed: 2016-03-02
+// Last changed: 2017-09-22
 
 #ifndef __MULTI_MESH_FUNCTION_SPACE_H
 #define __MULTI_MESH_FUNCTION_SPACE_H
@@ -33,6 +33,8 @@ namespace dolfin
 {
 
   // Forward declarations
+  class GenericMatrix;
+  class GenericVector;
   class FunctionSpace;
   class MultiMeshDofMap;
 
@@ -120,6 +122,9 @@ namespace dolfin
     /// computed from the full function spaces on each part.
     void build(const std::vector<dolfin::la_index>& offsets);
 
+    /// Lock inactive dofs of a system
+    void lock_inactive_dofs(GenericMatrix &A, GenericVector &b) const;
+
   private:
 
     // Friends
diff --git a/dolfin/generation/BoxMesh.cpp b/dolfin/generation/BoxMesh.cpp
index 5fe1fac..eb6dc25 100644
--- a/dolfin/generation/BoxMesh.cpp
+++ b/dolfin/generation/BoxMesh.cpp
@@ -44,11 +44,11 @@ BoxMesh::BoxMesh(const Point& p0, const Point& p1,
 BoxMesh::BoxMesh(MPI_Comm comm, const Point& p0, const Point& p1,
                  std::size_t nx, std::size_t ny, std::size_t nz) : Mesh(comm)
 {
-  build(*this, {{p0, p1}}, {{nx, ny, nz}});
+  build_tet(*this, {{p0, p1}}, {{nx, ny, nz}});
 }
 //-----------------------------------------------------------------------------
-void BoxMesh::build(Mesh& mesh, const std::array<Point,2 >& p,
-                    std::array<std::size_t, 3> n)
+void BoxMesh::build_tet(Mesh& mesh, const std::array<Point,2 >& p,
+                        std::array<std::size_t, 3> n)
 {
   Timer timer("Build BoxMesh");
 
@@ -100,7 +100,7 @@ void BoxMesh::build(Mesh& mesh, const std::array<Point,2 >& p,
 
   // Open mesh for editing
   MeshEditor editor;
-  editor.open(mesh, CellType::tetrahedron, 3, 3);
+  editor.open(mesh, CellType::Type::tetrahedron, 3, 3);
 
   // Storage for vertex coordinates
   std::vector<double> x(3);
@@ -169,3 +169,85 @@ void BoxMesh::build(Mesh& mesh, const std::array<Point,2 >& p,
   }
 }
 //-----------------------------------------------------------------------------
+void BoxMesh::build_hex(Mesh& mesh, std::array<std::size_t, 3> n)
+{
+  // Receive mesh according to parallel policy
+  if (MPI::is_receiver(mesh.mpi_comm()))
+  {
+    MeshPartitioning::build_distributed_mesh(mesh);
+    return;
+  }
+
+  const std::size_t nx = n[0];
+  const std::size_t ny = n[1];
+  const std::size_t nz = n[2];
+
+  MeshEditor editor;
+  editor.open(mesh, CellType::Type::hexahedron, 3, 3);
+
+  // Create vertices and cells:
+  editor.init_vertices_global((nx + 1)*(ny + 1)*(nz + 1),
+                              (nx + 1)*(ny + 1)*(nz + 1));
+  editor.init_cells_global(nx*ny*nz, nx*ny*nz);
+
+  // Storage for vertices
+  std::vector<double> x(3);
+
+  const double a = 0.0;
+  const double b = 1.0;
+  const double c = 0.0;
+  const double d = 1.0;
+  const double e = 0.0;
+  const double f = 1.0;
+
+  // Create main vertices:
+  std::size_t vertex = 0;
+  for (std::size_t iz = 0; iz <= nz; iz++)
+  {
+    x[2] = e + ((static_cast<double>(iz))*(f - e)/static_cast<double>(nz));
+    for (std::size_t iy = 0; iy <= ny; iy++)
+    {
+      x[1] = c + ((static_cast<double>(iy))*(d - c)/static_cast<double>(ny));
+      for (std::size_t ix = 0; ix <= nx; ix++)
+      {
+        x[0] = a + ((static_cast<double>(ix))*(b - a)/static_cast<double>(nx));
+        editor.add_vertex(vertex, x);
+        vertex++;
+      }
+    }
+  }
+
+  // Create cuboids
+  std::size_t cell = 0;
+  std::vector<std::size_t> v(8);
+  for (std::size_t iz = 0; iz < nz; iz++)
+  {
+    for (std::size_t iy = 0; iy < ny; iy++)
+    {
+      for (std::size_t ix = 0; ix < nx; ix++)
+      {
+        v[0] = (iz*(ny + 1) + iy)*(nx + 1) + ix;
+        v[1] = v[0] + 1;
+        v[2] = v[0] + (nx + 1);
+        v[3] = v[1] + (nx + 1);
+        v[4] = v[0] + (nx + 1)*(ny + 1);
+        v[5] = v[1] + (nx + 1)*(ny + 1);
+        v[6] = v[2] + (nx + 1)*(ny + 1);
+        v[7] = v[3] + (nx + 1)*(ny + 1);
+        editor.add_cell(cell, v);
+        ++cell;
+      }
+    }
+  }
+
+  // Close mesh editor
+  editor.close();
+
+  // Broadcast mesh according to parallel policy
+  if (MPI::is_broadcaster(mesh.mpi_comm()))
+  {
+    MeshPartitioning::build_distributed_mesh(mesh);
+    return;
+  }
+}
+//-----------------------------------------------------------------------------
diff --git a/dolfin/generation/BoxMesh.h b/dolfin/generation/BoxMesh.h
index eb6af19..cd4b624 100644
--- a/dolfin/generation/BoxMesh.h
+++ b/dolfin/generation/BoxMesh.h
@@ -20,6 +20,7 @@
 
 #include <array>
 #include <cstddef>
+#include <dolfin/log/log.h>
 #include <dolfin/common/MPI.h>
 #include <dolfin/mesh/Mesh.h>
 
@@ -44,6 +45,8 @@ namespace dolfin
     ///         Points of box.
     /// @param n (std::array<double, 3> )
     ///         Number of cells in each direction.
+    /// @param cell_type
+    ///         Tetrahedron or Hexahedron
     ///
     /// @code{.cpp}
     ///         // Mesh with 8 cells in each direction on the
@@ -52,8 +55,8 @@ namespace dolfin
     ///         Point p1(2, 2, 2);
     ///         auto mesh = BoxMesh::create({p0, p1}, {8, 8, 8});
     /// @endcode
-    static Mesh create(const std::array<Point,2 >& p, std::array<std::size_t, 3> n)
-    { return create(MPI_COMM_WORLD, p, n); }
+    static Mesh create(const std::array<Point,2 >& p, std::array<std::size_t, 3> n, CellType::Type cell_type)
+    { return create(MPI_COMM_WORLD, p, n, cell_type); }
 
     /// Create a uniform finite element _Mesh_ over the rectangular
     /// prism spanned by the two _Point_s p0 and p1. The order of the
@@ -66,6 +69,8 @@ namespace dolfin
     ///         Points of box.
     /// @param n (std::array<double, 3> )
     ///         Number of cells in each direction.
+    /// @param cell_type
+    ///         Tetrahedron or hexahedron
     ///
     /// @code{.cpp}
     ///         // Mesh with 8 cells in each direction on the
@@ -75,10 +80,20 @@ namespace dolfin
     ///         auto mesh = BoxMesh::create({p0, p1}, {8, 8, 8});
     /// @endcode
     static Mesh create(MPI_Comm comm, const std::array<Point, 2>& p,
-                       std::array<std::size_t, 3> n)
+                       std::array<std::size_t, 3> n, CellType::Type cell_type)
     {
       Mesh mesh(comm);
-      build(mesh, p, n);
+      if (cell_type == CellType::Type::tetrahedron)
+        build_tet(mesh, p, n);
+      else if (cell_type == CellType::Type::hexahedron)
+        build_hex(mesh, n);
+      else
+      {
+        dolfin_error("BoxMesh.h",
+                     "generate box mesh",
+                     "Wrong cell type '%d'", cell_type);
+      }
+
       return mesh;
     }
 
@@ -141,8 +156,10 @@ namespace dolfin
   private:
 
     // Build mesh
-    static void build(Mesh& mesh, const std::array<Point, 2>& p,
-                      std::array<std::size_t, 3> n);
+    static void build_tet(Mesh& mesh, const std::array<Point, 2>& p,
+                          std::array<std::size_t, 3> n);
+
+    static void build_hex(Mesh& mesh, std::array<std::size_t, 3> n);
 
   };
 
diff --git a/dolfin/generation/CMakeLists.txt b/dolfin/generation/CMakeLists.txt
index de80d24..b705cea 100644
--- a/dolfin/generation/CMakeLists.txt
+++ b/dolfin/generation/CMakeLists.txt
@@ -6,9 +6,7 @@ set(HEADERS
   SphericalShellMesh.h
   UnitCubeMesh.h
   UnitDiscMesh.h
-  UnitHexMesh.h
   UnitIntervalMesh.h
-  UnitQuadMesh.h
   UnitSquareMesh.h
   UnitTetrahedronMesh.h
   UnitTriangleMesh.h
@@ -20,8 +18,6 @@ set(SOURCES
   RectangleMesh.cpp
   SphericalShellMesh.cpp
   UnitDiscMesh.cpp
-  UnitHexMesh.cpp
-  UnitQuadMesh.cpp
   UnitTetrahedronMesh.cpp
   UnitTriangleMesh.cpp
   PARENT_SCOPE)
diff --git a/dolfin/generation/IntervalMesh.cpp b/dolfin/generation/IntervalMesh.cpp
index c2d180b..b49036a 100644
--- a/dolfin/generation/IntervalMesh.cpp
+++ b/dolfin/generation/IntervalMesh.cpp
@@ -75,7 +75,7 @@ void IntervalMesh::build(Mesh& mesh, std::size_t nx, std::array<double, 2> x)
 
   // Open mesh for editing
   MeshEditor editor;
-  editor.open(mesh, CellType::interval, 1, 1);
+  editor.open(mesh, CellType::Type::interval, 1, 1);
 
   // Create vertices and cells:
   editor.init_vertices_global((nx+1), (nx+1));
diff --git a/dolfin/generation/RectangleMesh.cpp b/dolfin/generation/RectangleMesh.cpp
index 63502ab..4697a05 100644
--- a/dolfin/generation/RectangleMesh.cpp
+++ b/dolfin/generation/RectangleMesh.cpp
@@ -40,12 +40,12 @@ RectangleMesh::RectangleMesh(MPI_Comm comm,
                              std::size_t nx, std::size_t ny,
                              std::string diagonal) : Mesh(comm)
 {
-  build(*this, {{p0, p1}}, {{nx, ny}}, diagonal);
+  build_tri(*this, {{p0, p1}}, {{nx, ny}}, diagonal);
 }
 //-----------------------------------------------------------------------------
-void RectangleMesh::build(Mesh& mesh, const std::array<Point, 2>& p,
-                          std::array<std::size_t, 2> n,
-                          std::string diagonal)
+void RectangleMesh::build_tri(Mesh& mesh, const std::array<Point, 2>& p,
+                              std::array<std::size_t, 2> n,
+                              std::string diagonal)
 {
   // Receive mesh according to parallel policy
   if (MPI::is_receiver(mesh.mpi_comm()))
@@ -98,7 +98,7 @@ void RectangleMesh::build(Mesh& mesh, const std::array<Point, 2>& p,
 
   // Open mesh for editing
   MeshEditor editor;
-  editor.open(mesh, CellType::triangle, 2, 2);
+  editor.open(mesh, CellType::Type::triangle, 2, 2);
 
   // Create vertices and cells:
   if (diagonal == "crossed")
@@ -232,3 +232,70 @@ void RectangleMesh::build(Mesh& mesh, const std::array<Point, 2>& p,
   }
 }
 //-----------------------------------------------------------------------------
+void RectangleMesh::build_quad(Mesh& mesh, const std::array<Point, 2>& p,
+                               std::array<std::size_t, 2> n)
+{
+  // Receive mesh according to parallel policy
+  if (MPI::is_receiver(mesh.mpi_comm()))
+  {
+    MeshPartitioning::build_distributed_mesh(mesh);
+    return;
+  }
+
+  const std::size_t nx = n[0];
+  const std::size_t ny = n[1];
+
+  MeshEditor editor;
+  editor.open(mesh, CellType::Type::quadrilateral, 2, 2);
+
+  // Create vertices and cells:
+  editor.init_vertices_global((nx + 1)*(ny + 1), (nx + 1)*(ny + 1));
+  editor.init_cells_global(nx*ny, nx*ny);
+
+  // Storage for vertices
+  std::vector<double> x(2);
+
+  const double a = 0.0;
+  const double b = 1.0;
+  const double c = 0.0;
+  const double d = 1.0;
+
+  // Create main vertices:
+  std::size_t vertex = 0;
+  for (std::size_t iy = 0; iy <= ny; iy++)
+  {
+    x[1] = c + ((static_cast<double>(iy))*(d - c)/static_cast<double>(ny));
+    for (std::size_t ix = 0; ix <= nx; ix++)
+    {
+      x[0] = a + ((static_cast<double>(ix))*(b - a)/static_cast<double>(nx));
+      editor.add_vertex(vertex, x);
+      vertex++;
+    }
+  }
+
+  // Create rectangles
+  std::size_t cell = 0;
+  std::vector<std::size_t> v(4);
+  for (std::size_t iy = 0; iy < ny; iy++)
+    for (std::size_t ix = 0; ix < nx; ix++)
+    {
+      v[0] = iy*(nx + 1) + ix;
+      v[1] = v[0] + 1;
+      v[2] = v[0] + (nx + 1);
+      v[3] = v[1] + (nx + 1);
+      editor.add_cell(cell, v);
+      ++cell;
+    }
+
+  // Close mesh editor
+  editor.close();
+
+  // Broadcast mesh according to parallel policy
+  if (MPI::is_broadcaster(mesh.mpi_comm()))
+  {
+    MeshPartitioning::build_distributed_mesh(mesh);
+    return;
+  }
+
+}
+//-----------------------------------------------------------------------------
diff --git a/dolfin/generation/RectangleMesh.h b/dolfin/generation/RectangleMesh.h
index 796dc03..1df237f 100644
--- a/dolfin/generation/RectangleMesh.h
+++ b/dolfin/generation/RectangleMesh.h
@@ -21,6 +21,8 @@
 #include <array>
 #include <string>
 #include <dolfin/common/MPI.h>
+#include <dolfin/log/log.h>
+#include <dolfin/mesh/CellType.h>
 #include <dolfin/mesh/Mesh.h>
 
 namespace dolfin
@@ -39,21 +41,24 @@ namespace dolfin
     ///         Vertex points.
     /// @param    n (std::array<std::size_t, 2>)
     ///         Number of cells in each direction
+    /// @param    cell_type (dolfin::CellType::Type)
+    ///         Cell type
     /// @param    diagonal (string)
     ///         Direction of diagonals: "left", "right", "left/right", "crossed"
     ///
     /// @code{.cpp}
     ///
-    ///         // Mesh with 8 cells in each direction on the
+    ///         // Mesh with 8 cell edges in each direction on the
     ///         // set [-1,2] x [-1,2]
     ///         Point p0(-1, -1);
     ///         Point p1(2, 2);
     ///         auto Mesh = RectangleMesh::create({p0, p1}, {8, 8});
     /// @endcode
-    static Mesh create(const std::array<Point, 2>& p, std::array<std::size_t, 2> n,
+    static Mesh create(const std::array<Point, 2>& p,
+                       std::array<std::size_t, 2> n,
+                       CellType::Type cell_type,
                        std::string diagonal="right")
-    { return create(MPI_COMM_WORLD, p, n); }
-
+    { return create(MPI_COMM_WORLD, p, n, cell_type, diagonal); }
 
     /// @param    comm (MPI_Comm)
     ///         MPI communicator
@@ -61,6 +66,8 @@ namespace dolfin
     ///         Vertex points.
     /// @param    n (std::array<std::size_t, 2>)
     ///         Number of cells in each direction
+    /// @param    cell_type (dolfin::CellType::Type)
+    ///         Cell type
     /// @param    diagonal (string)
     ///         Direction of diagonals: "left", "right", "left/right", "crossed"
     ///
@@ -74,12 +81,25 @@ namespace dolfin
     /// @endcode
     static Mesh create(MPI_Comm comm, const std::array<Point, 2>& p,
                        std::array<std::size_t, 2> n,
+                       CellType::Type cell_type,
                        std::string diagonal="right")
-    { Mesh mesh(comm);
-      build(mesh, p, n);
+    {
+      Mesh mesh(comm);
+      if (cell_type == CellType::Type::triangle)
+        build_tri(mesh, p, n, diagonal);
+      else if (cell_type == CellType::Type::quadrilateral)
+        build_quad(mesh, p, n);
+      else
+      {
+        dolfin_error("RectangleMesh.h",
+                     "generate rectangle mesh",
+                     "Wrong cell type '%d'", cell_type);
+      }
+
       return mesh;
     }
 
+    // Deprecated
     /// @param    p0 (_Point_)
     ///         First point.
     /// @param    p1 (_Point_)
@@ -103,6 +123,7 @@ namespace dolfin
                   std::size_t nx, std::size_t ny,
                   std::string diagonal="right");
 
+    // Deprecated
     /// @param    comm (MPI_Comm)
     ///         MPI communicator
     /// @param    p0 (_Point_)
@@ -132,10 +153,13 @@ namespace dolfin
   private:
 
     // Build mesh
-    static void build(Mesh& mesh, const std::array<Point, 2>& p,
-                      std::array<std::size_t, 2> n,
-                      std::string diagonal="right");
+    static void build_tri(Mesh& mesh, const std::array<Point, 2>& p,
+                          std::array<std::size_t, 2> n,
+                          std::string diagonal="right");
+
 
+    static void build_quad(Mesh& mesh, const std::array<Point, 2>& p,
+                           std::array<std::size_t, 2> n);
   };
 
 }
diff --git a/dolfin/generation/SphericalShellMesh.cpp b/dolfin/generation/SphericalShellMesh.cpp
index 963fc9e..eefc731 100644
--- a/dolfin/generation/SphericalShellMesh.cpp
+++ b/dolfin/generation/SphericalShellMesh.cpp
@@ -32,7 +32,7 @@ void SphericalShellMesh::build(Mesh& mesh, std::size_t degree)
   const std::size_t gdim = 3;
 
   dolfin_assert(degree > 0 and degree < 3);
-  editor.open(mesh, tdim, gdim, degree);
+  editor.open(mesh, CellType::Type::triangle, tdim, gdim, degree);
 
   editor.init_vertices_global(12, 12);
 
diff --git a/dolfin/generation/UnitCubeMesh.h b/dolfin/generation/UnitCubeMesh.h
index 4267bd6..0be213a 100644
--- a/dolfin/generation/UnitCubeMesh.h
+++ b/dolfin/generation/UnitCubeMesh.h
@@ -21,12 +21,13 @@
 #include <array>
 #include <cstddef>
 #include <dolfin/common/MPI.h>
+#include <dolfin/mesh/CellType.h>
 #include "BoxMesh.h"
 
 namespace dolfin
 {
 
-  /// Tetrahedral mesh of the 3D unit cube [0,1] x [0,1] x [0,1].
+  /// Tetrahedral/hexahedral mesh of the 3D unit cube [0,1] x [0,1] x [0,1].
   /// Given the number of cells (nx, ny, nz) in each direction, the
   /// total number of tetrahedra will be 6*nx*ny*nz and the total
   /// number of vertices will be (nx + 1)*(ny + 1)*(nz + 1).
@@ -40,13 +41,14 @@ namespace dolfin
     ///
     /// @param    n (std::array<std::size_t, 3>)
     ///         Number of cells in each direction.
-    ///
+    /// @param    cell_type
+    ///         Tetrahedron or hexahedron
     /// @code{.cpp}
     ///
-    ///         auto mesh = UnitCubeMesh::create(32, 32, 32);
+    ///         auto mesh = UnitCubeMesh::create(32, 32, 32, CellType::Type::tetrahedron);
     /// @endcode
-    static Mesh create(std::array<std::size_t, 3> n)
-    { return create(MPI_COMM_WORLD, n); }
+    static Mesh create(std::array<std::size_t, 3> n, CellType::Type cell_type)
+    { return create(MPI_COMM_WORLD, n, cell_type); }
 
     /// Create a uniform finite element _Mesh_ over the unit cube
     /// [0,1] x [0,1] x [0,1].
@@ -55,12 +57,26 @@ namespace dolfin
     ///         MPI communicator
     /// @param    n (std::aray<std::size_t, 3>)
     ///         Number of cells in each direction.
+    /// @param    cell_type
+    ///         Tetrahedron or hexahedron
     ///
     /// @code{.cpp}
-    ///         auto mesh = UnitCubeMesh::create(MPI_COMM_WORLD, 32, 32, 32);
+    ///         auto mesh = UnitCubeMesh::create(MPI_COMM_WORLD, {32, 32, 32}, CellType::Type::hexahedron);
     /// @endcode
-    static Mesh create(MPI_Comm comm, std::array<std::size_t, 3> n)
-    { return BoxMesh::create(comm, {{Point(0.0, 0.0, 0.0), Point(1.0, 1.0, 1.0)}}, n); }
+    static Mesh create(MPI_Comm comm, std::array<std::size_t, 3> n, CellType::Type cell_type)
+    { return BoxMesh::create(comm, {{Point(0.0, 0.0, 0.0), Point(1.0, 1.0, 1.0)}}, n, cell_type); }
+
+    // Temporary - part of pybind11 transition and will be
+    // removed. Avoid using.
+    static Mesh create(std::size_t nx, std::size_t ny, std::size_t nz,
+                       CellType::Type cell_type)
+    { return create({nx, ny, nz}, cell_type); }
+
+    // Temporary - part of pybind11 transition and will be
+    // removed. Avoid using.
+    static Mesh create(MPI_Comm comm, std::size_t nx, std::size_t ny, std::size_t nz,
+                       CellType::Type cell_type)
+    { return create({nx, ny, nz}, cell_type); }
 
     /// Create a uniform finite element _Mesh_ over the unit cube
     /// [0,1] x [0,1] x [0,1].
diff --git a/dolfin/generation/UnitDiscMesh.cpp b/dolfin/generation/UnitDiscMesh.cpp
index daaf5f8..3eaa0bc 100644
--- a/dolfin/generation/UnitDiscMesh.cpp
+++ b/dolfin/generation/UnitDiscMesh.cpp
@@ -45,7 +45,7 @@ void UnitDiscMesh::build(Mesh& mesh, std::size_t n, std::size_t degree,
   }
 
   MeshEditor editor;
-  editor.open(mesh, 2, gdim, degree);
+  editor.open(mesh, CellType::Type::triangle, 2, gdim, degree);
   editor.init_vertices_global(1 + 3*n*(n + 1), 1 + 3*n*(n + 1));
 
   std::size_t c = 0;
diff --git a/dolfin/generation/UnitHexMesh.cpp b/dolfin/generation/UnitHexMesh.cpp
deleted file mode 100644
index 2da4f66..0000000
--- a/dolfin/generation/UnitHexMesh.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright (C) 2015 Chris Richardson
-//
-// This file is part of DOLFIN.
-//
-// DOLFIN is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// DOLFIN 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 Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
-//
-
-// NB: this code is experimental, just for testing, and will generally not
-// work with anything else
-
-#include <dolfin/common/constants.h>
-#include <dolfin/mesh/MeshEditor.h>
-#include <dolfin/mesh/MeshPartitioning.h>
-#include "UnitHexMesh.h"
-
-using namespace dolfin;
-
-//-----------------------------------------------------------------------------
-void UnitHexMesh::build(Mesh& mesh, std::array<std::size_t, 3> n)
-{
-  // Receive mesh according to parallel policy
-  if (MPI::is_receiver(mesh.mpi_comm()))
-  {
-    MeshPartitioning::build_distributed_mesh(mesh);
-    return;
-  }
-
-  const std::size_t nx = n[0];
-  const std::size_t ny = n[1];
-  const std::size_t nz = n[2];
-
-  MeshEditor editor;
-  editor.open(mesh, CellType::hexahedron, 3, 3);
-
-  // Create vertices and cells:
-  editor.init_vertices_global((nx + 1)*(ny + 1)*(nz + 1),
-                              (nx + 1)*(ny + 1)*(nz + 1));
-  editor.init_cells_global(nx*ny*nz, nx*ny*nz);
-
-  // Storage for vertices
-  std::vector<double> x(3);
-
-  const double a = 0.0;
-  const double b = 1.0;
-  const double c = 0.0;
-  const double d = 1.0;
-  const double e = 0.0;
-  const double f = 1.0;
-
-  // Create main vertices:
-  std::size_t vertex = 0;
-  for (std::size_t iz = 0; iz <= nz; iz++)
-  {
-    x[2] = e + ((static_cast<double>(iz))*(f - e)/static_cast<double>(nz));
-    for (std::size_t iy = 0; iy <= ny; iy++)
-    {
-      x[1] = c + ((static_cast<double>(iy))*(d - c)/static_cast<double>(ny));
-      for (std::size_t ix = 0; ix <= nx; ix++)
-      {
-        x[0] = a + ((static_cast<double>(ix))*(b - a)/static_cast<double>(nx));
-        editor.add_vertex(vertex, x);
-        vertex++;
-      }
-    }
-  }
-
-  // Create cuboids
-  std::size_t cell = 0;
-  std::vector<std::size_t> v(8);
-  for (std::size_t iz = 0; iz < nz; iz++)
-  {
-    for (std::size_t iy = 0; iy < ny; iy++)
-    {
-      for (std::size_t ix = 0; ix < nx; ix++)
-      {
-        v[0] = (iz*(ny + 1) + iy)*(nx + 1) + ix;
-        v[1] = v[0] + 1;
-        v[2] = v[0] + (nx + 1);
-        v[3] = v[1] + (nx + 1);
-        v[4] = v[0] + (nx + 1)*(ny + 1);
-        v[5] = v[1] + (nx + 1)*(ny + 1);
-        v[6] = v[2] + (nx + 1)*(ny + 1);
-        v[7] = v[3] + (nx + 1)*(ny + 1);
-        editor.add_cell(cell, v);
-        ++cell;
-      }
-    }
-  }
-
-  // Close mesh editor
-  editor.close();
-
-  // Broadcast mesh according to parallel policy
-  if (MPI::is_broadcaster(mesh.mpi_comm()))
-  {
-    MeshPartitioning::build_distributed_mesh(mesh);
-    return;
-  }
-}
-//-----------------------------------------------------------------------------
diff --git a/dolfin/generation/UnitHexMesh.h b/dolfin/generation/UnitHexMesh.h
deleted file mode 100644
index 67b6657..0000000
--- a/dolfin/generation/UnitHexMesh.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (C) 2015 Chris Richardson
-//
-// This file is part of DOLFIN.
-//
-// DOLFIN is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// DOLFIN 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 Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
-//
-
-#ifndef __UNITHEXMESH_MESH_H
-#define __UNITHEXMESH_MESH_H
-
-#include <string>
-#include <dolfin/common/MPI.h>
-#include <dolfin/mesh/Mesh.h>
-
-namespace dolfin
-{
-
-  /// NB: this code is experimental, just for testing, and will
-  /// generally not work with anything else
-  class UnitHexMesh
-  {
-  public:
-
-    /// NB: this code is experimental, just for testing, and will generally not
-    /// work with anything else
-    static Mesh create(std::size_t nx, std::size_t ny, std::size_t nz)
-    { return create(MPI_COMM_WORLD, nx, ny, nz); }
-
-    /// Create mesh
-    static Mesh create(MPI_Comm comm, std::size_t nx, std::size_t ny, std::size_t nz)
-    {
-      Mesh mesh(comm);
-      build(mesh, {{nx, ny, nz}});
-      return mesh;
-    }
-
-  private:
-
-    static void build(Mesh& mesh, std::array<std::size_t, 3>);
-
-  };
-
-}
-
-#endif
diff --git a/dolfin/generation/UnitQuadMesh.cpp b/dolfin/generation/UnitQuadMesh.cpp
deleted file mode 100644
index f7d0746..0000000
--- a/dolfin/generation/UnitQuadMesh.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright (C) 2015 Chris Richardson
-//
-// This file is part of DOLFIN.
-//
-// DOLFIN is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// DOLFIN 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 Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
-//
-
-
-// NB: this code is experimental, just for testing, and will generally not
-// work with anything else
-
-#include <dolfin/common/constants.h>
-#include <dolfin/mesh/MeshEditor.h>
-#include <dolfin/mesh/MeshPartitioning.h>
-#include "UnitQuadMesh.h"
-
-using namespace dolfin;
-
-//-----------------------------------------------------------------------------
-void UnitQuadMesh::build(Mesh& mesh, std::array<std::size_t, 2> n)
-{
-  // Receive mesh according to parallel policy
-  if (MPI::is_receiver(mesh.mpi_comm()))
-  {
-    MeshPartitioning::build_distributed_mesh(mesh);
-    return;
-  }
-
-  const std::size_t nx = n[0];
-  const std::size_t ny = n[1];
-
-  MeshEditor editor;
-  editor.open(mesh, CellType::quadrilateral, 2, 2);
-
-  // Create vertices and cells:
-  editor.init_vertices_global((nx + 1)*(ny + 1), (nx + 1)*(ny + 1));
-  editor.init_cells_global(nx*ny, nx*ny);
-
-  // Storage for vertices
-  std::vector<double> x(2);
-
-  const double a = 0.0;
-  const double b = 1.0;
-  const double c = 0.0;
-  const double d = 1.0;
-
-  // Create main vertices:
-  std::size_t vertex = 0;
-  for (std::size_t iy = 0; iy <= ny; iy++)
-  {
-    x[1] = c + ((static_cast<double>(iy))*(d - c)/static_cast<double>(ny));
-    for (std::size_t ix = 0; ix <= nx; ix++)
-    {
-      x[0] = a + ((static_cast<double>(ix))*(b - a)/static_cast<double>(nx));
-      editor.add_vertex(vertex, x);
-      vertex++;
-    }
-  }
-
-  // Create rectangles
-  std::size_t cell = 0;
-  std::vector<std::size_t> v(4);
-  for (std::size_t iy = 0; iy < ny; iy++)
-    for (std::size_t ix = 0; ix < nx; ix++)
-    {
-      v[0] = iy*(nx + 1) + ix;
-      v[1] = v[0] + 1;
-      v[2] = v[0] + (nx + 1);
-      v[3] = v[1] + (nx + 1);
-      editor.add_cell(cell, v);
-      ++cell;
-    }
-
-  // Close mesh editor
-  editor.close();
-
-  // Broadcast mesh according to parallel policy
-  if (MPI::is_broadcaster(mesh.mpi_comm()))
-  {
-    MeshPartitioning::build_distributed_mesh(mesh);
-    return;
-  }
-
-}
-//-----------------------------------------------------------------------------
diff --git a/dolfin/generation/UnitQuadMesh.h b/dolfin/generation/UnitQuadMesh.h
deleted file mode 100644
index 5f389bb..0000000
--- a/dolfin/generation/UnitQuadMesh.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (C) 2015 Chris Richardson
-//
-// This file is part of DOLFIN.
-//
-// DOLFIN is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// DOLFIN 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 Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
-//
-
-#ifndef __UNITQUADMESH_MESH_H
-#define __UNITQUADMESH_MESH_H
-
-#include <string>
-#include <dolfin/common/MPI.h>
-#include <dolfin/mesh/Mesh.h>
-
-namespace dolfin
-{
-
-  /// NB: this code is experimental, just for testing, and will
-  /// generally not work with anything else
-
-  class UnitQuadMesh : public Mesh
-  {
-  public:
-
-    /// NB: this code is experimental, just for testing, and will generally not
-    /// work with anything else
-
-    /// Create a mesh
-    static Mesh create(std::size_t nx, std::size_t ny)
-    { return create(MPI_COMM_WORLD, nx, ny); }
-
-    /// Create a mesh
-    static Mesh create(MPI_Comm comm, std::size_t nx, std::size_t ny)
-    {
-      Mesh mesh(comm);
-      build(mesh, {{nx, ny}});;
-      return mesh;
-    }
-
-  private:
-
-    static void build(Mesh& mesh, std::array<std::size_t, 2> n);
-
-  };
-
-}
-
-#endif
diff --git a/dolfin/generation/UnitSquareMesh.h b/dolfin/generation/UnitSquareMesh.h
index 8d68533..6bb0dd5 100644
--- a/dolfin/generation/UnitSquareMesh.h
+++ b/dolfin/generation/UnitSquareMesh.h
@@ -25,12 +25,13 @@
 
 #include <array>
 #include <string>
+#include <dolfin/mesh/CellType.h>
 #include "RectangleMesh.h"
 
 namespace dolfin
 {
 
-  /// Triangular mesh of the 2D unit square [0,1] x [0,1].  Given the
+  /// Triangular/quadrilateral mesh of the 2D unit square [0,1] x [0,1].  Given the
   /// number of cells (nx, ny) in each direction, the total number of
   /// triangles will be 2*nx*ny and the total number of vertices will
   /// be (nx + 1)*(ny + 1).
@@ -47,6 +48,8 @@ namespace dolfin
     ///
     /// @param    n (std:::array<std::size_t, 2>)
     ///         Number of cells in each direction.
+    /// @param    cell_type
+    ///         Triangle or quadrilateral
     /// @param    diagonal (std::string)
     ///         Optional argument: A std::string indicating
     ///         the direction of the diagonals.
@@ -56,8 +59,32 @@ namespace dolfin
     ///         auto mesh1 = UnitSquareMesh::create(32, 32);
     ///         auto mesh2 = UnitSquareMesh::create(32, 32, "crossed");
     /// @endcode
-    static Mesh create(std::array<std::size_t, 2> n, std::string diagonal="right")
-    { return RectangleMesh::create({{Point(0.0, 0.0), Point(1.0, 1.0)}}, n); }
+    static Mesh create(std::array<std::size_t, 2> n,
+                       CellType::Type cell_type,
+                       std::string diagonal="right")
+    {
+      return RectangleMesh::create({{Point(0.0, 0.0), Point(1.0, 1.0)}}, n,
+                                   cell_type, diagonal);
+    }
+
+    // Temporary - part of pybind11 transition and will be
+    // removed. Avoid using.
+    static Mesh create(std::size_t nx, std::size_t ny, CellType::Type cell_type,
+                       std::string diagonal="right")
+    {
+      return RectangleMesh::create({{Point(0.0, 0.0), Point(1.0, 1.0)}}, {nx, ny},
+                                   cell_type, diagonal);
+    }
+
+    // Temporary - part of pybind11 transition and will be
+    // removed. Avoid using.
+    static Mesh create(MPI_Comm comm, std::size_t nx, std::size_t ny,
+                       CellType::Type cell_type,
+                       std::string diagonal="right")
+    {
+      return RectangleMesh::create(comm, {{Point(0.0, 0.0), Point(1.0, 1.0)}}, {nx, ny},
+                                   cell_type, diagonal);
+    }
 
     /// Create a uniform finite element _Mesh_ over the unit square
     /// [0,1] x [0,1].
@@ -66,6 +93,8 @@ namespace dolfin
     ///         MPI communicator
     /// @param    n (std:::array<std::size_t, 2>)
     ///         Number of cells in each direction.
+    /// @param    cell_type
+    ///         Triangle or quadrilateral.
     /// @param    diagonal (std::string)
     ///         Optional argument: A std::string indicating
     ///         the direction of the diagonals.
@@ -76,8 +105,10 @@ namespace dolfin
     ///         auto mesh2 = UnitSquareMesh::create(MPI_COMM_WORLD, 32, 32, "crossed");
     /// @endcode
     static Mesh create(MPI_Comm comm, std::array<std::size_t, 2> n,
+                       CellType::Type cell_type,
                        std::string diagonal="right")
-    { return RectangleMesh::create(comm, {{Point(0.0, 0.0), Point(1.0, 1.0)}}, n); }
+    { return RectangleMesh::create(comm, {{Point(0.0, 0.0), Point(1.0, 1.0)}}, n,
+                                   cell_type, diagonal); }
 
     /// Create a uniform finite element _Mesh_ over the unit square
     /// [0,1] x [0,1].
diff --git a/dolfin/generation/UnitTetrahedronMesh.cpp b/dolfin/generation/UnitTetrahedronMesh.cpp
index 1248535..ce1ed9e 100644
--- a/dolfin/generation/UnitTetrahedronMesh.cpp
+++ b/dolfin/generation/UnitTetrahedronMesh.cpp
@@ -39,7 +39,7 @@ dolfin::Mesh UnitTetrahedronMesh::create()
 
   // Open mesh for editing
   MeshEditor editor;
-  editor.open(mesh, CellType::tetrahedron, 3, 3);
+  editor.open(mesh, CellType::Type::tetrahedron, 3, 3);
 
   // Create vertices
   editor.init_vertices_global(4, 4);
diff --git a/dolfin/generation/UnitTriangleMesh.cpp b/dolfin/generation/UnitTriangleMesh.cpp
index 75d9332..1a81bfb 100644
--- a/dolfin/generation/UnitTriangleMesh.cpp
+++ b/dolfin/generation/UnitTriangleMesh.cpp
@@ -40,7 +40,7 @@ dolfin::Mesh UnitTriangleMesh::create()
 
   // Open mesh for editing
   MeshEditor editor;
-  editor.open(mesh, CellType::triangle, 2, 2);
+  editor.open(mesh, CellType::Type::triangle, 2, 2);
 
   // Create vertices
   editor.init_vertices_global(3, 3);
diff --git a/dolfin/generation/dolfin_generation.h b/dolfin/generation/dolfin_generation.h
index 8e99809..53f40cf 100644
--- a/dolfin/generation/dolfin_generation.h
+++ b/dolfin/generation/dolfin_generation.h
@@ -11,8 +11,6 @@
 #include <dolfin/generation/UnitIntervalMesh.h>
 #include <dolfin/generation/UnitTriangleMesh.h>
 #include <dolfin/generation/UnitSquareMesh.h>
-#include <dolfin/generation/UnitQuadMesh.h>
-#include <dolfin/generation/UnitHexMesh.h>
 #include <dolfin/generation/UnitDiscMesh.h>
 #include <dolfin/generation/SphericalShellMesh.h>
 
diff --git a/dolfin/geometry/BoundingBoxTree2D.h b/dolfin/geometry/BoundingBoxTree2D.h
index fc87e3e..7fd6f94 100644
--- a/dolfin/geometry/BoundingBoxTree2D.h
+++ b/dolfin/geometry/BoundingBoxTree2D.h
@@ -15,8 +15,10 @@
 // You should have received a copy of the GNU Lesser General Public License
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 //
+// Modified by August Johansson 2016
+//
 // First added:  2013-05-02
-// Last changed: 2013-11-30
+// Last changed: 2016-11-15
 
 #ifndef __BOUNDING_BOX_TREE_2D_H
 #define __BOUNDING_BOX_TREE_2D_H
@@ -99,7 +101,7 @@ namespace dolfin
       const double eps0 = DOLFIN_EPS_LARGE*(b[2] - b[0]);
       const double eps1 = DOLFIN_EPS_LARGE*(b[3] - b[1]);
       return (b[0] - eps0 <= a[2] && a[0] <= b[2] + eps0 &&
-              b[1] - eps1 <= a[3] && a[1] <= b[3] + eps1);
+      	      b[1] - eps1 <= a[3] && a[1] <= b[3] + eps1);
     }
 
     /// Compute squared distance between point and bounding box
diff --git a/dolfin/geometry/CGALExactArithmetic.h b/dolfin/geometry/CGALExactArithmetic.h
new file mode 100644
index 0000000..42227aa
--- /dev/null
+++ b/dolfin/geometry/CGALExactArithmetic.h
@@ -0,0 +1,1152 @@
+// Copyright (C) 2016-2017 Benjamin Kehlet, August Johansson, and Anders Logg
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN 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 Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added:  2016-05-03
+// Last changed: 2017-10-07
+//
+// Developer note:
+//
+// This file contains reference implementations of collision detection
+// algorithms using exact arithmetic with CGAL. It is not included in
+// a normal build but is used as a reference for verification and
+// debugging of the inexact DOLFIN collision detection algorithms.
+// To enable, set the option DOLFIN_ENABLE_GEOMETRY_DEBUGGING when
+// configuring DOLFIN
+
+#ifndef __CGAL_EXACT_ARITHMETIC_H
+#define __CGAL_EXACT_ARITHMETIC_H
+
+#ifndef DOLFIN_ENABLE_GEOMETRY_DEBUGGING
+
+// Comparison macro just bypasses CGAL and test when not enabled
+#define CHECK_CGAL(RESULT_DOLFIN, RESULT_CGAL) RESULT_DOLFIN
+
+#define CGAL_INTERSECTION_CHECK(RESULT_DOLFIN, RESULT_CGAL) RESULT_DOLFIN
+
+#else
+
+#define CGAL_CHECK_TOLERANCE 1e-10
+
+#include "Point.h"
+#include "predicates.h"
+#include <dolfin/log/log.h>
+#include <dolfin/math/basic.h>
+#include <vector>
+#include <algorithm>
+#include <sstream>
+#include <iomanip>
+
+// Check that results from DOLFIN and CGAL match
+namespace dolfin
+{
+  //---------------------------------------------------------------------------
+  // Functions to compare results between DOLFIN and CGAL
+  //---------------------------------------------------------------------------
+  inline bool
+  check_cgal(bool result_dolfin,
+	     bool result_cgal,
+	     const std::string& function)
+  {
+    if (result_dolfin != result_cgal)
+    {
+      // Convert results to strings
+      std::stringstream s_dolfin;
+      std::stringstream s_cgal;
+      s_dolfin << result_dolfin;
+      s_cgal << result_cgal;
+
+      // Issue error
+      dolfin_error("CGALExactArithmetic.h",
+                   "verify geometric predicate with exact types",
+                   "Error in predicate %s\n DOLFIN: %s\n CGAL: %s",
+                   function.c_str(), s_dolfin.str().c_str(), s_cgal.str().c_str());
+    }
+
+    return result_dolfin;
+  }
+  //-----------------------------------------------------------------------------
+  inline
+  std::vector<Point>
+  cgal_intersection_check(const std::vector<Point>& dolfin_result,
+			  const std::vector<Point>& cgal_result,
+			  const std::string& function)
+  {
+    if (dolfin_result.size() != cgal_result.size())
+    {
+      dolfin_error("CGALExactArithmetic.h",
+		   "verify intersection",
+		   "size of point set differs (%d vs %d)",
+		   dolfin_result.size(), cgal_result.size());
+    }
+
+    for (const Point& p1 : dolfin_result)
+    {
+      bool found = false;
+      for (const Point& p2 : cgal_result)
+      {
+	if ( (p1-p2).norm() < 1e-15 )
+	{
+	  found = true;
+	  break;
+	}
+      }
+
+      if (!found)
+	dolfin_error("CGALExactArithmetic.h",
+		     "verify intersection construction result",
+		     "Point (%f, %f, %f) in dolfin result not found in cgal result",
+		     p1[0], p1[1], p1[2]);
+    }
+    return dolfin_result;
+  }
+} // end namespace dolfin
+//-----------------------------------------------------------------------------
+// Comparison macro that calls comparison function
+#define CHECK_CGAL(RESULT_DOLFIN, RESULT_CGAL) \
+  check_cgal(RESULT_DOLFIN, RESULT_CGAL, __FUNCTION__)
+
+#define CGAL_INTERSECTION_CHECK(RESULT_DOLFIN, RESULT_CGAL) \
+  cgal_intersection_check(RESULT_DOLFIN, RESULT_CGAL, __FUNCTION__)
+
+// CGAL includes
+#define CGAL_HEADER_ONLY
+#include <CGAL/Cartesian.h>
+#include <CGAL/Quotient.h>
+#include <CGAL/MP_Float.h>
+#include <CGAL/Point_2.h>
+#include <CGAL/Triangle_2.h>
+#include <CGAL/Segment_2.h>
+#include <CGAL/Point_3.h>
+#include <CGAL/Triangle_3.h>
+#include <CGAL/Segment_3.h>
+#include <CGAL/Tetrahedron_3.h>
+#include <CGAL/Polyhedron_3.h>
+#include <CGAL/convex_hull_3.h>
+#include <CGAL/intersections.h>
+#include <CGAL/intersection_of_Polyhedra_3.h>
+#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
+#include <CGAL/Triangulation_2.h>
+#include <CGAL/Nef_polyhedron_3.h>
+
+namespace
+{
+  // CGAL typedefs
+  /* typedef CGAL::Quotient<CGAL::MP_Float> ExactNumber; */
+  /* typedef CGAL::Cartesian<ExactNumber>   ExactKernel; */
+  typedef CGAL::Exact_predicates_exact_constructions_kernel ExactKernel;
+  typedef ExactKernel::FT ExactNumber;
+
+  typedef ExactKernel::Point_2           Point_2;
+  typedef ExactKernel::Triangle_2        Triangle_2;
+  typedef ExactKernel::Segment_2         Segment_2;
+  typedef ExactKernel::Intersect_2       Intersect_2;
+  typedef ExactKernel::Point_3           Point_3;
+  typedef ExactKernel::Vector_3          Vector_3;
+  typedef ExactKernel::Triangle_3        Triangle_3;
+  typedef ExactKernel::Segment_3         Segment_3;
+  typedef ExactKernel::Tetrahedron_3     Tetrahedron_3;
+  typedef ExactKernel::Intersect_3       Intersect_3;
+  typedef CGAL::Nef_polyhedron_3<ExactKernel>  Nef_polyhedron_3;
+  typedef CGAL::Polyhedron_3<ExactKernel>      Polyhedron_3;
+  typedef CGAL::Triangulation_2<ExactKernel>   Triangulation_2;
+
+  //---------------------------------------------------------------------------
+  // CGAL utility functions
+  //---------------------------------------------------------------------------
+  inline Point_2 convert_to_cgal_2d(double a, double b)
+  {
+    return Point_2(a, b);
+  }
+  //-----------------------------------------------------------------------------
+  inline Point_3 convert_to_cgal_3d(double a, double b, double c)
+  {
+    return Point_3(a, b, c);
+  }
+  //-----------------------------------------------------------------------------
+  inline Point_2 convert_to_cgal_2d(const dolfin::Point& p)
+  {
+    return Point_2(p[0], p[1]);
+  }
+  //-----------------------------------------------------------------------------
+  inline Point_3 convert_to_cgal_3d(const dolfin::Point& p)
+  {
+    return Point_3(p[0], p[1], p[2]);
+  }
+  //-----------------------------------------------------------------------------
+  inline Segment_2 convert_to_cgal_2d(const dolfin::Point& a,
+				      const dolfin::Point& b)
+  {
+    return Segment_2(convert_to_cgal_2d(a), convert_to_cgal_2d(b));
+  }
+  //-----------------------------------------------------------------------------
+  inline Segment_3 convert_to_cgal_3d(const dolfin::Point& a,
+				      const dolfin::Point& b)
+  {
+    return Segment_3(convert_to_cgal_3d(a), convert_to_cgal_3d(b));
+  }
+  //-----------------------------------------------------------------------------
+  inline Triangle_2 convert_to_cgal_2d(const dolfin::Point& a,
+				       const dolfin::Point& b,
+				       const dolfin::Point& c)
+  {
+    return Triangle_2(convert_to_cgal_2d(a),
+		      convert_to_cgal_2d(b),
+		      convert_to_cgal_2d(c));
+  }
+  //-----------------------------------------------------------------------------
+  inline Triangle_3 convert_to_cgal_3d(const dolfin::Point& a,
+				       const dolfin::Point& b,
+				       const dolfin::Point& c)
+  {
+    return Triangle_3(convert_to_cgal_3d(a),
+		      convert_to_cgal_3d(b),
+		      convert_to_cgal_3d(c));
+  }
+  //-----------------------------------------------------------------------------
+  inline Tetrahedron_3 convert_to_cgal_3d(const dolfin::Point& a,
+					  const dolfin::Point& b,
+					  const dolfin::Point& c,
+					  const dolfin::Point& d)
+  {
+    return Tetrahedron_3(convert_to_cgal_3d(a),
+			 convert_to_cgal_3d(b),
+			 convert_to_cgal_3d(c),
+			 convert_to_cgal_3d(d));
+  }
+  //-----------------------------------------------------------------------------
+  inline bool is_degenerate_2d(const dolfin::Point& a,
+			       const dolfin::Point& b)
+  {
+    const Segment_2 s(convert_to_cgal_2d(a), convert_to_cgal_2d(b));
+    return s.is_degenerate();
+  }
+  //-----------------------------------------------------------------------------
+  inline bool is_degenerate_3d(const dolfin::Point& a,
+			       const dolfin::Point& b)
+  {
+    const Segment_3 s(convert_to_cgal_3d(a), convert_to_cgal_3d(b));
+    return s.is_degenerate();
+  }
+  //-----------------------------------------------------------------------------
+  inline bool is_degenerate_2d(const dolfin::Point& a,
+			       const dolfin::Point& b,
+			       const dolfin::Point& c)
+  {
+    const Triangle_2 t(convert_to_cgal_2d(a),
+		       convert_to_cgal_2d(b),
+		       convert_to_cgal_2d(c));
+    return t.is_degenerate();
+  }
+  //-----------------------------------------------------------------------------
+  inline bool is_degenerate_3d(const dolfin::Point& a,
+			       const dolfin::Point& b,
+			       const dolfin::Point& c)
+  {
+    const Triangle_3 t(convert_to_cgal_3d(a),
+		       convert_to_cgal_3d(b),
+		       convert_to_cgal_3d(c));
+    return t.is_degenerate();
+  }
+  //-----------------------------------------------------------------------------
+  inline bool is_degenerate_3d(const dolfin::Point& a,
+			       const dolfin::Point& b,
+			       const dolfin::Point& c,
+			       const dolfin::Point& d)
+  {
+    const Tetrahedron_3 t(convert_to_cgal_3d(a),
+			  convert_to_cgal_3d(b),
+			  convert_to_cgal_3d(c),
+			  convert_to_cgal_3d(d));
+    return t.is_degenerate();
+  }
+  //-----------------------------------------------------------------------------
+  inline dolfin::Point convert_from_cgal(const Point_2& p)
+  {
+    return dolfin::Point(CGAL::to_double(p.x()),CGAL::to_double(p.y()));
+  }
+  //-----------------------------------------------------------------------------
+  inline dolfin::Point convert_from_cgal(const Point_3& p)
+  {
+    return dolfin::Point(CGAL::to_double(p.x()),
+			 CGAL::to_double(p.y()),
+			 CGAL::to_double(p.z()));
+  }
+  //-----------------------------------------------------------------------------
+  inline std::vector<dolfin::Point> convert_from_cgal(const Segment_2& s)
+  {
+    const std::vector<dolfin::Point> triangulation =
+      {{ dolfin::Point(CGAL::to_double(s.vertex(0)[0]),
+		       CGAL::to_double(s.vertex(0)[1])),
+      	 dolfin::Point(CGAL::to_double(s.vertex(1)[0]),
+		       CGAL::to_double(s.vertex(1)[1]))
+	}};
+    return triangulation;
+  }
+  //-----------------------------------------------------------------------------
+  inline std::vector<dolfin::Point> convert_from_cgal(const Segment_3& s)
+  {
+    const std::vector<dolfin::Point> triangulation =
+      {{ dolfin::Point(CGAL::to_double(s.vertex(0)[0]),
+		       CGAL::to_double(s.vertex(0)[1]),
+		       CGAL::to_double(s.vertex(0)[2])),
+      	 dolfin::Point(CGAL::to_double(s.vertex(1)[0]),
+		       CGAL::to_double(s.vertex(1)[1]),
+		       CGAL::to_double(s.vertex(1)[2]))
+	}};
+    return triangulation;
+  }
+  //-----------------------------------------------------------------------------
+  inline std::vector<dolfin::Point> convert_from_cgal(const Triangle_2& t)
+  {
+    const std::vector<dolfin::Point> triangulation =
+      {{ dolfin::Point(CGAL::to_double(t.vertex(0)[0]),
+		       CGAL::to_double(t.vertex(0)[1])),
+      	 dolfin::Point(CGAL::to_double(t.vertex(2)[0]),
+		       CGAL::to_double(t.vertex(2)[1])),
+      	 dolfin::Point(CGAL::to_double(t.vertex(1)[0]),
+		       CGAL::to_double(t.vertex(1)[1]))
+	}};
+    return triangulation;
+  }
+  //-----------------------------------------------------------------------------
+  inline std::vector<dolfin::Point> convert_from_cgal(const Triangle_3& t)
+  {
+    const std::vector<dolfin::Point> triangulation =
+      {{ dolfin::Point(CGAL::to_double(t.vertex(0)[0]),
+		       CGAL::to_double(t.vertex(0)[1]),
+		       CGAL::to_double(t.vertex(0)[2])),
+      	 dolfin::Point(CGAL::to_double(t.vertex(2)[0]),
+		       CGAL::to_double(t.vertex(2)[1]),
+		       CGAL::to_double(t.vertex(2)[2])),
+      	 dolfin::Point(CGAL::to_double(t.vertex(1)[0]),
+		       CGAL::to_double(t.vertex(1)[1]),
+		       CGAL::to_double(t.vertex(1)[2]))
+	}};
+    return triangulation;
+  }
+  //-----------------------------------------------------------------------------
+  inline
+  std::vector<std::vector<dolfin::Point>>
+  triangulate_polygon_2d(const std::vector<dolfin::Point>& points)
+  {
+    // Convert points
+    std::vector<Point_2> pcgal(points.size());
+    for (std::size_t i = 0; i < points.size(); ++i)
+      pcgal[i] = convert_to_cgal_2d(points[i]);
+
+    // Triangulate
+    Triangulation_2 tcgal;
+    tcgal.insert(pcgal.begin(), pcgal.end());
+
+    // Convert back
+    std::vector<std::vector<dolfin::Point>> t;
+    for (Triangulation_2::Finite_faces_iterator fit = tcgal.finite_faces_begin();
+	 fit != tcgal.finite_faces_end(); ++fit)
+    {
+      t.push_back({{ convert_from_cgal(tcgal.triangle(fit)[0]),
+      	      convert_from_cgal(tcgal.triangle(fit)[1]),
+      	      convert_from_cgal(tcgal.triangle(fit)[2]) }});
+    }
+
+    return t;
+  }
+  //-----------------------------------------------------------------------------
+  inline
+  std::vector<std::vector<dolfin::Point>>
+  triangulate_polygon_3d(const std::vector<dolfin::Point>& points)
+  {
+    // FIXME
+    dolfin::dolfin_error("CGALExactArithmetic.h",
+			 "triangulate_polygon_3d",
+			 "Not implemented");
+    return std::vector<std::vector<dolfin::Point>>();
+  }
+  //-----------------------------------------------------------------------------
+}
+
+namespace dolfin
+{
+  //---------------------------------------------------------------------------
+  // Reference implementations of DOLFIN collision detection predicates
+  // using CGAL exact arithmetic
+  // ---------------------------------------------------------------------------
+  inline bool cgal_collides_segment_point_2d(const Point& q0,
+					     const Point& q1,
+					     const Point& p,
+					     bool only_interior=false)
+  {
+    const Point_2 q0_ = convert_to_cgal_2d(q0);
+    const Point_2 q1_ = convert_to_cgal_2d(q1);
+    const Point_2 p_ = convert_to_cgal_2d(p);
+
+    const bool intersects = CGAL::do_intersect(Segment_2(q0_, q1_), p_);
+    return only_interior ? intersects && p_ != q0_ && p_ != q1_ : intersects;
+  }
+  //-----------------------------------------------------------------------------
+  inline bool cgal_collides_segment_point_3d(const Point& q0,
+					     const Point& q1,
+					     const Point& p,
+					     bool only_interior=false)
+  {
+    const Point_3 q0_ = convert_to_cgal_3d(q0);
+    const Point_3 q1_ = convert_to_cgal_3d(q1);
+    const Point_3 p_ = convert_to_cgal_3d(p);
+
+    const Segment_3 segment(q0_, q1_);
+    const bool intersects = segment.has_on(p_);
+    return only_interior ? intersects && p_ != q0_ && p_ != q1_ : intersects;
+  }
+  //-----------------------------------------------------------------------------
+  inline bool cgal_collides_segment_segment_2d(const Point& p0,
+					       const Point& p1,
+					       const Point& q0,
+					       const Point& q1)
+  {
+    return CGAL::do_intersect(convert_to_cgal_2d(p0, p1),
+			      convert_to_cgal_2d(q0, q1));
+  }
+  //-----------------------------------------------------------------------------
+  inline bool cgal_collides_segment_segment_3d(const Point& p0,
+					       const Point& p1,
+					       const Point& q0,
+					       const Point& q1)
+  {
+    return CGAL::do_intersect(convert_to_cgal_3d(p0, p1),
+			      convert_to_cgal_3d(q0, q1));
+  }
+  //-----------------------------------------------------------------------------
+  inline bool cgal_collides_triangle_point_2d(const Point& p0,
+					      const Point& p1,
+					      const Point& p2,
+					      const Point &point)
+  {
+    return CGAL::do_intersect(convert_to_cgal_2d(p0, p1, p2),
+			      convert_to_cgal_2d(point));
+  }
+  //-----------------------------------------------------------------------------
+  inline bool cgal_collides_triangle_point_3d(const Point& p0,
+					      const Point& p1,
+					      const Point& p2,
+					      const Point &point)
+  {
+    const Triangle_3 tri = convert_to_cgal_3d(p0, p1, p2);
+    return tri.has_on(convert_to_cgal_3d(point));
+  }
+  //-----------------------------------------------------------------------------
+  inline bool cgal_collides_triangle_segment_2d(const Point& p0,
+						const Point& p1,
+						const Point& p2,
+						const Point& q0,
+						const Point& q1)
+  {
+    return CGAL::do_intersect(convert_to_cgal_2d(p0, p1, p2),
+			      convert_to_cgal_2d(q0, q1));
+  }
+  //-----------------------------------------------------------------------------
+  inline bool cgal_collides_triangle_segment_3d(const Point& p0,
+						const Point& p1,
+						const Point& p2,
+						const Point& q0,
+						const Point& q1)
+  {
+    return CGAL::do_intersect(convert_to_cgal_3d(p0, p1, p2),
+			      convert_to_cgal_3d(q0, q1));
+  }
+  //-----------------------------------------------------------------------------
+  inline bool cgal_collides_triangle_triangle_2d(const Point& p0,
+						 const Point& p1,
+						 const Point& p2,
+						 const Point& q0,
+						 const Point& q1,
+						 const Point& q2)
+  {
+    return CGAL::do_intersect(convert_to_cgal_2d(p0, p1, p2),
+			      convert_to_cgal_2d(q0, q1, q2));
+  }
+  //-----------------------------------------------------------------------------
+  inline bool cgal_collides_triangle_triangle_3d(const Point& p0,
+						 const Point& p1,
+						 const Point& p2,
+						 const Point& q0,
+						 const Point& q1,
+						 const Point& q2)
+  {
+    return CGAL::do_intersect(convert_to_cgal_3d(p0, p1, p2),
+			      convert_to_cgal_3d(q0, q1, q2));
+  }
+  //-----------------------------------------------------------------------------
+  inline bool cgal_collides_tetrahedron_point_3d(const Point& p0,
+                                                 const Point& p1,
+                                                 const Point& p2,
+                                                 const Point& p3,
+                                                 const Point& q0)
+  {
+    const Tetrahedron_3 tet = convert_to_cgal_3d(p0, p1, p2, p3);
+    return !tet.has_on_unbounded_side(convert_to_cgal_3d(q0));
+  }
+  //-----------------------------------------------------------------------------
+  inline bool cgal_collides_tetrahedron_segment_3d(const Point& p0,
+                                                   const Point& p1,
+                                                   const Point& p2,
+                                                   const Point& p3,
+                                                   const Point& q0,
+                                                   const Point& q1)
+  {
+    if (cgal_collides_tetrahedron_point_3d(p0, p1, p2, p3, q0) or
+	cgal_collides_tetrahedron_point_3d(p0, p1, p2, p3, q1))
+      return true;
+
+    if (cgal_collides_triangle_segment_3d(p0, p1, p2, q0, q1) or
+      	cgal_collides_triangle_segment_3d(p0, p2, p3, q0, q1) or
+      	cgal_collides_triangle_segment_3d(p0, p3, p1, q0, q1) or
+      	cgal_collides_triangle_segment_3d(p1, p3, p2, q0, q1))
+      return true;
+
+    return false;
+  }
+  //-----------------------------------------------------------------------------
+  inline bool cgal_collides_tetrahedron_triangle_3d(const Point& p0,
+                                                    const Point& p1,
+                                                    const Point& p2,
+                                                    const Point& p3,
+                                                    const Point& q0,
+                                                    const Point& q1,
+                                                    const Point& q2)
+  {
+    return CGAL::do_intersect(convert_to_cgal_3d(p0, p1, p2, p3),
+			      convert_to_cgal_3d(q0, q1, q2));
+  }
+  //-----------------------------------------------------------------------------
+  inline bool cgal_collides_tetrahedron_tetrahedron_3d(const Point& p0,
+                                                       const Point& p1,
+                                                       const Point& p2,
+                                                       const Point& p3,
+                                                       const Point& q0,
+                                                       const Point& q1,
+                                                       const Point& q2,
+                                                       const Point& q3)
+  {
+    // Check volume collisions
+    if (cgal_collides_tetrahedron_point_3d(p0, p1, p2, p3, q0)) return true;
+    if (cgal_collides_tetrahedron_point_3d(p0, p1, p2, p3, q1)) return true;
+    if (cgal_collides_tetrahedron_point_3d(p0, p1, p2, p3, q2)) return true;
+    if (cgal_collides_tetrahedron_point_3d(p0, p1, p2, p3, q3)) return true;
+    if (cgal_collides_tetrahedron_point_3d(q0, q1, q2, q3, p0)) return true;
+    if (cgal_collides_tetrahedron_point_3d(q0, q1, q2, q3, p1)) return true;
+    if (cgal_collides_tetrahedron_point_3d(q0, q1, q2, q3, p2)) return true;
+    if (cgal_collides_tetrahedron_point_3d(q0, q1, q2, q3, p3)) return true;
+
+    Polyhedron_3 tet_a;
+    tet_a.make_tetrahedron(convert_to_cgal_3d(p0),
+			   convert_to_cgal_3d(p1),
+			   convert_to_cgal_3d(p2),
+			   convert_to_cgal_3d(p3));
+
+    Polyhedron_3 tet_b;
+    tet_b.make_tetrahedron(convert_to_cgal_3d(q0),
+			   convert_to_cgal_3d(q1),
+			   convert_to_cgal_3d(q2),
+			   convert_to_cgal_3d(q3));
+
+    // Check for polyhedron intersection (recall that a polyhedron is
+    // only its vertices, edges and faces)
+    std::size_t cnt = 0;
+    CGAL::Counting_output_iterator out(&cnt);
+    CGAL::intersection_Polyhedron_3_Polyhedron_3<Polyhedron_3>(tet_a,
+							       tet_b,
+							       out);
+    // The tetrahedra does not intersect if cnt == 0
+    return cnt != 0;
+  }
+  //----------------------------------------------------------------------------
+  // Reference implementations of DOLFIN intersection triangulation
+  // functions using CGAL with exact arithmetic
+  // ---------------------------------------------------------------------------
+  inline
+  std::vector<Point> cgal_intersection_segment_segment_2d(const Point& p0,
+							  const Point& p1,
+							  const Point& q0,
+							  const Point& q1)
+  {
+    dolfin_assert(!is_degenerate_2d(p0, p1));
+    dolfin_assert(!is_degenerate_2d(q0, q1));
+
+    const auto I0 = convert_to_cgal_2d(p0, p1);
+    const auto I1 = convert_to_cgal_2d(q0, q1);
+
+    if (const auto ii = CGAL::intersection(I0, I1))
+    {
+      if (const Point_2* p = boost::get<Point_2>(&*ii))
+      {
+        return std::vector<Point>{convert_from_cgal(*p)};
+      }
+      else if (const Segment_2* s = boost::get<Segment_2>(&*ii))
+      {
+        return convert_from_cgal(*s);
+      }
+      else
+      {
+        dolfin_error("CGALExactArithmetic.h",
+                     "cgal_intersection_segment_segment_2d",
+                     "Unexpected behavior");
+      }
+    }
+
+    return std::vector<Point>();
+  }
+  //-----------------------------------------------------------------------------
+  inline
+  std::vector<Point> cgal_intersection_segment_segment_3d(const Point& p0,
+							  const Point& p1,
+							  const Point& q0,
+							  const Point& q1)
+  {
+    dolfin_assert(!is_degenerate_3d(p0, p1));
+    dolfin_assert(!is_degenerate_3d(q0, q1));
+
+    const auto I0 = convert_to_cgal_3d(p0, p1);
+    const auto I1 = convert_to_cgal_3d(q0, q1);
+
+    if (const auto ii = CGAL::intersection(I0, I1))
+    {
+      if (const Point_3* p = boost::get<Point_3>(&*ii))
+      {
+        return std::vector<Point>{convert_from_cgal(*p)};
+      }
+      else if (const Segment_3* s = boost::get<Segment_3>(&*ii))
+      {
+        return convert_from_cgal(*s);
+      }
+      else
+      {
+        dolfin_error("CGALExactArithmetic.h",
+                     "cgal_intersection_segment_segment_3d",
+                     "Unexpected behavior");
+      }
+    }
+
+    return std::vector<Point>();
+  }
+  //-----------------------------------------------------------------------------
+  inline
+  std::vector<Point> cgal_triangulate_segment_segment_2d(const Point& p0,
+							 const Point& p1,
+							 const Point& q0,
+							 const Point& q1)
+  {
+    return cgal_intersection_segment_segment_2d(p0, p1, q0, q1);
+  }
+  //-----------------------------------------------------------------------------
+  inline
+  std::vector<Point> cgal_triangulate_segment_segment_3d(const Point& p0,
+							 const Point& p1,
+							 const Point& q0,
+							 const Point& q1)
+  {
+    return cgal_intersection_segment_segment_3d(p0, p1, q0, q1);
+  }
+  //-----------------------------------------------------------------------------
+  inline
+  std::vector<Point> cgal_intersection_triangle_segment_2d(const Point& p0,
+                                                           const Point& p1,
+                                                           const Point& p2,
+                                                           const Point& q0,
+                                                           const Point& q1)
+  {
+    dolfin_assert(!is_degenerate_2d(p0, p1, p2));
+    dolfin_assert(!is_degenerate_2d(q0, q1));
+
+    const auto T = convert_to_cgal_2d(p0, p1, p2);
+    const auto I = convert_to_cgal_2d(q0, q1);
+
+    if (const auto ii = CGAL::intersection(T, I))
+    {
+      if (const Point_2* p = boost::get<Point_2>(&*ii))
+      {
+        return std::vector<Point>{convert_from_cgal(*p)};
+      }
+      else if (const Segment_2* s = boost::get<Segment_2>(&*ii))
+      {
+        return convert_from_cgal(*s);
+      }
+      else
+      {
+        dolfin_error("CGALExactArithmetic.h",
+                     "cgal_intersection_triangle_segment_2d",
+                     "Unexpected behavior");
+      }
+    }
+
+    return std::vector<Point>();
+  }
+  //-----------------------------------------------------------------------------
+  inline
+  std::vector<Point> cgal_intersection_triangle_segment_3d(const Point& p0,
+							   const Point& p1,
+							   const Point& p2,
+							   const Point& q0,
+							   const Point& q1)
+  {
+    dolfin_assert(!is_degenerate_3d(p0, p1, p2));
+    dolfin_assert(!is_degenerate_3d(q0, q1));
+
+    const auto T = convert_to_cgal_3d(p0, p1, p2);
+    const auto I = convert_to_cgal_3d(q0, q1);
+
+    if (const auto ii = CGAL::intersection(T, I))
+    {
+      if (const Point_3* p = boost::get<Point_3>(&*ii))
+        return std::vector<Point>{convert_from_cgal(*p)};
+      else if (const Segment_3* s = boost::get<Segment_3>(&*ii))
+        return convert_from_cgal(*s);
+      else
+      {
+        dolfin_error("CGALExactArithmetic.h",
+                     "cgal_intersection_triangle_segment_3d",
+                     "Unexpected behavior");
+      }
+    }
+
+    return std::vector<Point>();
+  }
+  //-----------------------------------------------------------------------------
+  inline
+  std::vector<Point> cgal_triangulate_triangle_segment_2d(const Point& p0,
+                                                          const Point& p1,
+                                                          const Point& p2,
+                                                          const Point& q0,
+							  const Point& q1)
+  {
+    return cgal_intersection_triangle_segment_2d(p0, p1, p2, q0, q1);
+  }
+  //-----------------------------------------------------------------------------
+  inline
+  std::vector<Point> cgal_triangulate_triangle_segment_3d(const Point& p0,
+							  const Point& p1,
+							  const Point& p2,
+							  const Point& q0,
+							  const Point& q1)
+  {
+    return cgal_intersection_triangle_segment_3d(p0, p1, p2, q0, q1);
+  }
+  //-----------------------------------------------------------------------------
+  inline
+  std::vector<Point> cgal_intersection_triangle_triangle_2d(const Point& p0,
+                                                            const Point& p1,
+                                                            const Point& p2,
+                                                            const Point& q0,
+                                                            const Point& q1,
+                                                            const Point& q2)
+  {
+    dolfin_assert(!is_degenerate_2d(p0, p1, p2));
+    dolfin_assert(!is_degenerate_2d(q0, q1, q2));
+
+    const Triangle_2 T0 = convert_to_cgal_2d(p0, p1, p2);
+    const Triangle_2 T1 = convert_to_cgal_2d(q0, q1, q2);
+    std::vector<Point> intersection;
+
+    if (const auto ii = CGAL::intersection(T0, T1))
+    {
+      if (const Point_2* p = boost::get<Point_2>(&*ii))
+      {
+        intersection.push_back(convert_from_cgal(*p));
+      }
+      else if (const Segment_2* s = boost::get<Segment_2>(&*ii))
+      {
+        intersection = convert_from_cgal(*s);
+      }
+      else if (const Triangle_2* t = boost::get<Triangle_2>(&*ii))
+      {
+        intersection = convert_from_cgal(*t);;
+      }
+      else if (const std::vector<Point_2>* cgal_points = boost::get<std::vector<Point_2>>(&*ii))
+      {
+        for (Point_2 p : *cgal_points)
+        {
+          intersection.push_back(convert_from_cgal(p));
+        }
+      }
+      else
+      {
+      	dolfin_error("CGALExactArithmetic.h",
+		     "cgal_intersection_triangle_triangle_2d",
+		     "Unexpected behavior");
+      }
+
+      // NB: the parsing can return triangulation of size 0, for example
+      // if it detected a triangle but it was found to be flat.
+      /* if (triangulation.size() == 0) */
+      /*   dolfin_error("CGALExactArithmetic.h", */
+      /*                "find intersection of two triangles in cgal_intersection_triangle_triangle function", */
+      /*                "no intersection found"); */
+    }
+
+    return intersection;
+  }
+  //-----------------------------------------------------------------------------
+  inline
+  std::vector<Point> cgal_intersection_triangle_triangle_3d(const Point& p0,
+							    const Point& p1,
+							    const Point& p2,
+							    const Point& q0,
+							    const Point& q1,
+							    const Point& q2)
+  {
+    dolfin_assert(!is_degenerate_3d(p0, p1, p2));
+    dolfin_assert(!is_degenerate_3d(q0, q1, q2));
+
+    const Triangle_3 T0 = convert_to_cgal_3d(p0, p1, p2);
+    const Triangle_3 T1 = convert_to_cgal_3d(q0, q1, q2);
+    std::vector<Point> intersection;
+
+    if (const auto ii = CGAL::intersection(T0, T1))
+    {
+      if (const Point_3* p = boost::get<Point_3>(&*ii))
+      {
+        intersection.push_back(convert_from_cgal(*p));
+      }
+      else if (const Segment_3* s = boost::get<Segment_3>(&*ii))
+      {
+        intersection = convert_from_cgal(*s);
+      }
+      else if (const Triangle_3* t = boost::get<Triangle_3>(&*ii))
+      {
+        intersection = convert_from_cgal(*t);;
+      }
+      else if (const std::vector<Point_3>* cgal_points = boost::get<std::vector<Point_3>>(&*ii))
+      {
+        for (Point_3 p : *cgal_points)
+        {
+          intersection.push_back(convert_from_cgal(p));
+        }
+      }
+      else
+      {
+        dolfin_error("CGALExactArithmetic.h",
+                     "cgal_intersection_triangle_triangle_3d",
+                     "Unexpected behavior");
+      }
+    }
+
+    return intersection;
+  }
+  //----------------------------------------------------------------------------
+  inline
+  std::vector<std::vector<Point>>
+  cgal_triangulate_triangle_triangle_2d(const Point& p0,
+					const Point& p1,
+					const Point& p2,
+					const Point& q0,
+					const Point& q1,
+					const Point& q2)
+  {
+    dolfin_assert(!is_degenerate_2d(p0, p1, p2));
+    dolfin_assert(!is_degenerate_2d(q0, q1, q2));
+
+    const std::vector<Point> intersection
+      = cgal_intersection_triangle_triangle_2d(p0, p1, p2, q0, q1, q2);
+
+    if (intersection.size() < 4)
+    {
+      return std::vector<std::vector<Point>>{intersection};
+    }
+    else
+    {
+      dolfin_assert(intersection.size() == 4 ||
+		    intersection.size() == 5 ||
+		    intersection.size() == 6);
+      return triangulate_polygon_2d(intersection);
+    }
+  }
+  //-----------------------------------------------------------------------------
+  inline
+  std::vector<std::vector<Point>>
+  cgal_triangulate_triangle_triangle_3d(const Point& p0,
+					const Point& p1,
+					const Point& p2,
+					const Point& q0,
+					const Point& q1,
+					const Point& q2)
+  {
+    dolfin_assert(!is_degenerate_3d(p0, p1, p2));
+    dolfin_assert(!is_degenerate_3d(q0, q1, q2));
+
+    const std::vector<Point> intersection
+      = cgal_intersection_triangle_triangle_3d(p0, p1, p2, q0, q1, q2);
+
+    if (intersection.size() < 4)
+    {
+      return std::vector<std::vector<Point>>{intersection};
+    }
+    else
+    {
+      dolfin_assert(intersection.size() == 4 ||
+		    intersection.size() == 5 ||
+		    intersection.size() == 6);
+      return triangulate_polygon_3d(intersection);
+    }
+  }
+  //-----------------------------------------------------------------------------
+  inline
+  std::vector<Point>
+  cgal_intersection_tetrahedron_triangle(const Point& p0,
+					 const Point& p1,
+					 const Point& p2,
+					 const Point& p3,
+					 const Point& q0,
+					 const Point& q1,
+					 const Point& q2)
+  {
+    dolfin_assert(!is_degenerate_3d(p0, p1, p2, p3));
+    dolfin_assert(!is_degenerate_3d(q0, q1, q2));
+
+    // const Tetrahedron_3 tet = convert_from_cgal(p0, p1, p2, p3);
+    // const Triangle_3 tri = convert_from_cgal(q0, q1, q2);
+
+    Polyhedron_3 tet;
+    tet.make_tetrahedron(convert_to_cgal_3d(p0),
+			 convert_to_cgal_3d(p1),
+			 convert_to_cgal_3d(p2),
+			 convert_to_cgal_3d(p3));
+    Polyhedron_3 tri;
+    tri.make_triangle(convert_to_cgal_3d(q0),
+		      convert_to_cgal_3d(q1),
+		      convert_to_cgal_3d(q2));
+
+    std::list<std::vector<Point_3> > triangulation;
+    CGAL::intersection_Polyhedron_3_Polyhedron_3(tet,
+						 tri,
+						 std::back_inserter(triangulation));
+
+    // FIXME: do we need to add interior point checks? Maybe
+    // Polyhedron_3 is only top dim 2?
+
+    // Shouldn't get here
+    dolfin_error("CGALExactArithmetic.h",
+		 "cgal_intersection_tetrahedron_triangle",
+		 "Not implemented");
+
+    return std::vector<Point>();
+  }
+  //-----------------------------------------------------------------------------
+  inline std::vector<std::vector<Point>>
+  cgal_triangulate_tetrahedron_triangle(const Point& p0,
+					const Point& p1,
+					const Point& p2,
+					const Point& p3,
+					const Point& q0,
+					const Point& q1,
+					const Point& q2)
+  {
+    dolfin_assert(!is_degenerate_3d(p0, p1, p2, p3));
+    dolfin_assert(!is_degenerate_3d(q0, q1, q2));
+
+    std::vector<Point> intersection =
+      cgal_intersection_tetrahedron_triangle(p0, p1, p2, p3, q0, q1, q2);
+
+    // Shouldn't get here
+    dolfin_error("CGALExactArithmetic.h",
+		 "cgal_triangulation_tetrahedron_triangle",
+		 "Not implemented");
+
+    return std::vector<std::vector<Point>>();
+  }
+  //-----------------------------------------------------------------------------
+  inline std::vector<Point>
+  cgal_intersection_tetrahedron_tetrahedron_3d(const Point& p0,
+					       const Point& p1,
+					       const Point& p2,
+					       const Point& p3,
+					       const Point& q0,
+					       const Point& q1,
+					       const Point& q2,
+					       const Point& q3)
+  {
+    dolfin_assert(!is_degenerate_3d(p0, p1, p2, p3));
+    dolfin_assert(!is_degenerate_3d(q0, q1, q2, q3));
+
+    Polyhedron_3 tet_a;
+    tet_a.make_tetrahedron(convert_to_cgal_3d(p0),
+			   convert_to_cgal_3d(p1),
+			   convert_to_cgal_3d(p2),
+			   convert_to_cgal_3d(p3));
+    Polyhedron_3 tet_b;
+    tet_b.make_tetrahedron(convert_to_cgal_3d(q0),
+			   convert_to_cgal_3d(q1),
+			   convert_to_cgal_3d(q2),
+			   convert_to_cgal_3d(q3));
+
+    const Nef_polyhedron_3 tet_a_nef(tet_a);
+    const Nef_polyhedron_3 tet_b_nef(tet_b);
+
+    const Nef_polyhedron_3 intersection_nef = tet_a_nef*tet_a_nef;
+
+    Polyhedron_3 intersection;
+    intersection_nef.convert_to_polyhedron(intersection);
+
+    std::vector<Point> res;
+    for (Polyhedron_3::Vertex_const_iterator vit = intersection.vertices_begin();
+	 vit != intersection.vertices_end(); vit++)
+    {
+      res.push_back(Point(CGAL::to_double(vit->point().x()),
+			  CGAL::to_double(vit->point().y()),
+			  CGAL::to_double(vit->point().z())));
+    }
+
+    return res;
+  }
+  //----------------------------------------------------------------------------
+  // Reference implementations of DOLFIN is_degenerate
+  //-----------------------------------------------------------------------------
+  inline bool cgal_is_degenerate_2d(const std::vector<Point>& s)
+  {
+    if (s.size() < 2 or s.size() > 3)
+    {
+      info("Degenerate 2D simplex with %d vertices.", s.size());
+      return true;
+    }
+
+    switch (s.size())
+    {
+    case 2: return is_degenerate_2d(s[0], s[1]);
+    case 3: return is_degenerate_2d(s[0], s[1], s[2]);
+    }
+
+    // Shouldn't get here
+    dolfin_error("CGALExactArithmetic.h",
+                 "call cgal_is_degenerate_2d",
+                 "Only implemented for simplices of tdim 0, 1 and 2, not tdim = %d", s.size() - 1);
+
+    return true;
+  }
+  //-----------------------------------------------------------------------------
+  inline bool cgal_is_degenerate_3d(const std::vector<Point>& s)
+  {
+    if (s.size() < 2 or s.size() > 4)
+    {
+      info("Degenerate 3D simplex with %d vertices.", s.size());
+      return true;
+    }
+
+    switch (s.size())
+    {
+    case 2: return is_degenerate_3d(s[0], s[1]);
+    case 3: return is_degenerate_3d(s[0], s[1], s[2]);
+    case 4: return is_degenerate_3d(s[0], s[1], s[2], s[3]);
+    }
+
+    // Shouldn't get here
+    dolfin_error("CGALExactArithmetic.h",
+                 "call cgal_is_degenerate_3d",
+                 "Only implemented for simplices of tdim 0, 1, 2 and 3, not tdim = %d", s.size() - 1);
+
+    return true;
+  }
+  //-----------------------------------------------------------------------------
+  // Computes the volume of the convex hull of the given points
+  inline double cgal_polyhedron_volume(const std::vector<Point>& ch)
+  {
+    std::vector<Point_3> exact_points;
+    exact_points.reserve(ch.size());
+    for (const Point p : ch)
+    {
+      exact_points.push_back(Point_3(p.x(), p.y(), p.z()));
+    }
+
+    // Compute the convex hull as a cgal polyhedron_3
+    Polyhedron_3 p;
+    CGAL::convex_hull_3(exact_points.begin(), exact_points.end(), p);
+
+    ExactNumber volume = .0;
+    for (Polyhedron_3::Facet_const_iterator it = p.facets_begin();
+         it != p.facets_end(); it++)
+    {
+      const Polyhedron_3::Halfedge_const_handle h = it->halfedge();
+      const Vector_3 V0 = h->vertex()->point()-CGAL::ORIGIN;
+      const Vector_3 V1 = h->next()->vertex()->point()-CGAL::ORIGIN;
+      const Vector_3 V2 = h->next()->next()->vertex()->point()-CGAL::ORIGIN;
+
+      volume += V0*CGAL::cross_product(V1, V2);
+    }
+
+    return std::abs(CGAL::to_double(volume/6.0));
+  }
+  //-----------------------------------------------------------------------------
+  inline double cgal_tet_volume(const std::vector<Point>& ch)
+  {
+    dolfin_assert(ch.size() == 3);
+    return CGAL::to_double(CGAL::volume(Point_3(ch[0].x(), ch[0].y(), ch[0].z()),
+                                        Point_3(ch[1].x(), ch[1].y(), ch[1].z()),
+                                        Point_3(ch[2].x(), ch[2].y(), ch[2].z()),
+                                        Point_3(ch[3].x(), ch[3].y(), ch[3].z())));
+  }
+  //-----------------------------------------------------------------------------
+  inline bool cgal_tet_is_degenerate(const std::vector<Point>& t)
+  {
+    Tetrahedron_3 tet(Point_3(t[0].x(), t[0].y(), t[0].z()),
+		      Point_3(t[1].x(), t[1].y(), t[1].z()),
+		      Point_3(t[2].x(), t[2].y(), t[2].z()),
+		      Point_3(t[3].x(), t[3].y(), t[3].z()));
+
+    return tet.is_degenerate();
+  }
+
+  //-----------------------------------------------------------------------------
+  inline bool cgal_triangulation_has_degenerate(std::vector<std::vector<Point>> triangulation)
+  {
+    for (const std::vector<Point>& t : triangulation)
+    {
+      if (cgal_tet_is_degenerate(t))
+        return true;
+    }
+
+    return false;
+  }
+
+  //-----------------------------------------------------------------------------
+  inline bool cgal_triangulation_overlap(std::vector<std::vector<Point>> triangulation)
+  {
+    std::vector<Tetrahedron_3> tets;
+
+    for (const std::vector<Point>& t : triangulation)
+    {
+      Tetrahedron_3 tet(Point_3(t[0].x(), t[0].y(), t[0].z()),
+                        Point_3(t[1].x(), t[1].y(), t[1].z()),
+                        Point_3(t[2].x(), t[2].y(), t[2].z()),
+                        Point_3(t[3].x(), t[3].y(), t[3].z()));
+
+      for (const Tetrahedron_3& t0 : tets)
+      {
+        for (int i = 0; i < 4; i++)
+        {
+          if (t0.has_on_bounded_side(tet[i]) || tet.has_on_bounded_side(t0[i]))
+	    return true;
+        }
+      }
+
+      tets.push_back(tet);
+    }
+
+    return false;
+  }
+
+  //-----------------------------------------------------------------------------
+
+}
+#endif
+
+#endif
diff --git a/dolfin/geometry/CMakeLists.txt b/dolfin/geometry/CMakeLists.txt
index 2e0c397..49812d9 100644
--- a/dolfin/geometry/CMakeLists.txt
+++ b/dolfin/geometry/CMakeLists.txt
@@ -3,23 +3,32 @@ set(HEADERS
   BoundingBoxTree2D.h
   BoundingBoxTree3D.h
   BoundingBoxTree.h
-  CollisionDetection.h
+  CGALExactArithmetic.h
+  CollisionPredicates.h
+  ConvexTriangulation.h
   dolfin_geometry.h
   GenericBoundingBoxTree.h
+  GeometryDebugging.h
+  GeometryPredicates.h
   intersect.h
-  IntersectionTriangulation.h
+  IntersectionConstruction.h
   MeshPointIntersection.h
   Point.h
+  predicates.h
   SimplexQuadrature.h
   PARENT_SCOPE)
 
 set(SOURCES
   BoundingBoxTree.cpp
-  CollisionDetection.cpp
+  CollisionPredicates.cpp
+  ConvexTriangulation.cpp
   GenericBoundingBoxTree.cpp
+  GeometryDebugging.cpp
+  GeometryPredicates.cpp
   intersect.cpp
-  IntersectionTriangulation.cpp
+  IntersectionConstruction.cpp
   MeshPointIntersection.cpp
   Point.cpp
+  predicates.cpp
   SimplexQuadrature.cpp
   PARENT_SCOPE)
diff --git a/dolfin/geometry/CollisionDetection.cpp b/dolfin/geometry/CollisionDetection.cpp
deleted file mode 100644
index 199d178..0000000
--- a/dolfin/geometry/CollisionDetection.cpp
+++ /dev/null
@@ -1,1158 +0,0 @@
-// Copyright (C) 2014 Anders Logg and August Johansson
-//
-// This file is part of DOLFIN.
-//
-// DOLFIN is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// DOLFIN 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 Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
-//
-// Modified by Chris Richardson, 2014.
-//
-// First added:  2014-02-03
-// Last changed: 2014-04-03
-//
-//-----------------------------------------------------------------------------
-// Special note regarding the function collides_tetrahedron_tetrahedron
-//-----------------------------------------------------------------------------
-//
-// The source code for the tetrahedron-tetrahedron collision test is
-// from Fabio Ganovelli, Federico Ponchio and Claudio Rocchini: Fast
-// Tetrahedron-Tetrahedron Overlap Algorithm, Journal of Graphics
-// Tools, 7(2), 2002, and is under the following copyright:
-//
-// Visual Computing Group
-// IEI Institute, CNUCE Institute, CNR Pisa
-//
-// Copyright(C) 2002 by Fabio Ganovelli, Federico Ponchio and Claudio
-// Rocchini
-//
-// All rights reserved.
-//
-// Permission to use, copy, modify, distribute and sell this software
-// and its documentation for any purpose is hereby granted without
-// fee, provided that the above copyright notice appear in all copies
-// and that both that copyright notice and this permission notice
-// appear in supporting documentation. the author makes no
-// representations about the suitability of this software for any
-// purpose. It is provided "as is" without express or implied
-// warranty.
-//
-//-----------------------------------------------------------------------------
-// Special note regarding the function collides_triangle_triangle
-//-----------------------------------------------------------------------------
-//
-// The source code for the triangle-triangle collision test is from
-// Tomas Moller: A Fast Triangle-Triangle Intersection Test, Journal
-// of Graphics Tools, 2(2), 1997, and is in the public domain.
-//
-//-----------------------------------------------------------------------------
-
-#include <dolfin/mesh/MeshEntity.h>
-#include "Point.h"
-#include "CollisionDetection.h"
-
-using namespace dolfin;
-
-//-----------------------------------------------------------------------------
-bool CollisionDetection::collides(const MeshEntity& entity,
-                                  const Point& point)
-{
-  switch (entity.dim())
-  {
-  case 0:
-    dolfin_not_implemented();
-    break;
-  case 1:
-    return collides_interval_point(entity, point);
-  case 2:
-    return collides_triangle_point(entity, point);
-  case 3:
-    return collides_tetrahedron_point(entity, point);
-  default:
-    dolfin_error("CollisionDetection.cpp",
-		 "collides entity with point",
-		 "Unknown dimension of entity");
-  }
-
-  return false;
-}
-//-----------------------------------------------------------------------------
-bool
-CollisionDetection::collides(const MeshEntity& entity_0,
-			     const MeshEntity& entity_1)
-{
-  switch (entity_0.dim())
-  {
-  case 0:
-    // Collision with PointCell
-    dolfin_not_implemented();
-    break;
-  case 1:
-    // Collision with interval
-    switch (entity_1.dim())
-    {
-    case 0:
-      dolfin_not_implemented();
-      break;
-    case 1:
-      return collides_interval_interval(entity_1, entity_0);
-      break;
-    case 2:
-      dolfin_not_implemented();
-      break;
-    case 3:
-      dolfin_not_implemented();
-      break;
-    default:
-      dolfin_error("CollisionDetection.cpp",
-                   "collides entity_0 with entity_1",
-                   "Unknown dimension of entity_1 in IntervalCell collision");
-    }
-    break;
-  case 2:
-    // Collision with triangle
-    switch (entity_1.dim())
-    {
-    case 0:
-      dolfin_not_implemented();
-      break;
-    case 1:
-      dolfin_not_implemented();
-      break;
-    case 2:
-      return collides_triangle_triangle(entity_0, entity_1);
-    case 3:
-      return collides_tetrahedron_triangle(entity_1, entity_0);
-    default:
-      dolfin_error("CollisionDetection.cpp",
-		   "collides entity_0 with entity_1",
-		   "Unknown dimension of entity_1 in TriangleCell collision");
-    }
-    break;
-  case 3:
-    // Collision with tetrahedron
-    switch (entity_1.dim())
-    {
-    case 0:
-     dolfin_not_implemented();
-      break;
-    case 1:
-      dolfin_not_implemented();
-      break;
-    case 2:
-      return collides_tetrahedron_triangle(entity_0, entity_1);
-      break;
-    case 3:
-      return collides_tetrahedron_tetrahedron(entity_0, entity_1);
-      break;
-    default:
-      dolfin_error("CollisionDetection.cpp",
-		   "collides entity_0 with entity_1",
-		   "Unknown dimension of entity_1 in TetrahedronCell collision");
-    }
-    break;
-  default:
-    dolfin_error("CollisionDetection.cpp",
-		 "collides entity_0 with entity_1",
-		 "Unknown dimension of entity_0");
-  }
-
-  return false;
-}
-//-----------------------------------------------------------------------------
-bool CollisionDetection::collides_interval_point(const MeshEntity& entity,
-                                                 const Point& point)
-{
-  // Get coordinates
-  const MeshGeometry& geometry = entity.mesh().geometry();
-  const unsigned int* vertices = entity.entities(0);
-  return collides_interval_point(geometry.point(vertices[0]),
-                                 geometry.point(vertices[1]),
-                                 point);
-}
-//-----------------------------------------------------------------------------
-bool
-CollisionDetection::collides_interval_interval(const MeshEntity& interval_0,
-                                               const MeshEntity& interval_1)
-{
-  // Get coordinates
-  const MeshGeometry& geometry_0 = interval_0.mesh().geometry();
-  const MeshGeometry& geometry_1 = interval_1.mesh().geometry();
-  const unsigned int* vertices_0 = interval_0.entities(0);
-  const unsigned int* vertices_1 = interval_1.entities(0);
-  const double x00 = geometry_0.point(vertices_0[0])[0];
-  const double x01 = geometry_0.point(vertices_0[1])[0];
-  const double x10 = geometry_1.point(vertices_1[0])[0];
-  const double x11 = geometry_1.point(vertices_1[1])[0];
-
-  const double a0 = std::min(x00, x01);
-  const double b0 = std::max(x00, x01);
-  const double a1 = std::min(x10, x11);
-  const double b1 = std::max(x10, x11);
-
-  // Check for collisions
-  const double dx = std::min(b0 - a0, b1 - a1);
-  const double eps = std::max(DOLFIN_EPS_LARGE, DOLFIN_EPS_LARGE*dx);
-  return b1 > a0 - eps && a1 < b0 + eps;
-}
-//-----------------------------------------------------------------------------
-bool CollisionDetection::collides_triangle_point(const MeshEntity& triangle,
-                                                 const Point& point)
-{
-  dolfin_assert(triangle.mesh().topology().dim() == 2);
-
-  const MeshGeometry& geometry = triangle.mesh().geometry();
-  const unsigned int* vertices = triangle.entities(0);
-
-  if (triangle.mesh().geometry().dim() == 2)
-    return collides_triangle_point_2d(geometry.point(vertices[0]),
-                                      geometry.point(vertices[1]),
-                                      geometry.point(vertices[2]),
-                                      point);
-  else
-    return collides_triangle_point(geometry.point(vertices[0]),
-                                   geometry.point(vertices[1]),
-                                   geometry.point(vertices[2]),
-                                   point);
-
-}
-//-----------------------------------------------------------------------------
-bool
-CollisionDetection::collides_triangle_triangle(const MeshEntity& triangle_0,
-                                               const MeshEntity& triangle_1)
-{
-  dolfin_assert(triangle_0.mesh().topology().dim() == 2);
-  dolfin_assert(triangle_1.mesh().topology().dim() == 2);
-
-  // Get vertices as points
-  const MeshGeometry& geometry_0 = triangle_0.mesh().geometry();
-  const unsigned int* vertices_0 = triangle_0.entities(0);
-  const MeshGeometry& geometry_1 = triangle_1.mesh().geometry();
-  const unsigned int* vertices_1 = triangle_1.entities(0);
-
-  return collides_triangle_triangle(geometry_0.point(vertices_0[0]),
-				    geometry_0.point(vertices_0[1]),
-				    geometry_0.point(vertices_0[2]),
-				    geometry_1.point(vertices_1[0]),
-				    geometry_1.point(vertices_1[1]),
-				    geometry_1.point(vertices_1[2]));
-}
-//-----------------------------------------------------------------------------
-bool
-CollisionDetection::collides_tetrahedron_point(const MeshEntity& tetrahedron,
-                                               const Point& point)
-{
-  dolfin_assert(tetrahedron.mesh().topology().dim() == 3);
-
-  // Get the vertices as points
-  const MeshGeometry& geometry = tetrahedron.mesh().geometry();
-  const unsigned int* vertices = tetrahedron.entities(0);
-
-  return collides_tetrahedron_point(geometry.point(vertices[0]),
-				    geometry.point(vertices[1]),
-				    geometry.point(vertices[2]),
-				    geometry.point(vertices[3]),
-				    point);
-}
-//-----------------------------------------------------------------------------
-bool
-CollisionDetection::collides_tetrahedron_triangle(const MeshEntity& tetrahedron,
-                                                  const MeshEntity& triangle)
-{
-  dolfin_assert(tetrahedron.mesh().topology().dim() == 3);
-  dolfin_assert(triangle.mesh().topology().dim() == 2);
-
-  // Get the vertices of the tetrahedron as points
-  const MeshGeometry& geometry_tet = tetrahedron.mesh().geometry();
-  const unsigned int* vertices_tet = tetrahedron.entities(0);
-
-  // Get the vertices of the triangle as points
-  const MeshGeometry& geometry_tri = triangle.mesh().geometry();
-  const unsigned int* vertices_tri = triangle.entities(0);
-
-  return collides_tetrahedron_triangle(geometry_tet.point(vertices_tet[0]),
-				       geometry_tet.point(vertices_tet[1]),
-				       geometry_tet.point(vertices_tet[2]),
-				       geometry_tet.point(vertices_tet[3]),
-				       geometry_tri.point(vertices_tri[0]),
-				       geometry_tri.point(vertices_tri[1]),
-				       geometry_tri.point(vertices_tri[2]));
-}
-//-----------------------------------------------------------------------------
-bool
-CollisionDetection::collides_tetrahedron_tetrahedron
-(const MeshEntity& tetrahedron_0,
- const MeshEntity& tetrahedron_1)
-{
-  // This algorithm checks whether two tetrahedra intersect.
-
-  // Algorithm and source code from Fabio Ganovelli, Federico Ponchio
-  // and Claudio Rocchini: Fast Tetrahedron-Tetrahedron Overlap
-  // Algorithm, Journal of Graphics Tools, 7(2), 2002. DOI:
-  // 10.1080/10867651.2002.10487557. Source code available at
-  // http://web.archive.org/web/20031130075955/http://www.acm.org/jgt/papers/GanovelliPonchioRocchini02/tet_a_tet.html
-
-  dolfin_assert(tetrahedron_0.mesh().topology().dim() == 3);
-  dolfin_assert(tetrahedron_1.mesh().topology().dim() == 3);
-
-  // Get the vertices as points
-  const MeshGeometry& geometry = tetrahedron_0.mesh().geometry();
-  const unsigned int* vertices = tetrahedron_0.entities(0);
-  const MeshGeometry& geometry_q = tetrahedron_1.mesh().geometry();
-  const unsigned int* vertices_q = tetrahedron_1.entities(0);
-  std::vector<Point> V1(4), V2(4);
-  for (std::size_t i = 0; i < 4; ++i)
-  {
-    V1[i] = geometry.point(vertices[i]);
-    V2[i] = geometry_q.point(vertices_q[i]);
-  }
-
-  // Get the vectors between V2 and V1[0]
-  std::vector<Point> P_V1(4);
-  for (std::size_t i = 0; i < 4; ++i)
-    P_V1[i] = V2[i]-V1[0];
-
-  // Data structure for edges of V1 and V2
-  std::vector<Point> e_v1(5), e_v2(5);
-  e_v1[0] = V1[1] - V1[0];
-  e_v1[1] = V1[2] - V1[0];
-  e_v1[2] = V1[3] - V1[0];
-  Point n = e_v1[1].cross(e_v1[0]);
-
-  // Maybe flip normal. Normal should be outward.
-  if (n.dot(e_v1[2]) > 0)
-    n *= -1;
-  std::vector<int> masks(4);
-  std::vector<std::vector<double>> Coord_1(4, std::vector<double>(4));
-  if (separating_plane_face_A_1(P_V1, n, Coord_1[0], masks[0]))
-    return false;
-  n = e_v1[0].cross(e_v1[2]);
-
-  // Maybe flip normal
-  if (n.dot(e_v1[1]) > 0)
-    n *= -1;
-  if (separating_plane_face_A_1(P_V1, n, Coord_1[1], masks[1]))
-    return false;
-  if (separating_plane_edge_A(Coord_1, masks, 0, 1))
-    return false;
-  n = e_v1[2].cross(e_v1[1]);
-
-  // Maybe flip normal
-  if (n.dot(e_v1[0]) > 0)
-    n *= -1;
-  if (separating_plane_face_A_1(P_V1, n, Coord_1[2], masks[2]))
-    return false;
-  if (separating_plane_edge_A(Coord_1, masks, 0, 2))
-    return false;
-  if (separating_plane_edge_A(Coord_1, masks, 1,2))
-    return false;
-  e_v1[4] = V1[3] - V1[1];
-  e_v1[3] = V1[2] - V1[1];
-  n = e_v1[3].cross(e_v1[4]);
-
-  // Maybe flip normal. Note the < since e_v1[0]=v1-v0.
-  if (n.dot(e_v1[0]) < 0)
-    n *= -1;
-  if (separating_plane_face_A_2(V1, V2, n, Coord_1[3], masks[3]))
-    return false;
-  if (separating_plane_edge_A(Coord_1, masks, 0, 3))
-    return false;
-  if (separating_plane_edge_A(Coord_1, masks, 1, 3))
-    return false;
-  if (separating_plane_edge_A(Coord_1, masks, 2, 3))
-    return false;
-  if ((masks[0] | masks[1] | masks[2] | masks[3] )!= 15)
-    return true;
-
-  // From now on, if there is a separating plane, it is parallel to a
-  // face of b.
-  std::vector<Point> P_V2(4);
-  for (std::size_t i = 0; i < 4; ++i)
-    P_V2[i] = V1[i] - V2[0];
-  e_v2[0] = V2[1] - V2[0];
-  e_v2[1] = V2[2] - V2[0];
-  e_v2[2] = V2[3] - V2[0];
-  n = e_v2[1].cross(e_v2[0]);
-
-  // Maybe flip normal
-  if (n.dot(e_v2[2])>0)
-    n *= -1;
-  if (separating_plane_face_B_1(P_V2, n))
-    return false;
-  n=e_v2[0].cross(e_v2[2]);
-
-  // Maybe flip normal
-  if (n.dot(e_v2[1]) > 0)
-    n *= -1;
-  if (separating_plane_face_B_1(P_V2, n))
-    return false;
-  n = e_v2[2].cross(e_v2[1]);
-
-  // Maybe flip normal
-  if (n.dot(e_v2[0]) > 0)
-    n *= -1;
-  if (separating_plane_face_B_1(P_V2, n))
-    return false;
-  e_v2[4] = V2[3] - V2[1];
-  e_v2[3] = V2[2] - V2[1];
-  n = e_v2[3].cross(e_v2[4]);
-
-  // Maybe flip normal. Note the < since e_v2[0] = V2[1] - V2[0].
-  if (n.dot(e_v2[0]) < 0)
-    n *= -1;
-  if (separating_plane_face_B_2(V1, V2, n))
-    return false;
-
-  return true;
-}
-//-----------------------------------------------------------------------------
-bool
-CollisionDetection::collides_edge_edge(const Point& a,
-				       const Point& b,
-				       const Point& c,
-				       const Point& d)
-{
-  const double tol = DOLFIN_EPS_LARGE;
-
-  // Check if two edges are the same
-  if ((a - c).norm() < tol and (b - d).norm() < tol)
-    return false;
-  if ((a - d).norm() < tol and (b - c).norm() < tol)
-    return false;
-
-  // Get edges as vectors and compute the normal
-  const Point L1 = b - a;
-  const Point L2 = d - c;
-  const Point n = L1.cross(L2);
-
-  // Check if L1 and L2 are coplanar
-  const Point ca = c - a;
-  if (std::abs(ca.dot(n)) > tol)
-    return false;
-
-  // Find orthogonal plane with normal n1
-  const Point n1 = n.cross(L1);
-  const double n1dotL2 = n1.dot(L2);
-  if (std::abs(n1dotL2) < tol)
-    return false;
-  const double t = n1.dot(a - c) / n1dotL2;
-  if (t <= 0 or t >= 1)
-    return false;
-
-  // Find orthogonal plane with normal n2
-  const Point n2 = n.cross(L2);
-  const double n2dotL1 = n2.dot(L1);
-  if (std::abs(n2dotL1) < tol)
-    return false;
-  const double s = n2.dot(c - a) / n2dotL1;
-  if (s <= 0 or s >= 1)
-    return false;
-
-  return true;
-}
-//-----------------------------------------------------------------------------
-bool CollisionDetection::collides_interval_point(const Point& p0,
-                                                 const Point& p1,
-                                                 const Point& point)
-{
-  // Compute angle between v = p1 - p0 and w = point - p0
-  Point v = p1 - p0;
-  const double vnorm = v.norm();
-
-  // p0 and p1 are the same points
-  if (vnorm < DOLFIN_EPS_LARGE)
-    return false;
-
-  const Point w = point - p0;
-  const double wnorm = w.norm();
-
-  // point and p0 are the same points
-  if (wnorm < DOLFIN_EPS)
-    return true;
-
-  // Compute cosine
-  v /= vnorm;
-  const double a = v.dot(w) / wnorm;
-
-  // Cosine should be 1, and point should lie between p0 and p1
-  if (std::abs(1-a) < DOLFIN_EPS_LARGE and wnorm <= vnorm)
-    return true;
-
-  return false;
-}
-
-//-----------------------------------------------------------------------------
-bool CollisionDetection::collides_triangle_point_2d(const Point& p0,
-                                                    const Point& p1,
-                                                    const Point& p2,
-                                                    const Point &point)
-{
-  // Simplified algorithm for coplanar triangles and points (z=0)
-  // This algorithm is robust because it will perform the same numerical
-  // test on each edge of neighbouring triangles. Points cannot slip
-  // between the edges, and evade detection.
-
-  // Vectors defining each edge in consistent orientation
-  const Point r0 = p0 - p2;
-  const Point r1 = p1 - p0;
-  const Point r2 = p2 - p1;
-
-  // Normal to triangle
-  double normal = r1.x()*r0.y() - r1.y()*r0.x();
-
-  // Compute normal to triangle based on point and first edge
-  // Will have opposite sign if outside triangle
-
-  Point r = point - p0;
-  double pnormal = r.x()*r0.y() - r.y()*r0.x();
-  if (pnormal != 0.0 and std::signbit(normal) != std::signbit(pnormal))
-    return false;
-
-  // Repeat for each edge
-  r = point - p1;
-  pnormal = r.x()*r1.y() - r.y()*r1.x();
-  if (pnormal != 0.0 and std::signbit(normal) != std::signbit(pnormal))
-    return false;
-
-  r = point - p2;
-  pnormal = r.x()*r2.y() - r.y()*r2.x();
-  if (pnormal != 0.0 and std::signbit(normal) != std::signbit(pnormal))
-    return false;
-
-  return true;
-}
-//-----------------------------------------------------------------------------
-bool CollisionDetection::collides_triangle_point(const Point& p0,
-                                                 const Point& p1,
-                                                 const Point& p2,
-                                                 const Point &point)
-{
-  // Algorithm from http://www.blackpawn.com/texts/pointinpoly/
-
-  // Vectors defining each edge in consistent orientation
-  const Point r0 = p0 - p2;
-  const Point r1 = p1 - p0;
-  const Point r2 = p2 - p1;
-
-  // Normal to triangle: should be the same as
-  // r2.cross(r1) and r0.cross(r2).
-  Point normal = r1.cross(r0);
-
-  Point r = point - p0;
-  // Check point is in plane of triangle (for manifold)
-  double volume = r.dot(normal);
-  if (std::abs(volume) > DOLFIN_EPS)
-    return false;
-
-  // Compute normal to triangle based on point and first edge
-  // Dot product of two normals should be positive, if inside.
-  Point pnormal = r.cross(r0);
-  double t1 = normal.dot(pnormal);
-  if (t1 < 0) return false;
-
-  // Repeat for each edge
-  r = point - p1;
-  pnormal = r.cross(r1);
-  double t2 = normal.dot(pnormal);
-  if (t2 < 0) return false;
-
-  r = point - p2;
-  pnormal = r.cross(r2);
-  double t3 = normal.dot(pnormal);
-  if (t3 < 0) return false;
-
-  return true;
-}
-//-----------------------------------------------------------------------------
-bool
-CollisionDetection::collides_triangle_triangle(const Point& p0,
-					       const Point& p1,
-					       const Point& p2,
-					       const Point& q0,
-					       const Point& q1,
-					       const Point& q2)
-{
-  // Algorithm and code from Tomas Moller: A Fast Triangle-Triangle
-  // Intersection Test, Journal of Graphics Tools, 2(2), 1997. Source
-  // code is available at
-  // http://fileadmin.cs.lth.se/cs/Personal/Tomas_Akenine-Moller/code/opttritri.txt
-
-  // First check if the triangles are the same. We need to do this
-  // separately if we do _not_ allow for adjacent edges to be
-  // classified as colliding (see the edge_edge_test).
-
-  const Point Vmid = (p0 + p1 + p2) / 3.;
-  const Point Umid = (q0 + q1 + q2) / 3.;
-  if ((Vmid-Umid).norm() < DOLFIN_EPS_LARGE)
-    return true;
-
-  Point E1, E2;
-  Point N1, N2;
-  double d1, d2;
-  double du0, du1, du2, dv0, dv1, dv2;
-  Point D;
-  double isect1[2], isect2[2];
-  double du0du1, du0du2, dv0dv1, dv0dv2;
-  int index;
-  double vp0, vp1, vp2;
-  double up0, up1, up2;
-  double bb, cc, max;
-
-  // Compute plane equation of triangle(p0,p1,p2)
-  E1 = p1-p0;
-  E2 = p2-p0;
-  N1 = E1.cross(E2);
-  d1 = -N1.dot(p0);
-
-  // Plane equation 1: N1.X+d1=0. Put q0,q1,q2 into plane equation 1
-  // to compute signed distances to the plane
-  du0 = N1.dot(q0)+d1;
-  du1 = N1.dot(q1)+d1;
-  du2 = N1.dot(q2)+d1;
-
-  // Coplanarity robustness check
-  if (std::abs(du0) < DOLFIN_EPS_LARGE)
-    du0 = 0.0;
-  if (std::abs(du1) < DOLFIN_EPS_LARGE)
-    du1 = 0.0;
-  if (std::abs(du2) < DOLFIN_EPS_LARGE)
-    du2 = 0.0;
-  du0du1 = du0*du1;
-  du0du2 = du0*du2;
-
-  // Same sign on all of them + not equal 0?
-  if (du0du1>0. && du0du2>0.)
-    return false;
-
-  // Compute plane of triangle (q0,q1,q2)
-  E1 = q1-q0;
-  E2 = q2-q0;
-  N2 = E1.cross(E2);
-  d2 = -N2.dot(q0);
-  // Plane equation 2: N2.X+d2=0. Put p0,p1,p2 into plane equation 2
-  dv0 = N2.dot(p0)+d2;
-  dv1 = N2.dot(p1)+d2;
-  dv2 = N2.dot(p2)+d2;
-
-  // Coplanarity check
-  if (std::abs(dv0) < DOLFIN_EPS_LARGE)
-    dv0 = 0.0;
-  if (std::abs(dv1) < DOLFIN_EPS_LARGE)
-    dv1 = 0.0;
-  if (std::abs(dv2) < DOLFIN_EPS_LARGE)
-    dv2 = 0.0;
-  dv0dv1 = dv0*dv1;
-  dv0dv2 = dv0*dv2;
-
-  // Same sign on all of them + not equal 0 ?
-  if (dv0dv1>0. && dv0dv2>0.)
-    return false;
-
-  // Compute direction of intersection line
-  D = N1.cross(N2);
-
-  // Compute and index to the largest component of D
-  max = (double)std::abs(D[0]);
-  index = 0;
-  bb = (double)std::abs(D[1]);
-  cc = (double)std::abs(D[2]);
-  if (bb > max)
-    max = bb, index = 1;
-  if (cc > max)
-    max = cc, index = 2;
-
-  // This is the simplified projection onto L
-  vp0 = p0[index];
-  vp1 = p1[index];
-  vp2 = p2[index];
-
-  up0 = q0[index];
-  up1 = q1[index];
-  up2 = q2[index];
-
-  // Compute interval for triangle 1
-  double a, b, c, x0, x1;
-  if (compute_intervals(vp0, vp1, vp2, dv0, dv1, dv2, dv0dv1, dv0dv2,
-                        a, b, c, x0, x1))
-    return coplanar_tri_tri(N1, p0, p1, p2, q0, q1, q2);
-
-  // Compute interval for triangle 2
-  double d, e, f, y0, y1;
-  if (compute_intervals(up0, up1, up2, du0, du1, du2, du0du1, du0du2,
-                        d, e, f, y0, y1))
-    return coplanar_tri_tri(N1, p0, p1, p2, q0, q1, q2);
-
-  double xx, yy, xxyy, tmp;
-  xx = x0*x1;
-  yy = y0*y1;
-  xxyy = xx*yy;
-
-  tmp = a*xxyy;
-  isect1[0] = tmp+b*x1*yy;
-  isect1[1] = tmp+c*x0*yy;
-
-  tmp = d*xxyy;
-  isect2[0] = tmp+e*xx*y1;
-  isect2[1] = tmp+f*xx*y0;
-
-  if (isect1[0] > isect1[1])
-    std::swap(isect1[0], isect1[1]);
-  if (isect2[0] > isect2[1])
-    std::swap(isect2[0], isect2[1]);
-
-  if (isect1[1] < isect2[0] ||
-      isect2[1] < isect1[0])
-    return false;
-
-  return true;
-}
-//-----------------------------------------------------------------------------
-bool
-CollisionDetection::collides_tetrahedron_point(const Point& p0,
-					       const Point& p1,
-					       const Point& p2,
-					       const Point& p3,
-					       const Point& point)
-{
-  // Algorithm from http://www.blackpawn.com/texts/pointinpoly/
-  // See also "Real-Time Collision Detection" by Christer Ericson.
-
-  const Point *p[4] = {&p0, &p1, &p2, &p3};
-
-  // Consider each face in turn
-  for (unsigned int i = 0; i != 4; ++i)
-  {
-    // Compute vectors relative to p[i]
-    const Point v1 = *p[(i + 1)%4] - *p[i];
-    const Point v2 = *p[(i + 2)%4] - *p[i];
-    const Point v3 = *p[(i + 3)%4] - *p[i];
-    const Point v = point - *p[i];
-    // Normal to plane containing v1 and v2
-    const Point n1 = v1.cross(v2);
-    // Find which side of face plane points v and v3 lie
-    const double t1 = n1.dot(v);
-    const double t2 = n1.dot(v3);
-    // Catch case where point is exactly on plane
-    // otherwise require points to be on same side
-    if (t1 != 0.0 and std::signbit(t1) != std::signbit(t2))
-      return false;
-  }
-  return true;
-}
-//-----------------------------------------------------------------------------
-bool
-CollisionDetection::collides_tetrahedron_triangle(const Point& p0,
-						  const Point& p1,
-						  const Point& p2,
-						  const Point& p3,
-						  const Point& q0,
-						  const Point& q1,
-						  const Point& q2)
-{
-  // Collision is determined by first if any triangle vertex is inside
-  // the tetrahedron. If not, we continue checking the intersection of
-  // the triangle with the four faces of the tetrahedron.
-
-  // Triangle vertex in tetrahedron collision
-  if (collides_tetrahedron_point(p0, p1, p2, p3, q0))
-    return true;
-  if (collides_tetrahedron_point(p0, p1, p2, p3, q1))
-    return true;
-  if (collides_tetrahedron_point(p0, p1, p2, p3, q2))
-    return true;
-
-  // Triangle-triangle collision tests
-  if (collides_triangle_triangle(q0, q1, q2, p1, p2, p3))
-    return true;
-  if (collides_triangle_triangle(q0, q1, q2, p0, p2, p3))
-    return true;
-  if (collides_triangle_triangle(q0, q1, q2, p0, p1, p3))
-    return true;
-  if (collides_triangle_triangle(q0, q1, q2, p0, p1, p2))
-    return true;
-
-  return false;
-}
-//-----------------------------------------------------------------------------
-bool CollisionDetection::edge_edge_test(int i0,
-                                        int i1,
-                                        double Ax,
-                                        double Ay,
-					const Point& V0,
-					const Point& U0,
-					const Point& U1)
-{
-  // Helper function for triangle triangle collision. Test edge vs
-  // edge.
-
-  // Here we have the option of classifying adjacent edges of two
-  // triangles as colliding by changing > to >= and < to <= below.
-
-  const double Bx = U0[i0] - U1[i0];
-  const double By = U0[i1] - U1[i1];
-  const double Cx = V0[i0] - U0[i0];
-  const double Cy = V0[i1] - U0[i1];
-  const double f = Ay*Bx - Ax*By;
-  const double d = By*Cx - Bx*Cy;
-
-  if ((f > 0 && d >= 0 && d <= f) ||
-      (f < 0 && d <= 0 && d >= f))
-  {
-    const double e = Ax*Cy - Ay*Cx;
-    if (f > 0)
-    {
-      // Allow or not allow adjacent edges as colliding:
-      //if (e >= 0 && e <= f) return true;
-      if (e > 0 && e < f)
-        return true;
-    }
-    else
-    {
-      // Allow or not allow adjacent edges as colliding:
-      //if (e <= 0 && e >= f) return true;
-      if (e < 0 && e > f)
-        return true;
-    }
-  }
-  return false;
-}
-//-----------------------------------------------------------------------------
-bool CollisionDetection::edge_against_tri_edges(int i0,
-                                                int i1,
-						const Point& V0,
-						const Point& V1,
-						const Point& U0,
-						const Point& U1,
-						const Point& U2)
-{
-  // Helper function for triangle triangle collision
-  const double Ax = V1[i0] - V0[i0];
-  const double Ay = V1[i1] - V0[i1];
-
-  // Test edge U0,U1 against V0,V1
-  if (edge_edge_test(i0, i1, Ax, Ay, V0, U0, U1))
-    return true;
-
-  // Test edge U1,U2 against V0,V1
-  if (edge_edge_test(i0, i1, Ax, Ay, V0, U1, U2))
-    return true;
-
-  // Test edge U2,U1 against V0,V1
-  if (edge_edge_test(i0, i1, Ax, Ay, V0, U2, U0))
-    return true;
-
-  return false;
-}
-//-----------------------------------------------------------------------------
-bool CollisionDetection::point_in_tri(int i0,
-                                      int i1,
-				      const Point& V0,
-				      const Point& U0,
-				      const Point& U1,
-				      const Point& U2)
-{
-  // Helper function for triangle triangle collision
-  // Is T1 completely inside T2?
-  // Check if V0 is inside tri(U0,U1,U2)
-  double a = U1[i1] - U0[i1];
-  double b = -(U1[i0] - U0[i0]);
-  double c = -a*U0[i0] - b*U0[i1];
-  const double d0 = a*V0[i0] + b*V0[i1] + c;
-
-  a = U2[i1] - U1[i1];
-  b = -(U2[i0] - U1[i0]);
-  c = -a*U1[i0] - b*U1[i1];
-  const double d1 = a*V0[i0] + b*V0[i1] + c;
-
-  a = U0[i1] - U2[i1];
-  b = -(U0[i0] - U2[i0]);
-  c = -a*U2[i0] - b*U2[i1];
-  const double d2 = a*V0[i0] + b*V0[i1] + c;
-
-  if (d0*d1 > 0.)
-  {
-    if (d0*d2 > 0.)
-      return true;
-  }
-
-  return false;
-}
-//-----------------------------------------------------------------------------
-bool CollisionDetection::coplanar_tri_tri(const Point& N,
-					  const Point& V0,
-					  const Point& V1,
-					  const Point& V2,
-					  const Point& U0,
-					  const Point& U1,
-					  const Point& U2)
-{
-  // Helper function for triangle triangle collision
-
-  double A[3];
-  int i0,i1;
-
-  // First project onto an axis-aligned plane, that maximizes the area
-  // of the triangles, compute indices: i0,i1.
-  A[0] = std::abs(N[0]);
-  A[1] = std::abs(N[1]);
-  A[2] = std::abs(N[2]);
-
-  if (A[0] > A[1])
-  {
-    if (A[0] > A[2])
-    {
-      i0 = 1;      // A[0] is greatest
-      i1 = 2;
-    }
-    else
-    {
-      i0 = 0;      // A[2] is greatest
-      i1 = 1;
-    }
-  }
-  else   // A[0]<=A[1]
-  {
-    if (A[2] > A[1])
-    {
-      i0 = 0;      // A[2] is greatest
-      i1 = 1;
-    }
-    else
-    {
-      i0 = 0;      // A[1] is greatest
-      i1 = 2;
-    }
-  }
-
-  // Test all edges of triangle 1 against the edges of triangle 2
-  if (edge_against_tri_edges(i0, i1, V0, V1, U0, U1, U2))
-    return true;
-  if (edge_against_tri_edges(i0, i1, V1, V2, U0, U1, U2))
-    return true;
-  if (edge_against_tri_edges(i0, i1, V2, V0, U0, U1, U2))
-    return true;
-
-  // Finally, test if tri1 is totally contained in tri2 or vice versa
-  if (point_in_tri(i0, i1, V0, U0, U1, U2))
-    return true;
-  if (point_in_tri(i0, i1, U0, V0, V1, V2))
-    return true;
-
-  return false;
-}
-//-----------------------------------------------------------------------------
-bool CollisionDetection::compute_intervals(double VV0,
-					   double VV1,
-					   double VV2,
-					   double D0,
-					   double D1,
-					   double D2,
-					   double D0D1,
-					   double D0D2,
-					   double& A,
-					   double& B,
-					   double& C,
-					   double& X0,
-					   double& X1)
-{
-  // Helper function for triangle triangle collision
-
-  if (D0D1 > 0.)
-  {
-    // Here we know that D0D2<=0.0, that is D0, D1 are on the same
-    // side, D2 on the other or on the plane
-    A = VV2;
-    B = (VV0 - VV2)*D2;
-    C = (VV1 - VV2)*D2;
-    X0 = D2 - D0;
-    X1 = D2 - D1;
-  }
-  else if (D0D2 > 0.)
-  {
-    // Here we know that d0d1<=0.0
-    A = VV1;
-    B = (VV0 - VV1)*D1;
-    C = (VV2 - VV1)*D1;
-    X0 = D1 - D0;
-    X1 = D1 - D2;
-  }
-  else if (D1*D2 > 0. || D0 != 0.)
-  {
-    // Here we know that d0d1<=0.0 or that D0!=0.0
-    A = VV0;
-    B = (VV1 - VV0)*D0;
-    C = (VV2 - VV0)*D0;
-    X0 = D0 - D1;
-    X1 = D0 - D2;
-  }
-  else if (D1 != 0.)
-  {
-    A = VV1;
-    B = (VV0 - VV1)*D1;
-    C = (VV2 - VV1)*D1;
-    X0 = D1 - D0;
-    X1 = D1 - D2;
-  }
-  else if (D2 != 0.)
-  {
-    A = VV2;
-    B = (VV0 - VV2)*D2;
-    C = (VV1 - VV2)*D2;
-    X0 = D2 - D0;
-    X1 = D2 - D1;
-  }
-  else {
-    // Go to coplanar test
-    return true;
-  }
-
-  return false;
-}
-//-----------------------------------------------------------------------------
-bool
-CollisionDetection::separating_plane_face_A_1(const std::vector<Point>& pv1,
-					      const Point& n,
-					      std::vector<double>& coord,
-					      int&  mask_edges)
-{
-  // Helper function for tetrahedron-tetrahedron collision test:
-  // checks if plane pv1 is a separating plane. Stores local
-  // coordinates and the mask bit mask_edges.
-
-  mask_edges = 0;
-  const int shifts[4] = {1, 2, 4, 8};
-
-  for (std::size_t i = 0; i < 4; ++i)
-  {
-    coord[i] = pv1[i].dot(n);
-    if (coord[i] > 0)
-      mask_edges |= shifts[i];
-  }
-
-  return (mask_edges == 15);
-}
-//-----------------------------------------------------------------------------
-bool
-CollisionDetection::separating_plane_face_A_2(const std::vector<Point>& V1,
-					      const std::vector<Point>& V2,
-					      const Point& n,
-					      std::vector<double>& coord,
-					      int&  mask_edges)
-{
-  // Helper function for tetrahedron-tetrahedron collision test:
-  // checks if plane v1,v2 is a separating plane. Stores local
-  // coordinates and the mask bit mask_edges.
-
-  mask_edges = 0;
-  const int shifts[4] = {1, 2, 4, 8};
-
-  for (std::size_t i = 0; i < 4; ++i)
-  {
-    coord[i] = (V2[i] - V1[1]).dot(n);
-    if (coord[i] > 0)
-      mask_edges |= shifts[i];
-  }
-
-  return (mask_edges == 15);
-}
-//-----------------------------------------------------------------------------
-bool CollisionDetection::separating_plane_edge_A(
-  const std::vector<std::vector<double>>& coord_1,
-  const std::vector<int>& masks, int f0, int f1)
-{
-  // Helper function for tetrahedron-tetrahedron collision: checks if
-  // edge is in the plane separating faces f0 and f1.
-
-  const std::vector<double>& coord_f0 = coord_1[f0];
-  const std::vector<double>& coord_f1 = coord_1[f1];
-
-  int maskf0 = masks[f0];
-  int maskf1 = masks[f1];
-
-  if ((maskf0 | maskf1) != 15) // if there is a vertex of b
-    return false; // included in (-,-) return false
-
-  maskf0 &= (maskf0 ^ maskf1); // exclude the vertices in (+,+)
-  maskf1 &= (maskf0 ^ maskf1);
-
-  // edge 0: 0--1
-  if ((maskf0 & 1) && // the vertex 0 of b is in (-,+)
-      (maskf1 & 2)) // the vertex 1 of b is in (+,-)
-    if ((coord_f0[1]*coord_f1[0] - coord_f0[0]*coord_f1[1]) > 0)
-      // the edge of b (0,1) intersect (-,-) (see the paper)
-      return false;
-
-  if ((maskf0 & 2) &&
-      (maskf1 & 1))
-    if ((coord_f0[1]*coord_f1[0] - coord_f0[0]*coord_f1[1]) < 0)
-      return false;
-
-  // edge 1: 0--2
-  if ((maskf0 & 1) &&
-      (maskf1 & 4))
-    if ((coord_f0[2]*coord_f1[0] - coord_f0[0]*coord_f1[2]) > 0)
-      return false;
-
-  if ((maskf0 & 4) &&
-      (maskf1 & 1))
-    if ((coord_f0[2]*coord_f1[0] - coord_f0[0]*coord_f1[2]) < 0)
-      return false;
-
-  // edge 2: 0--3
-  if ((maskf0 & 1) &&
-      (maskf1 & 8))
-    if ((coord_f0[3]*coord_f1[0] - coord_f0[0]*coord_f1[3]) > 0)
-      return false;
-
-  if ((maskf0 & 8) &&
-      (maskf1 & 1))
-    if ((coord_f0[3]*coord_f1[0] - coord_f0[0]*coord_f1[3]) < 0)
-      return false;
-
-  // edge 3: 1--2
-  if ((maskf0 & 2) &&
-      (maskf1 & 4))
-    if ((coord_f0[2]*coord_f1[1] - coord_f0[1]*coord_f1[2]) > 0)
-      return false;
-
-  if ((maskf0 & 4) &&
-      (maskf1 & 2))
-    if ((coord_f0[2]*coord_f1[1] - coord_f0[1]*coord_f1[2]) < 0)
-      return false;
-
-  // edge 4: 1--3
-  if ((maskf0 & 2) &&
-      (maskf1 & 8))
-    if ((coord_f0[3]*coord_f1[1] - coord_f0[1]*coord_f1[3]) > 0)
-      return false;
-
-  if ((maskf0 & 8) &&
-      (maskf1 & 2))
-    if ((coord_f0[3]*coord_f1[1] - coord_f0[1]*coord_f1[3]) < 0)
-      return false;
-
-  // edge 5: 2--3
-  if ((maskf0 & 4) &&
-      (maskf1 & 8))
-    if ((coord_f0[3]*coord_f1[2] - coord_f0[2]*coord_f1[3]) > 0)
-      return false;
-
-  if ((maskf0 & 8) &&
-      (maskf1 & 4))
-    if ((coord_f0[3]*coord_f1[2] - coord_f0[2]*coord_f1[3]) < 0)
-      return false;
-
-  // Now there exists a separating plane supported by the edge shared
-  // by f0 and f1.
-  return true;
-}
-//-----------------------------------------------------------------------------
diff --git a/dolfin/geometry/CollisionDetection.h b/dolfin/geometry/CollisionDetection.h
deleted file mode 100644
index 08c5f63..0000000
--- a/dolfin/geometry/CollisionDetection.h
+++ /dev/null
@@ -1,296 +0,0 @@
-// Copyright (C) 2014 Anders Logg and August Johansson
-//
-// This file is part of DOLFIN.
-//
-// DOLFIN is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// DOLFIN 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 Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
-//
-// First added:  2014-02-03
-// Last changed: 2014-04-03
-
-#include <vector>
-#include <dolfin/log/log.h>
-
-#ifndef __COLLISION_DETECTION_H
-#define __COLLISION_DETECTION_H
-
-namespace dolfin
-{
-
-  // Forward declarations
-  class MeshEntity;
-
-  /// This class implements algorithms for detecting pairwise
-  /// collisions between mesh entities of varying dimensions.
-
-  class CollisionDetection
-  {
-  public:
-
-    /// Check whether entity collides with point.
-    ///
-    /// @param    entity (_MeshEntity_)
-    ///         The entity.
-    /// @param    point (_Point_)
-    ///         The point.
-    ///
-    /// @return    bool
-    ///         True iff entity collides with cell.
-    static bool collides(const MeshEntity& entity,
-			 const Point& point);
-
-    /// Check whether two entities collide.
-    ///
-    /// @param    entity_0 (_MeshEntity_)
-    ///         The first entity.
-    /// @param    entity_1 (_MeshEntity_)
-    ///         The second entity.
-    ///
-    /// @return    bool
-    ///         True iff entity collides with cell.
-    static bool collides(const MeshEntity& entity_0,
-			 const MeshEntity& entity_1);
-
-    /// Check whether interval collides with point.
-    ///
-    /// @param    interval (MeshEntity)
-    ///         The interval.
-    /// @param    point (Point)
-    ///         The point.
-    ///
-    /// @return    bool
-    ///         True iff objects collide.
-    static bool collides_interval_point(const MeshEntity& interval,
-					const Point& point);
-
-    /// Check whether interval collides with interval.
-    ///
-    /// @param    interval_0 (MeshEntity)
-    ///         The first interval.
-    /// @param    interval_1 (MeshEntity)
-    ///         The second interval.
-    ///
-    /// @return    bool
-    ///         True iff objects collide.
-    static bool collides_interval_interval(const MeshEntity& interval_0,
-					   const MeshEntity& interval_1);
-
-    /// Check whether triangle collides with point.
-    ///
-    /// @param    triangle (MeshEntity)
-    ///         The triangle.
-    /// @param    point (Point)
-    ///         The point.
-    ///
-    /// @return    bool
-    ///         True iff objects collide.
-    static bool collides_triangle_point(const MeshEntity& triangle,
-					const Point& point);
-
-    /// Check whether triangle collides with triangle.
-    ///
-    /// @param    triangle_0 (_MeshEntity_)
-    ///         The first triangle.
-    /// @param    triangle_1 (_MeshEntity_)
-    ///         The second triangle.
-    ///
-    /// @return    bool
-    ///         True iff objects collide.
-    static bool collides_triangle_triangle(const MeshEntity& triangle_0,
-					   const MeshEntity& triangle_1);
-
-    /// Check whether tetrahedron collides with point.
-    ///
-    /// @param   tetrahedron (MeshEntity)
-    ///         The tetrahedron.
-    /// @param   point (Point)
-    ///         The point.
-    ///
-    /// @return    bool
-    ///         True iff objects collide.
-    static bool collides_tetrahedron_point(const MeshEntity& tetrahedron,
-                                           const Point& point);
-
-    /// Check whether tetrahedron collides with triangle.
-    ///
-    /// @param    tetrahedron (_MeshEntity_)
-    ///         The tetrahedron.
-    /// @param    triangle (_MeshEntity_)
-    ///         The triangle.
-    ///
-    /// @return    bool
-    ///         True iff objects collide.
-    static bool collides_tetrahedron_triangle(const MeshEntity& tetrahedron,
-                                              const MeshEntity& triangle);
-
-    /// Check whether tetrahedron collides with tetrahedron.
-    ///
-    /// @param    tetrahedron_0 (_MeshEntity_)
-    ///         The first tetrahedron.
-    /// @param    tetrahedron_1 (_MeshEntity_)
-    ///         The second tetrahedron.
-    ///
-    /// @return   bool
-    ///         True iff objects collide.
-    static bool collides_tetrahedron_tetrahedron(const MeshEntity& tetrahedron_0,
-                                                 const MeshEntity& tetrahedron_1);
-
-    /// Check whether edge a-b collides with edge c-d.
-    static bool collides_edge_edge(const Point& a, const Point& b,
-				   const Point& c, const Point& d);
-
-
-    /// The implementation of collides_interval_point
-    static bool collides_interval_point(const Point& p0, const Point& p1,
-                                        const Point& point);
-
-    /// The implementation of collides_triangle_point
-    static bool collides_triangle_point(const Point& p0,
-					const Point& p1,
-					const Point& p2,
-					const Point& point);
-
-    /// Specialised implementation of collides_triangle_point in 2D
-    static bool collides_triangle_point_2d(const Point& p0,
-                                           const Point& p1,
-                                           const Point& p2,
-                                           const Point& point);
-
-    /// The implementation of collides_tetrahedron_point
-    static bool collides_tetrahedron_point(const Point& p0,
-					   const Point& p1,
-					   const Point& p2,
-					   const Point& p3,
-					   const Point& point);
-  private:
-
-    // The implementation of collides_triangle_triangle
-    static bool collides_triangle_triangle(const Point& p0,
-					   const Point& p1,
-					   const Point& p2,
-					   const Point& q0,
-					   const Point& q1,
-					   const Point& q2);
-
-
-    // The implementation of collides_tetrahedron_triangle
-    static bool collides_tetrahedron_triangle(const Point& p0,
-					      const Point& p1,
-					      const Point& p2,
-					      const Point& p3,
-					      const Point& q0,
-					      const Point& q1,
-					      const Point& q2);
-
-    // Helper function for triangle-triangle collision
-    static bool edge_edge_test(int i0,
-                               int i1,
-                               double Ax,
-                               double Ay,
-			       const Point& V0,
-			       const Point& U0,
-			       const Point& U1);
-
-    // Helper function for triangle-triangle collision
-    static bool edge_against_tri_edges(int i0,
-                                       int i1,
-				       const Point& V0,
-				       const Point& V1,
-				       const Point& U0,
-				       const Point& U1,
-				       const Point& U2);
-
-    // Helper function for triangle-triangle collision
-    static bool point_in_tri(int i0,
-                             int i1,
-			     const Point& V0,
-			     const Point& U0,
-			     const Point& U1,
-			     const Point& U2);
-
-    // Helper function for triangle-triangle collision
-    static bool coplanar_tri_tri(const Point& N,
-				 const Point& V0,
-				 const Point& V1,
-				 const Point& V2,
-				 const Point& U0,
-				 const Point& U1,
-				 const Point& U2);
-
-    // Helper function for triangle-triangle collision
-    static bool compute_intervals(double VV0,
-                                  double VV1,
-                                  double VV2,
-				  double D0,
-                                  double D1,
-                                  double D2,
-				  double D0D1,
-                                  double D0D2,
-				  double& A,
-                                  double& B,
-                                  double& C,
-				  double& X0,
-                                  double& X1);
-
-    // Helper function for collides_tetrahedron_tetrahedron: checks if
-    // plane pv1 is a separating plane. Stores local coordinates bc
-    // and the mask bit mask_edges.
-    static bool separating_plane_face_A_1(const std::vector<Point>& pv1,
-					  const Point& n,
-					  std::vector<double>& bc,
-					  int& mask_edges);
-
-    // Helper function for collides_tetrahedron_tetrahedron: checks if
-    // plane v1, v2 is a separating plane. Stores local coordinates bc
-    // and the mask bit mask_edges.
-    static bool separating_plane_face_A_2(const std::vector<Point>& v1,
-					  const std::vector<Point>& v2,
-					  const Point& n,
-					  std::vector<double>& bc,
-					  int& mask_edges);
-
-    // Helper function for collides_tetrahedron_tetrahedron: checks if
-    // plane pv2 is a separating plane.
-    static bool separating_plane_face_B_1(const std::vector<Point>& P_V2,
-					  const Point& n)
-    {
-      return ((P_V2[0].dot(n) > 0) &&
-	      (P_V2[1].dot(n) > 0) &&
-	      (P_V2[2].dot(n) > 0) &&
-	      (P_V2[3].dot(n) > 0));
-    }
-
-    // Helper function for collides_tetrahedron_tetrahedron: checks if
-    // plane v1, v2 is a separating plane.
-    static bool separating_plane_face_B_2(const std::vector<Point>& V1,
-					  const std::vector<Point>& V2,
-					  const Point& n)
-    {
-      return (((V1[0] - V2[1]).dot(n) > 0) &&
-	      ((V1[1] - V2[1]).dot(n) > 0) &&
-	      ((V1[2] - V2[1]).dot(n) > 0) &&
-	      ((V1[3] - V2[1]).dot(n) > 0));
-    }
-
-    // Helper function for collides_tetrahedron_tetrahedron: checks if
-    // edge is in the plane separating faces f0 and f1.
-    static bool separating_plane_edge_A(const std::vector<std::vector<double> >& coord_1,
-					const std::vector<int>& masks,
-					int f0,
-					int f1);
-
-  };
-
-}
-
-#endif
diff --git a/dolfin/geometry/CollisionPredicates.cpp b/dolfin/geometry/CollisionPredicates.cpp
new file mode 100644
index 0000000..2a5bc5c
--- /dev/null
+++ b/dolfin/geometry/CollisionPredicates.cpp
@@ -0,0 +1,1053 @@
+// Copyright (C) 2014-2017 Anders Logg, August Johansson and Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN 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 Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added:  2014-02-03
+// Last changed: 2017-10-09
+
+#include <dolfin/mesh/MeshEntity.h>
+#include <dolfin/mesh/CellType.h>
+#include "predicates.h"
+#include "Point.h"
+#include "CollisionPredicates.h"
+#include "GeometryTools.h"
+
+#include "CGALExactArithmetic.h"
+
+using namespace dolfin;
+
+//-----------------------------------------------------------------------------
+// High-level collision detection predicates
+//-----------------------------------------------------------------------------
+bool CollisionPredicates::collides(const MeshEntity& entity,
+				   const Point& point)
+{
+  // Intersection is only implemented for simplex meshes
+  if (!entity.mesh().type().is_simplex())
+  {
+    dolfin_error("Cell.cpp",
+		 "intersect cell and point",
+		 "Intersection is only implemented for simplex meshes");
+  }
+
+  // Get data
+  const MeshGeometry& g = entity.mesh().geometry();
+  const unsigned int* v = entity.entities(0);
+  const std::size_t tdim = entity.mesh().topology().dim();
+  const std::size_t gdim = entity.mesh().geometry().dim();
+
+  // Pick correct specialized implementation
+  if (tdim == 1 && gdim == 1)
+    return collides_segment_point_1d(g.point(v[0])[0], g.point(v[1])[0], point[0]);
+
+  if (tdim == 1 && gdim == 2)
+    return collides_segment_point_2d(g.point(v[0]), g.point(v[1]), point);
+
+  if (tdim == 1 && gdim == 3)
+    return collides_segment_point_3d(g.point(v[0]), g.point(v[1]), point);
+
+  if (tdim == 2 && gdim == 2)
+    return collides_triangle_point_2d(g.point(v[0]),
+                                      g.point(v[1]),
+                                      g.point(v[2]),
+                                      point);
+
+  if (tdim == 2 && gdim == 3)
+    return collides_triangle_point_3d(g.point(v[0]),
+                                      g.point(v[1]),
+                                      g.point(v[2]),
+                                      point);
+
+  if (tdim == 3)
+    return collides_tetrahedron_point_3d(g.point(v[0]),
+                                         g.point(v[1]),
+                                         g.point(v[2]),
+                                         g.point(v[3]),
+                                         point);
+
+  dolfin_error("CollisionPredicates.cpp",
+               "compute entity-point collision",
+               "Not implemented for dimensions %d / %d", tdim, gdim);
+
+  return false;
+}
+//-----------------------------------------------------------------------------
+bool CollisionPredicates::collides(const MeshEntity& entity_0,
+				   const MeshEntity& entity_1)
+{
+  // Intersection is only implemented for simplex meshes
+  if (!entity_0.mesh().type().is_simplex() ||
+      !entity_1.mesh().type().is_simplex())
+  {
+    dolfin_error("Cell.cpp",
+		 "intersect cell and point",
+		 "intersection is only implemented for simplex meshes");
+  }
+
+  // Get data
+  const MeshGeometry& g0 = entity_0.mesh().geometry();
+  const MeshGeometry& g1 = entity_1.mesh().geometry();
+  const unsigned int* v0 = entity_0.entities(0);
+  const unsigned int* v1 = entity_1.entities(0);
+  const std::size_t d0 = entity_0.dim();
+  const std::size_t d1 = entity_1.dim();
+  const std::size_t gdim = g0.dim();
+  dolfin_assert(gdim == g1.dim());
+
+  // Pick correct specialized implementation
+  if (d0 == 1 && d1 == 1)
+  {
+    return collides_segment_segment(g0.point(v0[0]),
+                                    g0.point(v0[1]),
+                                    g1.point(v1[0]),
+                                    g1.point(v1[1]),
+                                    gdim);
+  }
+
+  if (d0 == 1 && d1 == 2)
+  {
+    return collides_triangle_segment(g1.point(v1[0]),
+				     g1.point(v1[1]),
+				     g1.point(v1[2]),
+				     g0.point(v0[0]),
+				     g0.point(v0[1]),
+				     gdim);
+  }
+
+  if (d0 == 2 && d1 == 1)
+  {
+    return collides_triangle_segment(g0.point(v0[0]),
+                                     g0.point(v0[1]),
+                                     g0.point(v0[2]),
+                                     g1.point(v1[0]),
+                                     g1.point(v1[1]),
+                                     gdim);
+  }
+
+  if (d0 == 2 && d1 == 2)
+  {
+    return collides_triangle_triangle(g0.point(v0[0]),
+                                      g0.point(v0[1]),
+                                      g0.point(v0[2]),
+                                      g1.point(v1[0]),
+                                      g1.point(v1[1]),
+                                      g1.point(v1[2]),
+                                      gdim);
+  }
+
+  if (d0 == 2 && d1 == 3)
+  {
+    return collides_tetrahedron_triangle_3d(g1.point(v1[0]),
+                                            g1.point(v1[1]),
+                                            g1.point(v1[2]),
+                                            g1.point(v1[3]),
+                                            g0.point(v0[0]),
+                                            g0.point(v0[1]),
+                                            g0.point(v0[2]));
+  }
+
+  if (d0 == 3 && d1 == 2)
+  {
+    return collides_tetrahedron_triangle_3d(g0.point(v0[0]),
+                                            g0.point(v0[1]),
+                                            g0.point(v0[2]),
+                                            g0.point(v0[3]),
+                                            g1.point(v1[0]),
+                                            g1.point(v1[1]),
+                                            g1.point(v1[2]));
+  }
+
+  if (d0 == 3 && d1 == 3)
+  {
+    return collides_tetrahedron_tetrahedron_3d(g0.point(v0[0]),
+                                               g0.point(v0[1]),
+                                               g0.point(v0[2]),
+                                               g0.point(v0[3]),
+                                               g1.point(v1[0]),
+                                               g1.point(v1[1]),
+                                               g1.point(v1[2]),
+                                               g1.point(v1[3]));
+  }
+
+  dolfin_error("CollisionPredicates.cpp",
+               "compute entity-entity collision",
+               "Not implemented for topological dimensions %d / %d and geometrical dimension %d", d0, d1, gdim);
+
+  return false;
+}
+//-----------------------------------------------------------------------------
+// Low-level collision detection predicates
+//-----------------------------------------------------------------------------
+bool CollisionPredicates::collides_segment_point(const Point& p0,
+                                                 const Point& p1,
+                                                 const Point& point,
+                                                 std::size_t gdim)
+{
+  switch (gdim)
+  {
+  case 1:
+    return collides_segment_point_1d(p0[0], p1[0], point[0]);
+  case 2:
+    return collides_segment_point_2d(p0, p1, point);
+  case 3:
+    return collides_segment_point_3d(p0, p1, point);
+  default:
+    dolfin_error("CollisionPredicates.cpp",
+		 "call collides_segment_point",
+		 "Unknown dimension (only implemented for dimension 2 and 3");
+  }
+  return false;
+}
+//-----------------------------------------------------------------------------
+bool CollisionPredicates::collides_segment_segment(const Point& p0,
+                                                   const Point& p1,
+                                                   const Point& q0,
+                                                   const Point& q1,
+                                                   std::size_t gdim)
+{
+  switch (gdim)
+  {
+  case 1:
+    return collides_segment_segment_1d(p0[0], p1[0], q0[0], q1[0]);
+  case 2:
+    return collides_segment_segment_2d(p0, p1, q0, q1);
+  case 3:
+    return collides_segment_segment_3d(p0, p1, q0, q1);
+  default:
+    dolfin_error("CollisionPredicates.cpp",
+		 "compute segment-segment collision ",
+		 "Unknown dimension (Implemented for dimension 1, 2 and 3)");
+  }
+  return false;
+}
+//------------------------------------------------------------------------------
+bool CollisionPredicates::collides_triangle_point(const Point& p0,
+                                                  const Point& p1,
+                                                  const Point& p2,
+                                                  const Point& point,
+                                                  std::size_t gdim)
+{
+  switch (gdim)
+  {
+  case 2:
+    return collides_triangle_point_2d(p0, p1, p2, point);
+  case 3:
+    return collides_triangle_point_3d(p0, p1, p2, point);
+  default:
+    dolfin_error("CollisionPredicates.cpp",
+		 "compute triangle-point collision ",
+		 "Implemented only for dimension 2 and 3.");
+  }
+  return false;
+}
+//------------------------------------------------------------------------------
+bool CollisionPredicates::collides_triangle_segment(const Point& p0,
+                                                    const Point& p1,
+                                                    const Point& p2,
+                                                    const Point& q0,
+                                                    const Point& q1,
+                                                    std::size_t gdim)
+{
+  switch (gdim)
+  {
+  case 2:
+    return collides_triangle_segment_2d(p0, p1, p2, q0, q1);
+  case 3:
+    return collides_triangle_segment_3d(p0, p1, p2, q0, q1);
+  default:
+    dolfin_error("CollisionPredicates.cpp",
+		 "compute triangle-segment collision ",
+		 "Implmented only for dimension 2 and 3.");
+  }
+  return false;
+}
+//------------------------------------------------------------------------------
+bool CollisionPredicates::collides_triangle_triangle(const Point& p0,
+                                                     const Point& p1,
+                                                     const Point& p2,
+                                                     const Point& q0,
+                                                     const Point& q1,
+                                                     const Point& q2,
+                                                     std::size_t gdim)
+{
+  switch (gdim)
+  {
+  case 2:
+    return collides_triangle_triangle_2d(p0, p1, p2, q0, q1, q2);
+  case 3:
+    return collides_triangle_triangle_3d(p0, p1, p2, q0, q1, q2);
+  default:
+    dolfin_error("CollisionPredicates.cpp",
+		 "compute triangle-triangle collision ",
+		 "Implmented only for dimension 2 and 3.");
+  }
+  return false;
+}
+
+
+
+    //--- Low-level collision detection predicates ---
+//------------------------------------------------------------------------------
+bool CollisionPredicates::collides_segment_point_1d(double p0,
+				      double p1,
+				      double point)
+{
+  // FIXME: Skip CGAL for now
+  return _collides_segment_point_1d(p0, p1, point);
+}
+//------------------------------------------------------------------------------
+bool CollisionPredicates::collides_segment_point_2d(const Point& p0,
+				      const Point& p1,
+				      const Point& point)
+{
+  return CHECK_CGAL(_collides_segment_point_2d(p0, p1, point),
+		    cgal_collides_segment_point_2d(p0, p1, point));
+}
+//------------------------------------------------------------------------------
+bool CollisionPredicates::collides_segment_point_3d(const Point& p0,
+						    const Point& p1,
+						    const Point& point)
+{
+  return CHECK_CGAL(_collides_segment_point_3d(p0, p1, point),
+		    cgal_collides_segment_point_3d(p0, p1, point));
+}
+//------------------------------------------------------------------------------
+bool CollisionPredicates::collides_segment_segment_1d(double p0,
+						      double p1,
+						      double q0,
+						      double q1)
+{
+  return _collides_segment_segment_1d(p0, p1, q0, q1);
+}
+//------------------------------------------------------------------------------
+bool CollisionPredicates::collides_segment_segment_2d(const Point& p0,
+						      const Point& p1,
+						      const Point& q0,
+						      const Point& q1)
+{
+  return CHECK_CGAL(_collides_segment_segment_2d(p0, p1, q0, q1),
+		    cgal_collides_segment_segment_2d(p0, p1, q0, q1));
+}
+//------------------------------------------------------------------------------
+bool CollisionPredicates::collides_segment_segment_3d(const Point& p0,
+						      const Point& p1,
+						      const Point& q0,
+						      const Point& q1)
+{
+  return CHECK_CGAL(_collides_segment_segment_3d(p0, p1, q0, q1),
+		    cgal_collides_segment_segment_3d(p0, p1, q0, q1));
+}
+//------------------------------------------------------------------------------
+bool CollisionPredicates::collides_triangle_point_2d(const Point& p0,
+						     const Point& p1,
+						     const Point& p2,
+						     const Point& point)
+{
+  return CHECK_CGAL(_collides_triangle_point_2d(p0, p1, p2, point),
+		    cgal_collides_triangle_point_2d(p0, p1, p2, point));
+}
+//------------------------------------------------------------------------------
+bool CollisionPredicates::collides_triangle_point_3d(const Point& p0,
+						     const Point& p1,
+						     const Point& p2,
+						     const Point& point)
+{
+  return CHECK_CGAL(_collides_triangle_point_3d(p0, p1, p2, point),
+		    cgal_collides_triangle_point_3d(p0, p1, p2, point));
+}
+//------------------------------------------------------------------------------
+bool CollisionPredicates::collides_triangle_segment_2d(const Point& p0,
+						       const Point& p1,
+						       const Point& p2,
+						       const Point& q0,
+						       const Point& q1)
+{
+  return CHECK_CGAL(_collides_triangle_segment_2d(p0, p1, p2, q0, q1),
+		    cgal_collides_triangle_segment_2d(p0, p1, p2, q0, q1));
+}
+//------------------------------------------------------------------------------
+bool CollisionPredicates::collides_triangle_segment_3d(const Point& p0,
+						       const Point& p1,
+						       const Point& p2,
+						       const Point& q0,
+						       const Point& q1)
+{
+  return CHECK_CGAL(_collides_triangle_segment_3d(p0, p1, p2, q0, q1),
+		    cgal_collides_triangle_segment_3d(p0, p1, p2, q0, q1));
+}
+//------------------------------------------------------------------------------
+bool CollisionPredicates::collides_triangle_triangle_2d(const Point& p0,
+							const Point& p1,
+							const Point& p2,
+							const Point& q0,
+							const Point& q1,
+							const Point& q2)
+{
+  return CHECK_CGAL(_collides_triangle_triangle_2d(p0, p1, p2, q0, q1, q2),
+		    cgal_collides_triangle_triangle_2d(p0, p1, p2, q0, q1, q2));
+}
+//------------------------------------------------------------------------------
+bool CollisionPredicates::collides_triangle_triangle_3d(const Point& p0,
+							const Point& p1,
+							const Point& p2,
+							const Point& q0,
+							const Point& q1,
+							const Point& q2)
+{
+  return CHECK_CGAL(_collides_triangle_triangle_3d(p0, p1, p2, q0, q1, q2),
+		    cgal_collides_triangle_triangle_3d(p0, p1, p2, q0, q1, q2));
+}
+//------------------------------------------------------------------------------
+bool CollisionPredicates::collides_tetrahedron_point_3d(const Point& p0,
+							const Point& p1,
+							const Point& p2,
+							const Point& p3,
+							const Point& point)
+{
+  return CHECK_CGAL(_collides_tetrahedron_point_3d(p0, p1, p2, p3, point),
+		    cgal_collides_tetrahedron_point_3d(p0, p1, p2, p3, point));
+}
+//------------------------------------------------------------------------------
+bool CollisionPredicates::collides_tetrahedron_segment_3d(const Point& p0,
+							  const Point& p1,
+							  const Point& p2,
+							  const Point& p3,
+							  const Point& q0,
+							  const Point& q1)
+{
+  return CHECK_CGAL(_collides_tetrahedron_segment_3d(p0, p1, p2, p3, q0, q1),
+		    cgal_collides_tetrahedron_segment_3d(p0, p1, p2, p3, q0, q1));
+}
+//------------------------------------------------------------------------------
+bool CollisionPredicates::collides_tetrahedron_triangle_3d(const Point& p0,
+							   const Point& p1,
+							   const Point& p2,
+							   const Point& p3,
+							   const Point& q0,
+							   const Point& q1,
+							   const Point& q2)
+{
+  return CHECK_CGAL(_collides_tetrahedron_triangle_3d(p0, p1, p2, p3, q0, q1, q2),
+		    cgal_collides_tetrahedron_triangle_3d(p0, p1, p2, p3, q0, q1, q2));
+}
+//------------------------------------------------------------------------------
+bool CollisionPredicates::collides_tetrahedron_tetrahedron_3d(const Point& p0,
+							      const Point& p1,
+							      const Point& p2,
+							      const Point& p3,
+							      const Point& q0,
+							      const Point& q1,
+							      const Point& q2,
+							      const Point& q3)
+{
+  return CHECK_CGAL(_collides_tetrahedron_tetrahedron_3d(p0, p1, p2, p3, q0, q1, q2, q3),
+		    cgal_collides_tetrahedron_tetrahedron_3d(p0, p1, p2, p3, q0, q1, q2, q3));
+}
+//-----------------------------------------------------------------------------
+// Implementation of private members
+//-----------------------------------------------------------------------------
+bool CollisionPredicates::_collides_segment_point_1d(double p0,
+                                                     double p1,
+                                                     double point)
+{
+  if (p0 > p1)
+    std::swap(p0, p1);
+  return p0 <= point and point <= p1;
+}
+//-----------------------------------------------------------------------------
+bool CollisionPredicates::_collides_segment_point_2d(const Point& p0,
+                                                     const Point& p1,
+                                                     const Point& point)
+{
+  const double orientation = orient2d(p0, p1, point);
+
+  const Point dp = p1 - p0;
+  const double segment_length = dp.squared_norm();
+
+  return orientation == 0.0 &&
+    (point-p0).squared_norm() <= segment_length &&
+    (point-p1).squared_norm() <= segment_length &&
+    dp.dot(p1-point) >= 0.0 && dp.dot(point-p0) >= 0.0;
+}
+//-----------------------------------------------------------------------------
+bool CollisionPredicates::_collides_segment_point_3d(const Point& p0,
+                                                     const Point& p1,
+                                                     const Point& point)
+{
+
+  if (point == p0 or point == p1)
+    return true;
+
+  // Poject to reduce to three 2d problems
+  const double det_xy = orient2d(p0, p1, point);
+
+  if (det_xy == 0.0)
+  {
+    const std::array<std::array<double, 2>, 3> xz = {{ {{p0.x(), p0.z()}},
+						       {{p1.x(), p1.z()}},
+						       {{point.x(), point.z()}} }};
+    const double det_xz = _orient2d(xz[0].data(),
+				    xz[1].data(),
+				    xz[2].data());
+
+    if (det_xz == 0.0)
+    {
+      const std::array<std::array<double, 2>, 3> yz = {{ {{p0.y(), p0.z()}},
+                                                         {{p1.y(), p1.z()}},
+                                                         {{point.y(), point.z()}} }};
+      const double det_yz = _orient2d(yz[0].data(),
+				      yz[1].data(),
+				      yz[2].data());
+
+      if (det_yz == 0.0)
+      {
+        // Point is aligned with segment
+        const double length = (p0 - p1).squared_norm();
+        return (point-p0).squared_norm() <= length and
+	  (point-p1).squared_norm() <= length;
+      }
+    }
+  }
+
+  return false;
+}
+//------------------------------------------------------------------------------
+bool CollisionPredicates::_collides_segment_segment_1d(double p0,
+                                                       double p1,
+                                                       double q0,
+                                                       double q1)
+{
+  // Get range
+  const double a0 = std::min(p0, p1);
+  const double b0 = std::max(p0, p1);
+  const double a1 = std::min(q0, q1);
+  const double b1 = std::max(q0, q1);
+
+  // Check for collision
+  const double dx = std::min(b0 - a0, b1 - a1);
+  return b1 >= a0 - dx && a1 <= b0 + dx;
+}
+//-----------------------------------------------------------------------------
+bool CollisionPredicates::_collides_segment_segment_2d(const Point& p0,
+                                                       const Point& p1,
+                                                       const Point& q0,
+                                                       const Point& q1)
+{
+  // FIXME: Optimize by avoiding redundant calls to orient2d
+
+  if (collides_segment_point_2d(p0, p1, q0))
+    return true;
+  if (collides_segment_point_2d(p0, p1, q1))
+    return true;
+  if (collides_segment_point_2d(q0, q1, p0))
+    return true;
+  if (collides_segment_point_2d(q0, q1, p1))
+    return true;
+
+  // Points must be on different sides
+  if (((orient2d(q0, q1, p0) > 0.0) xor (orient2d(q0, q1, p1) > 0.0)) and
+      ((orient2d(p0, p1, q0) > 0.0) xor (orient2d(p0, p1, q1) > 0.0)))
+    return true;
+  else
+    return false;
+}
+//-----------------------------------------------------------------------------
+bool CollisionPredicates::_collides_segment_segment_3d(const Point& p0,
+                                                       const Point& p1,
+                                                       const Point& q0,
+                                                       const Point& q1)
+{
+  // Vertex collisions
+  if (p0 == q0 || p0 == q1 || p1 == q0 || p1 == q1)
+    return true;
+
+  if (collides_segment_point_3d(p0, p1, q0) or
+      collides_segment_point_3d(p0, p1, q1) or
+      collides_segment_point_3d(q0, q1, p0) or
+      collides_segment_point_3d(q0, q1, p1))
+  {
+    return true;
+  }
+
+  // Determinant must be zero
+  const double det = orient3d(p0, p1, q0, q1);
+
+  if (det < 0.0 or det > 0.0)
+    return false;
+
+  // Now we know that the segments are in the same plane. This means
+  // that they can be parallel, or even collinear.
+
+  // Check for collinearity
+  const Point u = GeometryTools::cross_product(p0, p1, q0);
+  if (u[0] == 0.0 and u[1] == 0.0 and u[2] == 0.0)
+  {
+    const Point v = GeometryTools::cross_product(p0, p1, q1);
+    if (v[0] == 0.0 and v[1] == 0.0 and v[2] == 0.0)
+    {
+      // Now we know that the segments are collinear
+      if ((p0-q0).squared_norm() <= (q1-q0).squared_norm() and
+	  (p0-q1).squared_norm() <= (q0-q1).squared_norm())
+	return true;
+
+      if ((p1-q0).squared_norm() <= (q1-q0).squared_norm() and
+	  (p1-q1).squared_norm() <= (q0-q1).squared_norm())
+	return true;
+
+      if ((q0-p0).squared_norm() <= (p1-p0).squared_norm() and
+	  (q0-p1).squared_norm() <= (p0-p1).squared_norm())
+	return true;
+
+      if ((q1-p0).squared_norm() <= (p1-p0).squared_norm() and
+	  (q1-p1).squared_norm() <= (p0-p1).squared_norm())
+	return true;
+    }
+  }
+
+  // Segments are not collinear, but in the same plane
+  // Try to reduce to 2d by elimination
+
+  for (std::size_t d = 0; d < 3; ++d)
+  {
+    if (p0[d] == p1[d] and p0[d] == q0[d] and p0[d] == q1[d])
+    {
+      const std::array<std::array<std::size_t, 2>, 3> dims = {{ {{1, 2}},
+                                                                {{0, 2}},
+                                                                {{0, 1}} }};
+      const Point p0_2d(p0[dims[d][0]], p0[dims[d][1]]);
+      const Point p1_2d(p1[dims[d][0]], p1[dims[d][1]]);
+      const Point q0_2d(q0[dims[d][0]], q0[dims[d][1]]);
+      const Point q1_2d(q1[dims[d][0]], q1[dims[d][1]]);
+
+      return collides_segment_segment_2d(p0_2d, p1_2d, q0_2d, q1_2d);
+    }
+  }
+
+  return false;
+}
+//-----------------------------------------------------------------------------
+bool CollisionPredicates::_collides_triangle_point_2d(const Point& p0,
+                                                      const Point& p1,
+                                                      const Point& p2,
+                                                      const Point& point)
+{
+  const double ref = orient2d(p0, p1, p2);
+
+  if (ref > 0.0)
+  {
+    return (orient2d(p1, p2, point) >= 0.0 and
+	    orient2d(p2, p0, point) >= 0.0 and
+	    orient2d(p0, p1, point) >= 0.0);
+  }
+  else if (ref < 0.0)
+  {
+    return (orient2d(p1, p2, point) <= 0.0 and
+	    orient2d(p2, p0, point) <= 0.0 and
+	    orient2d(p0, p1, point) <= 0.0);
+  }
+  else
+  {
+    return ((orient2d(p0, p1, point) == 0.0 and
+	     collides_segment_point_1d(p0[0], p1[0], point[0]) and
+	     collides_segment_point_1d(p0[1], p1[1], point[1])) or
+	    (orient2d(p1, p2, point) == 0.0 and
+	     collides_segment_point_1d(p1[0], p2[0], point[0]) and
+	     collides_segment_point_1d(p1[1], p2[1], point[1])) or
+	    (orient2d(p2, p0, point) == 0.0 and
+	     collides_segment_point_1d(p2[0], p0[0], point[0]) and
+	     collides_segment_point_1d(p2[1], p0[1], point[1])));
+  }
+}
+//-----------------------------------------------------------------------------
+bool CollisionPredicates::_collides_triangle_point_3d(const Point& p0,
+                                                      const Point& p1,
+                                                      const Point& p2,
+                                                      const Point& point)
+{
+  if (p0 == point or p1 == point or p2 == point)
+    return true;
+
+  const double tet_det = orient3d(p0, p1, p2, point);
+
+  if (tet_det < 0.0 or tet_det > 0.0)
+    return false;
+
+  // Use normal
+  const Point n = GeometryTools::cross_product(p0, p1, p2);
+
+  return !(n.dot(GeometryTools::cross_product(point, p0, p1)) < 0.0 or
+	   n.dot(GeometryTools::cross_product(point, p2, p0)) < 0.0 or
+	   n.dot(GeometryTools::cross_product(point, p1, p2)) < 0.0);
+}
+//-----------------------------------------------------------------------------
+bool CollisionPredicates::_collides_triangle_segment_2d(const Point& p0,
+                                                        const Point& p1,
+                                                        const Point& p2,
+                                                        const Point& q0,
+                                                        const Point& q1)
+{
+  // FIXME: Optimize by avoiding redundant calls to orient2d
+
+  // Check if end points are in triangle
+  if (collides_triangle_point_2d(p0, p1, p2, q0))
+    return true;
+  if (collides_triangle_point_2d(p0, p1, p2, q1))
+    return true;
+
+  // Check if any of the triangle edges are cut by the segment
+  if (collides_segment_segment_2d(p0, p1, q0, q1))
+    return true;
+  if (collides_segment_segment_2d(p0, p2, q0, q1))
+    return true;
+  if (collides_segment_segment_2d(p1, p2, q0, q1))
+    return true;
+
+  return false;
+}
+//-----------------------------------------------------------------------------
+bool CollisionPredicates::_collides_triangle_segment_3d(const Point& r,
+                                                        const Point& s,
+                                                        const Point& t,
+                                                        const Point& a,
+                                                        const Point& b)
+{
+  // FIXME: Optimize by avoiding redundant calls to orient3d
+
+  // Compute correspondic tetrahedra determinants
+  const double rsta = orient3d(r, s, t, a);
+  const double rstb = orient3d(r, s, t, b);
+
+  // Check if a and b are on same side of triangle rst
+  if ((rsta < 0.0 and rstb < 0.0) or
+      (rsta > 0.0 and rstb > 0.0))
+    return false;
+
+  // We check triangle point first. We use this below.
+  if (collides_triangle_point_3d(r, s, t, a))
+    return true;
+
+  if (collides_triangle_point_3d(r, s, t, b))
+    return true;
+
+  // Now we know a and b are either on different sides or in the same
+  // plane (in which case rsta = rstb = 0). Check if intersection is
+  // in triangle by creating some other tets.
+
+  if (rsta == 0.0 and rstb == 0.0)
+  {
+    // Since we have checked that the points does not collide, the
+    // segment is either completely outside the triangle, or we have a
+    // collision over edges.
+
+    // FIXME: To avoid collision over edges, maybe we can test if both
+    // a and b are on the same side of one of the edges rs, rt or st.
+
+    if (collides_segment_segment_3d(r, s, a, b))
+      return true;
+    if (collides_segment_segment_3d(r, t, a, b))
+      return true;
+    if (collides_segment_segment_3d(s, t, a, b))
+      return true;
+
+    return false;
+  }
+  else
+  {
+    // Temporarily flip a and b to make sure a is above
+    Point _a = a;
+    Point _b = b;
+    if (rsta < 0.0)
+      std::swap(_a, _b);
+
+    const double rasb = orient3d(r, _a, s, _b);
+    if (rasb < 0)
+      return false;
+
+    const double satb = orient3d(s, _a, t, _b);
+    if (satb < 0)
+      return false;
+
+    const double tarb = orient3d(t, _a, r, _b);
+    if (tarb < 0)
+      return false;
+  }
+
+  return true;
+}
+//------------------------------------------------------------------------------
+bool CollisionPredicates::_collides_triangle_triangle_2d(const Point& p0,
+                                                         const Point& p1,
+                                                         const Point& p2,
+                                                         const Point& q0,
+                                                         const Point& q1,
+                                                         const Point& q2)
+{
+  // FIXME: Optimize by avoiding redundant calls to orient2d
+
+  // Pack points as vectors
+  const std::array<Point, 3> tri_0 = {{p0, p1, p2}};
+  const std::array<Point, 3> tri_1 = {{q0, q1, q2}};
+
+  const bool s0 = std::signbit(orient2d(p0, p1, p2));
+  const bool s1 = std::signbit(orient2d(q0, q1, q2));
+
+  for (std::size_t i = 0; i < 3; ++i)
+  {
+    if ((s0 and
+    	 orient2d(tri_0[0], tri_0[1], tri_1[i]) <= 0.0 and
+    	 orient2d(tri_0[1], tri_0[2], tri_1[i]) <= 0.0 and
+    	 orient2d(tri_0[2], tri_0[0], tri_1[i]) <= 0.0)
+	or
+    	(!s0 and
+    	 orient2d(tri_0[0], tri_0[1], tri_1[i]) >= 0.0 and
+    	 orient2d(tri_0[1], tri_0[2], tri_1[i]) >= 0.0 and
+    	 orient2d(tri_0[2], tri_0[0], tri_1[i]) >= 0.0))
+    {
+      return true;
+    }
+
+    if ((s1 and
+    	 orient2d(tri_1[0], tri_1[1], tri_0[i]) <= 0.0 and
+    	 orient2d(tri_1[1], tri_1[2], tri_0[i]) <= 0.0 and
+    	 orient2d(tri_1[2], tri_1[0], tri_0[i]) <= 0.0)
+	or
+    	(!s1 and
+    	 orient2d(tri_1[0], tri_1[1], tri_0[i]) >= 0.0 and
+    	 orient2d(tri_1[1], tri_1[2], tri_0[i]) >= 0.0 and
+    	 orient2d(tri_1[2], tri_1[0], tri_0[i]) >= 0.0))
+    {
+      return true;
+    }
+  }
+
+  // Find all edge-edge collisions
+  for (std::size_t i0 = 0; i0 < 3; i0++)
+  {
+    const std::size_t j0 = (i0 + 1) % 3;
+    const Point& p0 = tri_0[i0];
+    const Point& q0 = tri_0[j0];
+    for (std::size_t i1 = 0; i1 < 3; i1++)
+    {
+      const std::size_t j1 = (i1 + 1) % 3;
+      const Point& p1 = tri_1[i1];
+      const Point& q1 = tri_1[j1];
+      if (collides_segment_segment_2d(p0, q0, p1, q1))
+        return true;
+    }
+  }
+
+  return false;
+}
+//-----------------------------------------------------------------------------
+bool CollisionPredicates::_collides_triangle_triangle_3d(const Point& p0,
+                                                         const Point& p1,
+                                                         const Point& p2,
+                                                         const Point& q0,
+                                                         const Point& q1,
+                                                         const Point& q2)
+{
+  // FIXME: Optimize by avoiding redundant calls to orient3d
+
+  // Pack points as vectors
+  const std::array<Point, 3> tri_0 = {{p0, p1, p2}};
+  const std::array<Point, 3> tri_1 = {{q0, q1, q2}};
+
+  // First test edge-face collisions
+  for (std::size_t i = 0; i < 3; ++i)
+  {
+    const std::size_t j = (i + 1) % 3;
+
+    if (collides_triangle_segment_3d(p0, p1, p2, tri_1[i], tri_1[j]))
+      return true;
+
+    if (collides_triangle_segment_3d(q0, q1, q2, tri_0[i], tri_0[j]))
+      return true;
+  }
+
+  // Test edge-edge collisions
+  for (std::size_t i0 = 0; i0 < 3; i0++)
+  {
+    const std::size_t j0 = (i0 + 1) % 3;
+    for (std::size_t i1 = 0; i1 < 3; i1++)
+    {
+      const std::size_t j1 = (i1 + 1) % 3;
+      if (collides_segment_segment_3d(tri_0[i0], tri_0[j0],
+				      tri_1[i1], tri_1[j1]))
+      {
+	return true;
+      }
+    }
+  }
+
+  // FIXME
+  // Test point-face collisions (could also be detected by
+  // triangle_segment collision above)
+  for (std::size_t i = 0; i < 3; ++i)
+  {
+    if (collides_triangle_point_3d(p0, p1, p2, tri_1[i]))
+      return true;
+
+    if (collides_triangle_point_3d(q0, q1, q2, tri_0[i]))
+      return true;
+  }
+
+  return false;
+}
+//-----------------------------------------------------------------------------
+bool CollisionPredicates::_collides_tetrahedron_point_3d(const Point& p0,
+                                                         const Point& p1,
+                                                         const Point& p2,
+                                                         const Point& p3,
+                                                         const Point& point)
+{
+  const double ref = orient3d(p0, p1, p2, p3);
+
+  if (ref > 0.0)
+  {
+    return (orient3d(p0, p1, p2, point) >= 0.0 and
+	    orient3d(p0, p3, p1, point) >= 0.0 and
+	    orient3d(p0, p2, p3, point) >= 0.0 and
+	    orient3d(p1, p3, p2, point) >= 0.0);
+  }
+  else if (ref < 0.0)
+  {
+    return (orient3d(p0, p1, p2, point) <= 0.0 and
+	    orient3d(p0, p3, p1, point) <= 0.0 and
+	    orient3d(p0, p2, p3, point) <= 0.0 and
+	    orient3d(p1, p3, p2, point) <= 0.0);
+  }
+  else
+  {
+    dolfin_error("CollisionPredicates.cpp",
+		 "compute tetrahedron point collision",
+		 "Not implemented for degenerate tetrahedron");
+  }
+
+  return false;
+}
+//-----------------------------------------------------------------------------
+bool CollisionPredicates::_collides_tetrahedron_segment_3d(const Point& p0,
+                                                           const Point& p1,
+                                                           const Point& p2,
+                                                           const Point& p3,
+                                                           const Point& q0,
+                                                           const Point& q1)
+{
+  // FIXME: Optimize by avoiding redundant calls to orient3d
+
+  // Segment vertex in tetrahedron collision
+  if (collides_tetrahedron_point_3d(p0, p1, p2, p3, q0))
+    return true;
+  if (collides_tetrahedron_point_3d(p0, p1, p2, p3, q1))
+    return true;
+
+  // Triangle-segment collision tests
+  if (collides_triangle_segment_3d(p1, p2, p3, q0, q1))
+    return true;
+  if (collides_triangle_segment_3d(p0, p2, p3, q0, q1))
+    return true;
+  if (collides_triangle_segment_3d(p0, p1, p3, q0, q1))
+    return true;
+  if (collides_triangle_segment_3d(p0, p1, p2, q0, q1))
+    return true;
+
+  return false;
+}
+//-----------------------------------------------------------------------------
+bool CollisionPredicates::_collides_tetrahedron_triangle_3d(const Point& p0,
+                                                            const Point& p1,
+                                                            const Point& p2,
+                                                            const Point& p3,
+                                                            const Point& q0,
+                                                            const Point& q1,
+                                                            const Point& q2)
+{
+  // FIXME: Optimize by avoiding redundant calls to orient3d
+
+  // Triangle vertex in tetrahedron collision
+  if (collides_tetrahedron_point_3d(p0, p1, p2, p3, q0))
+    return true;
+  if (collides_tetrahedron_point_3d(p0, p1, p2, p3, q1))
+    return true;
+  if (collides_tetrahedron_point_3d(p0, p1, p2, p3, q2))
+    return true;
+
+  // Triangle-triangle collision tests
+  if (collides_triangle_triangle_3d(q0, q1, q2, p1, p2, p3))
+    return true;
+  if (collides_triangle_triangle_3d(q0, q1, q2, p0, p2, p3))
+    return true;
+  if (collides_triangle_triangle_3d(q0, q1, q2, p0, p1, p3))
+    return true;
+  if (collides_triangle_triangle_3d(q0, q1, q2, p0, p1, p2))
+    return true;
+
+  return false;
+}
+//-----------------------------------------------------------------------------
+bool CollisionPredicates::_collides_tetrahedron_tetrahedron_3d(const Point& p0,
+                                                               const Point& p1,
+                                                               const Point& p2,
+                                                               const Point& p3,
+                                                               const Point& q0,
+                                                               const Point& q1,
+                                                               const Point& q2,
+                                                               const Point& q3)
+{
+  // FIXME: Optimize by avoiding redundant calls to orient3d
+
+  const std::array<Point, 4> tetp = {{p0, p1, p2, p3}};
+  const std::array<Point, 4> tetq = {{q0, q1, q2, q3}};
+
+  // Triangle face collisions
+  const std::array<std::array<std::size_t, 3>, 4> faces = {{ {{1, 2, 3}},
+                                                             {{0, 2, 3}},
+                                                             {{0, 1, 3}},
+                                                             {{0, 1, 2}} }};
+  for (std::size_t i = 0; i < 4; ++i)
+  {
+    for (std::size_t j = 0; j < 4; ++j)
+    {
+      if (collides_triangle_triangle_3d(tetp[faces[i][0]], tetp[faces[i][1]], tetp[faces[i][2]],
+					tetq[faces[j][0]], tetq[faces[j][1]], tetq[faces[j][2]]))
+      {
+	return true;
+      }
+    }
+  }
+
+  // Vertex in tetrahedron collision
+  if (collides_tetrahedron_point_3d(p0, p1, p2, p3, q0))
+    return true;
+  if (collides_tetrahedron_point_3d(p0, p1, p2, p3, q1))
+    return true;
+  if (collides_tetrahedron_point_3d(p0, p1, p2, p3, q2))
+    return true;
+  if (collides_tetrahedron_point_3d(p0, p1, p2, p3, q3))
+    return true;
+
+  if (collides_tetrahedron_point_3d(q0, q1, q2, q3, p0))
+    return true;
+  if (collides_tetrahedron_point_3d(q0, q1, q2, q3, p1))
+    return true;
+  if (collides_tetrahedron_point_3d(q0, q1, q2, q3, p2))
+    return true;
+  if (collides_tetrahedron_point_3d(q0, q1, q2, q3, p3))
+    return true;
+
+  return false;
+}
+//-----------------------------------------------------------------------------
diff --git a/dolfin/geometry/CollisionPredicates.h b/dolfin/geometry/CollisionPredicates.h
new file mode 100644
index 0000000..f0966ab
--- /dev/null
+++ b/dolfin/geometry/CollisionPredicates.h
@@ -0,0 +1,316 @@
+// Copyright (C) 2014-2016 Anders Logg, August Johansson and Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN 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 Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added:  2014-02-03
+// Last changed: 2017-09-29
+
+#ifndef __COLLISION_PREDICATES_H
+#define __COLLISION_PREDICATES_H
+
+namespace dolfin
+{
+
+  // Forward declarations
+  class Point;
+  class MeshEntity;
+
+  /// This class implements algorithms for detecting pairwise
+  /// collisions between mesh entities of varying dimensions.
+
+  class CollisionPredicates
+  {
+  public:
+
+    //--- High-level collision detection predicates ---
+
+    /// Check whether entity collides with point.
+    ///
+    /// *Arguments*
+    ///     entity (_MeshEntity_)
+    ///         The entity.
+    ///     point (_Point_)
+    ///         The point.
+    ///
+    /// *Returns*
+    ///     bool
+    ///         True iff entity collides with cell.
+    static bool collides(const MeshEntity& entity,
+                         const Point& point);
+
+    /// Check whether two entities collide.
+    ///
+    /// *Arguments*
+    ///     entity_0 (_MeshEntity_)
+    ///         The first entity.
+    ///     entity_1 (_MeshEntity_)
+    ///         The second entity.
+    ///
+    /// *Returns*
+    ///     bool
+    ///         True iff entity collides with cell.
+    static bool collides(const MeshEntity& entity_0,
+                         const MeshEntity& entity_1);
+
+    //--- Low-level collision detection predicates ---
+
+    /// Check whether segment p0-p1 collides with point
+    static bool collides_segment_point(const Point& p0,
+                                       const Point& p1,
+                                       const Point& point,
+                                       std::size_t gdim);
+
+    /// Check whether segment p0-p1 collides with point (1D version)
+    static bool collides_segment_point_1d(double p0,
+                                          double p1,
+                                          double point);
+
+    /// Check whether segment p0-p1 collides with point (2D version)
+    static bool collides_segment_point_2d(const Point& p0,
+                                          const Point& p1,
+                                          const Point& point);
+
+    /// Check whether segment p0-p1 collides with point (3D version)
+    static bool collides_segment_point_3d(const Point& p0,
+                                          const Point& p1,
+                                          const Point& point);
+
+    /// Check whether segment p0-p1 collides with segment q0-q1
+    static bool collides_segment_segment(const Point& p0,
+                                         const Point& p1,
+                                         const Point& q0,
+                                         const Point& q1,
+                                         std::size_t gdim);
+
+    /// Check whether segment p0-p1 collides with segment q0-q1 (1D version)
+    static bool collides_segment_segment_1d(double p0,
+                                            double p1,
+                                            double q0,
+                                            double q1);
+
+    /// Check whether segment p0-p1 collides with segment q0-q1 (2D version)
+    static bool collides_segment_segment_2d(const Point& p0,
+                                            const Point& p1,
+                                            const Point& q0,
+                                            const Point& q1);
+
+    /// Check whether segment p0-p1 collides with segment q0-q1 (3D version)
+    static bool collides_segment_segment_3d(const Point& p0,
+                                            const Point& p1,
+                                            const Point& q0,
+                                            const Point& q1);
+
+    /// Check whether triangle p0-p1-p2 collides with point
+    static bool collides_triangle_point(const Point& p0,
+                                        const Point& p1,
+                                        const Point& p2,
+                                        const Point& point,
+                                        std::size_t gdim);
+
+    /// Check whether triangle p0-p1-p2 collides with point (2D version)
+    static bool collides_triangle_point_2d(const Point& p0,
+                                           const Point& p1,
+                                           const Point& p2,
+                                           const Point& point);
+
+    /// Check whether triangle p0-p1-p2 collides with point (3D version)
+    static bool collides_triangle_point_3d(const Point& p0,
+                                           const Point& p1,
+                                           const Point& p2,
+                                           const Point& point);
+
+    /// Check whether triangle p0-p1-p2 collides with segment q0-q1
+    static bool collides_triangle_segment(const Point& p0,
+                                          const Point& p1,
+                                          const Point& p2,
+                                          const Point& q0,
+                                          const Point& q1,
+                                          std::size_t gdim);
+
+    /// Check whether triangle p0-p1-p2 collides with segment q0-q1 (2D version)
+    static bool collides_triangle_segment_2d(const Point& p0,
+                                             const Point& p1,
+                                             const Point& p2,
+                                             const Point& q0,
+                                             const Point& q1);
+
+    /// Check whether triangle p0-p1-p2 collides with segment q0-q1 (3D version)
+    static bool collides_triangle_segment_3d(const Point& p0,
+                                             const Point& p1,
+                                             const Point& p2,
+                                             const Point& q0,
+                                             const Point& q1);
+
+    /// Check whether triangle p0-p1-p2 collides with triangle q0-q1-q2
+    static bool collides_triangle_triangle(const Point& p0,
+                                           const Point& p1,
+                                           const Point& p2,
+                                           const Point& q0,
+                                           const Point& q1,
+                                           const Point& q2,
+                                           std::size_t gdim);
+
+    /// Check whether triangle p0-p1-p2 collides with triangle q0-q1-q2 (2D version)
+    static bool collides_triangle_triangle_2d(const Point& p0,
+                                              const Point& p1,
+                                              const Point& p2,
+                                              const Point& q0,
+                                              const Point& q1,
+                                              const Point& q2);
+
+    /// Check whether triangle p0-p1-p2 collides with triangle q0-q1-q2 (3D version)
+    static bool collides_triangle_triangle_3d(const Point& p0,
+                                              const Point& p1,
+                                              const Point& p2,
+                                              const Point& q0,
+                                              const Point& q1,
+                                              const Point& q2);
+
+    /// Check whether tetrahedron p0-p1-p2-p3 collides with point
+    static bool collides_tetrahedron_point_3d(const Point& p0,
+                                              const Point& p1,
+                                              const Point& p2,
+                                              const Point& p3,
+                                              const Point& point);
+
+    /// Check whether tetrahedron p0-p1-p2-p3 collides with segment q0-q1
+    static bool collides_tetrahedron_segment_3d(const Point& p0,
+                                                const Point& p1,
+                                                const Point& p2,
+                                                const Point& p3,
+                                                const Point& q0,
+                                                const Point& q1);
+
+    /// Check whether tetrahedron p0-p1-p2-p3 collides with triangle q0-q1-q2
+    static bool collides_tetrahedron_triangle_3d(const Point& p0,
+                                                 const Point& p1,
+                                                 const Point& p2,
+                                                 const Point& p3,
+                                                 const Point& q0,
+                                                 const Point& q1,
+                                                 const Point& q2);
+
+    /// Check whether tetrahedron p0-p1-p2-p3 collides with tetrahedron q0-q1-q2
+    static bool collides_tetrahedron_tetrahedron_3d(const Point& p0,
+                                                    const Point& p1,
+                                                    const Point& p2,
+                                                    const Point& p3,
+                                                    const Point& q0,
+                                                    const Point& q1,
+                                                    const Point& q2,
+						    const Point& q3);
+
+  private:
+
+    // Implementation of collision detection predicates
+
+    static bool _collides_segment_point_1d(double p0,
+                                           double p1,
+                                           double point);
+
+    static bool _collides_segment_point_2d(const Point& p0,
+                                           const Point& p1,
+                                           const Point& point);
+
+    static bool _collides_segment_point_3d(const Point& p0,
+                                           const Point& p1,
+                                           const Point& point);
+
+    static bool _collides_segment_segment_1d(double p0,
+                                             double p1,
+                                             double q0,
+                                             double q1);
+
+    static bool _collides_segment_segment_2d(const Point& p0,
+                                             const Point& p1,
+                                             const Point& q0,
+                                             const Point& q1);
+
+    static bool _collides_segment_segment_3d(const Point& p0,
+                                             const Point& p1,
+                                             const Point& q0,
+                                             const Point& q1);
+
+    static bool _collides_triangle_point_2d(const Point& p0,
+                                            const Point& p1,
+                                            const Point& p2,
+                                            const Point& point);
+
+    static bool _collides_triangle_point_3d(const Point& p0,
+                                            const Point& p1,
+                                            const Point& p2,
+                                            const Point& point);
+
+    static bool _collides_triangle_segment_2d(const Point& p0,
+                                              const Point& p1,
+                                              const Point& p2,
+                                              const Point& q0,
+                                              const Point& q1);
+
+    static bool _collides_triangle_segment_3d(const Point& p0,
+                                              const Point& p1,
+                                              const Point& p2,
+                                              const Point& q0,
+                                              const Point& q1);
+
+    static bool _collides_triangle_triangle_2d(const Point& p0,
+                                               const Point& p1,
+                                               const Point& p2,
+                                               const Point& q0,
+                                               const Point& q1,
+                                               const Point& q2);
+
+    static bool _collides_triangle_triangle_3d(const Point& p0,
+                                               const Point& p1,
+                                               const Point& p2,
+                                               const Point& q0,
+                                               const Point& q1,
+                                               const Point& q2);
+
+    static bool _collides_tetrahedron_point_3d(const Point& p0,
+                                               const Point& p1,
+                                               const Point& p2,
+                                               const Point& p3,
+                                               const Point& point);
+
+    static bool _collides_tetrahedron_segment_3d(const Point& p0,
+                                                 const Point& p1,
+                                                 const Point& p2,
+                                                 const Point& p3,
+                                                 const Point& q0,
+                                                 const Point& q1);
+
+    static bool _collides_tetrahedron_triangle_3d(const Point& p0,
+                                                  const Point& p1,
+                                                  const Point& p2,
+                                                  const Point& p3,
+                                                  const Point& q0,
+                                                  const Point& q1,
+                                                  const Point& q2);
+
+    static bool _collides_tetrahedron_tetrahedron_3d(const Point& p0,
+                                                     const Point& p1,
+                                                     const Point& p2,
+                                                     const Point& p3,
+                                                     const Point& q0,
+                                                     const Point& q1,
+                                                     const Point& q2,
+                                                     const Point& q3);
+  };
+
+}
+
+#endif
diff --git a/dolfin/geometry/ConvexTriangulation.cpp b/dolfin/geometry/ConvexTriangulation.cpp
new file mode 100644
index 0000000..6445a61
--- /dev/null
+++ b/dolfin/geometry/ConvexTriangulation.cpp
@@ -0,0 +1,603 @@
+// Copyright (C) 2016-2017 Anders Logg, August Johansson and Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN 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 Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added:  2016-06-01
+// Last changed: 2017-10-09
+
+#include <algorithm>
+#include <tuple>
+#include <set>
+#include "predicates.h"
+#include "GeometryPredicates.h"
+#include "GeometryTools.h"
+#include "CollisionPredicates.h"
+#include "IntersectionConstruction.h"
+#include "ConvexTriangulation.h"
+
+#include "CGALExactArithmetic.h"
+
+using namespace dolfin;
+
+//-----------------------------------------------------------------------------
+namespace
+{
+  //-----------------------------------------------------------------------------
+  // Create a unique list of points in the sense that |p-q| > tol in each dimension
+  std::vector<Point>
+  unique_points(const std::vector<Point>& input_points,
+		std::size_t gdim,
+		double tol)
+  {
+    std::vector<Point> points;
+
+    for (std::size_t i = 0; i < input_points.size(); ++i)
+    {
+      bool unique = true;
+      for (std::size_t j = i+1; j < input_points.size(); ++j)
+      {
+	std::size_t cnt = 0;
+	for (std::size_t d = 0; d < gdim; ++d)
+	{
+	  if (std::abs(input_points[i][d] - input_points[j][d]) > tol)
+	  {
+	    cnt++;
+	  }
+	}
+	if (cnt == 0)
+	{
+	  unique = false;
+	  break;
+	}
+      }
+
+      if (unique)
+	points.push_back(input_points[i]);
+    }
+
+    return points;
+  }
+  //------------------------------------------------------------------------------
+  // Check if q lies between p0 and p1. p0, p1 and q are assumed to be colinear
+  bool is_between(Point p0, Point p1, Point q)
+  {
+    const double sqnorm = (p1-p0).squared_norm();
+    return (p0-q).squared_norm() < sqnorm && (p1-q).squared_norm() < sqnorm;
+  }
+  //------------------------------------------------------------------------------
+  // Return the indices to the points that forms the polygon that is
+  // the convex hull of the points. The points are assumed to be coplanar
+  std::vector<std::pair<std::size_t, std::size_t>>
+  compute_convex_hull_planar(const std::vector<Point>& points)
+  {
+    // FIXME: Ensure that 0, 1, 2 are not colinear
+    Point normal = GeometryTools::cross_product(points[0], points[1], points[2]);
+    normal /= normal.norm();
+
+    std::vector<std::pair<std::size_t, std::size_t>> edges;
+
+    // Filter out points which are in the interior of the
+    // convex hull of the planar points.
+    for (std::size_t i = 0; i < points.size(); i++)
+    {
+      for (std::size_t j = i+1; j < points.size(); j++)
+      {
+        // Form at plane of i, j  and i + the normal of plane
+        const Point r = points[i]+normal;
+
+        // search for the first point which is not in the
+        // i, j, p plane to determine sign of orietation
+        double edge_orientation = 0;
+        {
+          std::size_t a = 0;
+          while (edge_orientation == 0)
+          {
+            if (a != i && a != j)
+            {
+              edge_orientation = orient3d(points[i],
+                                          points[j],
+                                          r,
+                                          points[a]);
+            }
+            a++;
+          }
+        }
+
+        bool on_convex_hull = true;
+	std::vector<std::size_t> colinear;
+        for (std::size_t p = 0; p < points.size(); p++)
+        {
+          if (p != i && p != j)
+          {
+            const double orientation = orient3d(points[i],
+                                                points[j],
+                                                r,
+                                                points[p]);
+
+	    if (orientation == 0)
+	    {
+	      colinear.push_back(p);
+	    }
+
+            // Sign change: triangle is not on convex hull
+            if (edge_orientation * orientation < 0)
+            {
+              on_convex_hull = false;
+            }
+          }
+        }
+
+        if (on_convex_hull)
+        {
+	  if (!colinear.empty())
+	  {
+	    // Several points are colinear. Only add if i and j are
+	    // the 1d convex hull of the colinear points
+	    bool is_linear_convex_hull = true;
+	    for (std::size_t q : colinear)
+	    {
+	      if (!is_between(points[i], points[j], points[q]))
+	      {
+		is_linear_convex_hull = false;
+		break;
+	      }
+	    }
+
+	    if (is_linear_convex_hull)
+	    {
+	      edges.push_back(std::make_pair(i,  j));
+	    }
+	  }
+	  else
+	  {
+	    edges.push_back(std::make_pair(i, j));
+	  }
+        }
+      }
+    }
+
+    return edges;
+  }
+}
+
+//------------------------------------------------------------------------------
+std::vector<std::vector<Point>>
+ConvexTriangulation::triangulate(const std::vector<Point>& p,
+                                 std::size_t gdim,
+                                 std::size_t tdim)
+{
+  if (p.empty())
+    return std::vector<std::vector<Point>>();
+
+  if (tdim == 1)
+  {
+    return triangulate_1d(p, gdim);
+  }
+  else if (tdim == 2 && gdim == 2)
+  {
+    return triangulate_graham_scan_2d(p);
+  }
+  else if (tdim == 3 && gdim == 3)
+  {
+    return triangulate_graham_scan_3d(p);
+  }
+
+  dolfin_error("ConvexTriangulation.cpp",
+               "triangulate convex polyhedron",
+               "Triangulation of polyhedron of topological dimension %u and geometric dimension %u not implemented", tdim, gdim);
+
+  return std::vector<std::vector<Point>>();
+}
+//-----------------------------------------------------------------------------
+std::vector<std::vector<Point>>
+ConvexTriangulation::_triangulate_1d(const std::vector<Point>& p,
+				     std::size_t gdim)
+{
+  // A convex polyhedron of topological dimension 1 can not have more
+  // than two points. If more, they must be collinear (more or
+  // less). This can happen due to tolerances in
+  // IntersectionConstruction::intersection_segment_segment_2d.
+
+  if (gdim != 2)
+  {
+    dolfin_error("ConvexTriangulation.cpp",
+		 "triangulate topological 1d",
+		 "Function is only implemented for gdim = 2");
+  }
+
+  const std::vector<Point> unique_p = unique_points(p, gdim, DOLFIN_EPS);
+
+  if (unique_p.size() > 2)
+  {
+    // Make sure the points are approximately collinear
+    bool collinear = true;
+    for (std::size_t i = 2; i < unique_p.size(); ++i)
+    {
+      const double o = orient2d(unique_p[0], unique_p[1], unique_p[i]);
+      if (std::abs(o) > DOLFIN_EPS_LARGE)
+      {
+	collinear = false;
+	break;
+      }
+    }
+
+    dolfin_assert(collinear);
+
+    // Average
+    Point average(0.0, 0.0, 0.0);
+    for (const Point& q: unique_p)
+      average += q;
+    average /= unique_p.size();
+    std::vector<std::vector<Point>> t = {{ average }};
+    return t;
+
+    dolfin_error("ConvexTriangulation.cpp",
+  		 "triangulate convex polyhedron",
+  		 "A convex polyhedron of topological dimension 1 can not have more than 2 points");
+  }
+
+  std::vector<std::vector<Point>> t = { unique_p };
+  return t;
+}
+
+//------------------------------------------------------------------------------
+std::vector<std::vector<Point>>
+ConvexTriangulation::_triangulate_graham_scan_2d(const std::vector<Point>& input_points)
+{
+  dolfin_assert(GeometryPredicates::is_finite(input_points));
+
+  // Make sure the input points are unique
+  const std::size_t gdim = 2;
+  std::vector<Point> points = unique_points(input_points, gdim, DOLFIN_EPS);
+
+  if (points.size() < 3)
+    return std::vector<std::vector<Point>>();
+
+  if (points.size() == 3)
+  {
+    std::vector<std::vector<Point>> triangulation(1, points);
+    return triangulation;
+  }
+
+  // Sometimes we can get an extra point on an edge: a-----c--b. This
+  // point c may cause problems for the graham scan. To avoid this,
+  // use an extra center point.  Use this center point and point no 0
+  // as reference for the angle calculation
+  Point pointscenter = points[0];
+  for (std::size_t m = 1; m < points.size(); ++m)
+    pointscenter += points[m];
+  pointscenter /= points.size();
+
+  // Reference
+  const Point ref = points[0] - pointscenter;
+
+  // Calculate and store angles
+  std::vector<std::pair<double, std::size_t>> order;
+  for (std::size_t m = 1; m < points.size(); ++m)
+  {
+    const double A = orient2d(pointscenter, points[0], points[m]);
+    const Point s = points[m] - pointscenter;
+    double alpha = std::atan2(A, s.dot(ref));
+    if (alpha < 0)
+      alpha += 2.0*DOLFIN_PI;
+    order.emplace_back(alpha, m);
+  }
+
+  // Sort angles
+  std::sort(order.begin(), order.end());
+
+  // Tessellate
+  std::vector<std::vector<Point>> triangulation(order.size() - 1);
+
+  for (std::size_t m = 0; m < order.size()-1; ++m)
+  {
+    // FIXME: We could consider only triangles with area > tolerance here.
+    triangulation[m] = {{ points[0],
+    			  points[order[m].second],
+    			  points[order[m + 1].second] }};
+  }
+
+  return triangulation;
+}
+//-----------------------------------------------------------------------------
+std::vector<std::vector<Point>>
+ConvexTriangulation::_triangulate_graham_scan_3d(const std::vector<Point>& input_points)
+{
+  dolfin_assert(GeometryPredicates::is_finite(input_points));
+
+  //std::cout << "Input to 3D Graham scan:" << std::endl;
+  //for (auto p : input_points)
+  //  std::cout << p << std::endl;
+
+  // Make sure the input points are unique. We assume this has
+  // negligble effect on volume
+  const std::size_t gdim = 3;
+  std::vector<Point> points = unique_points(input_points, gdim, DOLFIN_EPS);
+
+  std::vector<std::vector<Point>> triangulation;
+
+  if (points.size() < 4)
+  {
+    // Empty
+    return triangulation;
+  }
+  else if (points.size() == 4)
+  {
+    // Single tetrahedron
+    triangulation.push_back(points);
+    return triangulation;
+  }
+  else
+  {
+    // Construct tetrahedra using facet points and a center point
+    Point polyhedroncenter(0,0,0);
+    for (const Point& p: points)
+      polyhedroncenter += p;
+    polyhedroncenter /= points.size();
+
+    // FIXME: Better data structure than set?
+    std::set<std::tuple<std::size_t, std::size_t, std::size_t> > checked;
+
+    // Loop over all triplets
+    for (std::size_t i = 0; i < points.size(); ++i)
+    {
+      for (std::size_t j = i+1; j < points.size(); ++j)
+      {
+        for (std::size_t k = j+1; k < points.size(); ++k)
+        {
+	  if (checked.emplace(std::make_tuple(i, j, k)).second)
+	  {
+            // Test for the special case where i, j, k are collinear
+            {
+              const Point ij = points[j] - points[i];
+              const Point ik = points[k] - points[i];
+              if ( -(std::abs( (ij/ij.norm() ).dot(ik/ik.norm()))-1)  < DOLFIN_EPS)
+                continue;
+            }
+
+            // Check whether all other points are on one side of this
+            // (i,j,k) facet, i.e. we're on the convex
+            // hull. Initialize as true for the case of only three
+            // coplanar points.
+	    bool on_convex_hull = true;
+
+	    // Use orient3d to determine if the plane (i,j,k) is on the
+	    // convex hull.
+	    std::vector<std::size_t> coplanar = { i, j, k };
+	    double previous_orientation;
+	    bool first = true;
+
+	    for (std::size_t m = 0; m < points.size(); ++m)
+	    {
+	      if (m != i and m != j and m != k)
+	      {
+		const double orientation = orient3d(points[i],
+						    points[j],
+						    points[k],
+						    points[m]);
+		// Save point index if we find coplanar points
+		if (orientation == 0)
+		  coplanar.push_back(m);
+                else
+                {
+                  if (first)
+                  {
+                    previous_orientation = orientation;
+                    first = false;
+                  }
+                  else
+                  {
+                    // Sign change: triangle is not on convex hull
+                    if (previous_orientation * orientation < 0)
+                    {
+                      on_convex_hull = false;
+                    }
+                  }
+		}
+	      }
+	    }
+
+	    if (on_convex_hull)
+	    {
+	      if (coplanar.size() == 3)
+	      {
+		// Form one tetrahedron
+		std::vector<Point> cand = { points[i],
+					    points[j],
+					    points[k],
+					    polyhedroncenter };
+
+#ifdef DOLFIN_ENABLE_GEOMETRY_DEBUGGING
+                if (cgal_tet_is_degenerate(cand))
+                  dolfin_error("ConvexTriangulation.cpp",
+			       "triangulation 3d points",
+			       "tet is degenerate");
+
+#endif
+
+		// FIXME: Here we could include if determinant is sufficiently large
+                //for (auto p : cand)
+                //  std::cout << " " << p;
+                //std::cout << std::endl;
+		triangulation.push_back(cand);
+	      }
+	      else // At least four coplanar points
+	      {
+		// Tessellate as in the triangle-triangle intersection
+		// case: First sort points using a Graham scan, then
+		// connect to form triangles. Finally form tetrahedra
+		// using the center of the polyhedron.
+
+		// Use the center of the coplanar points and point no 0
+		// as reference for the angle calculation
+
+		std::vector<Point> coplanar_points;
+		for (std::size_t i : coplanar)
+		  coplanar_points.push_back(points[i]);
+
+		std::vector<std::pair<std::size_t, std::size_t>> coplanar_convex_hull =
+		  compute_convex_hull_planar(coplanar_points);
+
+		Point coplanar_center(0,0,0);
+		for (Point p : coplanar_points)
+		  coplanar_center += p;
+		coplanar_center /= coplanar_points.size();
+
+		// Tessellate
+		for (const std::pair<std::size_t, std::size_t>& edge : coplanar_convex_hull)
+		{
+                  triangulation.push_back({polyhedroncenter,
+			coplanar_center,
+			coplanar_points[edge.first],
+			coplanar_points[edge.second]});
+
+#ifdef DOLFIN_ENABLE_GEOMETRY_DEBUGGING
+                  if (cgal_tet_is_degenerate(triangulation.back()))
+                  {
+                    dolfin_error("ConvexTriangulation.cpp:544",
+				 "triangulation 3d points",
+				 "tet is degenerate");
+                  }
+
+                  if (cgal_triangulation_overlap(triangulation))
+                  {
+                    dolfin_error("ConvexTriangulation.cpp:544",
+				 "triangulation 3d points",
+				 "now triangulation overlaps");
+                  }
+#endif
+		}
+
+		// Mark all combinations of the coplanar vertices as
+		// checked to avoid duplicating triangles
+                std::sort(coplanar.begin(), coplanar.end());
+
+                for (int i = 0; i < (int)coplanar.size()-2; i++)
+                {
+                  for (int j = i+1; j < (int)coplanar.size()-1; j++)
+                  {
+                    for (std::size_t k = j+1; k < coplanar.size(); k++)
+                    {
+                      checked.emplace( std::make_tuple(coplanar[i], coplanar[j], coplanar[k]) );
+                    }
+                  }
+                }
+	      } // end coplanar.size() > 3
+	    } // end on_convexhull
+	  }
+	}
+      }
+    }
+
+    return triangulation;
+  }
+}
+//-----------------------------------------------------------------------------
+std::vector<std::vector<Point>>
+ConvexTriangulation::triangulate_graham_scan_3d(const std::vector<Point>& pm)
+{
+  std::vector<std::vector<Point>> triangulation =
+    _triangulate_graham_scan_3d(pm);
+
+#ifdef DOLFIN_ENABLE_GEOMETRY_DEBUGGING
+
+  if (cgal_triangulation_has_degenerate(triangulation))
+    dolfin_error("ConvexTriangulation.cpp",
+		 "verify convex triangulation",
+		 "triangulation contains degenerate tetrahedron");
+
+  if (cgal_triangulation_overlap(triangulation))
+  {
+    dolfin_error("ConvexTriangulation.cpp",
+		 "verify convex triangulation",
+		 "tetrahedrons overlap");
+  }
+
+
+  double volume = .0;
+  for (const std::vector<Point>& tet : triangulation)
+  {
+    dolfin_assert(tet.size() == 4);
+    const double tet_volume = std::abs(orient3d(tet[0], tet[1], tet[2], tet[3]))/6.0;
+    volume += tet_volume;
+  }
+
+  const double reference_volume = cgal_polyhedron_volume(pm);
+
+  if (std::abs(volume - reference_volume) > DOLFIN_EPS)
+    dolfin_error("ConvexTriangulation.cpp",
+		 "verifying convex triangulation",
+		 "computed volume %f, but reference volume is %f",
+		 volume, reference_volume);
+
+
+#endif
+  return triangulation;
+}
+//-----------------------------------------------------------------------------
+bool ConvexTriangulation::selfintersects(const std::vector<std::vector<Point>>& p)
+{
+  for (std::size_t i = 0; i < p.size(); i++)
+  {
+    for (std::size_t j = i+1; j < p.size(); j++)
+    {
+      dolfin_assert(p[i].size() == p[j].size());
+      if (p[i].size() == 4)
+      {
+	if (CollisionPredicates::collides_tetrahedron_tetrahedron_3d(p[i][0],
+								     p[i][1],
+								     p[i][2],
+								     p[i][3],
+								     p[j][0],
+								     p[j][1],
+								     p[j][2],
+								     p[j][3]))
+	{
+	  auto intersection =
+	    IntersectionConstruction::intersection_tetrahedron_tetrahedron_3d(p[i][0],
+									      p[i][1],
+									      p[i][2],
+									      p[i][3],
+									      p[j][0],
+									      p[j][1],
+									      p[j][2],
+									      p[j][3]);
+	  if (intersection.size() > 3)
+	  {
+	    for (std::size_t k = 3; k < intersection.size(); k++)
+	    {
+	      // FIXME: Note that this fails if the first three points are colinear!
+	      if (orient3d(intersection[0],
+			   intersection[1],
+			   intersection[2],
+			   intersection[k]) != 0)
+	      {
+		return true;
+	      }
+	    }
+	  }
+	}
+      }
+      else if (p[i].size() == 3)
+      {
+	dolfin_not_implemented();
+      }
+    }
+  }
+
+  return false;
+}
+//-----------------------------------------------------------------------------
diff --git a/dolfin/geometry/ConvexTriangulation.h b/dolfin/geometry/ConvexTriangulation.h
new file mode 100644
index 0000000..44f7a3e
--- /dev/null
+++ b/dolfin/geometry/ConvexTriangulation.h
@@ -0,0 +1,84 @@
+// Copyright (C) 2016 Anders Logg, August Johansson and Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN 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 Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added:  2016-06-01
+// Last changed: 2017-09-30
+
+#ifndef __CONVEX_TRIANGULATION
+#define __CONVEX_TRIANGULATION
+
+#include <vector>
+#include "Point.h"
+
+namespace dolfin
+{
+
+  /// This class implements algorithms for triangulating convex
+  /// domains represented as a set of points.
+
+  class ConvexTriangulation
+  {
+  public:
+
+    /// Tdim independent wrapper
+    static std::vector<std::vector<Point>>
+    triangulate(const std::vector<Point>& p,
+                std::size_t gdim,
+                std::size_t tdim);
+
+    /// Triangulate 1D
+    static std::vector<std::vector<Point>>
+    triangulate_1d(const std::vector<Point>& pm,
+		   std::size_t gdim)
+    {
+      return _triangulate_1d(pm, gdim);
+    }
+
+    /// Triangulate using the Graham scan 2D
+    static std::vector<std::vector<Point>>
+    triangulate_graham_scan_2d(const std::vector<Point>& pm)
+    {
+      return _triangulate_graham_scan_2d(pm);
+    }
+
+    /// Triangulate using the Graham scan 3D
+    static std::vector<std::vector<Point>>
+    triangulate_graham_scan_3d(const std::vector<Point>& pm);
+
+    /// Determine if there are self-intersecting tetrahedra
+    static bool selfintersects(const std::vector<std::vector<Point>>& p);
+
+  private:
+
+    // Implementation declarations
+
+    /// Implementation of 1D triangulation
+    static std::vector<std::vector<Point>>
+    _triangulate_1d(const std::vector<Point>& pm,
+		    std::size_t gdim);
+
+    /// Implementation of Graham scan 2D
+    static std::vector<std::vector<Point>>
+    _triangulate_graham_scan_2d(const std::vector<Point>& pm);
+
+    /// Implementation of Graham scan 3D
+    static std::vector<std::vector<Point>>
+    _triangulate_graham_scan_3d(const std::vector<Point>& pm);
+  };
+
+} // end namespace dolfin
+#endif
diff --git a/dolfin/geometry/GenericBoundingBoxTree.cpp b/dolfin/geometry/GenericBoundingBoxTree.cpp
index 3103b1d..cd5c4d5 100644
--- a/dolfin/geometry/GenericBoundingBoxTree.cpp
+++ b/dolfin/geometry/GenericBoundingBoxTree.cpp
@@ -16,7 +16,7 @@
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 //
 // First added:  2013-05-02
-// Last changed: 2014-02-06
+// Last changed: 2016-11-15
 
 // Define a maximum dimension used for a local array in the recursive
 // build function. Speeds things up compared to allocating it in each
@@ -125,10 +125,6 @@ void GenericBoundingBoxTree::build(const Mesh& mesh, std::size_t tdim)
 
     info("Computed global bounding box tree with %d boxes.",
          _global_tree->num_bboxes());
-    // Print on rank 0
-    //    if(MPI::rank(mesh.mpi_comm()) == 0)
-    //      std::cout << _global_tree->str() << "\n";
-
   }
 }
 //-----------------------------------------------------------------------------
@@ -274,7 +270,13 @@ GenericBoundingBoxTree::compute_closest_entity(const Point& point,
 
   // Search point cloud to get a good starting guess
   dolfin_assert(_point_search_tree);
-  double r = _point_search_tree->compute_closest_point(point).second;
+  std::pair<unsigned int, double> guess
+    = _point_search_tree->compute_closest_point(point);
+  double r = guess.second;
+
+  // Return if we have found the point
+  if (r == 0.)
+    return guess;
 
   // Initialize index and distance to closest entity
   unsigned int closest_entity = std::numeric_limits<unsigned int>::max();
diff --git a/dolfin/geometry/GeometryDebugging.cpp b/dolfin/geometry/GeometryDebugging.cpp
new file mode 100644
index 0000000..d1c465f
--- /dev/null
+++ b/dolfin/geometry/GeometryDebugging.cpp
@@ -0,0 +1,151 @@
+// Copyright (C) 2016 Anders Logg
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN 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 Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added:  2016-05-05
+// Last changed: 2017-03-01
+
+#include <sstream>
+#include <dolfin/log/log.h>
+#include <dolfin/log/LogStream.h>
+#include "GeometryDebugging.h"
+
+using namespace dolfin;
+
+// Plotting not initialized
+bool GeometryDebugging::_initialized = false;
+
+//-----------------------------------------------------------------------------
+void GeometryDebugging::print(const Point& point)
+{
+  set_indentation_level(0);
+  cout << "Point: " << point << endl;
+}
+//-----------------------------------------------------------------------------
+void GeometryDebugging::print(const std::vector<Point>& simplex)
+{
+  set_indentation_level(0);
+  cout << "Simplex:";
+  for (const Point p : simplex)
+    cout << " " << p;
+  cout << endl;
+}
+//-----------------------------------------------------------------------------
+void GeometryDebugging::print(const std::vector<Point>& simplex_0,
+                              const std::vector<Point>& simplex_1)
+{
+  set_indentation_level(0);
+  cout << "Simplex 0:";
+  for (const Point p : simplex_0)
+    cout << "-" << point2string(p);
+  cout << endl;
+
+  cout << "Simplex 1:";
+  for (const Point p : simplex_1)
+    cout << "-" << point2string(p);
+  cout << endl;
+}
+//-----------------------------------------------------------------------------
+void GeometryDebugging::plot(const Point& point)
+{
+  set_indentation_level(0);
+  init_plot();
+
+  cout << "# Plot point" << endl;
+  cout << "ax.plot(" << simplex2string({point}) << ", 'x')" << endl;
+  cout << endl;
+}
+//-----------------------------------------------------------------------------
+void GeometryDebugging::plot(const std::vector<Point>& simplex)
+{
+  set_indentation_level(0);
+  init_plot();
+
+  cout << "# Plot simplex" << endl;
+  if (simplex.size() >= 3)
+  cout << "ax.plot_trisurf(" << simplex2string(simplex) << ")" << endl;
+  else
+    cout << "ax.plot(" << simplex2string(simplex) << ", marker='x')" << endl;
+  cout << endl;
+}
+//-----------------------------------------------------------------------------
+void GeometryDebugging::plot(const std::vector<Point>& simplex_0,
+                             const std::vector<Point>& simplex_1)
+{
+  set_indentation_level(0);
+  init_plot();
+
+  cout << "# Plot simplex intersection" << endl;
+  if (simplex_0.size() >= 3)
+  cout << "ax.plot_trisurf(" << simplex2string(simplex_0) << ", color='r')" << endl;
+  else
+    cout << "ax.plot(" << simplex2string(simplex_0) << ", marker='o', color='r')" << endl;
+  if (simplex_1.size() >= 3)
+  cout << "ax.plot_trisurf(" << simplex2string(simplex_1) << ", color='b')" << endl;
+  else
+    cout << "ax.plot(" << simplex2string(simplex_1) << ", marker='o', color='b')" << endl;
+  cout << endl;
+}
+//-----------------------------------------------------------------------------
+void GeometryDebugging::init_plot()
+{
+  if (_initialized)
+    return;
+
+  set_indentation_level(0);
+  cout << "# Initialize matplotlib 3D plotting" << endl;
+  cout << "from mpl_toolkits.mplot3d import Axes3D" << endl;
+  cout << "import matplotlib.pyplot as pl" << endl;
+  cout << "ax = pl.figure().gca(projection='3d')" << endl;
+  cout << "pl.ion(); pl.show()" << endl;
+  cout << endl;
+  cout << "# Note 1: Rotate/interact with figure to update plot." << endl;
+  cout << "# Note 2: Use pl.cla() to clear figure between plots." << endl;
+  cout << endl;
+
+  _initialized = true;
+}
+//-----------------------------------------------------------------------------
+std::string GeometryDebugging::point2string(const Point& p)
+{
+  std::stringstream s;
+  s << "(" << p.x() << "," << p.y() << "," << p.z() << ")";
+  return s.str();
+}
+//-----------------------------------------------------------------------------
+std::string GeometryDebugging::simplex2string(const std::vector<Point>& simplex)
+{
+  std::size_t n = simplex.size();
+  if (n == 0) return "";
+  std::stringstream s;
+  s << "[";
+  for (std::size_t i = 0; i < n - 1; i++)
+    s << simplex[i].x() << ",";
+  s << simplex[n - 1].x() << "]";
+  s << ",";
+  s << "[";
+  for (std::size_t i = 0; i < n - 1; i++)
+    s << simplex[i].y() << ",";
+  s << simplex[n - 1].y() << "]";
+  s << ",";
+  s << "[";
+  for (std::size_t i = 0; i < n - 1; i++)
+    s << simplex[i].z() << ",";
+  s << simplex[n - 1].z() << "]";
+
+  return s.str();
+}
+//-----------------------------------------------------------------------------
diff --git a/dolfin/geometry/GeometryDebugging.h b/dolfin/geometry/GeometryDebugging.h
new file mode 100644
index 0000000..bc8d287
--- /dev/null
+++ b/dolfin/geometry/GeometryDebugging.h
@@ -0,0 +1,83 @@
+// Copyright (C) 2016-2017 Anders Logg
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN 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 Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added:  2016-05-05
+// Last changed: 2017-05-17
+
+#ifndef __GEOMETRY_DEBUGGING_H
+#define __GEOMETRY_DEBUGGING_H
+
+#include <vector>
+#include <string>
+#include "Point.h"
+
+namespace dolfin
+{
+
+  /// This class provides useful functionality for debugging algorithms
+  /// dealing with geometry such as collision detection and intersection
+  /// triangulation.
+
+  class GeometryDebugging
+  {
+  public:
+
+    /// Print coordinates of a point.
+    /// Example usage: print(p0)
+    static void print(const Point& point);
+
+    /// Print coordinates of a simplex.
+    /// Example usage: print({p0, p1, p2})
+    static void print(const std::vector<Point>& simplex);
+
+    /// Print coordinates of a pair of simplices.
+    /// Example usage: print({p0, p1, p2}, {q0, q1})
+    static void print(const std::vector<Point>& simplex_0,
+                      const std::vector<Point>& simplex_1);
+
+    /// Plot a point (print matplotlib code).
+    /// Example usage: plot(p0)
+    static void plot(const Point& point);
+
+    /// Plot a simplex (print matplotlib code).
+    /// Example usage: plot({p0, p1, p2})
+    static void plot(const std::vector<Point>& simplex);
+
+    /// Plot a pair of simplices (print matplotlib code).
+    /// Example usage: plot({p0, p1, p2}, {q0, q1})
+    static void plot(const std::vector<Point>& simplex_0,
+                     const std::vector<Point>& simplex_1);
+
+    /// Initialize plotting (print matplotlib code).
+    static void init_plot();
+
+    /// Compact point to string conversion
+    static std::string point2string(const Point& p);
+
+    /// Compact simplex to string conversion
+    static std::string simplex2string(const std::vector<Point>& simplex);
+
+  private:
+
+    // Check whether plotting has been initialized
+    static bool _initialized;
+
+  };
+
+}
+
+#endif
diff --git a/dolfin/geometry/GeometryPredicates.cpp b/dolfin/geometry/GeometryPredicates.cpp
new file mode 100644
index 0000000..ea8a64e
--- /dev/null
+++ b/dolfin/geometry/GeometryPredicates.cpp
@@ -0,0 +1,214 @@
+// Copyright (C) 2016-2017 Anders Logg, August Johansson and Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN 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 Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added:  2016-11-21
+// Last changed: 2017-10-09
+
+#include <cmath>
+#include "CGALExactArithmetic.h"
+#include "predicates.h"
+#include "GeometryPredicates.h"
+
+using namespace dolfin;
+
+//-----------------------------------------------------------------------------
+bool GeometryPredicates::is_degenerate(const std::vector<Point>& simplex,
+                                       std::size_t gdim)
+{
+  switch (gdim)
+  {
+  case 2:
+    return is_degenerate_2d(simplex);
+  case 3:
+    return is_degenerate_3d(simplex);
+  default:
+    dolfin_error("GeometryPredicates.cpp",
+		 "is_degenerate",
+		 "Unkonwn dimension (only implemented for dimension 2 and 3");
+  }
+  return false;
+}
+//-----------------------------------------------------------------------------
+bool GeometryPredicates::_is_degenerate_2d(const std::vector<Point>& simplex)
+{
+  if (simplex.size() < 2 or simplex.size() > 3)
+  {
+    info("Degenerate 2D simplex with %d vertices.", simplex.size());
+    return true;
+  }
+
+  switch (simplex.size())
+  {
+  case 2:
+    return simplex[0] == simplex[1];
+  case 3:
+    return orient2d(simplex[0], simplex[1], simplex[2]) == 0.0;
+  }
+
+  // Shouldn't get here
+  dolfin_error("GeometryPredicates.h",
+               "call _is_degenerate_2d",
+               "Only implemented for simplices of tdim 0, 1 and 2, not tdim = %d",
+               simplex.size() - 1);
+
+  return true;
+}
+//------------------------------------------------------------------------------
+bool GeometryPredicates::_is_degenerate_3d(const std::vector<Point>& simplex)
+{
+  if (simplex.size() < 2 or simplex.size() > 4)
+  {
+    info("Degenerate 3D simplex with %d vertices.", simplex.size());
+    return true;
+  }
+
+  switch (simplex.size())
+  {
+  case 2:
+    return simplex[0] == simplex[1];
+  case 3:
+    {
+      const double ayz[2] = {simplex[0].y(), simplex[0].z()};
+      const double byz[2] = {simplex[1].y(), simplex[1].z()};
+      const double cyz[2] = {simplex[2].y(), simplex[2].z()};
+      if (_orient2d(ayz, byz, cyz) != 0.0)
+	return false;
+
+      const double azx[2] = {simplex[0].z(), simplex[0].x()};
+      const double bzx[2] = {simplex[1].z(), simplex[1].x()};
+      const double czx[2] = {simplex[2].z(), simplex[2].x()};
+      if (_orient2d(azx, bzx, czx) != 0.0)
+	return false;
+
+      const double axy[2] = {simplex[0].x(), simplex[0].y()};
+      const double bxy[2] = {simplex[1].x(), simplex[1].y()};
+      const double cxy[2] = {simplex[2].x(), simplex[2].y()};
+      if (_orient2d(axy, bxy, cxy) != 0.0)
+	return false;
+
+      return true;
+    }
+  case 4:
+    return orient3d(simplex[0], simplex[1], simplex[2], simplex[3]) == 0.0;
+  }
+
+  // Shouldn't get here
+  dolfin_error("GeometryPredicates.h",
+               "call _is_degenerate_3d",
+               "Only implemented for simplices of tdim 0, 1, 2 and 3, not tdim = %d",
+               simplex.size() - 1);
+
+  return true;
+}
+//-----------------------------------------------------------------------------
+bool GeometryPredicates::is_finite(const std::vector<Point>& simplex)
+{
+  for (auto p : simplex)
+  {
+    if (!std::isfinite(p.x()))
+      return false;
+    if (!std::isfinite(p.y()))
+      return false;
+    if (!std::isfinite(p.z()))
+      return false;
+  }
+  return true;
+}
+//-----------------------------------------------------------------------------
+bool GeometryPredicates::is_finite(const std::vector<double>& simplex)
+{
+  for (double p : simplex)
+  {
+    if (!std::isfinite(p))
+      return false;
+  }
+  return true;
+}
+//-----------------------------------------------------------------------------
+bool GeometryPredicates::convex_hull_is_degenerate(const std::vector<Point>& points,
+                                                   std::size_t gdim)
+{
+  // Points are assumed to be unique
+
+  if (points.size() < gdim+1)
+    return true;
+
+  if (gdim == 2)
+  {
+    // FIXME!
+    return false;
+  }
+  else if (gdim == 3)
+  {
+    std::size_t i = 0, j = 1, k = 2;
+    bool found = false;
+
+    // Find three point which are not collinear
+    for (; i < points.size(); i++)
+    {
+      for (j = i+1; j < points.size(); j++)
+      {
+        for (k = j+1; k < points.size(); k++)
+        {
+          const Point ij = points[j] - points[i];
+          const Point ik = points[k] - points[i];
+          if ( -(std::abs( (ij/ij.norm() ).dot(ik/ik.norm()))-1)  > DOLFIN_EPS)
+          {
+            found = true;
+            break;
+          }
+        }
+        if (found) break;
+      }
+      if (found)
+        break;
+    }
+
+    // All points are collinear
+    if (!found)
+      return false;
+
+    for (std::size_t l = 0; l < points.size();  l++)
+    {
+      if (l == i || l == j || l == k)
+        continue;
+
+      if (orient3d(points[i], points[j], points[k], points[l]) == 0.0)
+        return true;
+    }
+
+    return false;
+  }
+
+  dolfin_error("GeometryPredicates.h",
+               "call convex_hull_is_degenerate",
+               "Only fully implemented for gdim == 3, not gdim = %d", gdim);
+  return false;
+}
+//-----------------------------------------------------------------------------
+bool GeometryPredicates::is_degenerate_2d(const std::vector<Point>& simplex)
+{
+  return CHECK_CGAL(_is_degenerate_2d(simplex),
+		    cgal_is_degenerate_2d(simplex));
+}
+//-----------------------------------------------------------------------------
+bool GeometryPredicates::is_degenerate_3d(const std::vector<Point>& simplex)
+{
+  return CHECK_CGAL(_is_degenerate_3d(simplex),
+		    cgal_is_degenerate_3d(simplex));
+}
+//-----------------------------------------------------------------------------
diff --git a/dolfin/geometry/GeometryPredicates.h b/dolfin/geometry/GeometryPredicates.h
new file mode 100644
index 0000000..5e56a0a
--- /dev/null
+++ b/dolfin/geometry/GeometryPredicates.h
@@ -0,0 +1,70 @@
+// Copyright (C) 2016-2017 Anders Logg, August Johansson and Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN 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 Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added:  2016-11-21
+// Last changed: 2017-09-22
+
+#ifndef __GEOMETRY_PREDICATES_H
+#define __GEOMETRY_PREDICATES_H
+
+#include <vector>
+#include <dolfin/log/LogStream.h>
+#include "Point.h"
+
+namespace dolfin
+{
+
+  /// This class implements geometric predicates, i.e. function that
+  /// return either true or false.
+
+  class GeometryPredicates
+  {
+  public:
+
+    /// Check whether simplex is degenerate
+    static bool is_degenerate(const std::vector<Point>& simplex,
+			      std::size_t gdim);
+
+
+    /// Check whether simplex is degenerate (2D version)
+    static bool is_degenerate_2d(const std::vector<Point>& simplex);
+
+    /// Check whether simplex is degenerate (3D version)
+    static bool is_degenerate_3d(const std::vector<Point>& simplex);
+
+
+    /// Check whether simplex is finite (not Inf or NaN)
+    static bool is_finite(const std::vector<Point>& simplex);
+
+    /// Check whether simplex is finite (not Inf or NaN)
+    static bool is_finite(const std::vector<double>& simplex);
+
+    /// Check whether the convex hull is degenerate
+    static bool convex_hull_is_degenerate(const std::vector<Point>& p,
+                                          std::size_t gdim);
+
+  private:
+
+    // Implementations of is_degenerate
+    static bool _is_degenerate_2d(const std::vector<Point>& simplex);
+    static bool _is_degenerate_3d(const std::vector<Point>& simplex);
+
+  };
+
+}
+
+#endif
diff --git a/dolfin/geometry/GeometryTools.h b/dolfin/geometry/GeometryTools.h
new file mode 100644
index 0000000..94ce5c9
--- /dev/null
+++ b/dolfin/geometry/GeometryTools.h
@@ -0,0 +1,120 @@
+// Copyright (C) 2017 Anders Logg
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN 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 Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added:  2017-02-11
+// Last changed: 2017-02-17
+
+#ifndef __GEOMETRY_TOOLS_H
+#define __GEOMETRY_TOOLS_H
+
+#include "predicates.h"
+#include "Point.h"
+
+namespace dolfin
+{
+
+  /// This class provides useful tools (functions) for computational geometry.
+
+  class GeometryTools
+  {
+  public:
+
+    /// Compute numerically stable cross product (a - c) x (b - c)
+    static inline Point cross_product(const Point& a, const Point& b, const Point& c)
+    {
+      // See Shewchuk Lecture Notes on Geometric Robustness
+      double ayz[2] = {a.y(), a.z()};
+      double byz[2] = {b.y(), b.z()};
+      double cyz[2] = {c.y(), c.z()};
+      double azx[2] = {a.z(), a.x()};
+      double bzx[2] = {b.z(), b.x()};
+      double czx[2] = {c.z(), c.x()};
+      double axy[2] = {a.x(), a.y()};
+      double bxy[2] = {b.x(), b.y()};
+      double cxy[2] = {c.x(), c.y()};
+      return Point (_orient2d(ayz, byz, cyz),
+                    _orient2d(azx, bzx, czx),
+                    _orient2d(axy, bxy, cxy));
+    }
+
+    /// Compute determinant of 3 x 3 matrix defined by vectors, ab, dc, ec
+    inline double determinant(const Point& ab, const Point& dc, const Point& ec)
+    {
+      const double a = ab.x(), b = ab.y(), c = ab.z();
+      const double d = dc.x(), e = dc.y(), f = dc.z();
+      const double g = ec.x(), h = ec.y(), i = ec.z();
+      return a * (e * i - f * h)
+           + b * (f * g - d * i)
+           + c * (d * h - e * g);
+    }
+
+    /// Compute major (largest) axis of vector (2D)
+    static inline std::size_t major_axis_2d(const Point& v)
+    {
+      return (std::abs(v.x()) >= std::abs(v.y()) ? 0 : 1);
+    }
+
+    /// Compute major (largest) axis of vector (3D)
+    static inline std::size_t major_axis_3d(const Point& v)
+    {
+      const double vx = std::abs(v.x());
+      const double vy = std::abs(v.y());
+      const double vz = std::abs(v.z());
+      if (vx >= vy && vx >= vz)
+        return 0;
+      if (vy >= vz)
+        return 1;
+      return 2;
+    }
+
+    /// Project point to axis (2D)
+    static inline double project_to_axis_2d(const Point& p, std::size_t axis)
+    {
+      dolfin_assert(axis <= 1);
+      return p[axis];
+    }
+
+    /// Project point to plane (3D)
+    static inline Point project_to_plane_3d(const Point& p, std::size_t axis)
+    {
+      dolfin_assert(axis <= 2);
+      switch (axis)
+      {
+      case 0: return Point(p.y(), p.z());
+      case 1: return Point(p.x(), p.z());
+      case 2: return Point(p.x(), p.y());
+      }
+      return p;
+    }
+
+    /// Check whether x in [a, b]
+    static inline bool contains(double a, double b, double x)
+    {
+      return a <= x and x <= b;
+    }
+
+    /// Check whether x in (a, b)
+    static inline bool contains_strict(double a, double b, double x)
+    {
+      return a < x and x < b;
+    }
+
+  };
+
+}
+
+#endif
diff --git a/dolfin/geometry/IntersectionConstruction.cpp b/dolfin/geometry/IntersectionConstruction.cpp
new file mode 100644
index 0000000..284bd22
--- /dev/null
+++ b/dolfin/geometry/IntersectionConstruction.cpp
@@ -0,0 +1,862 @@
+// Copyright (C) 2014-2017 Anders Logg, August Johansson and Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN 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 Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added:  2014-02-03
+// Last changed: 2017-10-07
+
+#include <iomanip>
+#include <dolfin/mesh/MeshEntity.h>
+#include "predicates.h"
+#include "GeometryPredicates.h"
+#include "GeometryTools.h"
+#include "GeometryDebugging.h"
+#include "CollisionPredicates.h"
+#include "IntersectionConstruction.h"
+#include "CGALExactArithmetic.h"
+
+using namespace dolfin;
+
+namespace
+{
+  // Add points to vector
+  template <typename T>
+  inline void add(std::vector<T>& points,
+                  const std::vector<T>& _points)
+  {
+    points.insert(points.end(), _points.begin(), _points.end());
+  }
+
+  // Filter unique points
+  template <typename T>
+  inline std::vector<T> unique(const std::vector<T>& points)
+  {
+    std::vector<T> _unique;
+    _unique.reserve(points.size());
+
+    for (std::size_t i = 0; i < points.size(); ++i)
+    {
+      bool found = false;
+      for (std::size_t j = i+1; j < points.size(); ++j)
+      {
+        if (points[i] == points[j])
+        {
+          found = true;
+          break;
+        }
+      }
+      if (!found)
+        _unique.push_back(points[i]);
+    }
+
+    return _unique;
+  }
+
+  // Convert vector of doubles to vector of points
+  std::vector<Point> to_points(const std::vector<double>& points)
+  {
+    std::vector<Point> _points;
+    for (auto x : points)
+      _points.push_back(Point(x));
+    return _points;
+  }
+}
+
+//-----------------------------------------------------------------------------
+// High-level intersection construction functions
+//-----------------------------------------------------------------------------
+std::vector<Point>
+IntersectionConstruction::intersection(const MeshEntity& entity_0,
+                                       const MeshEntity& entity_1)
+{
+  // Get data
+  const MeshGeometry& g0 = entity_0.mesh().geometry();
+  const MeshGeometry& g1 = entity_1.mesh().geometry();
+  const unsigned int* v0 = entity_0.entities(0);
+  const unsigned int* v1 = entity_1.entities(0);
+
+  // Pack data as vectors of points
+  std::vector<Point> points_0(entity_0.dim() + 1);
+  std::vector<Point> points_1(entity_1.dim() + 1);
+  for (std::size_t i = 0; i <= entity_0.dim(); i++)
+    points_0[i] = g0.point(v0[i]);
+  for (std::size_t i = 0; i <= entity_1.dim(); i++)
+    points_1[i] = g1.point(v1[i]);
+
+  // Only look at first entity to get geometric dimension
+  std::size_t gdim = g0.dim();
+
+  // Call common implementation
+  return intersection(points_0, points_1, gdim);
+}
+//-----------------------------------------------------------------------------
+std::vector<Point>
+IntersectionConstruction::intersection(const std::vector<Point>& p,
+                                       const std::vector<Point>& q,
+                                       std::size_t gdim)
+{
+  // Get topological dimensions
+  const std::size_t d0 = p.size() - 1;
+  const std::size_t d1 = q.size() - 1;
+
+  // Swap if d0 < d1 (reduce from 16 to 10 cases)
+  if (d0 < d1)
+    return intersection(q, p, gdim);
+
+  // Pick correct specialized implementation
+  if (d0 == 0 and d1 == 0)
+  {
+    switch (gdim)
+    {
+    case 1: return to_points(intersection_point_point_1d(p[0][0], q[0][0]));
+    case 2: return intersection_point_point_2d(p[0], q[0]);
+    case 3: return intersection_point_point_3d(p[0], q[0]);
+    }
+  }
+  else if (d0 == 1 and d1 == 0)
+  {
+    switch (gdim)
+    {
+    case 1: return to_points(intersection_segment_point_1d(p[0][0], p[1][0], q[0][0]));
+    case 2: return intersection_segment_point_2d(p[0], p[1], q[0]);
+    case 3: return intersection_segment_point_3d(p[0], p[1], q[0]);
+    }
+  }
+  else if (d0 == 1 and d1 == 1)
+  {
+    switch (gdim)
+    {
+    case 1: return to_points(intersection_segment_segment_1d(p[0][0], p[1][0], q[0][0], q[1][0]));
+    case 2: return intersection_segment_segment_2d(p[0], p[1], q[0], q[1]);
+    case 3: return intersection_segment_segment_3d(p[0], p[1], q[0], q[1]);
+    }
+  }
+  else if (d0 == 2 and d1 == 0)
+  {
+    switch (gdim)
+    {
+    case 2: return intersection_triangle_point_2d(p[0], p[1], p[2], q[0]);
+    case 3: return intersection_triangle_point_3d(p[0], p[1], p[2], q[0]);
+    }
+  }
+  else if (d0 == 2 and d1 == 1)
+  {
+    switch (gdim)
+    {
+    case 2: return intersection_triangle_segment_2d(p[0], p[1], p[2], q[0], q[1]);
+    case 3: return intersection_triangle_segment_3d(p[0], p[1], p[2], q[0], q[1]);
+    }
+  }
+  else if (d0 == 2 and d1 == 2)
+  {
+    switch (gdim)
+    {
+    case 2: return intersection_triangle_triangle_2d(p[0], p[1], p[2], q[0], q[1], q[2]);
+    case 3: return intersection_triangle_triangle_3d(p[0], p[1], p[2], q[0], q[1], q[2]);
+    }
+  }
+  else if (d0 == 3 and d1 == 0)
+  {
+    switch (gdim)
+    {
+    case 3: return intersection_tetrahedron_point_3d(p[0], p[1], p[2], p[3], q[0]);
+    }
+  }
+  else if (d0 == 3 and d1 == 1)
+  {
+    switch (gdim)
+    {
+    case 3: return intersection_tetrahedron_segment_3d(p[0], p[1], p[2], p[3], q[0], q[1]);
+    }
+  }
+  else if (d0 == 3 and d1 == 2)
+  {
+    switch (gdim)
+    {
+    case 3: return intersection_tetrahedron_triangle_3d(p[0], p[1], p[2], p[3], q[0], q[1], q[2]);
+    }
+  }
+  else if (d0 == 3 and d1 == 3)
+  {
+    switch (gdim)
+    {
+    case 3: return intersection_tetrahedron_tetrahedron_3d(p[0], p[1], p[2], p[3], q[0], q[1], q[2], q[3]);
+    }
+  }
+
+  // We should not reach this point
+  dolfin_error("IntersectionConstruction.cpp",
+               "compute intersection",
+               "Unexpected intersection: %d-%d in %d dimensions", d0, d1, gdim);
+
+  return std::vector<Point>();
+}
+//-----------------------------------------------------------------------------
+// Low-level intersection construction functions
+//-----------------------------------------------------------------------------
+std::vector<double>
+IntersectionConstruction::intersection_point_point_1d(double p0,
+                                                      double q0)
+{
+  if (p0 == q0)
+    return std::vector<double>(1, p0);
+  return std::vector<double>();
+}
+//-----------------------------------------------------------------------------
+std::vector<Point>
+IntersectionConstruction::intersection_point_point_2d(const Point& p0,
+                                                      const Point& q0)
+{
+  if (p0.x() == q0.x() && p0.y() == q0.y())
+    return std::vector<Point>(1, p0);
+  else
+    return std::vector<Point>();
+}
+//-----------------------------------------------------------------------------
+std::vector<Point>
+IntersectionConstruction::intersection_point_point_3d(const Point& p0,
+                                                      const Point& q0)
+{
+  if (p0.x() == q0.x() && p0.y() == q0.y() && p0.z() == q0.z())
+    return std::vector<Point>(1, p0);
+  else
+    return std::vector<Point>();
+}
+//-----------------------------------------------------------------------------
+std::vector<double>
+IntersectionConstruction::intersection_segment_point_1d(double p0,
+                                                        double p1,
+                                                        double q0)
+{
+  if (CollisionPredicates::collides_segment_point_1d(p0, p1, q0))
+    return std::vector<double>(1, q0);
+  else
+    return std::vector<double>();
+}
+//-----------------------------------------------------------------------------
+std::vector<Point>
+IntersectionConstruction::intersection_segment_point_2d(const Point& p0,
+                                                        const Point& p1,
+                                                        const Point& q0)
+{
+  if (CollisionPredicates::collides_segment_point_2d(p0, p1, q0))
+    return std::vector<Point>(1, q0);
+  else
+    return std::vector<Point>();
+}
+//-----------------------------------------------------------------------------
+std::vector<Point>
+IntersectionConstruction::intersection_segment_point_3d(const Point& p0,
+                                                        const Point& p1,
+                                                        const Point& q0)
+{
+  if (CollisionPredicates::collides_segment_point_3d(p0, p1, q0))
+    return std::vector<Point>(1, q0);
+  else
+    return std::vector<Point>();
+}
+//-----------------------------------------------------------------------------
+std::vector<Point>
+IntersectionConstruction::intersection_triangle_point_2d(const Point& p0,
+                                                         const Point& p1,
+                                                         const Point& p2,
+                                                         const Point& q0)
+{
+  if (CollisionPredicates::collides_triangle_point_2d(p0, p1, p2, q0))
+    return std::vector<Point>(1, q0);
+  else
+    return std::vector<Point>();
+}
+//-----------------------------------------------------------------------------
+std::vector<Point>
+IntersectionConstruction::intersection_triangle_point_3d(const Point& p0,
+                                                         const Point& p1,
+                                                         const Point& p2,
+                                                         const Point& q0)
+{
+  if (CollisionPredicates::collides_triangle_point_3d(p0, p1, p2, q0))
+    return std::vector<Point>(1, q0);
+  else
+    return std::vector<Point>();
+}
+//-----------------------------------------------------------------------------
+std::vector<Point>
+IntersectionConstruction::intersection_tetrahedron_point_3d(const Point& p0,
+                                                            const Point& p1,
+                                                            const Point& p2,
+                                                            const Point& p3,
+                                                            const Point& q0)
+{
+  if (CollisionPredicates::collides_tetrahedron_point_3d(p0, p1, p2, p3, q0))
+    return std::vector<Point>(1, q0);
+  else
+    return std::vector<Point>();
+}
+//-----------------------------------------------------------------------------
+std::vector<double>
+IntersectionConstruction::intersection_segment_segment_1d(double p0,
+                                                          double p1,
+                                                          double q0,
+                                                          double q1)
+{
+  // The list of points (convex hull)
+  std::vector<double> points;
+
+  // Add point intersections (2)
+  add(points, intersection_segment_point_1d(p0, p1, q0));
+  add(points, intersection_segment_point_1d(p0, p1, q1));
+  add(points, intersection_segment_point_1d(q0, q1, p0));
+  add(points, intersection_segment_point_1d(q0, q1, p1));
+
+  dolfin_assert(GeometryPredicates::is_finite(points));
+  return unique(points);
+}
+//-----------------------------------------------------------------------------
+std::vector<Point>
+IntersectionConstruction::intersection_segment_segment_2d(const Point& p0,
+                                                          const Point& p1,
+                                                          const Point& q0,
+                                                          const Point& q1)
+{
+  // We consider the following 4 cases for the segment q0-q1
+  // relative to the line defined by the segment p0-p1:
+  //
+  // Case 0: qo = q0o*q1o > 0.
+  //
+  //   --> points on the same side.
+  //   --> no intersection
+  //
+  // Case 1: (q0o == 0. and q1o != 0.) or (q0o != 0. and q1o == 0.)
+  //
+  //   --> exactly one point on line
+  //   --> possible point intersection
+  //
+  // Case 2: q0o = 0. and q10 = 0. [or unstable case]
+  //
+  //   --> both points on line
+  //   --> project to 1D
+  //
+  // Case 3: qo = q0o*q1o < 0.
+  //
+  //   --> points on different sides
+  //   --> compute intersection point with line
+  //   --> project to 1D and check if point is inside segment
+  //
+  // Note that the computation in Case 3 may be sensitive to rounding
+  // errors if both points are almost on the line. If this happens
+  // we instead consider the points to be on the line [Case 2] to
+  // obtain one or more sensible points (if any).
+
+  // Compute orientation of segment end points wrt line
+  const double q0o = orient2d(p0, p1, q0);
+  const double q1o = orient2d(p0, p1, q1);
+
+  // Case 0: points on the same side --> no intersection
+  if ((q0o > 0.0 and q1o > 0.0) or(q0o < 0.0 and q1o < 0.0))
+    return std::vector<Point>();
+
+  // Repeat the same procedure for p
+  const double p0o = orient2d(q0, q1, p0);
+  const double p1o = orient2d(q0, q1, p1);
+  if ((p0o > 0.0 and p1o > 0.0) or (p0o < 0.0 and p1o < 0.0))
+    return std::vector<Point>();
+
+  // Case 1: exactly one point on line --> possible point intersection
+  if (q0o == 0.0 and q1o != 0.0)
+    return intersection_segment_point_2d(p0, p1, q0);
+  else if (q0o != 0.0 and q1o == 0.0)
+    return intersection_segment_point_2d(p0, p1, q1);
+  else if (p0o == 0.0 and p1o != 0.0)
+    return intersection_segment_point_2d(q0, q1, p0);
+  else if (p0o != 0.0 and p1o == 0.0)
+    return intersection_segment_point_2d(q0, q1, p1);
+
+  // Compute line vector and major axis
+  const Point v = p1 - p0;
+  const std::size_t major_axis = GeometryTools::major_axis_2d(v);
+
+  // Project points to major axis
+  const double P0 = GeometryTools::project_to_axis_2d(p0, major_axis);
+  const double P1 = GeometryTools::project_to_axis_2d(p1, major_axis);
+  const double Q0 = GeometryTools::project_to_axis_2d(q0, major_axis);
+  const double Q1 = GeometryTools::project_to_axis_2d(q1, major_axis);
+
+  // Case 2: both points on line (or almost)
+  if (std::abs(q0o) < DOLFIN_EPS and std::abs(q1o) < DOLFIN_EPS)
+  {
+    // Compute 1D intersection points
+    const std::vector<double>
+      points_1d = intersection_segment_segment_1d(P0, P1, Q0, Q1);
+
+    // Unproject points: add back second coordinate
+    std::vector<Point> points;
+    switch (major_axis)
+    {
+    case 0:
+      for (auto p : points_1d)
+      {
+        const double y = p0.y() + (p - p0.x()) * v.y() / v.x();
+        points.push_back(Point(p, y));
+      }
+      break;
+    default:
+      for (auto p : points_1d)
+      {
+        const double x = p0.x() + (p - p0.y()) * v.x() / v.y();
+        points.push_back(Point(x, p));
+      }
+    }
+
+    return unique(points);
+  }
+
+  // Case 3: points on different sides (main case)
+
+  // Compute determinant needed for intersection computation
+  const Point w = q1 - q0;
+  const double den = w.x()*v.y() - w.y()*v.x();
+
+  // Figure out which one of the four points we want to use
+  // as starting point for numerical robustness
+  const double p_dist = v.norm();
+  const double q_dist = w.norm();
+  enum orientation { P0O, P1O, Q0O, Q1O };
+  std::array<std::pair<double, orientation>, 4> oo
+		      = {{ { std::abs(p0o)*p_dist, P0O },
+			   { std::abs(p1o)*p_dist, P1O },
+			   { std::abs(q0o)*q_dist, Q0O },
+			   { std::abs(q1o)*q_dist, Q1O } }};
+  const auto it = std::min_element(oo.begin(), oo.end());
+
+  // Compute the intersection point
+  Point x;
+  switch (it->second)
+  {
+  case P0O:
+    // Flip sign because den = det(q1 - q0, v), but we want det(q1 - q0, -v)
+    x = p0 - p0o / den * v;
+    break;
+  case P1O:
+    // Flip sign because v = p1 - p0, but we want p0 - p1
+    x = p1 - p1o / den * v;
+    break;
+  case Q0O:
+    // Default case
+    x = q0 + q0o / den * w;
+    break;
+  case Q1O:
+    // Use q1o
+    x = q1 + q1o / den * w;
+    break;
+  }
+
+  // Project point to major axis and check if inside segment
+  const double X = GeometryTools::project_to_axis_2d(x, major_axis);
+  if (CollisionPredicates::collides_segment_point_1d(P0, P1, X))
+    return std::vector<Point>(1, x);
+
+  return std::vector<Point>();
+}
+//-----------------------------------------------------------------------------
+std::vector<Point>
+IntersectionConstruction::intersection_segment_segment_3d(const Point& p0,
+                                                          const Point& p1,
+                                                          const Point& q0,
+                                                          const Point& q1)
+{
+  // This function is not used so no need to spend time on the implementation.
+  dolfin_not_implemented();
+  return std::vector<Point>();
+}
+//-----------------------------------------------------------------------------
+std::vector<Point>
+IntersectionConstruction::intersection_triangle_segment_2d(const Point& p0,
+                                                           const Point& p1,
+                                                           const Point& p2,
+                                                           const Point& q0,
+                                                           const Point& q1)
+{
+  // The list of points (convex hull)
+  std::vector<Point> points;
+
+  // Add point intersections (2)
+  add(points, intersection_triangle_point_2d(p0, p1, p2, q0));
+  add(points, intersection_triangle_point_2d(p0, p1, p2, q1));
+
+  // Add segment-segment intersections (3)
+  add(points, intersection_segment_segment_2d(p0, p1, q0, q1));
+  add(points, intersection_segment_segment_2d(p0, p2, q0, q1));
+  add(points, intersection_segment_segment_2d(p1, p2, q0, q1));
+
+  dolfin_assert(GeometryPredicates::is_finite(points));
+  return unique(points);
+}
+//-----------------------------------------------------------------------------
+std::vector<Point>
+IntersectionConstruction::_intersection_triangle_segment_3d(const Point& p0,
+							    const Point& p1,
+							    const Point& p2,
+							    const Point& q0,
+							    const Point& q1)
+{
+  // We consider the following 4 cases for the segment q0-q1
+  // relative to the plane defined by the triangle p0-p1-p2:
+  //
+  // Case 0: qo = q0o*q1o > 0.
+  //
+  //   --> points on the same side
+  //   --> no intersection
+  //
+  // Case 1: (q0o == 0. and q1o != 0.) or (q0o != 0. and q1o == 0.)
+  //
+  //   --> exactly one point in plane
+  //   --> possible point intersection
+  //
+  // Case 2: q0o = 0. and q10 = 0. [or unstable case]
+  //
+  //   --> points in plane
+  //   --> project to 2D
+  //
+  // Case 3: qo = q0o*q1o < 0.
+  //
+  //   --> points on different sides
+  //   --> compute intersection point with plane
+  //   --> project to 2D and check if point is inside triangle
+  //
+  // Note that the computation in Case 3 may be sensitive to rounding
+  // errors if both points are almost in the plane. If this happens
+  // we instead consider the points to be in the plane [Case 2] to
+  // obtain one or more sensible points (if any).
+
+  // Compute orientation of segment end points wrt plane
+  const double q0o = orient3d(p0, p1, p2, q0);
+  const double q1o = orient3d(p0, p1, p2, q1);
+
+  // Compute total orientation of segment wrt plane
+  const double qo = q0o*q1o;
+
+  // Case 0: points on the same side --> no intersection
+  if (qo > 0.0)
+    return std::vector<Point>();
+
+  // Case 1: exactly one point in plane --> possible point intersection
+  if (q0o == 0.0 and q1o != 0.0)
+    return intersection_triangle_point_3d(p0, p1, p2, q0);
+  else if (q0o != 0.0 and q1o == 0.0)
+    return intersection_triangle_point_3d(p0, p1, p2, q1);
+
+  // Compute plane normal and major axis
+  const Point n = GeometryTools::cross_product(p0, p1, p2);
+  const std::size_t major_axis = GeometryTools::major_axis_3d(n);
+
+  // Project points to major axis plane
+  const Point P0 = GeometryTools::project_to_plane_3d(p0, major_axis);
+  const Point P1 = GeometryTools::project_to_plane_3d(p1, major_axis);
+  const Point P2 = GeometryTools::project_to_plane_3d(p2, major_axis);
+  const Point Q0 = GeometryTools::project_to_plane_3d(q0, major_axis);
+  const Point Q1 = GeometryTools::project_to_plane_3d(q1, major_axis);
+
+  // Case 2: both points in plane (or almost)
+  if (std::abs(q0o) < DOLFIN_EPS_LARGE and std::abs(q1o) < DOLFIN_EPS_LARGE)
+  {
+    // Compute 2D intersection points
+    const std::vector<Point>
+      points_2d = intersection_triangle_segment_2d(P0, P1, P2, Q0, Q1);
+
+    // Unproject points: add back third coordinate
+    std::vector<Point> points;
+    switch (major_axis)
+    {
+    case 0:
+      for (auto P : points_2d)
+      {
+        const double x = p0.x() + ((p0.y() - P.x())*n.y() + (p0.z() - P.y())*n.z()) / n.x();
+        points.push_back(Point(x, P.x(), P.y()));
+      }
+      break;
+    case 1:
+      for (auto P : points_2d)
+      {
+        const double y = p0.y() + ((p0.x() - P.x())*n.x() + (p0.z() - P.y())*n.z()) / n.y();
+        points.push_back(Point(P.x(), y, P.y()));
+      }
+      break;
+    default:
+      for (auto P : points_2d)
+      {
+        const double z = p0.z() + ((p0.x() - P.x())*n.x() + (p0.y() - P.y())*n.y()) / n.z();
+        points.push_back(Point(P.x(), P.y(), z));
+      }
+    }
+
+    return unique(points);
+  }
+
+  // Case 3: points on different sides (main case)
+
+  // Compute intersection point
+  const double num = n.dot(p0 - q0);
+  const double den = n.dot(q1 - q0);
+  const Point x = p0 + num / den * (p1 - p0);
+
+  // Project point to major axis plane and check if inside triangle
+  const Point X = GeometryTools::project_to_plane_3d(x, major_axis);
+  if (CollisionPredicates::collides_triangle_point_2d(P0, P1, P2, X))
+    return std::vector<Point>(1, x);
+
+  return std::vector<Point>();
+}
+//-----------------------------------------------------------------------------
+std::vector<Point>
+IntersectionConstruction::intersection_tetrahedron_segment_3d(const Point& p0,
+                                                              const Point& p1,
+                                                              const Point& p2,
+                                                              const Point& p3,
+                                                              const Point& q0,
+                                                              const Point& q1)
+{
+  // The list of points (convex hull)
+  std::vector<Point> points;
+
+  // Add point intersections (4 + 4 = 8)
+  add(points, intersection_tetrahedron_point_3d(p0, p1, p2, p3, q0));
+  add(points, intersection_tetrahedron_point_3d(p0, p1, p2, p3, q1));
+
+  // Add triangle-segment intersections (4)
+  add(points, intersection_triangle_segment_3d(p0, p1, p2, q0, q1));
+  add(points, intersection_triangle_segment_3d(p0, p1, p3, q0, q1));
+  add(points, intersection_triangle_segment_3d(p0, p2, p3, q0, q1));
+  add(points, intersection_triangle_segment_3d(p1, p2, p3, q0, q1));
+
+  dolfin_assert(GeometryPredicates::is_finite(points));
+  return unique(points);
+}
+//-----------------------------------------------------------------------------
+// Intersections with triangles and tetrahedra: computed by delegation
+//-----------------------------------------------------------------------------
+std::vector<Point>
+IntersectionConstruction::intersection_triangle_triangle_2d(const Point& p0,
+                                                            const Point& p1,
+                                                            const Point& p2,
+                                                            const Point& q0,
+                                                            const Point& q1,
+                                                            const Point& q2)
+{
+  // The list of points (convex hull)
+  std::vector<Point> points;
+
+  // Add point intersections (3 + 3 = 6)
+  add(points, intersection_triangle_point_2d(p0, p1, p2, q0));
+  add(points, intersection_triangle_point_2d(p0, p1, p2, q1));
+  add(points, intersection_triangle_point_2d(p0, p1, p2, q2));
+  add(points, intersection_triangle_point_2d(q0, q1, q2, p0));
+  add(points, intersection_triangle_point_2d(q0, q1, q2, p1));
+  add(points, intersection_triangle_point_2d(q0, q1, q2, p2));
+
+  // Add segment-segment intersections (3 x 3 = 9)
+  add(points, intersection_segment_segment_2d(p0, p1, q0, q1));
+  add(points, intersection_segment_segment_2d(p0, p1, q0, q2));
+  add(points, intersection_segment_segment_2d(p0, p1, q1, q2));
+  add(points, intersection_segment_segment_2d(p0, p2, q0, q1));
+  add(points, intersection_segment_segment_2d(p0, p2, q0, q2));
+  add(points, intersection_segment_segment_2d(p0, p2, q1, q2));
+  add(points, intersection_segment_segment_2d(p1, p2, q0, q1));
+  add(points, intersection_segment_segment_2d(p1, p2, q0, q2));
+  add(points, intersection_segment_segment_2d(p1, p2, q1, q2));
+
+  dolfin_assert(GeometryPredicates::is_finite(points));
+  return unique(points);
+}
+//-----------------------------------------------------------------------------
+std::vector<Point>
+IntersectionConstruction::intersection_triangle_triangle_3d(const Point& p0,
+                                                            const Point& p1,
+                                                            const Point& p2,
+                                                            const Point& q0,
+                                                            const Point& q1,
+                                                            const Point& q2)
+{
+  // The list of points (convex hull)
+  std::vector<Point> points;
+
+  // Add point intersections (3 + 3 = 6)
+  add(points, intersection_triangle_point_3d(p0, p1, p2, q0));
+  add(points, intersection_triangle_point_3d(p0, p1, p2, q1));
+  add(points, intersection_triangle_point_3d(p0, p1, p2, q2));
+  add(points, intersection_triangle_point_3d(q0, q1, q2, p0));
+  add(points, intersection_triangle_point_3d(q0, q1, q2, p1));
+  add(points, intersection_triangle_point_3d(q0, q1, q2, p2));
+
+  // Add triangle-segment intersections (3 + 3 = 6)
+  add(points, intersection_triangle_segment_3d(p0, p1, p2, q0, q1));
+  add(points, intersection_triangle_segment_3d(p0, p1, p2, q0, q2));
+  add(points, intersection_triangle_segment_3d(p0, p1, p2, q1, q2));
+  add(points, intersection_triangle_segment_3d(q0, q1, q2, p0, p1));
+  add(points, intersection_triangle_segment_3d(q0, q1, q2, p0, p2));
+  add(points, intersection_triangle_segment_3d(q0, q1, q2, p1, p2));
+
+  dolfin_assert(GeometryPredicates::is_finite(points));
+  return unique(points);
+}
+//-----------------------------------------------------------------------------
+std::vector<Point>
+IntersectionConstruction::intersection_tetrahedron_triangle_3d(const Point& p0,
+                                                               const Point& p1,
+                                                               const Point& p2,
+                                                               const Point& p3,
+                                                               const Point& q0,
+                                                               const Point& q1,
+                                                               const Point& q2)
+{
+  // The list of points (convex hull)
+  std::vector<Point> points;
+
+  // Add point intersections (3 + 4 = 7)
+  add(points, intersection_tetrahedron_point_3d(p0, p1, p2, p3, q0));
+  add(points, intersection_tetrahedron_point_3d(p0, p1, p2, p3, q1));
+  add(points, intersection_tetrahedron_point_3d(p0, p1, p2, p3, q2));
+  add(points, intersection_triangle_point_3d(q0, q1, q2, p0));
+  add(points, intersection_triangle_point_3d(q0, q1, q2, p1));
+  add(points, intersection_triangle_point_3d(q0, q1, q2, p2));
+  add(points, intersection_triangle_point_3d(q0, q1, q2, p3));
+
+  // Add triangle-segment intersections (4 x 3 + 1 x 6 = 18)
+  add(points, intersection_triangle_segment_3d(p0, p1, p2, q0, q1));
+  add(points, intersection_triangle_segment_3d(p0, p1, p2, q0, q2));
+  add(points, intersection_triangle_segment_3d(p0, p1, p2, q1, q2));
+  add(points, intersection_triangle_segment_3d(p0, p1, p3, q0, q1));
+  add(points, intersection_triangle_segment_3d(p0, p1, p3, q0, q2));
+  add(points, intersection_triangle_segment_3d(p0, p1, p3, q1, q2));
+  add(points, intersection_triangle_segment_3d(p0, p2, p3, q0, q1));
+  add(points, intersection_triangle_segment_3d(p0, p2, p3, q0, q2));
+  add(points, intersection_triangle_segment_3d(p0, p2, p3, q1, q2));
+  add(points, intersection_triangle_segment_3d(p1, p2, p3, q0, q1));
+  add(points, intersection_triangle_segment_3d(p1, p2, p3, q0, q2));
+  add(points, intersection_triangle_segment_3d(p1, p2, p3, q1, q2));
+  add(points, intersection_triangle_segment_3d(q0, q1, q2, p0, p1));
+  add(points, intersection_triangle_segment_3d(q0, q1, q2, p0, p2));
+  add(points, intersection_triangle_segment_3d(q0, q1, q2, p0, p3));
+  add(points, intersection_triangle_segment_3d(q0, q1, q2, p1, p2));
+  add(points, intersection_triangle_segment_3d(q0, q1, q2, p1, p3));
+  add(points, intersection_triangle_segment_3d(q0, q1, q2, p2, p3));
+
+  dolfin_assert(GeometryPredicates::is_finite(points));
+  return unique(points);
+}
+//-----------------------------------------------------------------------------
+std::vector<Point>
+IntersectionConstruction::_intersection_tetrahedron_tetrahedron_3d(const Point& p0,
+								   const Point& p1,
+								   const Point& p2,
+								   const Point& p3,
+								   const Point& q0,
+								   const Point& q1,
+								   const Point& q2,
+								   const Point& q3)
+{
+  // The list of points (convex hull)
+  std::vector<Point> points;
+
+  // Add point intersections (4 + 4 = 8)
+  add(points, intersection_tetrahedron_point_3d(p0, p1, p2, p3, q0));
+  add(points, intersection_tetrahedron_point_3d(p0, p1, p2, p3, q1));
+  add(points, intersection_tetrahedron_point_3d(p0, p1, p2, p3, q2));
+  add(points, intersection_tetrahedron_point_3d(p0, p1, p2, p3, q3));
+  add(points, intersection_tetrahedron_point_3d(q0, q1, q2, q3, p0));
+  add(points, intersection_tetrahedron_point_3d(q0, q1, q2, q3, p1));
+  add(points, intersection_tetrahedron_point_3d(q0, q1, q2, q3, p2));
+  add(points, intersection_tetrahedron_point_3d(q0, q1, q2, q3, p3));
+
+  // Let's hope we got this right... :-)
+
+  // Add triangle-segment intersections (4 x 6 + 4 x 6 = 48)
+  add(points, intersection_triangle_segment_3d(p0, p1, p2, q0, q1));
+  add(points, intersection_triangle_segment_3d(p0, p1, p2, q0, q2));
+  add(points, intersection_triangle_segment_3d(p0, p1, p2, q0, q3));
+  add(points, intersection_triangle_segment_3d(p0, p1, p2, q1, q2));
+  add(points, intersection_triangle_segment_3d(p0, p1, p2, q1, q3));
+  add(points, intersection_triangle_segment_3d(p0, p1, p2, q2, q3));
+  add(points, intersection_triangle_segment_3d(p0, p1, p3, q0, q1));
+  add(points, intersection_triangle_segment_3d(p0, p1, p3, q0, q2));
+  add(points, intersection_triangle_segment_3d(p0, p1, p3, q0, q3));
+  add(points, intersection_triangle_segment_3d(p0, p1, p3, q1, q2));
+  add(points, intersection_triangle_segment_3d(p0, p1, p3, q1, q3));
+  add(points, intersection_triangle_segment_3d(p0, p1, p3, q2, q3));
+  add(points, intersection_triangle_segment_3d(p0, p2, p3, q0, q1));
+  add(points, intersection_triangle_segment_3d(p0, p2, p3, q0, q2));
+  add(points, intersection_triangle_segment_3d(p0, p2, p3, q0, q3));
+  add(points, intersection_triangle_segment_3d(p0, p2, p3, q1, q2));
+  add(points, intersection_triangle_segment_3d(p0, p2, p3, q1, q3));
+  add(points, intersection_triangle_segment_3d(p0, p2, p3, q2, q3));
+  add(points, intersection_triangle_segment_3d(p1, p2, p3, q0, q1));
+  add(points, intersection_triangle_segment_3d(p1, p2, p3, q0, q2));
+  add(points, intersection_triangle_segment_3d(p1, p2, p3, q0, q3));
+  add(points, intersection_triangle_segment_3d(p1, p2, p3, q1, q2));
+  add(points, intersection_triangle_segment_3d(p1, p2, p3, q1, q3));
+  add(points, intersection_triangle_segment_3d(p1, p2, p3, q2, q3));
+  add(points, intersection_triangle_segment_3d(q0, q1, q2, p0, p1));
+  add(points, intersection_triangle_segment_3d(q0, q1, q2, p0, p2));
+  add(points, intersection_triangle_segment_3d(q0, q1, q2, p0, p3));
+  add(points, intersection_triangle_segment_3d(q0, q1, q2, p1, p2));
+  add(points, intersection_triangle_segment_3d(q0, q1, q2, p1, p3));
+  add(points, intersection_triangle_segment_3d(q0, q1, q2, p2, p3));
+  add(points, intersection_triangle_segment_3d(q0, q1, q3, p0, p1));
+  add(points, intersection_triangle_segment_3d(q0, q1, q3, p0, p2));
+  add(points, intersection_triangle_segment_3d(q0, q1, q3, p0, p3));
+  add(points, intersection_triangle_segment_3d(q0, q1, q3, p1, p2));
+  add(points, intersection_triangle_segment_3d(q0, q1, q3, p1, p3));
+  add(points, intersection_triangle_segment_3d(q0, q1, q3, p2, p3));
+  add(points, intersection_triangle_segment_3d(q0, q2, q3, p0, p1));
+  add(points, intersection_triangle_segment_3d(q0, q2, q3, p0, p2));
+  add(points, intersection_triangle_segment_3d(q0, q2, q3, p0, p3));
+  add(points, intersection_triangle_segment_3d(q0, q2, q3, p1, p2));
+  add(points, intersection_triangle_segment_3d(q0, q2, q3, p1, p3));
+  add(points, intersection_triangle_segment_3d(q0, q2, q3, p2, p3));
+  add(points, intersection_triangle_segment_3d(q1, q2, q3, p0, p1));
+  add(points, intersection_triangle_segment_3d(q1, q2, q3, p0, p2));
+  add(points, intersection_triangle_segment_3d(q1, q2, q3, p0, p3));
+  add(points, intersection_triangle_segment_3d(q1, q2, q3, p1, p2));
+  add(points, intersection_triangle_segment_3d(q1, q2, q3, p1, p3));
+  add(points, intersection_triangle_segment_3d(q1, q2, q3, p2, p3));
+
+  dolfin_assert(GeometryPredicates::is_finite(points));
+  return unique(points);
+}
+//-----------------------------------------------------------------------------
+std::vector<Point>
+IntersectionConstruction::intersection_triangle_segment_3d(const Point& p0,
+							   const Point& p1,
+							   const Point& p2,
+							   const Point& q0,
+							   const Point& q1)
+{
+  return CGAL_INTERSECTION_CHECK(_intersection_triangle_segment_3d(p0, p1, p2, q0, q1),
+				 cgal_intersection_triangle_segment_3d(p0, p1, p2, q0, q1));
+}
+//-----------------------------------------------------------------------------
+std::vector<Point>
+IntersectionConstruction::intersection_tetrahedron_tetrahedron_3d(const Point& p0,
+								  const Point& p1,
+								  const Point& p2,
+								  const Point& p3,
+								  const Point& q0,
+								  const Point& q1,
+								  const Point& q2,
+								  const Point& q3)
+{
+  return CGAL_INTERSECTION_CHECK(_intersection_tetrahedron_tetrahedron_3d(p0, p1, p2, p3, q0, q1, q2, q3),
+				 cgal_intersection_tetrahedron_tetrahedron_3d(p0, p1, p2, p3, q0, q1, q2, q3));
+}
diff --git a/dolfin/geometry/IntersectionConstruction.h b/dolfin/geometry/IntersectionConstruction.h
new file mode 100644
index 0000000..8511a68
--- /dev/null
+++ b/dolfin/geometry/IntersectionConstruction.h
@@ -0,0 +1,292 @@
+// Copyright (C) 2014-2016 Anders Logg, August Johansson and Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN 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 Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// First added:  2014-02-03
+// Last changed: 2017-09-29
+
+#ifndef __INTERSECTION_CONSTRUCTION_H
+#define __INTERSECTION_CONSTRUCTION_H
+
+#include <vector>
+#include <dolfin/log/log.h>
+#include "Point.h"
+
+namespace dolfin
+{
+  // Forward declarations
+  class MeshEntity;
+
+  /// This class implements algorithms for computing pairwise
+  /// intersections of simplices. The computed intersection is always
+  /// convex and represented as a set of points s.t. the intersection
+  /// is the convex hull of these points.
+
+  class IntersectionConstruction
+  {
+  public:
+
+    /// Compute intersection of two entities.
+    ///
+    /// *Arguments*
+    ///     entity_0 (_MeshEntity_)
+    ///         The first entity.
+    ///     entity_1 (_MeshEntity_)
+    ///         The second entity.
+    ///
+    /// *Returns*
+    ///     std::vector<Pointdouble>
+    ///         A vector of points s.t. the intersection is the convex hull of
+    ///         these points.
+    static std::vector<Point>
+    intersection(const MeshEntity& entity_0,
+                 const MeshEntity& entity_1);
+
+    /// Compute intersection of two entities.
+    /// This version takes two vectors of points representing the entities.
+    ///
+    /// *Arguments*
+    ///     points_0 (std::vector<Point>)
+    ///         The vertex coordinates of the first entity.
+    ///     points_1 (std::vector<Point>)
+    ///         The vertex coordinates of the second entity.
+    ///     gdim (std::size_t)
+    ///         The geometric dimension.
+    ///
+    /// *Returns*
+    ///     std::vector<Point>
+    ///         A vector of points s.t. the intersection is the convex hull of
+    ///         these points.
+    static std::vector<Point>
+    intersection(const std::vector<Point>& points_0,
+                 const std::vector<Point>& points_1,
+                 std::size_t gdim);
+
+    //--- Low-level intersection construction functions ---
+
+    // There are 19 different intersections to consider. Initially, we have
+    // 4 different entities: point, segment, triangle, tetrahedron, and thus
+    // 16 combinations. Because of symmetry, these are reduced to 10. However,
+    // some of the combination are relevant in both 1D, 2D and 3D, and thus
+    // the total number of intersections lands at 19. The table indicates the
+    // number of versions (1D, 2D, 3D) for each relevant combination.
+    //
+    //     | 0  1  2  3
+    //   --------------
+    //   0 | 3  x  x  x  point-foo       (1D, 2D, 3D)
+    //   1 | 3  3  x  x  segment-foo     (1D, 2D, 3D)
+    //   2 | 2  2  2  x  triangle-foo    (--, 2D, 3D)
+    //   3 | 1  1  1  1  tetrahedron-foo (--, --, 3D)
+    //
+    // The intersection construction functions can be grouped into
+    // three classes:
+    //
+    // [P] Use point collision predicates (9)
+    // [C] Compute collision by solving for intersection points (3)
+    // [D] Delegate computation to [P] or [C] for subsimplices (7)
+    //
+    // [P] intersection_point_point_1d
+    // [P] intersection_point_point_2d
+    // [P] intersection_point_point_3d
+    // [P] intersection_segment_point_1d
+    // [P] intersection_segment_point_2d
+    // [P] intersection_segment_point_3d
+    // [P] intersection_triangle_point_2d
+    // [P] intersection_triangle_point_3d
+    // [P] intersection_tetrahedron_point_3d
+    // [D] intersection_segment_segment_1d
+    // [C] intersection_segment_segment_2d
+    // [C] intersection_segment_segment_3d           <-- not used/implemented
+    // [D] intersection_triangle_segment_2d
+    // [C] intersection_triangle_segment_3d          <-- needs review
+    // [D] intersection_tetrahedron_segment_3d
+    // [D] intersection_triangle_triangle_2d
+    // [D] intersection_triangle_triangle_3d
+    // [D] intersection_tetrahedron_triangle_3d
+    // [D] intersection_tetrahedron_tetrahedron_3d
+    //
+    // Note that intersection_segment_segment_3d is not used/implemented.
+    // In summary, this means that there are only two functions that require
+    // computation, other than simple checks for point collisions or delegation
+    // to lower-level intersection functions. These two functions are:
+    //
+    // [C] intersection_segment_segment_2d
+    // [C] intersection_triangle_segment_3d
+
+    /// Compute intersection of points p0 and q0 (1D)
+    static std::vector<double>
+    intersection_point_point_1d(double p0,
+                                double q0);
+
+    /// Compute intersection of points p0 and q0 (2D)
+    static std::vector<Point>
+    intersection_point_point_2d(const Point& p0,
+                                const Point& q0);
+
+    /// Compute intersection of points p0 and q0 (3D)
+    static std::vector<Point>
+    intersection_point_point_3d(const Point& p0,
+                                const Point& q0);
+
+    /// Compute intersection of segment p0-p1 with point q0 (1D)
+    static std::vector<double>
+    intersection_segment_point_1d(double p0,
+                                  double p1,
+                                  double q0);
+
+    /// Compute intersection of segment p0-p1 with point q0 (2D)
+    static std::vector<Point>
+    intersection_segment_point_2d(const Point& p0,
+                                  const Point& p1,
+                                  const Point& q0);
+
+    /// Compute intersection of segment p0-p1 with point q0 (3D)
+    static std::vector<Point>
+    intersection_segment_point_3d(const Point& p0,
+                                  const Point& p1,
+                                  const Point& q0);
+
+    /// Compute intersection of triangle p0-p1-p2 with point q0 (2D)
+    static std::vector<Point>
+    intersection_triangle_point_2d(const Point& p0,
+                                   const Point& p1,
+                                   const Point& p2,
+                                   const Point& q0);
+
+    /// Compute intersection of triangle p0-p1-p2 with point q0 (3D)
+    static std::vector<Point>
+    intersection_triangle_point_3d(const Point& p0,
+                                   const Point& p1,
+                                   const Point& p2,
+                                   const Point& q0);
+
+    /// Compute intersection of tetrahedron p0-p1-p2-p3 with point q0 (3D)
+    static std::vector<Point>
+    intersection_tetrahedron_point_3d(const Point& p0,
+                                      const Point& p1,
+                                      const Point& p2,
+                                      const Point& p3,
+                                      const Point& q0);
+
+    /// Compute intersection of segment p0-p1 with segment q0-q1 (1D)
+    static std::vector<double>
+    intersection_segment_segment_1d(double p0,
+                                    double p1,
+                                    double q0,
+                                    double q1);
+
+    /// Compute intersection of segment p0-p1 with segment q0-q1 (2D)
+    static std::vector<Point>
+    intersection_segment_segment_2d(const Point& p0,
+                                    const Point& p1,
+                                    const Point& q0,
+                                    const Point& q1);
+
+    /// Compute intersection of segment p0-p1 with segment q0-q1 (3D)
+    static std::vector<Point>
+    intersection_segment_segment_3d(const Point& p0,
+                                    const Point& p1,
+                                    const Point& q0,
+                                    const Point& q1);
+
+    /// Compute intersection of triangle p0-p1-p2 with segment q0-q1 (2D)
+    static std::vector<Point>
+    intersection_triangle_segment_2d(const Point& p0,
+                                     const Point& p1,
+                                     const Point& p2,
+                                     const Point& q0,
+                                     const Point& q1);
+
+    /// Compute intersection of triangle p0-p1-p2 with segment q0-q1 (3D)
+    static std::vector<Point>
+    intersection_triangle_segment_3d(const Point& p0,
+                                     const Point& p1,
+                                     const Point& p2,
+                                     const Point& q0,
+                                     const Point& q1);
+
+    /// Compute intersection of tetrahedron p0-p1-p2-p3 with segment q0-q1 (3D)
+    static std::vector<Point>
+    intersection_tetrahedron_segment_3d(const Point& p0,
+                                        const Point& p1,
+                                        const Point& p2,
+                                        const Point& p3,
+                                        const Point& q0,
+                                        const Point& q1);
+
+    /// Compute intersection of triangle p0-p1-p2 with triangle q0-q1-q2 (2D)
+    static std::vector<Point>
+    intersection_triangle_triangle_2d(const Point& p0,
+                                      const Point& p1,
+                                      const Point& p2,
+                                      const Point& q0,
+                                      const Point& q1,
+                                      const Point& q2);
+
+    /// Compute intersection of triangle p0-p1-p2 with triangle q0-q1-q2 (3D)
+    static std::vector<Point>
+    intersection_triangle_triangle_3d(const Point& p0,
+                                      const Point& p1,
+                                      const Point& p2,
+                                      const Point& q0,
+                                      const Point& q1,
+                                      const Point& q2);
+
+    /// Compute intersection of tetrahedron p0-p1-p2-p3 with triangle q0-q1-q2 (3D)
+    static std::vector<Point>
+    intersection_tetrahedron_triangle_3d(const Point& p0,
+                                         const Point& p1,
+                                         const Point& p2,
+                                         const Point& p3,
+                                         const Point& q0,
+                                         const Point& q1,
+                                         const Point& q2);
+
+    /// Compute intersection of tetrahedron p0-p1-p2-p3 with tetrahedron q0-q1-q2-q3 (3D)
+    static std::vector<Point>
+    intersection_tetrahedron_tetrahedron_3d(const Point& p0,
+                                            const Point& p1,
+                                            const Point& p2,
+                                            const Point& p3,
+                                            const Point& q0,
+                                            const Point& q1,
+                                            const Point& q2,
+                                            const Point& q3);
+
+  private :
+    /// Compute intersection of triangle p0-p1-p2 with segment q0-q1 (3D)
+    static std::vector<Point>
+    _intersection_triangle_segment_3d(const Point& p0,
+				      const Point& p1,
+				      const Point& p2,
+				      const Point& q0,
+				      const Point& q1);
+
+    static std::vector<Point>
+    _intersection_tetrahedron_tetrahedron_3d(const Point& p0,
+					     const Point& p1,
+					     const Point& p2,
+					     const Point& p3,
+					     const Point& q0,
+					     const Point& q1,
+					     const Point& q2,
+					     const Point& q3);
+
+  };
+
+}
+
+#endif
diff --git a/dolfin/geometry/IntersectionTriangulation.cpp b/dolfin/geometry/IntersectionTriangulation.cpp
deleted file mode 100644
index 9009865..0000000
--- a/dolfin/geometry/IntersectionTriangulation.cpp
+++ /dev/null
@@ -1,1365 +0,0 @@
-// Copyright (C) 2014 Anders Logg and August Johansson
-//
-// This file is part of DOLFIN.
-//
-// DOLFIN is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// DOLFIN 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 Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
-//
-// First added:  2014-02-03
-// Last changed: 2014-05-28
-
-#include <dolfin/mesh/MeshEntity.h>
-#include "IntersectionTriangulation.h"
-#include "CollisionDetection.h"
-
-using namespace dolfin;
-
-//-----------------------------------------------------------------------------
-std::vector<double>
-IntersectionTriangulation::triangulate_intersection(const MeshEntity& entity_0,
-						    const MeshEntity& entity_1)
-{
-  switch (entity_0.dim())
-  {
-  case 0:
-    // PointCell
-    dolfin_not_implemented();
-    break;
-  case 1:
-    // IntervalCell
-    dolfin_not_implemented();
-    break;
-  case 2:
-    // TriangleCell
-    switch (entity_1.dim())
-    {
-    case 0:
-      dolfin_not_implemented();
-      break;
-    case 1:
-      return triangulate_intersection_triangle_interval(entity_0, entity_1);
-    case 2:
-      return triangulate_intersection_triangle_triangle(entity_0, entity_1);
-    case 3:
-      return triangulate_intersection_tetrahedron_triangle(entity_1, entity_0);
-    default:
-      dolfin_error("IntersectionTriangulation.cpp",
-		   "triangulate intersection of entity_0 and entity_1",
-		   "unknown dimension of entity_1 in TriangleCell");
-    }
-  case 3:
-    // TetrahedronCell
-    switch (entity_1.dim())
-    {
-    case 0:
-      dolfin_not_implemented();
-      break;
-    case 1:
-      dolfin_not_implemented();
-      break;
-    case 2:
-      return triangulate_intersection_tetrahedron_triangle(entity_0, entity_1);
-    case 3:
-      return triangulate_intersection_tetrahedron_tetrahedron(entity_0, entity_1);
-    default:
-      dolfin_error("IntersectionTriangulation.cpp",
-		   "triangulate intersection of entity_0 and entity_1",
-		   "unknown dimension of entity_1 in TetrahedronCell");
-    }
-  default:
-    dolfin_error("IntersectionTriangulation.cpp",
-		 "triangulate intersection of entity_0 and entity_1",
-		 "unknown dimension of entity_0");
-  }
-  return std::vector<double>();
-}
-//-----------------------------------------------------------------------------
-std::vector<double>
-IntersectionTriangulation::triangulate_intersection_interval_interval
-(const MeshEntity& interval_0, const MeshEntity& interval_1)
-{
-  dolfin_assert(interval_0.mesh().topology().dim() == 1);
-  dolfin_assert(interval_1.mesh().topology().dim() == 1);
-
-  const std::size_t gdim = interval_0.mesh().geometry().dim();
-  dolfin_assert(interval_1.mesh().topology().dim() == gdim);
-
-  // Get geometry and vertex data
-  std::vector<Point> inter_0(2), inter_1(2);
-  for (std::size_t i = 0; i < 2; ++i)
-  {
-    inter_0[i] = interval_0.mesh().geometry().point(interval_0.entities(0)[i]);
-    inter_1[i] = interval_1.mesh().geometry().point(interval_1.entities(0)[i]);
-  }
-
-  return triangulate_intersection_interval_interval(inter_0, inter_1, gdim);
-}
-//-----------------------------------------------------------------------------
-std::vector<double>
-IntersectionTriangulation::triangulate_intersection_triangle_interval
-(const MeshEntity& triangle,
- const MeshEntity& interval)
-{
-  dolfin_assert(triangle.mesh().topology().dim() == 2);
-  dolfin_assert(interval.mesh().topology().dim() == 1);
-
-  const std::size_t gdim = triangle.mesh().geometry().dim();
-  dolfin_assert(interval.mesh().geometry().dim() == gdim);
-
-  // Get geometry and vertex data
-  std::vector<Point> tri(3);
-  for (std::size_t i = 0; i < 3; ++i)
-    tri[i] = triangle.mesh().geometry().point(triangle.entities(0)[i]);
-
-  std::vector<Point> inter(2);
-  for (std::size_t i = 0; i < 2; ++i)
-    inter[i] = interval.mesh().geometry().point(interval.entities(0)[i]);
-
-  return triangulate_intersection_triangle_interval(tri, inter, gdim);
-}
-//-----------------------------------------------------------------------------
-std::vector<double>
-IntersectionTriangulation::triangulate_intersection_triangle_triangle
-(const MeshEntity& c0, const MeshEntity& c1)
-{
-  // Triangulate the intersection of the two triangles c0 and c1
-
-  dolfin_assert(c0.mesh().topology().dim() == 2);
-  dolfin_assert(c1.mesh().topology().dim() == 2);
-
-  // FIXME: Only 2D for now
-  dolfin_assert(c0.mesh().geometry().dim() == 2);
-
-  // Get geometry and vertex data
-  const MeshGeometry& geometry_0 = c0.mesh().geometry();
-  const MeshGeometry& geometry_1 = c1.mesh().geometry();
-  const unsigned int* vertices_0 = c0.entities(0);
-  const unsigned int* vertices_1 = c1.entities(0);
-
-  std::vector<Point> tri_0(3), tri_1(3);
-
-  for (std::size_t i = 0; i < 3; ++i)
-  {
-    tri_0[i] = geometry_0.point(vertices_0[i]);
-    tri_1[i] = geometry_1.point(vertices_1[i]);
-  }
-
-  return triangulate_intersection_triangle_triangle(tri_0, tri_1);
-}
-//-----------------------------------------------------------------------------
-std::vector<double>
-IntersectionTriangulation::triangulate_intersection_tetrahedron_triangle
-(const MeshEntity& tetrahedron, const MeshEntity& triangle)
-{
-  // Triangulate the intersection of a tetrahedron and a triangle
-
-  dolfin_assert(tetrahedron.mesh().topology().dim() == 3);
-  dolfin_assert(triangle.mesh().topology().dim() == 2);
-
-  // Get geometry and vertex data
-  const MeshGeometry& tet_geom = tetrahedron.mesh().geometry();
-  const unsigned int* tet_vert = tetrahedron.entities(0);
-  std::vector<Point> tet(4);
-  for (std::size_t i = 0; i < 4; ++i)
-    tet[i] = tet_geom.point(tet_vert[i]);
-
-  const MeshGeometry& tri_geom = triangle.mesh().geometry();
-  const unsigned int* tri_vert = triangle.entities(0);
-  std::vector<Point> tri(3);
-  for (std::size_t i = 0; i < 3; ++i)
-    tri[i] = tri_geom.point(tri_vert[i]);
-
-  return triangulate_intersection_tetrahedron_triangle(tet, tri);
-}
-//-----------------------------------------------------------------------------
-std::vector<double>
-IntersectionTriangulation::triangulate_intersection_tetrahedron_tetrahedron
-(const MeshEntity& tetrahedron_0,
- const MeshEntity& tetrahedron_1)
-{
-  // Triangulate the intersection of the two tetrahedra
-
-  dolfin_assert(tetrahedron_0.mesh().topology().dim() == 3);
-  dolfin_assert(tetrahedron_1.mesh().topology().dim() == 3);
-
-  // Get the vertices as points
-  const MeshGeometry& geometry_0 = tetrahedron_0.mesh().geometry();
-  const unsigned int* vertices_0 = tetrahedron_0.entities(0);
-  const MeshGeometry& geometry_1 = tetrahedron_1.mesh().geometry();
-  const unsigned int* vertices_1 = tetrahedron_1.entities(0);
-
-  std::vector<Point> tet_0(4), tet_1(4);
-
-  for (std::size_t i = 0; i < 4; ++i)
-  {
-    tet_0[i] = geometry_0.point(vertices_0[i]);
-    tet_1[i] = geometry_1.point(vertices_1[i]);
-  }
-
-  return triangulate_intersection_tetrahedron_tetrahedron(tet_0, tet_1);
-}
-//-----------------------------------------------------------------------------
-std::vector<double>
-IntersectionTriangulation::triangulate_intersection(const std::vector<Point>& s0,
-                                                    std::size_t tdim0,
-                                                    const std::vector<Point>& s1,
-                                                    std::size_t tdim1,
-                                                    std::size_t gdim)
-{
-  // General intersection computation of two simplices with different
-  // topological dimension but the same geometrical dimension
-
-  switch (tdim0) {
-    // s0 is interval
-  case 1:
-    switch (tdim1) {
-    case 1: // s1 is interval
-      return triangulate_intersection_interval_interval(s0, s1, gdim);
-    case 2: // s1 is triangle
-      return triangulate_intersection_triangle_interval(s1, s0, gdim);
-    case 3: // s1 is tetrahedron
-      dolfin_not_implemented();
-      break;
-    default:
-      dolfin_error("IntersectionTriangulation.cpp",
-                   "triangulate intersection of two simplices s0 and s1",
-                   "unknown topology %d", tdim1);
-    }
-    break;
-    // s0 is a triangle
-  case 2:
-    switch (tdim1) {
-    case 1: // s1 is interval
-      return triangulate_intersection_triangle_interval(s0, s1, gdim);
-    case 2: // s1 is triangle
-      return triangulate_intersection_triangle_triangle(s0, s1);
-    case 3: // s1 is tetrahedron
-      return triangulate_intersection_tetrahedron_triangle(s1, s0);
-    default:
-      dolfin_error("IntersectionTriangulation.cpp",
-                   "triangulate intersection of two simplices s0 and s1",
-                   "unknown topology %d", tdim1);
-    }
-    break;
-    // s0 is a tetrahedron
-  case 3:
-    switch (tdim1) {
-    case 1: // s1 is interval
-      dolfin_not_implemented();
-      break;
-    case 2: // s1 is triangle
-      return triangulate_intersection_tetrahedron_triangle(s0, s1);
-    case 3: // s1 is tetrahedron
-      return triangulate_intersection_tetrahedron_tetrahedron(s0, s1);
-    default:
-      dolfin_error("IntersectionTriangulation.cpp",
-                   "triangulate intersection of two simplices s0 and s1",
-                   "unknown topology %d", tdim1);
-    }
-    break;
-  default:
-    dolfin_error("IntersectionTriangulation.cpp",
-                 "triangulate intersection of two simplices s0 and s1",
-                 "unknown topology %d", tdim0);
-  }
-
-  // We never end up here
-  return std::vector<double>();
-}
-//-----------------------------------------------------------------------------
-std::vector<double>
-IntersectionTriangulation::triangulate_intersection_interval_interval
-(const std::vector<Point>& interval_0,
- const std::vector<Point>& interval_1,
- std::size_t gdim)
-{
-  // Flat array for triangulation
-  std::vector<double> triangulation;
-
-  if (CollisionDetection::collides_edge_edge(interval_0[0], interval_0[1],
-                                             interval_1[0], interval_1[1]))
-  {
-    // List of colliding points
-    std::vector<Point> points;
-
-    for (std::size_t i = 0; i < 2; ++i)
-    {
-      if (CollisionDetection::collides_interval_point(interval_0[0], interval_0[1],
-                                                      interval_1[i]))
-        points.push_back(interval_1[i]);
-      if (CollisionDetection::collides_interval_point(interval_1[0], interval_1[1],
-                                                      interval_0[i]))
-        points.push_back(interval_0[i]);
-    }
-
-    // Must not have more than two points
-    if (points.size() == 2)
-    {
-      triangulation.resize(2*gdim);
-      for (std::size_t d = 0; d < gdim; ++d)
-      {
-        triangulation[d] = points[0][d];
-        triangulation[gdim+d] = points[1][d];
-      }
-    }
-  }
-
-  return triangulation;
-}
-//-----------------------------------------------------------------------------
-std::vector<double>
-IntersectionTriangulation::triangulate_intersection_triangle_interval
-(const std::vector<Point>& triangle,
- const std::vector<Point>& interval,
- std::size_t gdim)
-{
-  std::vector<double> triangulation;
-  std::vector<Point> points;
-
-  // Detect edge intersection points
-  Point pt;
-  if (intersection_edge_edge(triangle[0], triangle[1],
-                             interval[0], interval[1],
-                             pt))
-    points.push_back(pt);
-  if (intersection_edge_edge(triangle[0], triangle[2],
-                             interval[0], interval[1],
-                             pt))
-    points.push_back(pt);
-  if (intersection_edge_edge(triangle[1], triangle[2],
-                             interval[0], interval[1],
-                             pt))
-    points.push_back(pt);
-
-  // If we get zero intersection points, then both interval ends must
-  // be inside
-  // FIXME: can we really use two different types of intersection tests: intersection_edge_edge above and Collides here?
-  if (points.size() == 0)
-  {
-    if (CollisionDetection::collides_triangle_point(triangle[0],
-                                                    triangle[1],
-                                                    triangle[2],
-                                                    interval[0]) and
-        CollisionDetection::collides_triangle_point(triangle[0],
-                                                    triangle[1],
-                                                    triangle[2],
-                                                    interval[1]))
-    {
-      triangulation.resize(2*gdim);
-      for (std::size_t d = 0; d < gdim; ++d)
-      {
-        triangulation[d] = interval[0][d];
-        triangulation[gdim+d] = interval[1][d];
-      }
-      return triangulation;
-    }
-  }
-
-  // If we get one intersection point, find the interval end point
-  // which is inside the triangle. Note that this points should
-  // absolutely not be the same point as we found above. This can
-  // happen since we use different types of tests here and above.
-  if (points.size() == 1)
-  {
-    for (std::size_t k = 0; k < 2; ++k)
-    {
-      // Make sure the point interval[k] is not points[0]
-      if ((interval[k]-points[0]).norm() > DOLFIN_EPS_LARGE and
-	  CollisionDetection::collides_triangle_point(triangle[0],
-						      triangle[1],
-						      triangle[2],
-						      interval[k]))
-      {
-        triangulation.resize(2*gdim);
-        for (std::size_t d = 0; d < gdim; ++d)
-        {
-          triangulation[d] = points[0][d];
-          triangulation[gdim+d] = interval[k][d];
-        }
-        return triangulation;
-      }
-    }
-  }
-
-  // If we get two intersection points, triangulate this line.
-  if (points.size() == 2)
-  {
-    triangulation.resize(2*gdim);
-    for (std::size_t d = 0; d < gdim; ++d)
-    {
-      triangulation[d] = points[0][d];
-      triangulation[gdim+d] = points[1][d];
-    }
-    return triangulation;
-  }
-
-  return triangulation;
-}
-//-----------------------------------------------------------------------------
-std::vector<double>
-IntersectionTriangulation::triangulate_intersection_triangle_triangle
-(const std::vector<Point>& tri_0,
- const std::vector<Point>& tri_1)
-{
-  // This algorithm computes the (convex) polygon resulting from the
-  // intersection of two triangles. It then triangulates the polygon
-  // by trivially drawing an edge from one vertex to all other
-  // vertices. The polygon is computed by first identifying all
-  // vertex-cell collisions and then all edge-edge collisions. The
-  // points are then sorted using a simplified Graham scan (simplified
-  // since we know the polygon is convex).
-
-  // Tolerance for duplicate points (p and q are the same if
-  // (p-q).norm() < same_point_tol)
-  const double same_point_tol = DOLFIN_EPS_LARGE;
-
-
-  // Create empty list of collision points
-  std::vector<Point> points;
-
-  // Find all vertex-cell collisions
-  for (std::size_t i = 0; i < 3; i++)
-  {
-    // Note: this routine is changed to being public:
-    if (CollisionDetection::collides_triangle_point(tri_1[0],
-                                                    tri_1[1],
-                                                    tri_1[2],
-                                                    tri_0[i]))
-      points.push_back(tri_0[i]);
-
-    if (CollisionDetection::collides_triangle_point(tri_0[0],
-                                                    tri_0[1],
-                                                    tri_0[2],
-                                                    tri_1[i]))
-      points.push_back(tri_1[i]);
-  }
-
-  // Find all edge-edge collisions (not needed?)
-  for (std::size_t i0 = 0; i0 < 3; i0++)
-  {
-    const std::size_t j0 = (i0 + 1) % 3;
-    const Point p0 = tri_0[i0];
-    const Point q0 = tri_0[j0];
-    for (std::size_t i1 = 0; i1 < 3; i1++)
-    {
-      const std::size_t j1 = (i1 + 1) % 3;
-      const Point p1 = tri_1[i1];
-      const Point q1 = tri_1[j1];
-      Point point;
-      if (intersection_edge_edge(p0, q0, p1, q1, point))
-        points.push_back(point);
-    }
-  }
-
-  // Remove duplicate points
-  std::vector<Point> tmp;
-  tmp.reserve(points.size());
-
-  for (std::size_t i = 0; i < points.size(); ++i)
-  {
-    bool different = true;
-    for (std::size_t j = i+1; j < points.size(); ++j)
-      if ((points[i] - points[j]).norm() < same_point_tol)
-      {
-	different = false;
-	break;
-      }
-    if (different)
-      tmp.push_back(points[i]);
-  }
-  points = tmp;
-
-  // Special case: no points found
-  std::vector<double> triangulation;
-  if (points.size() < 3)
-    return triangulation;
-
-  // Find left-most point (smallest x-coordinate)
-  std::size_t i_min = 0;
-  double x_min = points[0].x();
-  for (std::size_t i = 1; i < points.size(); i++)
-  {
-    const double x = points[i].x();
-    if (x < x_min)
-    {
-      x_min = x;
-      i_min = i;
-    }
-  }
-
-  // Compute signed squared cos of angle with (0, 1) from i_min to all points
-  std::vector<std::pair<double, std::size_t>> order;
-  for (std::size_t i = 0; i < points.size(); i++)
-  {
-    // Skip left-most point used as origin
-    if (i == i_min)
-      continue;
-
-    // Compute vector to point
-    const Point v = points[i] - points[i_min];
-
-    // Compute square cos of angle
-    const double cos2 = (v.y() < 0.0 ? -1.0 : 1.0)*v.y()*v.y() / v.squared_norm();
-
-    // Store for sorting
-    order.push_back(std::make_pair(cos2, i));
-  }
-
-  // Sort points based on angle
-  std::sort(order.begin(), order.end());
-
-  // Triangulate polygon by connecting i_min with the ordered points
-  triangulation.reserve((points.size() - 2)*3*2);
-  const Point& p0 = points[i_min];
-  for (std::size_t i = 0; i < points.size() - 2; i++)
-  {
-    const Point& p1 = points[order[i].second];
-    const Point& p2 = points[order[i + 1].second];
-    triangulation.push_back(p0.x());
-    triangulation.push_back(p0.y());
-    triangulation.push_back(p1.x());
-    triangulation.push_back(p1.y());
-    triangulation.push_back(p2.x());
-    triangulation.push_back(p2.y());
-  }
-
-  return triangulation;
-}
-//-----------------------------------------------------------------------------
-std::vector<double>
-IntersectionTriangulation::triangulate_intersection_tetrahedron_tetrahedron
-(const std::vector<Point>& tet_0,
- const std::vector<Point>& tet_1)
-{
-  // This algorithm computes the intersection of cell_0 and cell_1 by
-  // returning a vector<double> with points describing a tetrahedral
-  // mesh of the intersection. We will use the fact that the
-  // intersection is a convex polyhedron. The algorithm works by first
-  // identifying intersection points: vertex points inside a cell,
-  // edge-face collision points and edge-edge collision points (the
-  // edge-edge is a rare occurance). Having the intersection points,
-  // we identify points that are coplanar and thus form a facet of the
-  // polyhedron. These points are then used to form a tessellation of
-  // triangles, which are used to form tetrahedra by the use of the
-  // center point of the polyhedron. This center point is thus an
-  // additional point not found on the polyhedron facets.
-
-  // Tolerance for coplanar points
-  const double coplanar_tol = 1000*DOLFIN_EPS_LARGE;
-
-  // Tolerance for the tetrahedron determinant (otherwise problems
-  // with warped tets)
-  const double tet_det_tol = DOLFIN_EPS_LARGE;
-
-  // Tolerance for duplicate points (p and q are the same if
-  // (p-q).norm() < same_point_tol)
-  const double same_point_tol = DOLFIN_EPS_LARGE;
-
-  // Tolerance for small triangle (could be improved by identifying
-  // sliver and small triangles)
-  const double tri_det_tol = DOLFIN_EPS_LARGE;
-
-  // Points in the triangulation (unique)
-  std::vector<Point> points;
-
-  // Node intersection
-  for (int i = 0; i<4; ++i)
-  {
-    if (CollisionDetection::collides_tetrahedron_point(tet_0[0],
-                                                       tet_0[1],
-                                                       tet_0[2],
-                                                       tet_0[3],
-                                                       tet_1[i]))
-      points.push_back(tet_1[i]);
-
-    if (CollisionDetection::collides_tetrahedron_point(tet_1[0],
-                                                       tet_1[1],
-                                                       tet_1[2],
-                                                       tet_1[3],
-                                                       tet_0[i]))
-      points.push_back(tet_0[i]);
-  }
-
-  // Edge face intersections
-  std::vector<std::vector<std::size_t>> edges_0(6, std::vector<std::size_t>(2));
-  edges_0[0][0] = 2;
-  edges_0[0][1] = 3;
-  edges_0[1][0] = 1;
-  edges_0[1][1] = 3;
-  edges_0[2][0] = 1;
-  edges_0[2][1] = 2;
-  edges_0[3][0] = 0;
-  edges_0[3][1] = 3;
-  edges_0[4][0] = 0;
-  edges_0[4][1] = 2;
-  edges_0[5][0] = 0;
-  edges_0[5][1] = 1;
-
-  std::vector<std::vector<std::size_t>> edges_1(6, std::vector<std::size_t>(2));
-  edges_1[0][0] = 2;
-  edges_1[0][1] = 3;
-  edges_1[1][0] = 1;
-  edges_1[1][1] = 3;
-  edges_1[2][0] = 1;
-  edges_1[2][1] = 2;
-  edges_1[3][0] = 0;
-  edges_1[3][1] = 3;
-  edges_1[4][0] = 0;
-  edges_1[4][1] = 2;
-  edges_1[5][0] = 0;
-  edges_1[5][1] = 1;
-
-  std::vector<std::vector<std::size_t>> faces_0(4, std::vector<std::size_t>(3));
-  faces_0[0][0] = 1;
-  faces_0[0][1] = 2;
-  faces_0[0][2] = 3;
-  faces_0[1][0] = 0;
-  faces_0[1][1] = 2;
-  faces_0[1][2] = 3;
-  faces_0[2][0] = 0;
-  faces_0[2][1] = 1;
-  faces_0[2][2] = 3;
-  faces_0[3][0] = 0;
-  faces_0[3][1] = 1;
-  faces_0[3][2] = 2;
-
-  std::vector<std::vector<std::size_t>> faces_1(4, std::vector<std::size_t>(3));
-  faces_1[0][0] = 1;
-  faces_1[0][1] = 2;
-  faces_1[0][2] = 3;
-  faces_1[1][0] = 0;
-  faces_1[1][1] = 2;
-  faces_1[1][2] = 3;
-  faces_1[2][0] = 0;
-  faces_1[2][1] = 1;
-  faces_1[2][2] = 3;
-  faces_1[3][0] = 0;
-  faces_1[3][1] = 1;
-  faces_1[3][2] = 2;
-
-  // Loop over edges e and faces f
-  for (std::size_t e = 0; e < 6; ++e)
-    for (std::size_t f = 0; f < 4; ++f)
-    {
-      Point pta;
-      if (intersection_face_edge(tet_0[faces_0[f][0]],
-				 tet_0[faces_0[f][1]],
-				 tet_0[faces_0[f][2]],
-				 tet_1[edges_1[e][0]],
-				 tet_1[edges_1[e][1]],
-				 pta))
-  	points.push_back(pta);
-
-      Point ptb;
-      if (intersection_face_edge(tet_1[faces_1[f][0]],
-				 tet_1[faces_1[f][1]],
-				 tet_1[faces_1[f][2]],
-				 tet_0[edges_0[e][0]],
-				 tet_0[edges_0[e][1]],
-				 ptb))
-  	points.push_back(ptb);
-    }
-
-  // Edge edge intersection
-  Point pt;
-  for (int i = 0; i < 6; ++i)
-    for (int j = 0; j < 6; ++j)
-    {
-      if (intersection_edge_edge(tet_0[edges_0[i][0]],
-				 tet_0[edges_0[i][1]],
-				 tet_1[edges_1[j][0]],
-				 tet_1[edges_1[j][1]],
-				 pt))
-  	points.push_back(pt);
-    }
-
-  // Remove duplicate nodes
-  std::vector<Point> tmp;
-  tmp.reserve(points.size());
-  for (std::size_t i = 0; i < points.size(); ++i)
-  {
-    bool different=true;
-    for (std::size_t j = i+1; j < points.size(); ++j)
-    {
-      if ((points[i] - points[j]).norm() < same_point_tol) {
-  	different = false;
-  	break;
-      }
-    }
-
-    if (different)
-      tmp.push_back(points[i]);
-  }
-  points = tmp;
-
-  // We didn't find sufficiently many points: can't form any
-  // tetrahedra.
-  if (points.size() < 4)
-    return std::vector<double>();
-
-  // Points forming the tetrahedral partitioning of the polyhedron. We
-  // have 4 points per tetrahedron in three dimensions => 12 doubles
-  // per tetrahedron.
-  std::vector<double> triangulation;
-
-  // Start forming a tessellation
-  if (points.size() == 4)
-  {
-    // Include if determinant is sufficiently large. The determinant
-    // can possibly be computed in a more stable way if needed.
-    const double det = (points[3] - points[0]).dot
-      ((points[1] - points[0]).cross(points[2] - points[0]));
-
-    if (std::abs(det) > tet_det_tol)
-    {
-      if (det < -tet_det_tol)
-        std::swap(points[0], points[1]);
-
-      // One tet with four vertices in 3D gives 12 doubles
-      triangulation.resize(12);
-      for (std::size_t m = 0, idx = 0; m < 4; ++m)
-  	for (std::size_t d = 0; d < 3; ++d, ++idx)
-  	  triangulation[idx] = points[m][d];
-    }
-    // Note: this can be empty if the tetrahedron was not sufficiently
-    // large
-    return triangulation;
-  }
-
-  // Tetrahedra are created using the facet points and a center point.
-  Point polyhedroncenter = points[0];
-  for (std::size_t i = 1; i < points.size(); ++i)
-    polyhedroncenter += points[i];
-  polyhedroncenter /= points.size();
-
-  // Data structure for storing checked triangle indices (do this
-  // better with some fancy stl structure?)
-  const std::size_t N = points.size(), N2 = points.size()*points.size();
-  std::vector<bool> checked(N*N2 + N2 + N, false);
-
-  // Find coplanar points
-  for (std::size_t i = 0; i < N; ++i)
-    for (std::size_t j = i+1; j < N; ++j)
-      for (std::size_t k = 0; k < N; ++k)
-  	if (!checked[i*N2 + j*N + k] and k != i and k != j)
-  	{
-  	  // Check that triangle area is sufficiently large
-  	  Point n = (points[j] - points[i]).cross(points[k] - points[i]);
-  	  const double tridet = n.norm();
-  	  if (tridet < tri_det_tol)
-            break;
-
-  	  // Normalize normal
-  	  n /= tridet;
-
-  	  // Compute triangle center
-  	  const Point tricenter = (points[i] + points[j] + points[k]) / 3.;
-
-  	  // Check whether all other points are on one side of thus
-  	  // facet. Initialize as true for the case of only three
-  	  // coplanar points.
-  	  bool on_convex_hull = true;
-
-  	  // Compute dot products to check which side of the plane
-  	  // (i,j,k) we're on. Note: it seems to be better to compute
-  	  // n.dot(points[m]-n.dot(tricenter) rather than
-  	  // n.dot(points[m]-tricenter).
-  	  std::vector<double> ip(N, -(n.dot(tricenter)));
-  	  for (std::size_t m = 0; m < N; ++m)
-  	    ip[m] += n.dot(points[m]);
-
-  	  // Check inner products range by finding max & min (this
-  	  // seemed possibly more numerically stable than checking all
-  	  // vs all and then break).
-  	  double minip = 9e99, maxip = -9e99;
-  	  for (size_t m = 0; m < N; ++m)
-  	    if (m != i and m != j and m != k)
-  	    {
-  	      minip = (minip > ip[m]) ? ip[m] : minip;
-  	      maxip = (maxip < ip[m]) ? ip[m] : maxip;
-  	    }
-
-  	  // Different sign => triangle is not on the convex hull
-  	  if (minip*maxip < -DOLFIN_EPS)
-  	    on_convex_hull = false;
-
-  	  if (on_convex_hull)
-  	  {
-  	    // Find all coplanar points on this facet given the
-  	    // tolerance coplanar_tol
-  	    std::vector<std::size_t> coplanar;
-  	    for (std::size_t m = 0; m < N; ++m)
-  	      if (std::abs(ip[m]) < coplanar_tol)
-  		coplanar.push_back(m);
-
-  	    // Mark this plane (how to do this better?)
-  	    for (std::size_t m = 0; m < coplanar.size(); ++m)
-  	      for (std::size_t n = m+1; n < coplanar.size(); ++n)
-  		for (std::size_t o = n+1; o < coplanar.size(); ++o)
-  		  checked[coplanar[m]*N2 + coplanar[n]*N + coplanar[o]]
-                    = checked[coplanar[m]*N2 + coplanar[o]*N + coplanar[n]]
-  		    = checked[coplanar[n]*N2 + coplanar[m]*N + coplanar[o]]
-  		    = checked[coplanar[n]*N2 + coplanar[o]*N + coplanar[m]]
-  		    = checked[coplanar[o]*N2 + coplanar[n]*N + coplanar[m]]
-  		    = checked[coplanar[o]*N2 + coplanar[m]*N + coplanar[n]]
-                    = true;
-
-  	    // Do the actual tessellation using the coplanar points and
-  	    // a center point
-  	    if (coplanar.size() == 3)
-  	    {
-  	      // Form one tetrahedron
-  	      std::vector<Point> cand(4);
-  	      cand[0] = points[coplanar[0]];
-  	      cand[1] = points[coplanar[1]];
-  	      cand[2] = points[coplanar[2]];
-  	      cand[3] = polyhedroncenter;
-
-  	      // Include if determinant is sufficiently large
-  	      const double det = (cand[3]-cand[0]).dot
-                ((cand[1] - cand[0]).cross(cand[2] - cand[0]));
-  	      if (std::abs(det) > tet_det_tol)
-  	      {
-  		if (det < -tet_det_tol)
-  		  std::swap(cand[0], cand[1]);
-
-  		for (std::size_t m = 0; m < 4; ++m)
-  		  for (std::size_t d = 0; d < 3; ++d)
-  		    triangulation.push_back(cand[m][d]);
-  	      }
-
-  	    }
-  	    else if (coplanar.size() > 3)
-  	    {
-  	      // Tessellate as in the triangle-triangle intersection
-  	      // case: First sort points using a Graham scan, then
-  	      // connect to form triangles. Finally form tetrahedra
-  	      // using the center of the polyhedron.
-
-  	      // Use the center of the coplanar points and point no 0
-  	      // as reference for the angle calculation
-  	      Point pointscenter = points[coplanar[0]];
-  	      for (std::size_t m = 1; m < coplanar.size(); ++m)
-  		pointscenter += points[coplanar[m]];
-  	      pointscenter /= coplanar.size();
-
-  	      std::vector<std::pair<double, std::size_t>> order;
-  	      Point ref = points[coplanar[0]] - pointscenter;
-  	      ref /= ref.norm();
-
-  	      // Calculate and store angles
-  	      for (std::size_t m = 1; m < coplanar.size(); ++m)
-  	      {
-  		const Point v = points[coplanar[m]] - pointscenter;
-  		const double frac = ref.dot(v) / v.norm();
-  		double alpha;
-  		if (frac <= -1)
-                  alpha=DOLFIN_PI;
-  		else if (frac>=1)
-                  alpha=0;
-  		else
-                {
-  		  alpha = acos(frac);
-  		  if (v.dot(n.cross(ref)) < 0)
-                    alpha = 2*DOLFIN_PI-alpha;
-  		}
-  		order.push_back(std::make_pair(alpha, m));
-  	      }
-
-  	      // Sort angles
-  	      std::sort(order.begin(), order.end());
-
-  	      // Tessellate
-  	      for (std::size_t m = 0; m < coplanar.size()-2; ++m)
-  	      {
-  		// Candidate tetrahedron:
-  		std::vector<Point> cand(4);
-  		cand[0] = points[coplanar[0]];
-  		cand[1] = points[coplanar[order[m].second]];
-  		cand[2] = points[coplanar[order[m + 1].second]];
-  		cand[3] = polyhedroncenter;
-
-  		// Include tetrahedron if determinant is "large"
-  		const double det = (cand[3] - cand[0]).dot
-                  ((cand[1] - cand[0]).cross(cand[2] - cand[0]));
-  		if (std::abs(det) > tet_det_tol)
-  		{
-  		  if (det < -tet_det_tol)
-  		    std::swap(cand[0], cand[1]);
-  		  for (std::size_t n = 0; n < 4; ++n)
-  		    for (std::size_t d = 0; d < 3; ++d)
-  		      triangulation.push_back(cand[n][d]);
-  		}
-  	      }
-  	    }
-  	  }
-  	}
-
-
-  return triangulation;
-
-
-}
-//-----------------------------------------------------------------------------
-std::vector<double>
-IntersectionTriangulation::triangulate_intersection_tetrahedron_triangle
-(const std::vector<Point>& tet,
- const std::vector<Point>& tri)
-{
-  // This code mimics the
-  // triangulate_intersection_tetrahedron_tetrahedron and the
-  // triangulate_intersection_tetrahedron_tetrahedron_triangle_codes:
-  // we first identify triangle nodes in the tetrahedra. Them we
-  // continue with edge-face detection for the four faces of the
-  // tetrahedron and the triangle. The points found are used to form a
-  // triangulation by first sorting them using a Graham scan.
-
-  // Tolerance for duplicate points (p and q are the same if
-  // (p-q).norm() < same_point_tol)
-  const double same_point_tol = DOLFIN_EPS_LARGE;
-
-  // Tolerance for small triangle (could be improved by identifying
-  // sliver and small triangles)
-  const double tri_det_tol = DOLFIN_EPS_LARGE;
-
-  std::vector<Point> points;
-
-  // Triangle node in tetrahedron intersection
-  for (std::size_t i = 0; i < 3; ++i)
-    if (CollisionDetection::collides_tetrahedron_point(tet[0],
-                                                       tet[1],
-                                                       tet[2],
-                                                       tet[3],
-                                                       tri[i]))
-    points.push_back(tri[i]);
-
-  // Check if a tetrahedron edge intersects the triangle
-  std::vector<std::vector<int>> tet_edges(6, std::vector<int>(2));
-  tet_edges[0][0] = 2;
-  tet_edges[0][1] = 3;
-  tet_edges[1][0] = 1;
-  tet_edges[1][1] = 3;
-  tet_edges[2][0] = 1;
-  tet_edges[2][1] = 2;
-  tet_edges[3][0] = 0;
-  tet_edges[3][1] = 3;
-  tet_edges[4][0] = 0;
-  tet_edges[4][1] = 2;
-  tet_edges[5][0] = 0;
-  tet_edges[5][1] = 1;
-
-  Point pt;
-  for (std::size_t e = 0; e < 6; ++e)
-    if (intersection_face_edge(tri[0], tri[1], tri[2],
-			       tet[tet_edges[e][0]],
-			       tet[tet_edges[e][1]],
-			       pt))
-      points.push_back(pt);
-
-  // Check if a triangle edge intersects a tetrahedron face
-  std::vector<std::vector<std::size_t>>
-    tet_faces(4, std::vector<std::size_t>(3));
-
-  tet_faces[0][0] = 1;
-  tet_faces[0][1] = 2;
-  tet_faces[0][2] = 3;
-  tet_faces[1][0] = 0;
-  tet_faces[1][1] = 2;
-  tet_faces[1][2] = 3;
-  tet_faces[2][0] = 0;
-  tet_faces[2][1] = 1;
-  tet_faces[2][2] = 3;
-  tet_faces[3][0] = 0;
-  tet_faces[3][1] = 1;
-  tet_faces[3][2] = 2;
-
-  for (std::size_t f = 0; f < 4; ++f)
-  {
-    if (intersection_face_edge(tet[tet_faces[f][0]],
-			       tet[tet_faces[f][1]],
-			       tet[tet_faces[f][2]],
-			       tri[0], tri[1],
-                               pt))
-      points.push_back(pt);
-    if (intersection_face_edge(tet[tet_faces[f][0]],
-			       tet[tet_faces[f][1]],
-			       tet[tet_faces[f][2]],
-			       tri[0], tri[2],
-                               pt))
-      points.push_back(pt);
-    if (intersection_face_edge(tet[tet_faces[f][0]],
-			       tet[tet_faces[f][1]],
-			       tet[tet_faces[f][2]],
-			       tri[1], tri[2],
-                               pt))
-      points.push_back(pt);
-  }
-
-
-  // edge edge intersection
-  for (std::size_t f = 0; f < 6; ++f)
-  {
-    if (intersection_edge_edge(tet[tet_edges[f][0]],
-			       tet[tet_edges[f][1]],
-			       tri[0], tri[1],
-			       pt))
-      points.push_back(pt);
-    if (intersection_edge_edge(tet[tet_edges[f][0]],
-			       tet[tet_edges[f][1]],
-			       tri[0], tri[2],
-			       pt))
-      points.push_back(pt);
-    if (intersection_edge_edge(tet[tet_edges[f][0]],
-			       tet[tet_edges[f][1]],
-			       tri[1], tri[2],
-			       pt))
-      points.push_back(pt);
-  }
-
-
-
-  // Remove duplicate nodes
-  std::vector<Point> tmp;
-  tmp.reserve(points.size());
-
-  for (std::size_t i = 0; i < points.size(); ++i)
-  {
-    bool different = true;
-    for (std::size_t j = i+1; j < points.size(); ++j)
-      if ((points[i] - points[j]).norm() < same_point_tol)
-      {
-	different = false;
-	break;
-      }
-    if (different)
-      tmp.push_back(points[i]);
-  }
-  points = tmp;
-
-  // We didn't find sufficiently many points
-  if (points.size() < 3)
-    return std::vector<double>();
-
-  std::vector<double> triangulation;
-
-  Point n = (points[2] - points[0]).cross(points[1] - points[0]);
-  const double det = n.norm();
-  n /= det;
-
-  if (points.size() == 3) {
-    // Include if determinant is sufficiently large
-    if (det > tri_det_tol)
-    {
-      // One triangle with three vertices in 3D gives 9 doubles
-      triangulation.resize(9);
-      for (std::size_t m = 0, idx = 0; m < 3; ++m)
-	for (std::size_t d = 0; d < 3; ++d, ++idx)
-	  triangulation[idx] = points[m][d];
-    }
-    return triangulation;
-  }
-
-  // Tessellate as in the triangle-triangle intersection case: First
-  // sort points using a Graham scan, then connect to form triangles.
-
-  // Use the center of the points and point no 0 as reference for the
-  // angle calculation
-  Point pointscenter = points[0];
-  for (std::size_t m = 1; m < points.size(); ++m)
-    pointscenter += points[m];
-  pointscenter /= points.size();
-
-  std::vector<std::pair<double, std::size_t>> order;
-  Point ref = points[0]-pointscenter;
-  ref /= ref.norm();
-
-  // Calculate and store angles
-  for (std::size_t m = 1; m < points.size(); ++m)
-  {
-    const Point v = points[m] - pointscenter;
-    const double frac = ref.dot(v) / v.norm();
-    double alpha;
-    if (frac <= -1)
-      alpha = DOLFIN_PI;
-    else if (frac >= 1)
-      alpha = 0;
-    else
-    {
-      alpha = acos(frac);
-      if (v.dot(n.cross(ref)) < 0)
-        alpha = 2*DOLFIN_PI-alpha;
-    }
-    order.push_back(std::make_pair(alpha, m));
-  }
-
-  // Sort angles
-  std::sort(order.begin(), order.end());
-
-  // Tessellate
-  std::vector<Point> cand(3);
-  for (std::size_t m = 0; m < order.size()-1; ++m)
-  {
-    // Candidate triangle
-    cand[0] = points[0];
-    cand[1] = points[order[m].second];
-    cand[2] = points[order[m + 1].second];
-
-    // Include triangle if determinant is sufficiently large
-    const double det = ((cand[2] - cand[1]).cross(cand[1] - cand[0])).norm();
-    if (det > tri_det_tol)
-    {
-      for (std::size_t n = 0; n < 3; ++n)
-	for (std::size_t d = 0; d < 3; ++d)
-	  triangulation.push_back(cand[n][d]);
-    }
-  }
-
-  return triangulation;
-}
-//-----------------------------------------------------------------------------
-std::vector<double>
-IntersectionTriangulation::triangulate_intersection
-(const MeshEntity &cell,
- const std::vector<double> &triangulation,
- std::size_t tri_tdim)
-{
-  // Compute the triangulation of the intersection of the cell and the
-  // simplices of the flat triangulation vector with topology tdim.
-
-  std::vector<double> total_triangulation;
-
-  // Get dimensions (geometrical dimension assumed to be the same)
-  const std::size_t cell_tdim = cell.mesh().topology().dim();
-  const std::size_t gdim = cell.mesh().geometry().dim();
-
-  // Store cell as std::vector<Point>
-  // FIXME: Store as Point& ?
-  std::vector<Point> simplex_cell(cell_tdim+1);
-  const MeshGeometry& geometry = cell.mesh().geometry();
-  const unsigned int* vertices = cell.entities(0);
-  for (std::size_t j = 0; j < cell_tdim+1; ++j)
-    simplex_cell[j] = geometry.point(vertices[j]);
-
-  // Simplex in triangulation
-  std::vector<Point> simplex(tri_tdim+1);
-  const std::size_t offset = (tri_tdim+1)*gdim;
-
-  // Loop over all simplices
-  for (std::size_t i = 0; i < triangulation.size()/offset; ++i)
-  {
-    // Store simplices as std::vector<Point>
-    for (std::size_t j = 0; j < tri_tdim+1; ++j)
-      for (std::size_t d = 0; d < gdim; ++d)
-        simplex[j][d] = triangulation[offset*i+gdim*j+d];
-
-    // Compute intersection
-    std::vector<double> local_triangulation
-      = triangulate_intersection(simplex_cell, cell_tdim,
-                                 simplex, tri_tdim,
-                                 gdim);
-
-    // Add these to the net triangulation
-    total_triangulation.insert(total_triangulation.end(),
-                               local_triangulation.begin(),
-                               local_triangulation.end());
-  }
-
-  return total_triangulation;
-}
-//-----------------------------------------------------------------------------
-void
-IntersectionTriangulation::triangulate_intersection
-(const MeshEntity &cell,
- const std::vector<double> &triangulation,
- const std::vector<Point>& normals,
- std::vector<double>& intersection_triangulation,
- std::vector<Point>& intersection_normals,
- std::size_t tri_tdim)
-{
-  // Compute the triangulation of the intersection of the cell and the
-  // simplices of the flat triangulation vector with topology tdim.
-
-  // FIXME: clear or not?
-  // intersection_triangulation.clear();
-  // intersection_normals.clear();
-
-  // Get dimensions (geometrical dimension assumed to be the same)
-  const std::size_t cell_tdim = cell.mesh().topology().dim();
-  const std::size_t gdim = cell.mesh().geometry().dim();
-
-  // Store cell as std::vector<Point>
-  // FIXME: Store as Point& ?
-  std::vector<Point> simplex_cell(cell_tdim+1);
-  const MeshGeometry& geometry = cell.mesh().geometry();
-  const unsigned int* vertices = cell.entities(0);
-  for (std::size_t j = 0; j < cell_tdim+1; ++j)
-    simplex_cell[j] = geometry.point(vertices[j]);
-
-  // Simplex in triangulation
-  std::vector<Point> simplex(tri_tdim+1);
-  const std::size_t offset = (tri_tdim+1)*gdim;
-
-  // Loop over all simplices
-  for (std::size_t i = 0; i < triangulation.size()/offset; ++i)
-  {
-    // Store simplices as std::vector<Point>
-    for (std::size_t j = 0; j < tri_tdim+1; ++j)
-      for (std::size_t d = 0; d < gdim; ++d)
-        simplex[j][d] = triangulation[offset*i+gdim*j+d];
-
-    // Compute intersection
-    std::vector<double> local_triangulation
-      = triangulate_intersection(simplex_cell, cell_tdim,
-                                 simplex, tri_tdim,
-                                 gdim);
-
-    // Add these to the net triangulation
-    intersection_triangulation.insert(intersection_triangulation.end(),
-                                      local_triangulation.begin(),
-                                      local_triangulation.end());
-
-    // Add the normal
-    intersection_normals.resize(intersection_normals.size() + local_triangulation.size()/offset,
-                                normals[i]);
-  }
-
-}
-//-----------------------------------------------------------------------------
-bool
-IntersectionTriangulation::intersection_edge_edge(const Point& a,
-						  const Point& b,
-						  const Point& c,
-						  const Point& d,
-						  Point& pt)
-{
-  // Check if two edges are the same
-  const double same_point_tol = DOLFIN_EPS_LARGE;
-  if ((a - c).norm() < same_point_tol and
-      (b - d).norm() < same_point_tol)
-    return false;
-  if ((a - d).norm() < same_point_tol and
-      (b - c).norm() < same_point_tol)
-    return false;
-
-  // Tolerance for orthogonality
-  const double orth_tol = DOLFIN_EPS_LARGE;
-
-  // Tolerance for coplanarity
-  const double coplanar_tol = DOLFIN_EPS_LARGE;
-
-  const Point L1 = b - a;
-  const Point L2 = d - c;
-  const Point ca = c - a;
-  const Point n = L1.cross(L2);
-
-  // Check if L1 and L2 are coplanar (what if they're overlapping?)
-  if (std::abs(ca.dot(n)) > coplanar_tol)
-    return false;
-
-  // Find orthogonal plane with normal n1
-  const Point n1 = n.cross(L1);
-  const double n1dotL2 = n1.dot(L2);
-
-  // If we have orthogonality
-  if (std::abs(n1dotL2) > orth_tol)
-  {
-    const double t = n1.dot(a - c) / n1dotL2;
-
-    // Find orthogonal plane with normal n2
-    const Point n2 = n.cross(L2);
-    const double n2dotL1 = n2.dot(L1);
-    if (t >= 0 and
-        t <= 1 and
-        std::abs(n2dotL1) > orth_tol)
-    {
-      const double s = n2.dot(c - a) / n2dotL1;
-      if (s >= 0 and
-          s <= 1)
-      {
-	pt = a + s*L1;
-	return true;
-      }
-    }
-  }
-
-  return false;
-}
-//-----------------------------------------------------------------------------
-bool
-IntersectionTriangulation::intersection_face_edge(const Point& r,
-						  const Point& s,
-						  const Point& t,
-						  const Point& a,
-						  const Point& b,
-						  Point& pt)
-{
-  // This standard edge face intersection test is as follows:
-  // - Check if end points of the edge (a,b) on opposite side of plane
-  // given by the face (r,s,t)
-  // - If we have sign change, compute intersection with plane.
-  // - Check if computed point is on triangle given by face.
-
-  // If the edge and the face are in the same plane, we return false
-  // and leave this to the edge-edge intersection test.
-
-  // Tolerance for edge and face in plane (topologically 2D problem)
-  const double top_2d_tol = DOLFIN_EPS_LARGE;
-
-  // Compute normal
-  const Point rs = s - r;
-  const Point rt = t - r;
-  Point n = rs.cross(rt);
-  n /= n.norm();
-
-  // Check sign change (note that if either dot product is zero it's
-  // orthogonal)
-  const double da = n.dot(a - r);
-  const double db = n.dot(b - r);
-
-  // Note: if da and db we may have edge intersection (detected in
-  // other routine)
-  if (da*db > 0)
-    return false;
-
-  // Face and edge are in topological 2d: taken care of in edge-edge
-  // intersection or point in simplex.
-  const double sum = std::abs(da) + std::abs(db);
-  if (sum < top_2d_tol)
-    return false;
-
-  // Calculate intersection
-  pt = a + std::abs(da) / sum * (b - a);
-
-  // Check if point is in triangle by calculating and checking
-  // barycentric coords.
-  const double d00 = rs.squared_norm();
-  const double d01 = rs.dot(rt);
-  const double d11 = rt.squared_norm();
-  const Point e2 = pt-r;
-  const double d20 = e2.dot(rs);
-  const double d21 = e2.dot(rt);
-  const double invdet = 1. / (d00*d11 - d01*d01);
-  const double v = (d11*d20 - d01*d21)*invdet;
-  if (v < 0.)
-    return false;
-
-  const double w = (d00*d21 - d01*d20)*invdet;
-  if (w < 0.)
-    return false;
-
-  if (v+w > 1.)
-    return false;
-
-  return true;
-}
-//-----------------------------------------------------------------------------
diff --git a/dolfin/geometry/IntersectionTriangulation.h b/dolfin/geometry/IntersectionTriangulation.h
deleted file mode 100644
index c76c03f..0000000
--- a/dolfin/geometry/IntersectionTriangulation.h
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright (C) 2014 Anders Logg and August Johansson
-//
-// This file is part of DOLFIN.
-//
-// DOLFIN is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// DOLFIN 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 Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
-//
-// First added:  2014-02-03
-// Last changed: 2014-05-28
-
-#include <vector>
-#include <dolfin/log/log.h>
-
-#ifndef __INTERSECTION_TRIANGULATION_H
-#define __INTERSECTION_TRIANGULATION_H
-
-namespace dolfin
-{
-
-  // Forward declarations
-  class MeshEntity;
-
-  /// This class implements algorithms for computing triangulations of
-  /// pairwise intersections of simplices.
-
-  class IntersectionTriangulation
-  {
-  public:
-
-    /// Compute triangulation of intersection of two entities
-    ///
-    /// @param    entity_0 (_MeshEntity_)
-    ///         The first entity.
-    /// @param    entity_1 (_MeshEntity_)
-    ///         The second entity.
-    ///
-    /// @return    std::vector<double>
-    ///         A flattened array of simplices of dimension
-    ///         num_simplices x num_vertices x gdim =
-    ///         num_simplices x (tdim + 1) x gdim
-    static std::vector<double>
-    triangulate_intersection(const MeshEntity& entity_0,
-                             const MeshEntity& entity_1);
-
-    /// Compute triangulation of intersection of two intervals
-    ///
-    /// @param    interval_0 (_MeshEntity_)
-    ///         The first interval.
-    /// @param    interval_1 (_MeshEntity_)
-    ///         The second interval.
-    ///
-    /// @return    std::vector<double>
-    ///         A flattened array of simplices of dimension
-    ///         num_simplices x num_vertices x gdim =
-    ///         num_simplices x (tdim + 1) x gdim
-    static std::vector<double>
-    triangulate_intersection_interval_interval(const MeshEntity& interval_0,
-                                               const MeshEntity& interval_1);
-
-    /// Compute triangulation of intersection of a triangle and an interval
-    ///
-    /// @param    triangle (_MeshEntity_)
-    ///         The triangle.
-    /// @param    interval (_MeshEntity_)
-    ///         The interval.
-    ///
-    /// @return    std::vector<double>
-    ///         A flattened array of simplices of dimension
-    ///         num_simplices x num_vertices x gdim =
-    ///         num_simplices x (tdim + 1) x gdim
-    static std::vector<double>
-    triangulate_intersection_triangle_interval(const MeshEntity& triangle,
-                                               const MeshEntity& interval);
-
-    /// Compute triangulation of intersection of two triangles
-    ///
-    /// @param   triangle_0 (_MeshEntity_)
-    ///         The first triangle.
-    /// @param   triangle_1 (_MeshEntity_)
-    ///         The second triangle.
-    ///
-    /// @return    std::vector<double>
-    ///         A flattened array of simplices of dimension
-    ///         num_simplices x num_vertices x gdim =
-    ///         num_simplices x (tdim + 1) x gdim
-    static std::vector<double>
-    triangulate_intersection_triangle_triangle(const MeshEntity& triangle_0,
-                                               const MeshEntity& triangle_1);
-
-    /// Compute triangulation of intersection of a tetrahedron and a triangle
-    ///
-    /// @param    tetrahedron (_MeshEntity_)
-    ///         The tetrahedron.
-    /// @param   triangle (_MeshEntity_)
-    ///         The triangle
-    ///
-    /// @return    std::vector<double>
-    ///         A flattened array of simplices of dimension
-    ///         num_simplices x num_vertices x gdim =
-    ///         num_simplices x (tdim + 1) x gdim
-    static std::vector<double>
-    triangulate_intersection_tetrahedron_triangle(const MeshEntity& tetrahedron,
-                                                  const MeshEntity& triangle);
-
-    /// Compute triangulation of intersection of two tetrahedra
-    ///
-    /// @param    tetrahedron_0 (_MeshEntity_)
-    ///         The first tetrahedron.
-    /// @param    tetrahedron_1 (_MeshEntity_)
-    ///         The second tetrahedron.
-    ///
-    /// @return    std::vector<double>
-    ///         A flattened array of simplices of dimension
-    ///         num_simplices x num_vertices x gdim =
-    ///         num_simplices x (tdim + 1) x gdim
-    static std::vector<double>
-    triangulate_intersection_tetrahedron_tetrahedron(const MeshEntity& tetrahedron_0,
-                                                     const MeshEntity& tetrahedron_1);
-
-    /// Function for general intersection computation of two simplices
-    /// with different topological dimension but the same geometrical
-    /// dimension
-    static std::vector<double>
-    triangulate_intersection(const std::vector<Point>& s0,
-                             std::size_t tdim0,
-                             const std::vector<Point>& s1,
-                             std::size_t tdim1,
-                             std::size_t gdim);
-
-    /// Function for computing the intersection of a cell with a flat
-    /// vector of simplices with topological dimension tdim. The
-    /// geometrical dimension is assumed to be the same as for the
-    /// cell.
-    static std::vector<double>
-    triangulate_intersection(const MeshEntity& cell,
-                             const std::vector<double> &triangulation,
-                             std::size_t tdim);
-
-    /// Function for computing the intersection of a cell with a flat
-    /// vector of simplices with topological dimension tdim. The
-    /// geometrical dimension is assumed to be the same as for the
-    /// cell. The corresponding normals are also saved.
-    static void
-    triangulate_intersection(const MeshEntity& cell,
-                             const std::vector<double>& triangulation,
-                             const std::vector<Point>& normals,
-                             std::vector<double>& intersection_triangulation,
-                             std::vector<Point>& intersection_normals,
-                             std::size_t tdim);
-
-  private:
-
-    // Function for computing the intersection of two triangles given
-    // by std::vector<Point>.
-    static std::vector<double>
-    triangulate_intersection_interval_interval(const std::vector<Point>& interval_0,
-                                               const std::vector<Point>& interval_1,
-                                               std::size_t gdim);
-
-    // Function for computing the intersection of a triangle and an interval
-    // by std::vector<Point>.
-    static std::vector<double>
-    triangulate_intersection_triangle_interval(const std::vector<Point>& triangle,
-                                               const std::vector<Point>& interval,
-                                               std::size_t gdim);
-
-    // Function for computing the intersection of two triangles given
-    // by std::vector<Point>.
-    static std::vector<double>
-    triangulate_intersection_triangle_triangle(const std::vector<Point>& tri_0,
-                                               const std::vector<Point>& tri_1);
-
-    // Function for computing the intersection of two tetrahedra given
-    // by std::vector<Point>.
-    static std::vector<double>
-    triangulate_intersection_tetrahedron_tetrahedron(const std::vector<Point>& tet_0,
-                                                     const std::vector<Point>& tet_1);
-
-    // Function for computing the intersection of a tetrahedron with a
-    // triangle given by std::vector<Point>.
-    static std::vector<double>
-    triangulate_intersection_tetrahedron_triangle(const std::vector<Point>& tet,
-                                                  const std::vector<Point>& tri);
-
-    // Helper function
-    static bool intersection_edge_edge(const Point& a,
-				       const Point& b,
-				       const Point& c,
-				       const Point& d,
-				       Point& pt);
-
-    // Helper function
-    static bool intersection_face_edge(const Point& r,
-				       const Point& s,
-				       const Point& t,
-				       const Point& a,
-				       const Point& b,
-				       Point& pt);
-
-  };
-
-}
-
-#endif
diff --git a/dolfin/geometry/Point.h b/dolfin/geometry/Point.h
index 2dc6ad9..dc2ca33 100644
--- a/dolfin/geometry/Point.h
+++ b/dolfin/geometry/Point.h
@@ -19,7 +19,7 @@
 // Modified by Andre Massing 2009
 //
 // First added:  2006-06-12
-// Last changed: 2014-06-06
+// Last changed: 2017-09-28
 
 #ifndef __POINT_H
 #define __POINT_H
@@ -193,6 +193,14 @@ namespace dolfin
     const Point& operator= (const Point& p)
     { _x = {{p._x[0], p._x[1], p._x[2]}}; return *this; }
 
+    /// Equal to operator
+    bool operator== (const Point& p) const
+    { return _x == p._x; }
+
+    /// Not equal to operator
+    bool operator!= (const Point& p) const
+    { return _x != p._x; }
+
     /// Compute squared distance to given point
     ///
     /// @param p (Point)
diff --git a/dolfin/geometry/SimplexQuadrature.cpp b/dolfin/geometry/SimplexQuadrature.cpp
index 5c56b91..d0de5df 100644
--- a/dolfin/geometry/SimplexQuadrature.cpp
+++ b/dolfin/geometry/SimplexQuadrature.cpp
@@ -14,43 +14,73 @@
 //
 // You should have received a copy of the GNU Lesser General Public License
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
-//
-// First added:  2014-02-24
-// Last changed: 2014-04-25
 
 #include <dolfin/log/log.h>
 #include <dolfin/mesh/Cell.h>
 #include <dolfin/mesh/Mesh.h>
 #include <dolfin/mesh/MeshGeometry.h>
 #include "SimplexQuadrature.h"
+#include "predicates.h"
 
 using namespace dolfin;
 
 //-----------------------------------------------------------------------------
+SimplexQuadrature::SimplexQuadrature(std::size_t tdim, std::size_t order)
+{
+  // Create and store quadrature rule for reference simplex
+  switch (tdim)
+  {
+  case 1:
+    setup_qr_reference_interval(order);
+    break;
+  case 2:
+    setup_qr_reference_triangle(order);
+    break;
+  case 3:
+    setup_qr_reference_tetrahedron(order);
+    break;
+  default:
+    dolfin_error("SimplexQuadrature.cpp",
+                 "setup quadrature rule for reference simplex",
+                 "Only implemented for topological dimension 1, 2, 3");
+  }
+
+}
+//-----------------------------------------------------------------------------
 std::pair<std::vector<double>, std::vector<double>>
   SimplexQuadrature::compute_quadrature_rule(const Cell& cell,
-                                             std::size_t order)
+                                             std::size_t order) const
 {
   // Extract dimensions
   const std::size_t tdim = cell.mesh().topology().dim();
   const std::size_t gdim = cell.mesh().geometry().dim();
 
   // Get vertex coordinates
-  std::vector<double> coordinates;
-  cell.get_vertex_coordinates(coordinates);
+  std::vector<double> x;
+  cell.get_coordinate_dofs(x);
+
+  // Convert to std::vector<Point>
+  std::vector<Point> s(tdim + 1);
+  for (std::size_t t = 0; t < tdim + 1; ++t)
+    for (std::size_t d = 0; d < gdim; ++d)
+      s[t][d] = x[gdim*t + d];
 
   // Call function to compute quadrature rule
-  return compute_quadrature_rule(&coordinates[0], tdim, gdim, order);
+  return compute_quadrature_rule(s, gdim, order);
 }
 //-----------------------------------------------------------------------------
 std::pair<std::vector<double>, std::vector<double>>
-  SimplexQuadrature::compute_quadrature_rule(const double* coordinates,
-                                             std::size_t tdim,
+  SimplexQuadrature::compute_quadrature_rule(const std::vector<Point>& coordinates,
                                              std::size_t gdim,
-                                             std::size_t order)
+                                             std::size_t order) const
 {
+  std::size_t tdim = coordinates.size() - 1;
+
   switch (tdim)
   {
+  case 0:
+    // FIXME: should we return empty qr or should we have detected this earlier?
+    break;
   case 1:
     return compute_quadrature_rule_interval(coordinates, gdim, order);
     break;
@@ -71,549 +101,3591 @@ std::pair<std::vector<double>, std::vector<double>>
 }
 //-----------------------------------------------------------------------------
 std::pair<std::vector<double>, std::vector<double>>
-SimplexQuadrature::compute_quadrature_rule_interval(const double* coordinates,
-                                                    std::size_t gdim,
-                                                    std::size_t order)
+  SimplexQuadrature::compute_quadrature_rule_interval(const std::vector<Point>& coordinates,
+						      std::size_t gdim,
+						      std::size_t order) const
 {
+  log(PROGRESS, "Create quadrature rule using given interval coordinates");
+
   std::pair<std::vector<double>, std::vector<double>> quadrature_rule;
 
-  // Weights and points in local coordinates on [-1, 1]
-  std::vector<double> w, p;
+  // Find the determinant of the Jacobian (inspired by ufc_geometry.h)
+  double det = -1;
 
-  switch (order)
+  switch (gdim)
   {
   case 1:
-    // Assign weight 2, point 0
-    w.assign(1, 2.);
-    p.assign(1, 0.);
-
-    break;
+  {
+      det = coordinates[1].x() - coordinates[0].x();
+      break;
+  }
   case 2:
-    // Assign weights 1.
-    w.assign(2, 1.);
-
-    // Assign points corresponding to -1/sqrt(3) and 1/sqrt(3)
-    p.resize(2);
-    p[0] = -1./std::sqrt(3);
-    p[1] = 1./std::sqrt(3);
-
-    break;
-  case 3:
-    // Assign weights
-    w = { 5./9, 8./9, 5./9 };
-
-    // Assign points
-    p = { -std::sqrt(3./5), 0., std::sqrt(3./5) };
-
-    break;
-  case 4:
-    // Assign weights
-    w.resize(4);
-    w[0] = (18 - std::sqrt(30)) / 36;
-    w[1] = (18 + std::sqrt(30)) / 36;
-    w[2] = w[1];
-    w[3] = w[0];
-
-    // Assign points
-    p.resize(4);
-    p[0] = -std::sqrt(3./7 + 2./7*std::sqrt(6./5));
-    p[1] = -std::sqrt(3./7 - 2./7*std::sqrt(6./5));
-    p[2] = -p[1];
-    p[3] = -p[0];
-
-    break;
-  case 5:
-    // Assign weights
-    w = {
-      0.2369268850561890875142640,
-      0.4786286704993664680412915,
-      0.5688888888888888888888889,
-      0.4786286704993664680412915,
-      0.2369268850561890875142640 };
-
-    // Assign points
-    p = {
-      -0.9061798459386639927976269,
-      -0.5384693101056830910363144,
-      0.0000000000000000000000000,
-      0.5384693101056830910363144,
-      0.9061798459386639927976269 };
-
-    break;
-  case 6:
-    // Assign weights
-    w = {0.1713244923791703450402961,
-	 0.3607615730481386075698335,
-	 0.4679139345726910473898703,
-	 0.4679139345726910473898703,
-	 0.3607615730481386075698335,
-	 0.1713244923791703450402961};
-
-    // Assign points
-    p = {
-      -0.9324695142031520278123016,
-      -0.6612093864662645136613996,
-      -0.2386191860831969086305017,
-      0.2386191860831969086305017 ,
-      0.6612093864662645136613996 ,
-      0.9324695142031520278123016
-    };
-
+  {
+    const std::array<double, 2> J = {{coordinates[1].x() - coordinates[0].x(),
+                                      coordinates[1].y() - coordinates[0].y()}};
+    const double det2 = J[0]*J[0] + J[1]*J[1];
+    det = std::sqrt(det2);
     break;
-  default:
-    dolfin_error("SimplexQuadrature.cpp",
-                 "compute quadrature rule for interval",
-                 "Not implemented for order ",order);
   }
-
-  // Find the determinant of the Jacobian (inspired by ufc_geometry.h)
-  double det;
-
-  switch (gdim)
+  case 3:
   {
-  case 1:
-    det = coordinates[1] - coordinates[0];
+    const std::array<double, 3>  J = {{coordinates[1].x() - coordinates[0].x(),
+                                       coordinates[1].y() - coordinates[0].y(),
+                                       coordinates[1].z() - coordinates[0].z()}};
+    const double det2 = J[0]*J[0] + J[1]*J[1];
+    det = std::sqrt(det2);
     break;
-
-  case 2:
-    {
-      const double J[] = {coordinates[2] - coordinates[0],
-                          coordinates[3] - coordinates[1]};
-      const double det2 = J[0]*J[0] + J[1]*J[1];
-      det = std::sqrt(det2);
-      break;
-    }
-  case 3:
-    {
-      const double J[] = {coordinates[3] - coordinates[0],
-                          coordinates[4] - coordinates[1],
-                          coordinates[5] - coordinates[2]};
-      const double det2 = J[0]*J[0] + J[1]*J[1] + J[2]*J[2];
-      det = std::sqrt(det2);
-      break;
-    }
+  }
   default:
     dolfin_error("SimplexQuadrature.cpp",
                  "compute quadrature rule for interval",
-                 "Not implemented for dimension ", gdim);
+                 "Not implemented for dimension %d", gdim);
   }
 
-  // Map (local) quadrature points
-  quadrature_rule.first.resize(gdim*p.size());
-  for (std::size_t i = 0; i < p.size(); ++i)
+  // Map (local) quadrature points (note that _p is a
+  // std::vector<std::vector<double> >)
+  quadrature_rule.first.resize(gdim*_p[0].size());
+  for (std::size_t i = 0; i < _p[0].size(); ++i)
   {
     for (std::size_t d = 0; d < gdim; ++d)
     {
       quadrature_rule.first[d + i*gdim]
-        = 0.5*(coordinates[d]*(1 - p[i]) + coordinates[gdim + d]*(1 + p[i]));
+        = 0.5*(coordinates[0][d]*(1. - _p[0][i])
+	       + coordinates[1][d]*(1. + _p[0][i]));
+      dolfin_assert(std::isfinite(quadrature_rule.first[d + i*gdim]));
     }
   }
+  dolfin_assert(det >= 0);
 
   // Store weights
-  quadrature_rule.second.assign(w.size(), 0.5*std::abs(det));
-  for (std::size_t i = 0; i < w.size(); ++i)
-    quadrature_rule.second[i] *= w[i];
+  quadrature_rule.second.assign(_w.size(), 0.5*std::abs(det));
+  for (std::size_t i = 0; i < _w.size(); ++i)
+  {
+    quadrature_rule.second[i] *= _w[i];
+    dolfin_assert(std::isfinite(quadrature_rule.second[i]));
+  }
+  dolfin_assert(quadrature_rule.first.size() == gdim*quadrature_rule.second.size());
 
   return quadrature_rule;
 }
 //-----------------------------------------------------------------------------
 std::pair<std::vector<double>, std::vector<double>>
-SimplexQuadrature::compute_quadrature_rule_triangle(const double* coordinates,
+SimplexQuadrature::compute_quadrature_rule_triangle(const std::vector<Point>& coordinates,
                                                     std::size_t gdim,
-                                                    std::size_t order)
+                                                    std::size_t order) const
 {
+  log(PROGRESS, "Create quadrature rule using given triangle coordinates");
+
   std::pair<std::vector<double>, std::vector<double>> quadrature_rule;
 
-  // Weights and points in local coordinates on triangle [0,0], [1,0]
-  // and [0,1]
-  std::vector<double> w;
-  std::vector<std::vector<double>> p;
+  // Find the determinant of the Jacobian (inspired by ufc_geometry.h)
+  double det = 0; // To keep compiler happy
 
-  switch (order)
+  switch (gdim)
   {
-  case 1:
-    // Assign weight 1 and midpoint
-    w.assign(1, 1.);
-    p.assign(1, std::vector<double>(3, 1./3));
-
-    break;
   case 2:
-    // Assign weight 1/3
-    w.assign(3, 1./3);
-
-    // Assign points corresponding to 2/3, 1/6, 1/6
-    p.assign(3, std::vector<double>(3, 1./6));
-    p[0][0] = p[1][1] = p[2][2] = 2./3;
+  {
+    det = orient2d(coordinates[0], coordinates[1], coordinates[2]);
 
     break;
+  }
   case 3:
-    // Assign weights
-    w.resize(4);
-    w[0] = -27./48;
-    w[1] = w[2] = w[3] = 25./48;
-
-    // Assign points
-    p.resize(4);
-    p[0] = { 1./3, 1./3, 1./3 };
-    p[1] = { 0.2, 0.2, 0.6 };
-    p[2] = { 0.2, 0.6, 0.2 };
-    p[3] = { 0.6, 0.2, 0.2 };
+  {
+    const std::array<double, 6> J = {{coordinates[1].x() - coordinates[0].x(),
+                                      coordinates[2].x() - coordinates[0].x(),
+                                      coordinates[1].y() - coordinates[0].y(),
+                                      coordinates[2].y() - coordinates[0].y(),
+                                      coordinates[1].z() - coordinates[0].z(),
+                                      coordinates[2].z() - coordinates[0].z()}};
+    const double d_0 = J[2]*J[5] - J[4]*J[3];
+    const double d_1 = J[4]*J[1] - J[0]*J[5];
+    const double d_2 = J[0]*J[3] - J[2]*J[1];
+    const double det2 = d_0*d_0 + d_1*d_1 + d_2*d_2;
+    det = std::sqrt(det2);
 
     break;
-  case 4:
-    // Assign weights
-    w = { 0.223381589678011,
-	  0.223381589678011,
-	  0.223381589678011,
-	  0.109951743655322,
-	  0.109951743655322,
-	  0.109951743655322 };
-
-    // Assign points
-    p.resize(6);
-    p[0] = { 0.445948490915965, 0.445948490915965, 0.10810301816807 };
-    p[1] = { 0.445948490915965, 0.10810301816807,  0.445948490915965 };
-    p[2] = { 0.10810301816807,  0.445948490915965, 0.445948490915965 };
-    p[3] = { 0.091576213509771, 0.091576213509771, 0.816847572980458 };
-    p[4] = { 0.091576213509771, 0.816847572980459, 0.09157621350977 };
-    p[5] = { 0.816847572980459, 0.091576213509771, 0.09157621350977 };
+  }
+  default:
+    dolfin_error("SimplexQuadrature.cpp",
+                 "compute quadrature rule for triangle",
+                 "Not implemented for dimension ", gdim);
+  }
 
-    break;
-  case 5:
-    // Assign weights
-    w = {0.225,
-	 0.132394152788506,
-	 0.132394152788506,
-	 0.132394152788506,
-	 0.125939180544827,
-	 0.125939180544827,
-	 0.125939180544827 };
+  // Store points
+  quadrature_rule.first.resize(gdim*_p.size());
+  for (std::size_t i = 0; i < _p.size(); ++i)
+  {
+    for (std::size_t d = 0; d < gdim; ++d)
+    {
+      quadrature_rule.first[d + i*gdim]
+        = _p[i][0]*coordinates[0][d]
+        + _p[i][1]*coordinates[1][d]
+        + (1. - _p[i][0] - _p[i][1])*coordinates[2][d];
+      dolfin_assert(std::isfinite(quadrature_rule.first[d + i*gdim]));
+    }
+  }
 
-    // Assign points
-    p.resize(7);
-    p[0] = { 0.3333333333333335, 0.3333333333333335, 0.3333333333333330 };
-    p[1] = { 0.4701420641051150, 0.4701420641051150, 0.0597158717897700 };
-    p[2] = { 0.4701420641051150, 0.0597158717897700, 0.4701420641051151 };
-    p[3] = { 0.0597158717897700, 0.4701420641051150, 0.4701420641051151 };
-    p[4] = { 0.1012865073234560, 0.1012865073234560, 0.7974269853530880 };
-    p[5] = { 0.1012865073234560, 0.7974269853530870, 0.1012865073234570 };
-    p[6] = { 0.7974269853530870, 0.1012865073234560, 0.1012865073234570 };
+  // Store weights
+  quadrature_rule.second.assign(_w.size(), 0.5*std::abs(det));
+  for (std::size_t i = 0; i < _w.size(); ++i)
+  {
+    quadrature_rule.second[i] *= _w[i];
+    dolfin_assert(std::isfinite(quadrature_rule.second[i]));
+  }
 
-    break;
-  case 6:
-    // Assign weights
-    w = { 0.1167862757263790,
-	  0.1167862757263790,
-	  0.1167862757263790,
-	  0.0508449063702070,
-	  0.0508449063702070,
-	  0.0508449063702070,
-	  0.0828510756183740,
-	  0.0828510756183740,
-	  0.0828510756183740,
-	  0.0828510756183740,
-	  0.0828510756183740,
-	  0.0828510756183740 };
+  dolfin_assert(quadrature_rule.first.size() == gdim*quadrature_rule.second.size());
 
-    // Assign points
-    p.resize(12);
-    p[0] = { 0.2492867451709100, 0.2492867451709100, 0.5014265096581800 };
-    p[1] = { 0.2492867451709100, 0.5014265096581790, 0.2492867451709110 };
-    p[2] = { 0.5014265096581790, 0.2492867451709100, 0.2492867451709110 };
-    p[3] = { 0.0630890144915020, 0.0630890144915020, 0.8738219710169960 };
-    p[4] = { 0.0630890144915020, 0.8738219710169960, 0.0630890144915019 };
-    p[5] = { 0.8738219710169960, 0.0630890144915020, 0.0630890144915019 };
-    p[6] = { 0.3103524510337840, 0.6365024991213990, 0.0531450498448169 };
-    p[7] = { 0.6365024991213990, 0.0531450498448170, 0.3103524510337841 };
-    p[8] = { 0.0531450498448170, 0.3103524510337840, 0.6365024991213990 };
-    p[9] = { 0.3103524510337840, 0.0531450498448170, 0.6365024991213990 };
-    p[10] = { 0.6365024991213990, 0.3103524510337840, 0.0531450498448169 };
-    p[11] = { 0.0531450498448170, 0.6365024991213990, 0.3103524510337841 };
+  return quadrature_rule;
+}
+//-----------------------------------------------------------------------------
+std::pair<std::vector<double>, std::vector<double>>
+SimplexQuadrature::compute_quadrature_rule_tetrahedron(const std::vector<Point>& coordinates,
+                                                       std::size_t gdim,
+                                                       std::size_t order) const
+{
+  log(PROGRESS, "Create quadrature rule using given tetrahedron coordinates");
 
-    break;
-  default:
-    dolfin_error("SimplexQuadrature.cpp",
-                 "compute quadrature rule for triangle",
-                 "Not implemented for order ", order);
-  }
+  std::pair<std::vector<double>, std::vector<double>> quadrature_rule;
 
-  // Find the determinant of the Jacobian (inspired by ufc_geometry.h)
+  // Find the determinant of the Jacobian (from ufc_geometry.h)
   double det = 0; // To keep compiler happy
 
   switch (gdim)
   {
-  case 2:
-    {
-      const double J[] = {coordinates[2] - coordinates[0],
-                          coordinates[4] - coordinates[0],
-                          coordinates[3] - coordinates[1],
-                          coordinates[5] - coordinates[1]};
-      det = J[0]*J[3] - J[1]*J[2];
-      break;
-    }
   case 3:
-    {
-      const double J[] = {coordinates[3] - coordinates[0],
-                          coordinates[6] - coordinates[0],
-                          coordinates[4] - coordinates[1],
-                          coordinates[7] - coordinates[1],
-                          coordinates[5] - coordinates[2],
-                          coordinates[8] - coordinates[2]};
-      const double d_0 = J[2]*J[5] - J[4]*J[3];
-      const double d_1 = J[4]*J[1] - J[0]*J[5];
-      const double d_2 = J[0]*J[3] - J[2]*J[1];
-      const double det2 = d_0*d_0 + d_1*d_1 + d_2*d_2;
-      det = std::sqrt(det2);
-
-      break;
-    }
+  {
+    const std::array<double, 9> J = {{coordinates[1].x() - coordinates[0].x(),
+                                      coordinates[2].x() - coordinates[0].x(),
+                                      coordinates[3].x() - coordinates[0].x(),
+                                      coordinates[1].y() - coordinates[0].y(),
+                                      coordinates[2].y() - coordinates[0].y(),
+                                      coordinates[3].y() - coordinates[0].y(),
+                                      coordinates[1].z() - coordinates[0].z(),
+                                      coordinates[2].z() - coordinates[0].z(),
+                                      coordinates[3].z() - coordinates[0].z()}};
+    const std::array<double, 3> d = {{J[4]*J[8] - J[5]*J[7],
+                                      J[2]*J[7] - J[1]*J[8],
+                                      J[1]*J[5] - J[2]*J[4]}};
+    det = J[0]*d[0] + J[3]*d[1] + J[6]*d[2];
+    break;
+  }
   default:
     dolfin_error("SimplexQuadrature.cpp",
-                 "compute quadrature rule for triangle",
+                 "compute quadrature rule for tetrahedron",
                  "Not implemented for dimension ", gdim);
   }
 
   // Store points
-  quadrature_rule.first.resize(gdim*p.size());
-  for (std::size_t i = 0; i < p.size(); ++i)
+  quadrature_rule.first.resize(gdim*_p.size());
+  for (std::size_t i = 0; i < _p.size(); ++i)
+  {
     for (std::size_t d = 0; d < gdim; ++d)
+    {
       quadrature_rule.first[d + i*gdim]
-        = p[i][0]*coordinates[d]
-        + p[i][1]*coordinates[gdim + d]
-        + p[i][2]*coordinates[2*gdim + d];
+        = _p[i][0]*coordinates[0][d]
+        + _p[i][1]*coordinates[1][d]
+        + _p[i][2]*coordinates[2][d]
+        + (1. - _p[i][0] - _p[i][1] - _p[i][2])*coordinates[3][d];
+    }
+  }
 
   // Store weights
-  quadrature_rule.second.assign(w.size(), 0.5*std::abs(det));
-  for (std::size_t i = 0; i < w.size(); ++i)
-    quadrature_rule.second[i] *= w[i];
+  quadrature_rule.second.assign(_w.size(), std::abs(det)/6.0);
+  for (std::size_t i = 0; i < _w.size(); ++i)
+    quadrature_rule.second[i] *= _w[i];
+
+  dolfin_assert(quadrature_rule.first.size() == gdim*quadrature_rule.second.size());
 
   return quadrature_rule;
 }
 //-----------------------------------------------------------------------------
-std::pair<std::vector<double>, std::vector<double>>
-  SimplexQuadrature::compute_quadrature_rule_tetrahedron(
-    const double* coordinates,
-    std::size_t gdim,
-    std::size_t order)
+std::vector<std::size_t>
+SimplexQuadrature::compress(std::pair<std::vector<double>, std::vector<double>>& qr,
+			    std::size_t gdim,
+			    std::size_t quadrature_order)
 {
-  std::pair<std::vector<double>, std::vector<double>> quadrature_rule;
+  // Polynomial degree N that can be integrated exactly using the
+  // qr_base
+  const std::size_t N = quadrature_order;
+
+  // By construction the compressed quadrature rule will not have more
+  // than choose(N + gdim, gdim) points.
+  const std::size_t N_compressed_min = choose(N + gdim, gdim);
+  if (qr.second.size() <= N_compressed_min)
+  {
+    // We cannot improve this rule. Return empty vector
+    return std::vector<std::size_t>();
+  }
+
+  log(PROGRESS, "Compressing %d quadrature points down to %d",
+      qr.second.size(), N_compressed_min);
+
+  // Copy the input qr since we'll overwrite the input
+  const std::pair<std::vector<double>, std::vector<double>> qr_input = qr;
+
+  // Create Vandermonde-type matrix using a basis of Chebyshev
+  // polynomials of the first kind
+  const Eigen::MatrixXd V = Chebyshev_Vandermonde_matrix(qr_input, gdim, N);
+
+  // A QR decomposition selects the subset of N columns (geometrically
+  // the N columns with same volume as spanned by all M columns).
+  Eigen::ColPivHouseholderQR<Eigen::MatrixXd> QR(V);
+  Eigen::MatrixXd Q = QR.householderQ();
+
+  // We do not need the full Q matrix but only what's known as the
+  // "economy size" decomposition
+  Q *= Eigen::MatrixXd::Identity(V.rows(), std::min(V.rows(), V.cols()));
+
+  // We'll use Q^T
+  Q.transposeInPlace();
+
+  // Compute weights in the new basis
+  Eigen::Map<const Eigen::VectorXd> w_base(qr_input.second.data(),
+					   qr_input.second.size());
+  const Eigen::VectorXd nu = Q*w_base;
+
+  // Compute new weights
+  const Eigen::VectorXd w_new = Q.colPivHouseholderQr().solve(nu);
+
+  // Construct new qr using the non-zero weights. First find the
+  // indices for these weights.
+  std::vector<std::size_t> indices;
+  for (int i = 0; i < w_new.size(); ++i)
+  {
+    if (std::abs(w_new[i]) > 0.0)
+      indices.push_back(i);
+  }
+
+  // Resize qr and overwrite the points and weights
+  dolfin_assert(indices.size() <= N_compressed_min);
+  qr.first.resize(gdim*indices.size());
+  qr.second.resize(indices.size());
+
+  for (std::size_t i = 0; i < indices.size(); ++i)
+  {
+    // Save points
+    for (std::size_t d = 0; d < gdim; ++d)
+      qr.first[gdim*i + d] = qr_input.first[gdim*indices[i] + d];
 
-  // Weights and points in local coordinates on tetrahedron [0,0,0],
-  // [1,0,0], [0,1,0] and [0,0,1]
-  std::vector<double> w;
-  std::vector<std::vector<double>> p;
+    // Save weights
+    qr.second[i] = w_new[indices[i]];
+  }
+
+  // Return indices. These are useful for mapping additional data, for
+  // example the normals.
+  return indices;
+}
+//-----------------------------------------------------------------------------
+void SimplexQuadrature::setup_qr_reference_interval(std::size_t order)
+{
+  // Create quadrature rule with points on reference element [-1, 1].
+  _p.resize(1);
+  legendre_compute_glr(order, _p[0], _w);
+}
+//-----------------------------------------------------------------------------
+void SimplexQuadrature::setup_qr_reference_triangle(std::size_t order)
+{
+  // Create quadrature rule with points on reference triangle [0, 0],
+  // [1, 0] and [0, 1]
+  return dunavant_rule(order, _p, _w);
+}
+//-----------------------------------------------------------------------------
+void SimplexQuadrature::setup_qr_reference_tetrahedron(std::size_t order)
+{
+  // FIXME: Replace these hard coded rules by a general function
 
   switch (order)
   {
   case 1:
     // Assign weight 1 and midpoint
-    w.assign(1, 1.);
-    p.assign(1, std::vector<double>(4, 0.25));
+    _w.assign(1, 1.);
+    _p.assign(1, std::vector<double>(3, 0.25));
 
     break;
   case 2:
-    // Assign weight 0.25
-    w.assign(4, 0.25);
+    // Assign weights
+    _w.assign(4, 0.25);
 
-    // Assign points corresponding to 0.585410196624969,
-    // 0.138196601125011, 0.138196601125011 and 0.138196601125011
-    p.assign(4, std::vector<double>(4, 0.138196601125011));
-    p[0][0] = p[1][1] = p[2][2] = p[3][3] = 0.585410196624969;
+    // Assign points
+    _p.assign(4, std::vector<double>(3, 0.138196601125011));
+    _p[0][0] = _p[1][1] = _p[2][2] = 0.585410196624969;
 
     break;
   case 3:
     // Assign weights
-    w = { -4./5,
-	   9./20,
-	   9./20,
-	   9./20,
-	   9./20 };
+    _w = { -4./5.,
+           9./20.,
+           9./20.,
+           9./20.,
+           9./20. };
 
     // Assign points
-    p.resize(5);
-    p[0] = { 0.25, 0.25, 0.25, 0.25 };
-    p[1] = { 1./6, 1./6, 1./6, 0.5 };
-    p[2] = { 1./6, 1./6, 0.5,  1./6 };
-    p[3] = { 1./6, 0.5,  1./6, 1./6 };
-    p[4] = { 0.5,  1./6, 1./6, 1./6 };
+    _p = { { 0.25,  0.25,  0.25  },
+	   { 1./6., 1./6., 1./6. },
+	   { 1./6., 1./6., 0.5,  },
+	   { 1./6., 0.5,   1./6. },
+	   { 0.5,   1./6., 1./6. } };
 
     break;
   case 4:
     // Assign weights
-    w = { -0.0789333333333330,
-	  0.0457333333333335,
-	  0.0457333333333335,
-	  0.0457333333333335,
-	  0.0457333333333335,
-	  0.1493333333333332,
-	  0.1493333333333332,
-	  0.1493333333333332,
-	  0.1493333333333332,
-	  0.1493333333333332,
-	  0.1493333333333332 };
+    // FIXME: Find new rule to avoid negative weight
+    _w = { -0.0789333333333330,
+	   0.0457333333333335,
+	   0.0457333333333335,
+	   0.0457333333333335,
+	   0.0457333333333335,
+	   0.1493333333333332,
+	   0.1493333333333332,
+	   0.1493333333333332,
+	   0.1493333333333332,
+	   0.1493333333333332,
+	   0.1493333333333332 };
 
     // Assign points
-    p.resize(11);
-    p[0] = { 0.2500000000000000, 0.2500000000000000, 0.2500000000000000, 0.2500000000000000 };
-    p[1] = { 0.0714285714285715, 0.0714285714285715, 0.0714285714285715, 0.7857142857142855 };
-    p[2] = { 0.0714285714285715, 0.0714285714285715, 0.7857142857142855, 0.0714285714285715 };
-    p[3] = { 0.0714285714285715, 0.7857142857142855, 0.0714285714285715, 0.0714285714285715 };
-    p[4] = { 0.7857142857142855, 0.0714285714285715, 0.0714285714285715, 0.0714285714285715 };
-    p[5] = { 0.3994035761667990, 0.3994035761667990, 0.1005964238332010, 0.1005964238332010 };
-    p[6] = { 0.3994035761667990, 0.1005964238332010, 0.3994035761667990, 0.1005964238332010 };
-    p[7] = { 0.1005964238332010, 0.3994035761667990, 0.3994035761667990, 0.1005964238332010 };
-    p[8] = { 0.3994035761667990, 0.1005964238332010, 0.1005964238332010, 0.3994035761667990 };
-    p[9] = { 0.1005964238332010, 0.3994035761667990, 0.1005964238332010, 0.3994035761667990 };
-    p[10] = { 0.1005964238332010, 0.1005964238332010, 0.3994035761667990, 0.3994035761667990 };
+    _p = { { 0.2500000000000000, 0.2500000000000000, 0.2500000000000000 },
+	   { 0.0714285714285715, 0.0714285714285715, 0.0714285714285715 },
+	   { 0.0714285714285715, 0.0714285714285715, 0.7857142857142855 },
+	   { 0.0714285714285715, 0.7857142857142855, 0.0714285714285715 },
+	   { 0.7857142857142855, 0.0714285714285715, 0.0714285714285715 },
+	   { 0.3994035761667990, 0.3994035761667990, 0.1005964238332010 },
+	   { 0.3994035761667990, 0.1005964238332010, 0.3994035761667990 },
+	   { 0.1005964238332010, 0.3994035761667990, 0.3994035761667990 },
+	   { 0.3994035761667990, 0.1005964238332010, 0.1005964238332010 },
+	   { 0.1005964238332010, 0.3994035761667990, 0.1005964238332010 },
+	   { 0.1005964238332010, 0.1005964238332010, 0.3994035761667990 } };
 
     break;
   case 5:
     // Assign weights
-    w = { 0.0734930431163618,
-	  0.0734930431163618,
-	  0.0734930431163618,
-	  0.0734930431163618,
-	  0.1126879257180158,
-	  0.1126879257180158,
-	  0.1126879257180158,
-	  0.1126879257180158,
-	  0.0425460207770813,
-	  0.0425460207770813,
-	  0.0425460207770813,
-	  0.0425460207770813,
-	  0.0425460207770813,
-	  0.0425460207770813 };
+    _w = { 0.0734930431163618,
+	   0.0734930431163618,
+	   0.0734930431163618,
+	   0.0734930431163618,
+	   0.1126879257180158,
+	   0.1126879257180158,
+	   0.1126879257180158,
+	   0.1126879257180158,
+	   0.0425460207770813,
+	   0.0425460207770813,
+	   0.0425460207770813,
+	   0.0425460207770813,
+	   0.0425460207770813,
+	   0.0425460207770813 };
 
     // Assign points
-    p.resize(14);
-    p[0] = { 0.0927352503108910, 0.0927352503108910, 0.0927352503108910, 0.7217942490673269 };
-    p[1] = { 0.7217942490673265, 0.0927352503108910, 0.0927352503108910, 0.0927352503108915 };
-    p[2] = { 0.0927352503108910, 0.7217942490673265, 0.0927352503108910, 0.0927352503108915 };
-    p[3] = { 0.0927352503108910, 0.0927352503108910, 0.7217942490673265, 0.0927352503108915 };
-    p[4] = { 0.3108859192633005, 0.3108859192633005, 0.3108859192633005, 0.0673422422100984 };
-    p[5] = { 0.0673422422100980, 0.3108859192633005, 0.3108859192633005, 0.3108859192633010 };
-    p[6] = { 0.3108859192633005, 0.0673422422100980, 0.3108859192633005, 0.3108859192633010 };
-    p[7] = { 0.3108859192633005, 0.3108859192633005, 0.0673422422100980, 0.3108859192633010 };
-    p[8] = { 0.4544962958743505, 0.4544962958743505, 0.0455037041256495, 0.0455037041256495 };
-    p[9] = { 0.4544962958743505, 0.0455037041256495, 0.4544962958743505, 0.0455037041256495 };
-    p[10] = { 0.0455037041256495, 0.4544962958743505, 0.4544962958743505, 0.0455037041256495 };
-    p[11] = { 0.4544962958743505, 0.0455037041256495, 0.0455037041256495, 0.4544962958743505 };
-    p[12] = { 0.0455037041256495, 0.4544962958743505, 0.0455037041256495, 0.4544962958743505 };
-    p[13] = { 0.0455037041256495, 0.0455037041256495, 0.4544962958743505, 0.4544962958743505 };
+    _p = { { 0.0927352503108910, 0.0927352503108910, 0.0927352503108910 },
+	   { 0.7217942490673265, 0.0927352503108910, 0.0927352503108910 },
+	   { 0.0927352503108910, 0.7217942490673265, 0.0927352503108910 },
+	   { 0.0927352503108910, 0.0927352503108910, 0.7217942490673265 },
+	   { 0.3108859192633005, 0.3108859192633005, 0.3108859192633005 },
+	   { 0.0673422422100980, 0.3108859192633005, 0.3108859192633005 },
+	   { 0.3108859192633005, 0.0673422422100980, 0.3108859192633005 },
+	   { 0.3108859192633005, 0.3108859192633005, 0.0673422422100980 },
+	   { 0.4544962958743505, 0.4544962958743505, 0.0455037041256495 },
+	   { 0.4544962958743505, 0.0455037041256495, 0.4544962958743505 },
+	   { 0.0455037041256495, 0.4544962958743505, 0.4544962958743505 },
+	   { 0.4544962958743505, 0.0455037041256495, 0.0455037041256495 },
+	   { 0.0455037041256495, 0.4544962958743505, 0.0455037041256495 },
+	   { 0.0455037041256495, 0.0455037041256495, 0.4544962958743505 } };
 
     break;
   case 6:
     // Assign weights
-    w = { 0.0399227502581678,
-	  0.0399227502581678,
-	  0.0399227502581678,
-	  0.0399227502581678,
-	  0.0100772110553205,
-	  0.0100772110553205,
-	  0.0100772110553205,
-	  0.0100772110553205,
-	  0.0553571815436550,
-	  0.0553571815436550,
-	  0.0553571815436550,
-	  0.0553571815436550,
-	  0.0482142857142855,
-	  0.0482142857142855,
-	  0.0482142857142855,
-	  0.0482142857142855,
-	  0.0482142857142855,
-	  0.0482142857142855,
-	  0.0482142857142855,
-	  0.0482142857142855,
-	  0.0482142857142855,
-	  0.0482142857142855,
-	  0.0482142857142855,
-	  0.0482142857142855 };
+    _w = { 0.0399227502581678,
+	   0.0399227502581678,
+	   0.0399227502581678,
+	   0.0399227502581678,
+	   0.0100772110553205,
+	   0.0100772110553205,
+	   0.0100772110553205,
+	   0.0100772110553205,
+	   0.0553571815436550,
+	   0.0553571815436550,
+	   0.0553571815436550,
+	   0.0553571815436550,
+	   0.0482142857142855,
+	   0.0482142857142855,
+	   0.0482142857142855,
+	   0.0482142857142855,
+	   0.0482142857142855,
+	   0.0482142857142855,
+	   0.0482142857142855,
+	   0.0482142857142855,
+	   0.0482142857142855,
+	   0.0482142857142855,
+	   0.0482142857142855,
+	   0.0482142857142855 };
 
     // Assign points
-    p.resize(24);
-    p[0] = { 0.2146028712591520, 0.2146028712591520, 0.2146028712591520, 0.3561913862225440 };
-    p[1] = { 0.3561913862225440, 0.2146028712591520, 0.2146028712591520, 0.2146028712591520 };
-    p[2] = { 0.2146028712591520, 0.3561913862225440, 0.2146028712591520, 0.2146028712591520 };
-    p[3] = { 0.2146028712591520, 0.2146028712591520, 0.3561913862225440, 0.2146028712591520 };
-    p[4] = { 0.0406739585346115, 0.0406739585346115, 0.0406739585346115, 0.8779781243961655 };
-    p[5] = { 0.8779781243961660, 0.0406739585346115, 0.0406739585346115, 0.0406739585346112 };
-    p[6] = { 0.0406739585346115, 0.8779781243961660, 0.0406739585346115, 0.0406739585346112 };
-    p[7] = { 0.0406739585346115, 0.0406739585346115, 0.8779781243961660, 0.0406739585346111 };
-    p[8] = { 0.3223378901422755, 0.3223378901422755, 0.3223378901422755, 0.0329863295731734 };
-    p[9] = { 0.0329863295731735, 0.3223378901422755, 0.3223378901422755, 0.3223378901422754 };
-    p[10] = { 0.3223378901422755, 0.0329863295731735, 0.3223378901422755, 0.3223378901422754 };
-    p[11] = { 0.3223378901422755, 0.3223378901422755, 0.0329863295731735, 0.3223378901422754 };
-    p[12] = { 0.0636610018750175, 0.0636610018750175, 0.2696723314583160, 0.6030056647916490 };
-    p[13] = { 0.0636610018750175, 0.2696723314583160, 0.0636610018750175, 0.6030056647916490 };
-    p[14] = { 0.0636610018750175, 0.0636610018750175, 0.6030056647916490, 0.2696723314583160 };
-    p[15] = { 0.0636610018750175, 0.6030056647916490, 0.0636610018750175, 0.2696723314583160 };
-    p[16] = { 0.0636610018750175, 0.2696723314583160, 0.6030056647916490, 0.0636610018750174 };
-    p[17] = { 0.0636610018750175, 0.6030056647916490, 0.2696723314583160, 0.0636610018750174 };
-    p[18] = { 0.2696723314583160, 0.0636610018750175, 0.0636610018750175, 0.6030056647916490 };
-    p[19] = { 0.2696723314583160, 0.0636610018750175, 0.6030056647916490, 0.0636610018750174 };
-    p[20] = { 0.2696723314583160, 0.6030056647916490, 0.0636610018750175, 0.0636610018750174 };
-    p[21] = { 0.6030056647916490, 0.0636610018750175, 0.2696723314583160, 0.0636610018750174 };
-    p[22] = { 0.6030056647916490, 0.0636610018750175, 0.0636610018750175, 0.2696723314583160 };
-    p[23] = { 0.6030056647916490, 0.2696723314583160, 0.0636610018750175, 0.0636610018750174 };
+    _p = { { 0.2146028712591520, 0.2146028712591520, 0.2146028712591520 },
+	   { 0.3561913862225440, 0.2146028712591520, 0.2146028712591520 },
+	   { 0.2146028712591520, 0.3561913862225440, 0.2146028712591520 },
+	   { 0.2146028712591520, 0.2146028712591520, 0.3561913862225440 },
+	   { 0.0406739585346115, 0.0406739585346115, 0.0406739585346115 },
+	   { 0.8779781243961660, 0.0406739585346115, 0.0406739585346115 },
+	   { 0.0406739585346115, 0.8779781243961660, 0.0406739585346115 },
+	   { 0.0406739585346115, 0.0406739585346115, 0.8779781243961660 },
+	   { 0.3223378901422755, 0.3223378901422755, 0.3223378901422755 },
+	   { 0.0329863295731735, 0.3223378901422755, 0.3223378901422755 },
+	   { 0.3223378901422755, 0.0329863295731735, 0.3223378901422755 },
+	   { 0.3223378901422755, 0.3223378901422755, 0.0329863295731735 },
+	   { 0.0636610018750175, 0.0636610018750175, 0.2696723314583160 },
+	   { 0.0636610018750175, 0.2696723314583160, 0.0636610018750175 },
+	   { 0.0636610018750175, 0.0636610018750175, 0.6030056647916490 },
+	   { 0.0636610018750175, 0.6030056647916490, 0.0636610018750175 },
+	   { 0.0636610018750175, 0.2696723314583160, 0.6030056647916490 },
+	   { 0.0636610018750175, 0.6030056647916490, 0.2696723314583160 },
+	   { 0.2696723314583160, 0.0636610018750175, 0.0636610018750175 },
+	   { 0.2696723314583160, 0.0636610018750175, 0.6030056647916490 },
+	   { 0.2696723314583160, 0.6030056647916490, 0.0636610018750175 },
+	   { 0.6030056647916490, 0.0636610018750175, 0.2696723314583160 },
+	   { 0.6030056647916490, 0.0636610018750175, 0.0636610018750175 },
+	   { 0.6030056647916490, 0.2696723314583160, 0.0636610018750175 } };
 
     break;
   default:
     dolfin_error("SimplexQuadrature.cpp",
-                 "compute quadrature rule for triangle",
+                 "compute quadrature rule for tetrahedron",
                  "Not implemented for order ", order);
   }
+}
+//-----------------------------------------------------------------------------
+Eigen::MatrixXd SimplexQuadrature::Chebyshev_Vandermonde_matrix
+(const std::pair<std::vector<double>, std::vector<double>>& qr,
+ std::size_t gdim,
+ std::size_t N)
+{
+  // Create the Chebyshev basis matrix for each dimension separately
+  std::vector<std::vector<Eigen::VectorXd>> T(gdim);
+  Eigen::VectorXd x(qr.second.size());
+
+  for (std::size_t d = 0; d < gdim; ++d)
+  {
+    // Extract coordinates in one dimension
+    for (std::size_t i = 0; i < qr.second.size(); ++i)
+      x(i) = qr.first[i*gdim + d];
+
+    // Map points to [-1, 1]
+    const double xmin = x.minCoeff();
+    const double xmax = x.maxCoeff();
+    const double hx = xmax - xmin;
+    const Eigen::VectorXd xmap = (2./hx) * x - ((xmin+xmax)/hx) * Eigen::VectorXd::Ones(x.size());
+
+    // Evaluate the basis
+    T[d] = Chebyshev_polynomial(xmap, N);
+  }
 
-  // Find the determinant of the Jacobian (from ufc_geometry.h)
-  double det = 0; // To keep compiler happy
+  // Find the order of the polynomials in graded lexicographic
+  // ordering
+  const std::vector<std::vector<std::size_t>> P = grlex(gdim, N);
+
+  // Setup the Vandermonde type matrix
+  const std::size_t n_cols = P.size();
+  Eigen::MatrixXd V(Eigen::MatrixXd::Ones(qr.second.size(), n_cols));
+
+  // The first column is always [1, 1, ..., 1], hence we can start from 1
+  for (std::size_t i = 1; i < n_cols; ++i)
+  {
+    // Pick out the correct order of polynomial from the P
+    // matrix. Start with dimension 0.
+    const std::size_t d = 0;
+    const std::size_t grlex_order = P[i][d];
+    Eigen::VectorXd V_col = T[d][grlex_order];
+
+    // Do a .* style multiplication for each other dimension
+    for (std::size_t d = 1; d < gdim; ++d)
+    {
+      const std::size_t grlex_order = P[i][d];
+      V_col = V_col.cwiseProduct(T[d][grlex_order]);
+    }
+    V.col(i) = V_col;
+  }
 
+  return V;
+}
+//-----------------------------------------------------------------------------
+std::vector<Eigen::VectorXd>
+SimplexQuadrature::Chebyshev_polynomial(const Eigen::VectorXd& x,
+					std::size_t N)
+{
+  // Create Chebyshev polynomial of the first kind of order N on [-1, 1]
+  //
+  // T_0(x) = 1
+  // T_1(x) = x
+  // T_{k}(x) = 2 * x * T_{k-1}(x) - T_{k-2}(x), k = 2, ..., N
+
+  // Store in a matrix T such that (T)_ij = T_i(x_j). We don't use
+  // Eigen::MatrixXd, because we want to slice out the rows later.
+  std::vector<Eigen::VectorXd> T(N + 1, Eigen::VectorXd(x.size()));
+
+  // Reccurence construction
+  T[0] = Eigen::VectorXd::Ones(x.size());
+
+  if (N >= 1)
+  {
+    T[1] = x;
+    for (std::size_t k = 2; k <= N; ++k)
+      T[k] = 2*x.cwiseProduct(T[k-1]) - T[k-2];
+  }
+
+  return T;
+}
+//-----------------------------------------------------------------------------
+std::vector<std::vector<std::size_t>>
+SimplexQuadrature::grlex(std::size_t gdim, std::size_t N)
+{
+  // Generate a matrix with numbers in graded lexicographic ordering,
+  // i.e. if N = 3 and dim = 2, P should be
+  // P = [ 0 0
+  //       0 1
+  //       1 0
+  //       0 2
+  //       1 1
+  //       2 0
+  //       0 3
+  //       1 2
+  //       2 1
+  //       3 0 ]
+
+  const std::size_t n_rows = choose(N + gdim, gdim);
+  std::vector<std::vector<std::size_t>> P(n_rows, std::vector<std::size_t>(gdim));
+
+  // FIXME: Make this a dimension independent loop
   switch (gdim)
   {
+  case 2:
+    for (std::size_t sum = 0, row = 0; sum <= N; ++sum)
+      for (std::size_t xi = 0; xi <= N; ++xi)
+	for (std::size_t yi = 0; yi <= N; ++yi)
+	  if (xi + yi == sum)
+	  {
+	    P[row][0] = xi;
+	    P[row][1] = yi;
+	    row++;
+	  }
+    break;
   case 3:
+    for (std::size_t sum = 0, row = 0; sum <= N; ++sum)
+      for (std::size_t xi = 0; xi <= N; ++xi)
+	for (std::size_t yi = 0; yi <= N; ++yi)
+	  for (std::size_t zi = 0; zi <= N; ++zi)
+	    if (xi + yi + zi == sum)
+	    {
+	      P[row][0] = xi;
+	      P[row][1] = yi;
+	      P[row][2] = zi;
+	      row++;
+	    }
+    break;
+  default:
+    dolfin_assert(false);
+  }
+
+  return P;
+}
+//-----------------------------------------------------------------------------
+std::size_t
+SimplexQuadrature::choose(std::size_t n,
+			  std::size_t k)
+{
+  // Compute the number of combinations n over k
+  if (k == 0)
+    return 1;
+  return (n * choose(n - 1, k - 1)) / k;
+}
+//-----------------------------------------------------------------------------
+void SimplexQuadrature::dunavant_rule(std::size_t rule,
+				      std::vector<std::vector<double> >& p,
+				      std::vector<double>& w)
+{
+  //****************************************************************************80
+  //
+  //  Purpose:
+  //
+  //    DUNAVANT_RULE returns the points and weights of a Dunavant rule.
+  //
+  //  Licensing:
+  //
+  //    This code is distributed under the GNU LGPL license.
+  //
+  //  Modified:
+  //
+  //    11 December 2006
+  //
+  //  Author:
+  //
+  //    John Burkardt
+  //
+  //  Reference:
+  //
+  //    David Dunavant,
+  //    High Degree Efficient Symmetrical Gaussian Quadrature Rules
+  //    for the Triangle,
+  //    International Journal for Numerical Methods in Engineering,
+  //    Volume 21, 1985, pages 1129-1148.
+  //
+  //    James Lyness, Dennis Jespersen,
+  //    Moderate Degree Symmetric Quadrature Rules for the Triangle,
+  //    Journal of the Institute of Mathematics and its Applications,
+  //    Volume 15, Number 1, February 1975, pages 19-32.
+  //
+  //  Parameters:
+  //
+  //    Input, int RULE, the index of the rule.
+  //
+  //    Input, int ORDER_NUM, the order (number of points) of the rule.
+  //
+  //    Output, double XY[2*ORDER_NUM], the points of the rule.
+  //
+  //    Output, double W[ORDER_NUM], the weights of the rule.
+  //
+
+  // Get the suborder information
+  const std::size_t suborder_num = dunavant_suborder_num(rule);
+  std::vector<double> suborder_xyz(3*suborder_num);
+  std::vector<double> suborder_w(suborder_num);;
+  const std::vector<std::size_t> suborder = dunavant_suborder(rule, suborder_num);
+  dunavant_subrule(rule, suborder_num, suborder_xyz, suborder_w);
+
+  // Resize p and w
+  const std::size_t order_num = dunavant_order_num(rule);
+  p.resize(order_num, std::vector<double>(2));
+  w.resize(order_num);
+
+  // Expand the suborder information to a full order rule
+  std::size_t o = 0;
+
+  for (std::size_t s = 0; s < suborder_num; s++)
+  {
+    if (suborder[s] == 1)
     {
-      const double J[] = {coordinates[3]  - coordinates[0],
-                          coordinates[6]  - coordinates[0],
-                          coordinates[9]  - coordinates[0],
-                          coordinates[4]  - coordinates[1],
-                          coordinates[7]  - coordinates[1],
-                          coordinates[10] - coordinates[1],
-                          coordinates[5]  - coordinates[2],
-                          coordinates[8]  - coordinates[2],
-                          coordinates[11] - coordinates[2]};
-      double d[9];
-      d[0*3 + 0] = J[4]*J[8] - J[5]*J[7];
-      // d[0*3 + 1] = J[5]*J[6] - J[3]*J[8];
-      // d[0*3 + 2] = J[3]*J[7] - J[4]*J[6];
-      d[1*3 + 0] = J[2]*J[7] - J[1]*J[8];
-      // d[1*3 + 1] = J[0]*J[8] - J[2]*J[6];
-      // d[1*3 + 2] = J[1]*J[6] - J[0]*J[7];
-      d[2*3 + 0] = J[1]*J[5] - J[2]*J[4];
-      // d[2*3 + 1] = J[2]*J[3] - J[0]*J[5];
-      // d[2*3 + 2] = J[0]*J[4] - J[1]*J[3];
-
-      det = J[0]*d[0*3 + 0] + J[3]*d[1*3 + 0] + J[6]*d[2*3 + 0];
-      break;
+      p[o][0] = suborder_xyz[0+s*3];
+      p[o][1] = suborder_xyz[1+s*3];
+      w[o] = suborder_w[s];
+      o = o + 1;
+    }
+    else if (suborder[s] == 3)
+    {
+      for (std::size_t k = 0; k < 3; k++)
+      {
+        p[o][0] = suborder_xyz[i4_wrap(k,  0,2) + s*3];
+        p[o][1] = suborder_xyz[i4_wrap(k+1,0,2) + s*3];
+        w[o] = suborder_w[s];
+        o = o + 1;
+      }
+    }
+    else if (suborder[s] == 6)
+    {
+      for (std::size_t k = 0; k < 3; k++)
+      {
+        p[o][0] = suborder_xyz[i4_wrap(k,  0,2) + s*3];
+        p[o][1] = suborder_xyz[i4_wrap(k+1,0,2) + s*3];
+        w[o] = suborder_w[s];
+        o = o + 1;
+      }
+
+      for (std::size_t k = 0; k < 3; k++)
+      {
+        p[o][0] = suborder_xyz[i4_wrap(k+1,0,2) + s*3];
+        p[o][1] = suborder_xyz[i4_wrap(k,  0,2) + s*3];
+        w[o] = suborder_w[s];
+        o = o + 1;
+      }
+    }
+    else
+    {
+      dolfin_error("SimplexQuadrature.cpp",
+		   "compute quadrature rule for triangle",
+		   "Dunavant rule not implemented for suborder ", suborder[s]);
     }
-  default:
-    dolfin_error("SimplexQuadrature.cpp",
-                 "compute quadrature rule for tetrahedron",
-                 "Not implemented for dimension ", gdim);
   }
 
-  // Store points
-  quadrature_rule.first.resize(gdim*p.size());
-  for (std::size_t i = 0; i < p.size(); ++i)
-    for (std::size_t d = 0; d < gdim; ++d)
-      quadrature_rule.first[d + i*gdim]
-        = p[i][0]*coordinates[d]
-        + p[i][1]*coordinates[gdim + d]
-        + p[i][2]*coordinates[2*gdim + d]
-        + p[i][3]*coordinates[3*gdim + d];
+}
+//****************************************************************************80
 
-  // Store weights
-  quadrature_rule.second.assign(w.size(), std::abs(det) / 6.);
-  for (std::size_t i = 0; i < w.size(); ++i)
-    quadrature_rule.second[i] *= w[i];
+std::size_t SimplexQuadrature::dunavant_order_num(std::size_t rule)
 
-  return quadrature_rule;
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    DUNAVANT_ORDER_NUM returns the order of a Dunavant rule for the triangle.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 December 2006
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    David Dunavant,
+//    High Degree Efficient Symmetrical Gaussian Quadrature Rules
+//    for the Triangle,
+//    International Journal for Numerical Methods in Engineering,
+//    Volume 21, 1985, pages 1129-1148.
+//
+//    James Lyness, Dennis Jespersen,
+//    Moderate Degree Symmetric Quadrature Rules for the Triangle,
+//    Journal of the Institute of Mathematics and its Applications,
+//    Volume 15, Number 1, February 1975, pages 19-32.
+//
+//  Parameters:
+//
+//    Input, int RULE, the index of the rule.
+//
+//    Output, int DUNAVANT_ORDER_NUM, the order (number of points) of the rule.
+//
+{
+  std::size_t order;
+  std::size_t order_num;
+  std::size_t suborder_num;
+
+  suborder_num = dunavant_suborder_num(rule);
+
+  std::vector<std::size_t> suborder = dunavant_suborder(rule, suborder_num);
+
+  order_num = 0;
+  for (order = 0; order < suborder_num; order++)
+  {
+    order_num = order_num + suborder[order];
+  }
+
+  return order_num;
+}
+//****************************************************************************80
+
+std::vector<std::size_t> SimplexQuadrature::dunavant_suborder(int rule, int suborder_num)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    DUNAVANT_SUBORDER returns the suborders for a Dunavant rule.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 December 2006
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    David Dunavant,
+//    High Degree Efficient Symmetrical Gaussian Quadrature Rules
+//    for the Triangle,
+//    International Journal for Numerical Methods in Engineering,
+//    Volume 21, 1985, pages 1129-1148.
+//
+//    James Lyness, Dennis Jespersen,
+//    Moderate Degree Symmetric Quadrature Rules for the Triangle,
+//    Journal of the Institute of Mathematics and its Applications,
+//    Volume 15, Number 1, February 1975, pages 19-32.
+//
+//  Parameters:
+//
+//    Input, int RULE, the index of the rule.
+//
+//    Input, int SUBORDER_NUM, the number of suborders of the rule.
+//
+//    Output, int DUNAVANT_SUBORDER[SUBORDER_NUM], the suborders of the rule.
+//
+{
+  std::vector<std::size_t> suborder(suborder_num);
+
+  if (rule == 1)
+  {
+    suborder[0] = 1;
+  }
+  else if (rule == 2)
+  {
+    suborder[0] = 3;
+  }
+  else if (rule == 3)
+  {
+    suborder[0] = 1;
+    suborder[1] = 3;
+  }
+  else if (rule == 4)
+  {
+    suborder[0] = 3;
+    suborder[1] = 3;
+  }
+  else if (rule == 5)
+  {
+    suborder[0] = 1;
+    suborder[1] = 3;
+    suborder[2] = 3;
+  }
+  else if (rule == 6)
+  {
+    suborder[0] = 3;
+    suborder[1] = 3;
+    suborder[2] = 6;
+  }
+  else if (rule == 7)
+  {
+    suborder[0] = 1;
+    suborder[1] = 3;
+    suborder[2] = 3;
+    suborder[3] = 6;
+  }
+  else if (rule == 8)
+  {
+    suborder[0] = 1;
+    suborder[1] = 3;
+    suborder[2] = 3;
+    suborder[3] = 3;
+    suborder[4] = 6;
+  }
+  else if (rule == 9)
+  {
+    suborder[0] = 1;
+    suborder[1] = 3;
+    suborder[2] = 3;
+    suborder[3] = 3;
+    suborder[4] = 3;
+    suborder[5] = 6;
+  }
+  else if (rule == 10)
+  {
+    suborder[0] = 1;
+    suborder[1] = 3;
+    suborder[2] = 3;
+    suborder[3] = 6;
+    suborder[4] = 6;
+    suborder[5] = 6;
+  }
+  else if (rule == 11)
+  {
+    suborder[0] = 3;
+    suborder[1] = 3;
+    suborder[2] = 3;
+    suborder[3] = 3;
+    suborder[4] = 3;
+    suborder[5] = 6;
+    suborder[6] = 6;
+  }
+  else if (rule == 12)
+  {
+    suborder[0] = 3;
+    suborder[1] = 3;
+    suborder[2] = 3;
+    suborder[3] = 3;
+    suborder[4] = 3;
+    suborder[5] = 6;
+    suborder[6] = 6;
+    suborder[7] = 6;
+  }
+  else if (rule == 13)
+  {
+    suborder[0] = 1;
+    suborder[1] = 3;
+    suborder[2] = 3;
+    suborder[3] = 3;
+    suborder[4] = 3;
+    suborder[5] = 3;
+    suborder[6] = 3;
+    suborder[7] = 6;
+    suborder[8] = 6;
+    suborder[9] = 6;
+  }
+  else if (rule == 14)
+  {
+    suborder[0] = 3;
+    suborder[1] = 3;
+    suborder[2] = 3;
+    suborder[3] = 3;
+    suborder[4] = 3;
+    suborder[5] = 3;
+    suborder[6] = 6;
+    suborder[7] = 6;
+    suborder[8] = 6;
+    suborder[9] = 6;
+  }
+  else if (rule == 15)
+  {
+    suborder[0] = 3;
+    suborder[1] = 3;
+    suborder[2] = 3;
+    suborder[3] = 3;
+    suborder[4] = 3;
+    suborder[5] = 3;
+    suborder[6] = 6;
+    suborder[7] = 6;
+    suborder[8] = 6;
+    suborder[9] = 6;
+    suborder[10] = 6;
+  }
+  else if (rule == 16)
+  {
+    suborder[0] = 1;
+    suborder[1] = 3;
+    suborder[2] = 3;
+    suborder[3] = 3;
+    suborder[4] = 3;
+    suborder[5] = 3;
+    suborder[6] = 3;
+    suborder[7] = 3;
+    suborder[8] = 6;
+    suborder[9] = 6;
+    suborder[10] = 6;
+    suborder[11] = 6;
+    suborder[12] = 6;
+  }
+  else if (rule == 17)
+  {
+    suborder[0] = 1;
+    suborder[1] = 3;
+    suborder[2] = 3;
+    suborder[3] = 3;
+    suborder[4] = 3;
+    suborder[5] = 3;
+    suborder[6] = 3;
+    suborder[7] = 3;
+    suborder[8] = 3;
+    suborder[9] = 6;
+    suborder[10] = 6;
+    suborder[11] = 6;
+    suborder[12] = 6;
+    suborder[13] = 6;
+    suborder[14] = 6;
+  }
+  else if (rule == 18)
+  {
+    suborder[0] = 1;
+    suborder[1] = 3;
+    suborder[2] = 3;
+    suborder[3] = 3;
+    suborder[4] = 3;
+    suborder[5] = 3;
+    suborder[6] = 3;
+    suborder[7] = 3;
+    suborder[8] = 3;
+    suborder[9] = 3;
+    suborder[10] = 6;
+    suborder[11] = 6;
+    suborder[12] = 6;
+    suborder[13] = 6;
+    suborder[14] = 6;
+    suborder[15] = 6;
+    suborder[16] = 6;
+  }
+  else if (rule == 19)
+  {
+    suborder[0] = 1;
+    suborder[1] = 3;
+    suborder[2] = 3;
+    suborder[3] = 3;
+    suborder[4] = 3;
+    suborder[5] = 3;
+    suborder[6] = 3;
+    suborder[7] = 3;
+    suborder[8] = 3;
+    suborder[9] = 6;
+    suborder[10] = 6;
+    suborder[11] = 6;
+    suborder[12] = 6;
+    suborder[13] = 6;
+    suborder[14] = 6;
+    suborder[15] = 6;
+    suborder[16] = 6;
+  }
+  else if (rule == 20)
+  {
+    suborder[0] = 1;
+    suborder[1] = 3;
+    suborder[2] = 3;
+    suborder[3] = 3;
+    suborder[4] = 3;
+    suborder[5] = 3;
+    suborder[6] = 3;
+    suborder[7] = 3;
+    suborder[8] = 3;
+    suborder[9] = 3;
+    suborder[10] = 3;
+    suborder[11] = 6;
+    suborder[12] = 6;
+    suborder[13] = 6;
+    suborder[14] = 6;
+    suborder[15] = 6;
+    suborder[16] = 6;
+    suborder[17] = 6;
+    suborder[18] = 6;
+  }
+  else
+  {
+    dolfin_error("SimplexQuadrature.cpp",
+                 "compute quadrature rule for triangle",
+                 "dunavant_suborder not implemented for rule ", rule);
+  }
+
+  return suborder;
+}
+//****************************************************************************80
+
+std::size_t SimplexQuadrature::dunavant_suborder_num(int rule)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    DUNAVANT_SUBORDER_NUM returns the number of suborders for a Dunavant rule.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 December 2006
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    David Dunavant,
+//    High Degree Efficient Symmetrical Gaussian Quadrature Rules
+//    for the Triangle,
+//    International Journal for Numerical Methods in Engineering,
+//    Volume 21, 1985, pages 1129-1148.
+//
+//    James Lyness, Dennis Jespersen,
+//    Moderate Degree Symmetric Quadrature Rules for the Triangle,
+//    Journal of the Institute of Mathematics and its Applications,
+//    Volume 15, Number 1, February 1975, pages 19-32.
+//
+//  Parameters:
+//
+//    Input, int RULE, the index of the rule.
+//
+//    Output, int DUNAVANT_SUBORDER_NUM, the number of suborders of the rule.
+//
+{
+  std::size_t suborder_num = 0;
+
+  if (rule == 1)
+  {
+    suborder_num = 1;
+  }
+  else if (rule == 2)
+  {
+    suborder_num = 1;
+  }
+  else if (rule == 3)
+  {
+    suborder_num = 2;
+  }
+  else if (rule == 4)
+  {
+    suborder_num = 2;
+  }
+  else if (rule == 5)
+  {
+    suborder_num = 3;
+  }
+  else if (rule == 6)
+  {
+    suborder_num = 3;
+  }
+  else if (rule == 7)
+  {
+    suborder_num = 4;
+  }
+  else if (rule == 8)
+  {
+    suborder_num = 5;
+  }
+  else if (rule == 9)
+  {
+    suborder_num = 6;
+  }
+  else if (rule == 10)
+  {
+    suborder_num = 6;
+  }
+  else if (rule == 11)
+  {
+    suborder_num = 7;
+  }
+  else if (rule == 12)
+  {
+    suborder_num = 8;
+  }
+  else if (rule == 13)
+  {
+    suborder_num = 10;
+  }
+  else if (rule == 14)
+  {
+    suborder_num = 10;
+  }
+  else if (rule == 15)
+  {
+    suborder_num = 11;
+  }
+  else if (rule == 16)
+  {
+    suborder_num = 13;
+  }
+  else if (rule == 17)
+  {
+    suborder_num = 15;
+  }
+  else if (rule == 18)
+  {
+    suborder_num = 17;
+  }
+  else if (rule == 19)
+  {
+    suborder_num = 17;
+  }
+  else if (rule == 20)
+  {
+    suborder_num = 19;
+  }
+  else
+  {
+    dolfin_error("SimplexQuadrature.cpp",
+                 "compute quadrature rule for triangle",
+                 "dunavant_suborder_num not implemented for rule ", rule);
+  }
+
+  return suborder_num;
+}
+//****************************************************************************80
+
+void SimplexQuadrature::dunavant_subrule(std::size_t rule,
+					 std::size_t suborder_num,
+					 std::vector<double>& suborder_xyz,
+					 std::vector<double>& suborder_w)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    DUNAVANT_SUBRULE returns a compressed Dunavant rule.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 December 2006
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    David Dunavant,
+//    High Degree Efficient Symmetrical Gaussian Quadrature Rules
+//    for the Triangle,
+//    International Journal for Numerical Methods in Engineering,
+//    Volume 21, 1985, pages 1129-1148.
+//
+//    James Lyness, Dennis Jespersen,
+//    Moderate Degree Symmetric Quadrature Rules for the Triangle,
+//    Journal of the Institute of Mathematics and its Applications,
+//    Volume 15, Number 1, February 1975, pages 19-32.
+//
+//  Parameters:
+//
+//    Input, int RULE, the index of the rule.
+//
+//    Input, int SUBORDER_NUM, the number of suborders of the rule.
+//
+//    Output, double SUBORDER_XYZ[3*SUBORDER_NUM],
+//    the barycentric coordinates of the abscissas.
+//
+//    Output, double SUBORDER_W[SUBORDER_NUM], the suborder weights.
+//
+{
+  if (rule == 1)
+  {
+    dunavant_subrule_01(suborder_num, suborder_xyz, suborder_w);
+  }
+  else if (rule == 2)
+  {
+    dunavant_subrule_02(suborder_num, suborder_xyz, suborder_w);
+  }
+  else if (rule == 3)
+  {
+    dunavant_subrule_03(suborder_num, suborder_xyz, suborder_w);
+  }
+  else if (rule == 4)
+  {
+    dunavant_subrule_04(suborder_num, suborder_xyz, suborder_w);
+  }
+  else if (rule == 5)
+  {
+    dunavant_subrule_05(suborder_num, suborder_xyz, suborder_w);
+  }
+  else if (rule == 6)
+  {
+    dunavant_subrule_06(suborder_num, suborder_xyz, suborder_w);
+  }
+  else if (rule == 7)
+  {
+    dunavant_subrule_07(suborder_num, suborder_xyz, suborder_w);
+  }
+  else if (rule == 8)
+  {
+    dunavant_subrule_08(suborder_num, suborder_xyz, suborder_w);
+  }
+  else if (rule == 9)
+  {
+    dunavant_subrule_09(suborder_num, suborder_xyz, suborder_w);
+  }
+  else if (rule == 10)
+  {
+    dunavant_subrule_10(suborder_num, suborder_xyz, suborder_w);
+  }
+  else if (rule == 11)
+  {
+    dunavant_subrule_11(suborder_num, suborder_xyz, suborder_w);
+  }
+  else if (rule == 12)
+  {
+    dunavant_subrule_12(suborder_num, suborder_xyz, suborder_w);
+  }
+  else if (rule == 13)
+  {
+    dunavant_subrule_13(suborder_num, suborder_xyz, suborder_w);
+  }
+  else if (rule == 14)
+  {
+    dunavant_subrule_14(suborder_num, suborder_xyz, suborder_w);
+  }
+  else if (rule == 15)
+  {
+    dunavant_subrule_15(suborder_num, suborder_xyz, suborder_w);
+  }
+  else if (rule == 16)
+  {
+    dunavant_subrule_16(suborder_num, suborder_xyz, suborder_w);
+  }
+  else if (rule == 17)
+  {
+    dunavant_subrule_17(suborder_num, suborder_xyz, suborder_w);
+  }
+  else if (rule == 18)
+  {
+    dunavant_subrule_18(suborder_num, suborder_xyz, suborder_w);
+  }
+  else if (rule == 19)
+  {
+    dunavant_subrule_19(suborder_num, suborder_xyz, suborder_w);
+  }
+  else if (rule == 20)
+  {
+    dunavant_subrule_20(suborder_num, suborder_xyz, suborder_w);
+  }
+  else
+  {
+    dolfin_error("SimplexQuadrature.cpp",
+                 "compute quadrature rule for triangle",
+                 "dunavant_subrule not implemented for rule ", rule);
+  }
+
+  return;
+}
+
+//-----------------------------------------------------------------------------
+void SimplexQuadrature::dunavant_subrule_01(int suborder_num, std::vector<double>& suborder_xyz,
+					    std::vector<double>& suborder_w)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    DUNAVANT_SUBRULE_01 returns a compressed Dunavant rule 1.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 December 2006
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    David Dunavant,
+//    High Degree Efficient Symmetrical Gaussian Quadrature Rules
+//    for the Triangle,
+//    International Journal for Numerical Methods in Engineering,
+//    Volume 21, 1985, pages 1129-1148.
+//
+//    James Lyness, Dennis Jespersen,
+//    Moderate Degree Symmetric Quadrature Rules for the Triangle,
+//    Journal of the Institute of Mathematics and its Applications,
+//    Volume 15, Number 1, February 1975, pages 19-32.
+//
+//  Parameters:
+//
+//    Input, int SUBORDER_NUM, the number of suborders of the rule.
+//
+//    Output, double SUBORDER_XYZ[3*SUBORDER_NUM],
+//    the barycentric coordinates of the abscissas.
+//
+//    Output, double SUBORDER_W[SUBORDER_NUM], the suborder weights.
+//
+{
+  int s;
+  double suborder_xy_rule_01[3*1] = {
+    0.333333333333333,  0.333333333333333, 0.333333333333333
+  };
+  double suborder_w_rule_01[1] = {
+    1.000000000000000
+  };
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_xyz[0+s*3] = suborder_xy_rule_01[0+s*3];
+    suborder_xyz[1+s*3] = suborder_xy_rule_01[1+s*3];
+    suborder_xyz[2+s*3] = suborder_xy_rule_01[2+s*3];
+  }
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_w[s] = suborder_w_rule_01[s];
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void SimplexQuadrature::dunavant_subrule_02(int suborder_num, std::vector<double>& suborder_xyz,
+					    std::vector<double>& suborder_w)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    DUNAVANT_SUBRULE_02 returns a compressed Dunavant rule 2.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 December 2006
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    David Dunavant,
+//    High Degree Efficient Symmetrical Gaussian Quadrature Rules
+//    for the Triangle,
+//    International Journal for Numerical Methods in Engineering,
+//    Volume 21, 1985, pages 1129-1148.
+//
+//    James Lyness, Dennis Jespersen,
+//    Moderate Degree Symmetric Quadrature Rules for the Triangle,
+//    Journal of the Institute of Mathematics and its Applications,
+//    Volume 15, Number 1, February 1975, pages 19-32.
+//
+//  Parameters:
+//
+//    Input, int SUBORDER_NUM, the number of suborders of the rule.
+//
+//    Output, double SUBORDER_XYZ[3*SUBORDER_NUM],
+//    the barycentric coordinates of the abscissas.
+//
+//    Output, double SUBORDER_W[SUBORDER_NUM], the suborder weights.
+//
+{
+  int s;
+  double suborder_xy_rule_02[3*1] = {
+    0.666666666666667, 0.166666666666667, 0.166666666666667
+  };
+  double suborder_w_rule_02[1] = {
+    0.333333333333333
+  };
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_xyz[0+s*3] = suborder_xy_rule_02[0+s*3];
+    suborder_xyz[1+s*3] = suborder_xy_rule_02[1+s*3];
+    suborder_xyz[2+s*3] = suborder_xy_rule_02[2+s*3];
+  }
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_w[s] = suborder_w_rule_02[s];
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void SimplexQuadrature::dunavant_subrule_03(int suborder_num, std::vector<double>& suborder_xyz,
+					    std::vector<double>& suborder_w)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    DUNAVANT_SUBRULE_03 returns a compressed Dunavant rule 3.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 December 2006
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    David Dunavant,
+//    High Degree Efficient Symmetrical Gaussian Quadrature Rules
+//    for the Triangle,
+//    International Journal for Numerical Methods in Engineering,
+//    Volume 21, 1985, pages 1129-1148.
+//
+//    James Lyness, Dennis Jespersen,
+//    Moderate Degree Symmetric Quadrature Rules for the Triangle,
+//    Journal of the Institute of Mathematics and its Applications,
+//    Volume 15, Number 1, February 1975, pages 19-32.
+//
+//  Parameters:
+//
+//    Input, int SUBORDER_NUM, the number of suborders of the rule.
+//
+//    Output, double SUBORDER_XYZ[3*SUBORDER_NUM],
+//    the barycentric coordinates of the abscissas.
+//
+//    Output, double SUBORDER_W[SUBORDER_NUM], the suborder weights.
+//
+{
+  int s;
+  double suborder_xy_rule_03[3*2] = {
+    0.333333333333333, 0.333333333333333, 0.333333333333333,
+    0.600000000000000, 0.200000000000000, 0.200000000000000
+  };
+  double suborder_w_rule_03[2] = {
+    -0.562500000000000,
+    0.520833333333333
+  };
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_xyz[0+s*3] = suborder_xy_rule_03[0+s*3];
+    suborder_xyz[1+s*3] = suborder_xy_rule_03[1+s*3];
+    suborder_xyz[2+s*3] = suborder_xy_rule_03[2+s*3];
+  }
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_w[s] = suborder_w_rule_03[s];
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void SimplexQuadrature::dunavant_subrule_04(int suborder_num, std::vector<double>& suborder_xyz,
+					    std::vector<double>& suborder_w)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    DUNAVANT_SUBRULE_04 returns a compressed Dunavant rule 4.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 December 2006
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    David Dunavant,
+//    High Degree Efficient Symmetrical Gaussian Quadrature Rules
+//    for the Triangle,
+//    International Journal for Numerical Methods in Engineering,
+//    Volume 21, 1985, pages 1129-1148.
+//
+//    James Lyness, Dennis Jespersen,
+//    Moderate Degree Symmetric Quadrature Rules for the Triangle,
+//    Journal of the Institute of Mathematics and its Applications,
+//    Volume 15, Number 1, February 1975, pages 19-32.
+//
+//  Parameters:
+//
+//    Input, int SUBORDER_NUM, the number of suborders of the rule.
+//
+//    Output, double SUBORDER_XYZ[3*SUBORDER_NUM],
+//    the barycentric coordinates of the abscissas.
+//
+//    Output, double SUBORDER_W[SUBORDER_NUM], the suborder weights.
+//
+{
+  int s;
+  double suborder_xy_rule_04[3*2] = {
+    0.108103018168070, 0.445948490915965, 0.445948490915965,
+    0.816847572980459, 0.091576213509771, 0.091576213509771
+  };
+  double suborder_w_rule_04[2] = {
+    0.223381589678011,
+    0.109951743655322
+  };
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_xyz[0+s*3] = suborder_xy_rule_04[0+s*3];
+    suborder_xyz[1+s*3] = suborder_xy_rule_04[1+s*3];
+    suborder_xyz[2+s*3] = suborder_xy_rule_04[2+s*3];
+  }
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_w[s] = suborder_w_rule_04[s];
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void SimplexQuadrature::dunavant_subrule_05(int suborder_num, std::vector<double>& suborder_xyz,
+					    std::vector<double>& suborder_w)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    DUNAVANT_SUBRULE_05 returns a compressed Dunavant rule 5.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 December 2006
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    David Dunavant,
+//    High Degree Efficient Symmetrical Gaussian Quadrature Rules
+//    for the Triangle,
+//    International Journal for Numerical Methods in Engineering,
+//    Volume 21, 1985, pages 1129-1148.
+//
+//    James Lyness, Dennis Jespersen,
+//    Moderate Degree Symmetric Quadrature Rules for the Triangle,
+//    Journal of the Institute of Mathematics and its Applications,
+//    Volume 15, Number 1, February 1975, pages 19-32.
+//
+//  Parameters:
+//
+//    Input, int SUBORDER_NUM, the number of suborders of the rule.
+//
+//    Output, double SUBORDER_XYZ[3*SUBORDER_NUM],
+//    the barycentric coordinates of the abscissas.
+//
+//    Output, double SUBORDER_W[SUBORDER_NUM], the suborder weights.
+//
+{
+  int s;
+  double suborder_xy_rule_05[3*3] = {
+    0.333333333333333, 0.333333333333333, 0.333333333333333,
+    0.059715871789770, 0.470142064105115, 0.470142064105115,
+    0.797426985353087, 0.101286507323456, 0.101286507323456
+  };
+  double suborder_w_rule_05[3] = {
+    0.225000000000000,
+    0.132394152788506,
+    0.125939180544827
+  };
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_xyz[0+s*3] = suborder_xy_rule_05[0+s*3];
+    suborder_xyz[1+s*3] = suborder_xy_rule_05[1+s*3];
+    suborder_xyz[2+s*3] = suborder_xy_rule_05[2+s*3];
+  }
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_w[s] = suborder_w_rule_05[s];
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void SimplexQuadrature::dunavant_subrule_06(int suborder_num, std::vector<double>& suborder_xyz,
+					    std::vector<double>& suborder_w)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    DUNAVANT_SUBRULE_06 returns a compressed Dunavant rule 6.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 December 2006
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    David Dunavant,
+//    High Degree Efficient Symmetrical Gaussian Quadrature Rules
+//    for the Triangle,
+//    International Journal for Numerical Methods in Engineering,
+//    Volume 21, 1985, pages 1129-1148.
+//
+//    James Lyness, Dennis Jespersen,
+//    Moderate Degree Symmetric Quadrature Rules for the Triangle,
+//    Journal of the Institute of Mathematics and its Applications,
+//    Volume 15, Number 1, February 1975, pages 19-32.
+//
+//  Parameters:
+//
+//    Input, int SUBORDER_NUM, the number of suborders of the rule.
+//
+//    Output, double SUBORDER_XYZ[3*SUBORDER_NUM],
+//    the barycentric coordinates of the abscissas.
+//
+//    Output, double SUBORDER_W[SUBORDER_NUM], the suborder weights.
+//
+{
+  int s;
+  double suborder_xy_rule_06[3*3] = {
+    0.501426509658179, 0.249286745170910, 0.249286745170910,
+    0.873821971016996, 0.063089014491502, 0.063089014491502,
+    0.053145049844817, 0.310352451033784, 0.636502499121399
+  };
+  double suborder_w_rule_06[3] = {
+    0.116786275726379,
+    0.050844906370207,
+    0.082851075618374
+  };
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_xyz[0+s*3] = suborder_xy_rule_06[0+s*3];
+    suborder_xyz[1+s*3] = suborder_xy_rule_06[1+s*3];
+    suborder_xyz[2+s*3] = suborder_xy_rule_06[2+s*3];
+  }
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_w[s] = suborder_w_rule_06[s];
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void SimplexQuadrature::dunavant_subrule_07(int suborder_num, std::vector<double>& suborder_xyz,
+					    std::vector<double>& suborder_w)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    DUNAVANT_SUBRULE_07 returns a compressed Dunavant rule 7.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 December 2006
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    David Dunavant,
+//    High Degree Efficient Symmetrical Gaussian Quadrature Rules
+//    for the Triangle,
+//    International Journal for Numerical Methods in Engineering,
+//    Volume 21, 1985, pages 1129-1148.
+//
+//    James Lyness, Dennis Jespersen,
+//    Moderate Degree Symmetric Quadrature Rules for the Triangle,
+//    Journal of the Institute of Mathematics and its Applications,
+//    Volume 15, Number 1, February 1975, pages 19-32.
+//
+//  Parameters:
+//
+//    Input, int SUBORDER_NUM, the number of suborders of the rule.
+//
+//    Output, double SUBORDER_XYZ[3*SUBORDER_NUM],
+//    the barycentric coordinates of the abscissas.
+//
+//    Output, double SUBORDER_W[SUBORDER_NUM], the suborder weights.
+//
+{
+  int s;
+  double suborder_xy_rule_07[3*4] = {
+    0.333333333333333, 0.333333333333333, 0.333333333333333,
+    0.479308067841920, 0.260345966079040, 0.260345966079040,
+    0.869739794195568, 0.065130102902216, 0.065130102902216,
+    0.048690315425316, 0.312865496004874, 0.638444188569810
+  };
+  double suborder_w_rule_07[4] = {
+    -0.149570044467682,
+    0.175615257433208,
+    0.053347235608838,
+    0.077113760890257
+  };
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_xyz[0+s*3] = suborder_xy_rule_07[0+s*3];
+    suborder_xyz[1+s*3] = suborder_xy_rule_07[1+s*3];
+    suborder_xyz[2+s*3] = suborder_xy_rule_07[2+s*3];
+  }
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_w[s] = suborder_w_rule_07[s];
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void SimplexQuadrature::dunavant_subrule_08(int suborder_num, std::vector<double>& suborder_xyz,
+					    std::vector<double>& suborder_w)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    DUNAVANT_SUBRULE_08 returns a compressed Dunavant rule 8.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 December 2006
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    David Dunavant,
+//    High Degree Efficient Symmetrical Gaussian Quadrature Rules
+//    for the Triangle,
+//    International Journal for Numerical Methods in Engineering,
+//    Volume 21, 1985, pages 1129-1148.
+//
+//    James Lyness, Dennis Jespersen,
+//    Moderate Degree Symmetric Quadrature Rules for the Triangle,
+//    Journal of the Institute of Mathematics and its Applications,
+//    Volume 15, Number 1, February 1975, pages 19-32.
+//
+//  Parameters:
+//
+//    Input, int SUBORDER_NUM, the number of suborders of the rule.
+//
+//    Output, double SUBORDER_XYZ[3*SUBORDER_NUM],
+//    the barycentric coordinates of the abscissas.
+//
+//    Output, double SUBORDER_W[SUBORDER_NUM], the suborder weights.
+//
+{
+  int s;
+  double suborder_xy_rule_08[3*5] = {
+    0.333333333333333, 0.333333333333333, 0.333333333333333,
+    0.081414823414554, 0.459292588292723, 0.459292588292723,
+    0.658861384496480, 0.170569307751760, 0.170569307751760,
+    0.898905543365938, 0.050547228317031, 0.050547228317031,
+    0.008394777409958, 0.263112829634638, 0.728492392955404
+  };
+  double suborder_w_rule_08[5] = {
+    0.144315607677787,
+    0.095091634267285,
+    0.103217370534718,
+    0.032458497623198,
+    0.027230314174435
+  };
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_xyz[0+s*3] = suborder_xy_rule_08[0+s*3];
+    suborder_xyz[1+s*3] = suborder_xy_rule_08[1+s*3];
+    suborder_xyz[2+s*3] = suborder_xy_rule_08[2+s*3];
+  }
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_w[s] = suborder_w_rule_08[s];
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void SimplexQuadrature::dunavant_subrule_09(int suborder_num, std::vector<double>& suborder_xyz,
+					    std::vector<double>& suborder_w)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    DUNAVANT_SUBRULE_09 returns a compressed Dunavant rule 9.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 December 2006
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    David Dunavant,
+//    High Degree Efficient Symmetrical Gaussian Quadrature Rules
+//    for the Triangle,
+//    International Journal for Numerical Methods in Engineering,
+//    Volume 21, 1985, pages 1129-1148.
+//
+//    James Lyness, Dennis Jespersen,
+//    Moderate Degree Symmetric Quadrature Rules for the Triangle,
+//    Journal of the Institute of Mathematics and its Applications,
+//    Volume 15, Number 1, February 1975, pages 19-32.
+//
+//  Parameters:
+//
+//    Input, int SUBORDER_NUM, the number of suborders of the rule.
+//
+//    Output, double SUBORDER_XYZ[3*SUBORDER_NUM],
+//    the barycentric coordinates of the abscissas.
+//
+//    Output, double SUBORDER_W[SUBORDER_NUM], the suborder weights.
+//
+{
+  int s;
+  double suborder_xy_rule_09[3*6] = {
+    0.333333333333333, 0.333333333333333, 0.333333333333333,
+    0.020634961602525, 0.489682519198738, 0.489682519198738,
+    0.125820817014127, 0.437089591492937, 0.437089591492937,
+    0.623592928761935, 0.188203535619033, 0.188203535619033,
+    0.910540973211095, 0.044729513394453, 0.044729513394453,
+    0.036838412054736, 0.221962989160766, 0.741198598784498
+  };
+  double suborder_w_rule_09[6] = {
+    0.097135796282799,
+    0.031334700227139,
+    0.077827541004774,
+    0.079647738927210,
+    0.025577675658698,
+    0.043283539377289
+  };
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_xyz[0+s*3] = suborder_xy_rule_09[0+s*3];
+    suborder_xyz[1+s*3] = suborder_xy_rule_09[1+s*3];
+    suborder_xyz[2+s*3] = suborder_xy_rule_09[2+s*3];
+  }
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_w[s] = suborder_w_rule_09[s];
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void SimplexQuadrature::dunavant_subrule_10(int suborder_num, std::vector<double>& suborder_xyz,
+					    std::vector<double>& suborder_w)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    DUNAVANT_SUBRULE_10 returns a compressed Dunavant rule 10.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 December 2006
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    David Dunavant,
+//    High Degree Efficient Symmetrical Gaussian Quadrature Rules
+//    for the Triangle,
+//    International Journal for Numerical Methods in Engineering,
+//    Volume 21, 1985, pages 1129-1148.
+//
+//    James Lyness, Dennis Jespersen,
+//    Moderate Degree Symmetric Quadrature Rules for the Triangle,
+//    Journal of the Institute of Mathematics and its Applications,
+//    Volume 15, Number 1, February 1975, pages 19-32.
+//
+//  Parameters:
+//
+//    Input, int SUBORDER_NUM, the number of suborders of the rule.
+//
+//    Output, double SUBORDER_XYZ[3*SUBORDER_NUM],
+//    the barycentric coordinates of the abscissas.
+//
+//    Output, double SUBORDER_W[SUBORDER_NUM], the suborder weights.
+//
+{
+  int s;
+  double suborder_xy_rule_10[3*6] = {
+    0.333333333333333, 0.333333333333333, 0.333333333333333,
+    0.028844733232685, 0.485577633383657, 0.485577633383657,
+    0.781036849029926, 0.109481575485037, 0.109481575485037,
+    0.141707219414880, 0.307939838764121, 0.550352941820999,
+    0.025003534762686, 0.246672560639903, 0.728323904597411,
+    0.009540815400299, 0.066803251012200, 0.923655933587500
+  };
+  double suborder_w_rule_10[6] = {
+    0.090817990382754,
+    0.036725957756467,
+    0.045321059435528,
+    0.072757916845420,
+    0.028327242531057,
+    0.009421666963733
+  };
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_xyz[0+s*3] = suborder_xy_rule_10[0+s*3];
+    suborder_xyz[1+s*3] = suborder_xy_rule_10[1+s*3];
+    suborder_xyz[2+s*3] = suborder_xy_rule_10[2+s*3];
+  }
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_w[s] = suborder_w_rule_10[s];
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void SimplexQuadrature::dunavant_subrule_11(int suborder_num, std::vector<double>& suborder_xyz,
+					    std::vector<double>& suborder_w)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    DUNAVANT_SUBRULE_11 returns a compressed Dunavant rule 11.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 December 2006
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    David Dunavant,
+//    High Degree Efficient Symmetrical Gaussian Quadrature Rules
+//    for the Triangle,
+//    International Journal for Numerical Methods in Engineering,
+//    Volume 21, 1985, pages 1129-1148.
+//
+//    James Lyness, Dennis Jespersen,
+//    Moderate Degree Symmetric Quadrature Rules for the Triangle,
+//    Journal of the Institute of Mathematics and its Applications,
+//    Volume 15, Number 1, February 1975, pages 19-32.
+//
+//  Parameters:
+//
+//    Input, int SUBORDER_NUM, the number of suborders of the rule.
+//
+//    Output, double SUBORDER_XYZ[3*SUBORDER_NUM],
+//    the barycentric coordinates of the abscissas.
+//
+//    Output, double SUBORDER_W[SUBORDER_NUM], the suborder weights.
+//
+{
+  int s;
+  double suborder_xy_rule_11[3*7] = {
+    -0.069222096541517, 0.534611048270758, 0.534611048270758,
+    0.202061394068290, 0.398969302965855, 0.398969302965855,
+    0.593380199137435, 0.203309900431282, 0.203309900431282,
+    0.761298175434837, 0.119350912282581, 0.119350912282581,
+    0.935270103777448, 0.032364948111276, 0.032364948111276,
+    0.050178138310495, 0.356620648261293, 0.593201213428213,
+    0.021022016536166, 0.171488980304042, 0.807489003159792
+  };
+  double suborder_w_rule_11[7] = {
+    0.000927006328961,
+    0.077149534914813,
+    0.059322977380774,
+    0.036184540503418,
+    0.013659731002678,
+    0.052337111962204,
+    0.020707659639141
+  };
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_xyz[0+s*3] = suborder_xy_rule_11[0+s*3];
+    suborder_xyz[1+s*3] = suborder_xy_rule_11[1+s*3];
+    suborder_xyz[2+s*3] = suborder_xy_rule_11[2+s*3];
+  }
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_w[s] = suborder_w_rule_11[s];
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void SimplexQuadrature::dunavant_subrule_12(int suborder_num, std::vector<double>& suborder_xyz,
+					    std::vector<double>& suborder_w)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    DUNAVANT_SUBRULE_12 returns a compressed Dunavant rule 12.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 December 2006
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    David Dunavant,
+//    High Degree Efficient Symmetrical Gaussian Quadrature Rules
+//    for the Triangle,
+//    International Journal for Numerical Methods in Engineering,
+//    Volume 21, 1985, pages 1129-1148.
+//
+//    James Lyness, Dennis Jespersen,
+//    Moderate Degree Symmetric Quadrature Rules for the Triangle,
+//    Journal of the Institute of Mathematics and its Applications,
+//    Volume 15, Number 1, February 1975, pages 19-32.
+//
+//  Parameters:
+//
+//    Input, int SUBORDER_NUM, the number of suborders of the rule.
+//
+//    Output, double SUBORDER_XYZ[3*SUBORDER_NUM],
+//    the barycentric coordinates of the abscissas.
+//
+//    Output, double SUBORDER_W[SUBORDER_NUM], the suborder weights.
+//
+{
+  int s;
+  double suborder_xy_rule_12[3*8] = {
+    0.023565220452390, 0.488217389773805, 0.488217389773805,
+    0.120551215411079, 0.439724392294460, 0.439724392294460,
+    0.457579229975768, 0.271210385012116, 0.271210385012116,
+    0.744847708916828, 0.127576145541586, 0.127576145541586,
+    0.957365299093579, 0.021317350453210, 0.021317350453210,
+    0.115343494534698, 0.275713269685514, 0.608943235779788,
+    0.022838332222257, 0.281325580989940, 0.695836086787803,
+    0.025734050548330, 0.116251915907597, 0.858014033544073
+  };
+  double suborder_w_rule_12[8] = {
+    0.025731066440455,
+    0.043692544538038,
+    0.062858224217885,
+    0.034796112930709,
+    0.006166261051559,
+    0.040371557766381,
+    0.022356773202303,
+    0.017316231108659
+  };
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_xyz[0+s*3] = suborder_xy_rule_12[0+s*3];
+    suborder_xyz[1+s*3] = suborder_xy_rule_12[1+s*3];
+    suborder_xyz[2+s*3] = suborder_xy_rule_12[2+s*3];
+  }
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_w[s] = suborder_w_rule_12[s];
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void SimplexQuadrature::dunavant_subrule_13(int suborder_num, std::vector<double>& suborder_xyz,
+					    std::vector<double>& suborder_w)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    DUNAVANT_SUBRULE_13 returns a compressed Dunavant rule 13.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 December 2006
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    David Dunavant,
+//    High Degree Efficient Symmetrical Gaussian Quadrature Rules
+//    for the Triangle,
+//    International Journal for Numerical Methods in Engineering,
+//    Volume 21, 1985, pages 1129-1148.
+//
+//    James Lyness, Dennis Jespersen,
+//    Moderate Degree Symmetric Quadrature Rules for the Triangle,
+//    Journal of the Institute of Mathematics and its Applications,
+//    Volume 15, Number 1, February 1975, pages 19-32.
+//
+//  Parameters:
+//
+//    Input, int SUBORDER_NUM, the number of suborders of the rule.
+//
+//    Output, double SUBORDER_XYZ[3*SUBORDER_NUM],
+//    the barycentric coordinates of the abscissas.
+//
+//    Output, double SUBORDER_W[SUBORDER_NUM], the suborder weights.
+//
+{
+  int s;
+  double suborder_xy_rule_13[3*10] = {
+    0.333333333333333, 0.333333333333333, 0.333333333333333,
+    0.009903630120591, 0.495048184939705, 0.495048184939705,
+    0.062566729780852, 0.468716635109574, 0.468716635109574,
+    0.170957326397447, 0.414521336801277, 0.414521336801277,
+    0.541200855914337, 0.229399572042831, 0.229399572042831,
+    0.771151009607340, 0.114424495196330, 0.114424495196330,
+    0.950377217273082, 0.024811391363459, 0.024811391363459,
+    0.094853828379579, 0.268794997058761, 0.636351174561660,
+    0.018100773278807, 0.291730066734288, 0.690169159986905,
+    0.022233076674090, 0.126357385491669, 0.851409537834241
+  };
+  double suborder_w_rule_13[10] = {
+    0.052520923400802,
+    0.011280145209330,
+    0.031423518362454,
+    0.047072502504194,
+    0.047363586536355,
+    0.031167529045794,
+    0.007975771465074,
+    0.036848402728732,
+    0.017401463303822,
+    0.015521786839045
+  };
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_xyz[0+s*3] = suborder_xy_rule_13[0+s*3];
+    suborder_xyz[1+s*3] = suborder_xy_rule_13[1+s*3];
+    suborder_xyz[2+s*3] = suborder_xy_rule_13[2+s*3];
+  }
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_w[s] = suborder_w_rule_13[s];
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void SimplexQuadrature::dunavant_subrule_14(int suborder_num, std::vector<double>& suborder_xyz,
+					    std::vector<double>& suborder_w)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    DUNAVANT_SUBRULE_14 returns a compressed Dunavant rule 14.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 December 2006
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    David Dunavant,
+//    High Degree Efficient Symmetrical Gaussian Quadrature Rules
+//    for the Triangle,
+//    International Journal for Numerical Methods in Engineering,
+//    Volume 21, 1985, pages 1129-1148.
+//
+//    James Lyness, Dennis Jespersen,
+//    Moderate Degree Symmetric Quadrature Rules for the Triangle,
+//    Journal of the Institute of Mathematics and its Applications,
+//    Volume 15, Number 1, February 1975, pages 19-32.
+//
+//  Parameters:
+//
+//    Input, int SUBORDER_NUM, the number of suborders of the rule.
+//
+//    Output, double SUBORDER_XYZ[3*SUBORDER_NUM],
+//    the barycentric coordinates of the abscissas.
+//
+//    Output, double SUBORDER_W[SUBORDER_NUM], the suborder weights.
+//
+{
+  int s;
+  double suborder_xy_rule_14[3*10] = {
+    0.022072179275643, 0.488963910362179, 0.488963910362179,
+    0.164710561319092, 0.417644719340454, 0.417644719340454,
+    0.453044943382323, 0.273477528308839, 0.273477528308839,
+    0.645588935174913, 0.177205532412543, 0.177205532412543,
+    0.876400233818255, 0.061799883090873, 0.061799883090873,
+    0.961218077502598, 0.019390961248701, 0.019390961248701,
+    0.057124757403648, 0.172266687821356, 0.770608554774996,
+    0.092916249356972, 0.336861459796345, 0.570222290846683,
+    0.014646950055654, 0.298372882136258, 0.686980167808088,
+    0.001268330932872, 0.118974497696957, 0.879757171370171
+  };
+  double suborder_w_rule_14[10] = {
+    0.021883581369429,
+    0.032788353544125,
+    0.051774104507292,
+    0.042162588736993,
+    0.014433699669777,
+    0.004923403602400,
+    0.024665753212564,
+    0.038571510787061,
+    0.014436308113534,
+    0.005010228838501
+  };
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_xyz[0+s*3] = suborder_xy_rule_14[0+s*3];
+    suborder_xyz[1+s*3] = suborder_xy_rule_14[1+s*3];
+    suborder_xyz[2+s*3] = suborder_xy_rule_14[2+s*3];
+  }
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_w[s] = suborder_w_rule_14[s];
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void SimplexQuadrature::dunavant_subrule_15(int suborder_num, std::vector<double>& suborder_xyz,
+					    std::vector<double>& suborder_w)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    DUNAVANT_SUBRULE_15 returns a compressed Dunavant rule 15.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 December 2006
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    David Dunavant,
+//    High Degree Efficient Symmetrical Gaussian Quadrature Rules
+//    for the Triangle,
+//    International Journal for Numerical Methods in Engineering,
+//    Volume 21, 1985, pages 1129-1148.
+//
+//    James Lyness, Dennis Jespersen,
+//    Moderate Degree Symmetric Quadrature Rules for the Triangle,
+//    Journal of the Institute of Mathematics and its Applications,
+//    Volume 15, Number 1, February 1975, pages 19-32.
+//
+//  Parameters:
+//
+//    Input, int SUBORDER_NUM, the number of suborders of the rule.
+//
+//    Output, double SUBORDER_XYZ[3*SUBORDER_NUM],
+//    the barycentric coordinates of the abscissas.
+//
+//    Output, double SUBORDER_W[SUBORDER_NUM], the suborder weights.
+//
+{
+  int s;
+  double suborder_xy_rule_15[3*11] = {
+    -0.013945833716486, 0.506972916858243, 0.506972916858243,
+    0.137187291433955, 0.431406354283023, 0.431406354283023,
+    0.444612710305711, 0.277693644847144, 0.277693644847144,
+    0.747070217917492, 0.126464891041254, 0.126464891041254,
+    0.858383228050628, 0.070808385974686, 0.070808385974686,
+    0.962069659517853, 0.018965170241073, 0.018965170241073,
+    0.133734161966621, 0.261311371140087, 0.604954466893291,
+    0.036366677396917, 0.388046767090269, 0.575586555512814,
+    -0.010174883126571, 0.285712220049916, 0.724462663076655,
+    0.036843869875878, 0.215599664072284, 0.747556466051838,
+    0.012459809331199, 0.103575616576386, 0.883964574092416
+  };
+  double suborder_w_rule_15[11] = {
+    0.001916875642849,
+    0.044249027271145,
+    0.051186548718852,
+    0.023687735870688,
+    0.013289775690021,
+    0.004748916608192,
+    0.038550072599593,
+    0.027215814320624,
+    0.002182077366797,
+    0.021505319847731,
+    0.007673942631049
+  };
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_xyz[0+s*3] = suborder_xy_rule_15[0+s*3];
+    suborder_xyz[1+s*3] = suborder_xy_rule_15[1+s*3];
+    suborder_xyz[2+s*3] = suborder_xy_rule_15[2+s*3];
+  }
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_w[s] = suborder_w_rule_15[s];
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void SimplexQuadrature::dunavant_subrule_16(int suborder_num, std::vector<double>& suborder_xyz,
+					    std::vector<double>& suborder_w)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    DUNAVANT_SUBRULE_16 returns a compressed Dunavant rule 16.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 December 2006
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    David Dunavant,
+//    High Degree Efficient Symmetrical Gaussian Quadrature Rules
+//    for the Triangle,
+//    International Journal for Numerical Methods in Engineering,
+//    Volume 21, 1985, pages 1129-1148.
+//
+//    James Lyness, Dennis Jespersen,
+//    Moderate Degree Symmetric Quadrature Rules for the Triangle,
+//    Journal of the Institute of Mathematics and its Applications,
+//    Volume 15, Number 1, February 1975, pages 19-32.
+//
+//  Parameters:
+//
+//    Input, int SUBORDER_NUM, the number of suborders of the rule.
+//
+//    Output, double SUBORDER_XYZ[3*SUBORDER_NUM],
+//    the barycentric coordinates of the abscissas.
+//
+//    Output, double SUBORDER_W[SUBORDER_NUM], the suborder weights.
+//
+{
+  int s;
+  double suborder_xy_rule_16[3*13] = {
+    0.333333333333333, 0.333333333333333, 0.333333333333333,
+    0.005238916103123, 0.497380541948438, 0.497380541948438,
+    0.173061122901295, 0.413469438549352, 0.413469438549352,
+    0.059082801866017, 0.470458599066991, 0.470458599066991,
+    0.518892500060958, 0.240553749969521, 0.240553749969521,
+    0.704068411554854, 0.147965794222573, 0.147965794222573,
+    0.849069624685052, 0.075465187657474, 0.075465187657474,
+    0.966807194753950, 0.016596402623025, 0.016596402623025,
+    0.103575692245252, 0.296555596579887, 0.599868711174861,
+    0.020083411655416, 0.337723063403079, 0.642193524941505,
+    -0.004341002614139, 0.204748281642812, 0.799592720971327,
+    0.041941786468010, 0.189358492130623, 0.768699721401368,
+    0.014317320230681, 0.085283615682657, 0.900399064086661
+  };
+  double suborder_w_rule_16[13] = {
+    0.046875697427642,
+    0.006405878578585,
+    0.041710296739387,
+    0.026891484250064,
+    0.042132522761650,
+    0.030000266842773,
+    0.014200098925024,
+    0.003582462351273,
+    0.032773147460627,
+    0.015298306248441,
+    0.002386244192839,
+    0.019084792755899,
+    0.006850054546542
+  };
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_xyz[0+s*3] = suborder_xy_rule_16[0+s*3];
+    suborder_xyz[1+s*3] = suborder_xy_rule_16[1+s*3];
+    suborder_xyz[2+s*3] = suborder_xy_rule_16[2+s*3];
+  }
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_w[s] = suborder_w_rule_16[s];
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void SimplexQuadrature::dunavant_subrule_17(int suborder_num, std::vector<double>& suborder_xyz,
+					    std::vector<double>& suborder_w)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    DUNAVANT_SUBRULE_17 returns a compressed Dunavant rule 17.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 December 2006
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    David Dunavant,
+//    High Degree Efficient Symmetrical Gaussian Quadrature Rules
+//    for the Triangle,
+//    International Journal for Numerical Methods in Engineering,
+//    Volume 21, 1985, pages 1129-1148.
+//
+//    James Lyness, Dennis Jespersen,
+//    Moderate Degree Symmetric Quadrature Rules for the Triangle,
+//    Journal of the Institute of Mathematics and its Applications,
+//    Volume 15, Number 1, February 1975, pages 19-32.
+//
+//  Parameters:
+//
+//    Input, int SUBORDER_NUM, the number of suborders of the rule.
+//
+//    Output, double SUBORDER_XYZ[3*SUBORDER_NUM],
+//    the barycentric coordinates of the abscissas.
+//
+//    Output, double SUBORDER_W[SUBORDER_NUM], the suborder weights.
+//
+{
+  int s;
+  double suborder_xy_rule_17[3*15] = {
+    0.333333333333333, 0.333333333333333, 0.333333333333333,
+    0.005658918886452, 0.497170540556774, 0.497170540556774,
+    0.035647354750751, 0.482176322624625, 0.482176322624625,
+    0.099520061958437, 0.450239969020782, 0.450239969020782,
+    0.199467521245206, 0.400266239377397, 0.400266239377397,
+    0.495717464058095, 0.252141267970953, 0.252141267970953,
+    0.675905990683077, 0.162047004658461, 0.162047004658461,
+    0.848248235478508, 0.075875882260746, 0.075875882260746,
+    0.968690546064356, 0.015654726967822, 0.015654726967822,
+    0.010186928826919, 0.334319867363658, 0.655493203809423,
+    0.135440871671036, 0.292221537796944, 0.572337590532020,
+    0.054423924290583, 0.319574885423190, 0.626001190286228,
+    0.012868560833637, 0.190704224192292, 0.796427214974071,
+    0.067165782413524, 0.180483211648746, 0.752351005937729,
+    0.014663182224828, 0.080711313679564, 0.904625504095608
+  };
+  double suborder_w_rule_17[15] = {
+    0.033437199290803,
+    0.005093415440507,
+    0.014670864527638,
+    0.024350878353672,
+    0.031107550868969,
+    0.031257111218620,
+    0.024815654339665,
+    0.014056073070557,
+    0.003194676173779,
+    0.008119655318993,
+    0.026805742283163,
+    0.018459993210822,
+    0.008476868534328,
+    0.018292796770025,
+    0.006665632004165
+  };
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_xyz[0+s*3] = suborder_xy_rule_17[0+s*3];
+    suborder_xyz[1+s*3] = suborder_xy_rule_17[1+s*3];
+    suborder_xyz[2+s*3] = suborder_xy_rule_17[2+s*3];
+  }
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_w[s] = suborder_w_rule_17[s];
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void SimplexQuadrature::dunavant_subrule_18(int suborder_num, std::vector<double>& suborder_xyz,
+					    std::vector<double>& suborder_w)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    DUNAVANT_SUBRULE_18 returns a compressed Dunavant rule 18.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 December 2006
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    David Dunavant,
+//    High Degree Efficient Symmetrical Gaussian Quadrature Rules
+//    for the Triangle,
+//    International Journal for Numerical Methods in Engineering,
+//    Volume 21, 1985, pages 1129-1148.
+//
+//    James Lyness, Dennis Jespersen,
+//    Moderate Degree Symmetric Quadrature Rules for the Triangle,
+//    Journal of the Institute of Mathematics and its Applications,
+//    Volume 15, Number 1, February 1975, pages 19-32.
+//
+//  Parameters:
+//
+//    Input, int SUBORDER_NUM, the number of suborders of the rule.
+//
+//    Output, double SUBORDER_XYZ[3*SUBORDER_NUM],
+//    the barycentric coordinates of the abscissas.
+//
+//    Output, double SUBORDER_W[SUBORDER_NUM], the suborder weights.
+//
+{
+  int s;
+  double suborder_xy_rule_18[3*17] = {
+    0.333333333333333, 0.333333333333333, 0.333333333333333,
+    0.013310382738157, 0.493344808630921, 0.493344808630921,
+    0.061578811516086, 0.469210594241957, 0.469210594241957,
+    0.127437208225989, 0.436281395887006, 0.436281395887006,
+    0.210307658653168, 0.394846170673416, 0.394846170673416,
+    0.500410862393686, 0.249794568803157, 0.249794568803157,
+    0.677135612512315, 0.161432193743843, 0.161432193743843,
+    0.846803545029257, 0.076598227485371, 0.076598227485371,
+    0.951495121293100, 0.024252439353450, 0.024252439353450,
+    0.913707265566071, 0.043146367216965, 0.043146367216965,
+    0.008430536202420, 0.358911494940944, 0.632657968856636,
+    0.131186551737188, 0.294402476751957, 0.574410971510855,
+    0.050203151565675, 0.325017801641814, 0.624779046792512,
+    0.066329263810916, 0.184737559666046, 0.748933176523037,
+    0.011996194566236, 0.218796800013321, 0.769207005420443,
+    0.014858100590125, 0.101179597136408, 0.883962302273467,
+    -0.035222015287949, 0.020874755282586, 1.014347260005363
+  };
+  double suborder_w_rule_18[17] = {
+    0.030809939937647,
+    0.009072436679404,
+    0.018761316939594,
+    0.019441097985477,
+    0.027753948610810,
+    0.032256225351457,
+    0.025074032616922,
+    0.015271927971832,
+    0.006793922022963,
+    -0.002223098729920,
+    0.006331914076406,
+    0.027257538049138,
+    0.017676785649465,
+    0.018379484638070,
+    0.008104732808192,
+    0.007634129070725,
+    0.000046187660794
+  };
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_xyz[0+s*3] = suborder_xy_rule_18[0+s*3];
+    suborder_xyz[1+s*3] = suborder_xy_rule_18[1+s*3];
+    suborder_xyz[2+s*3] = suborder_xy_rule_18[2+s*3];
+  }
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_w[s] = suborder_w_rule_18[s];
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void SimplexQuadrature::dunavant_subrule_19(int suborder_num, std::vector<double>& suborder_xyz,
+					    std::vector<double>& suborder_w)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    DUNAVANT_SUBRULE_19 returns a compressed Dunavant rule 19.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 December 2006
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    David Dunavant,
+//    High Degree Efficient Symmetrical Gaussian Quadrature Rules
+//    for the Triangle,
+//    International Journal for Numerical Methods in Engineering,
+//    Volume 21, 1985, pages 1129-1148.
+//
+//    James Lyness, Dennis Jespersen,
+//    Moderate Degree Symmetric Quadrature Rules for the Triangle,
+//    Journal of the Institute of Mathematics and its Applications,
+//    Volume 15, Number 1, February 1975, pages 19-32.
+//
+//  Parameters:
+//
+//    Input, int SUBORDER_NUM, the number of suborders of the rule.
+//
+//    Output, double SUBORDER_XYZ[3*SUBORDER_NUM],
+//    the barycentric coordinates of the abscissas.
+//
+//    Output, double SUBORDER_W[SUBORDER_NUM], the suborder weights.
+//
+{
+  int s;
+  double suborder_xy_rule_19[3*17] = {
+    0.333333333333333, 0.333333333333333, 0.333333333333333,
+    0.020780025853987, 0.489609987073006, 0.489609987073006,
+    0.090926214604215, 0.454536892697893, 0.454536892697893,
+    0.197166638701138, 0.401416680649431, 0.401416680649431,
+    0.488896691193805, 0.255551654403098, 0.255551654403098,
+    0.645844115695741, 0.177077942152130, 0.177077942152130,
+    0.779877893544096, 0.110061053227952, 0.110061053227952,
+    0.888942751496321, 0.055528624251840, 0.055528624251840,
+    0.974756272445543, 0.012621863777229, 0.012621863777229,
+    0.003611417848412, 0.395754787356943, 0.600633794794645,
+    0.134466754530780, 0.307929983880436, 0.557603261588784,
+    0.014446025776115, 0.264566948406520, 0.720987025817365,
+    0.046933578838178, 0.358539352205951, 0.594527068955871,
+    0.002861120350567, 0.157807405968595, 0.839331473680839,
+    0.223861424097916, 0.075050596975911, 0.701087978926173,
+    0.034647074816760, 0.142421601113383, 0.822931324069857,
+    0.010161119296278, 0.065494628082938, 0.924344252620784
+  };
+  double suborder_w_rule_19[17] = {
+    0.032906331388919,
+    0.010330731891272,
+    0.022387247263016,
+    0.030266125869468,
+    0.030490967802198,
+    0.024159212741641,
+    0.016050803586801,
+    0.008084580261784,
+    0.002079362027485,
+    0.003884876904981,
+    0.025574160612022,
+    0.008880903573338,
+    0.016124546761731,
+    0.002491941817491,
+    0.018242840118951,
+    0.010258563736199,
+    0.003799928855302
+  };
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_xyz[0+s*3] = suborder_xy_rule_19[0+s*3];
+    suborder_xyz[1+s*3] = suborder_xy_rule_19[1+s*3];
+    suborder_xyz[2+s*3] = suborder_xy_rule_19[2+s*3];
+  }
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_w[s] = suborder_w_rule_19[s];
+  }
+
+  return;
+}
+//****************************************************************************80
+
+void SimplexQuadrature::dunavant_subrule_20(int suborder_num, std::vector<double>& suborder_xyz,
+					    std::vector<double>& suborder_w)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    DUNAVANT_SUBRULE_20 returns a compressed Dunavant rule 20.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    11 December 2006
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Reference:
+//
+//    David Dunavant,
+//    High Degree Efficient Symmetrical Gaussian Quadrature Rules
+//    for the Triangle,
+//    International Journal for Numerical Methods in Engineering,
+//    Volume 21, 1985, pages 1129-1148.
+//
+//    James Lyness, Dennis Jespersen,
+//    Moderate Degree Symmetric Quadrature Rules for the Triangle,
+//    Journal of the Institute of Mathematics and its Applications,
+//    Volume 15, Number 1, February 1975, pages 19-32.
+//
+//  Parameters:
+//
+//    Input, int SUBORDER_NUM, the number of suborders of the rule.
+//
+//    Output, double SUBORDER_XYZ[3*SUBORDER_NUM],
+//    the barycentric coordinates of the abscissas.
+//
+//    Output, double SUBORDER_W[SUBORDER_NUM], the suborder weights.
+//
+{
+  int s;
+  double suborder_xy_rule_20[3*19] = {
+    0.333333333333333, 0.333333333333333, 0.333333333333333,
+    -0.001900928704400, 0.500950464352200, 0.500950464352200,
+    0.023574084130543, 0.488212957934729, 0.488212957934729,
+    0.089726636099435, 0.455136681950283, 0.455136681950283,
+    0.196007481363421, 0.401996259318289, 0.401996259318289,
+    0.488214180481157, 0.255892909759421, 0.255892909759421,
+    0.647023488009788, 0.176488255995106, 0.176488255995106,
+    0.791658289326483, 0.104170855336758, 0.104170855336758,
+    0.893862072318140, 0.053068963840930, 0.053068963840930,
+    0.916762569607942, 0.041618715196029, 0.041618715196029,
+    0.976836157186356, 0.011581921406822, 0.011581921406822,
+    0.048741583664839, 0.344855770229001, 0.606402646106160,
+    0.006314115948605, 0.377843269594854, 0.615842614456541,
+    0.134316520547348, 0.306635479062357, 0.559048000390295,
+    0.013973893962392, 0.249419362774742, 0.736606743262866,
+    0.075549132909764, 0.212775724802802, 0.711675142287434,
+    -0.008368153208227, 0.146965436053239, 0.861402717154987,
+    0.026686063258714, 0.137726978828923, 0.835586957912363,
+    0.010547719294141, 0.059696109149007, 0.929756171556853
+  };
+  double suborder_w_rule_20[19] = {
+    0.033057055541624,
+    0.000867019185663,
+    0.011660052716448,
+    0.022876936356421,
+    0.030448982673938,
+    0.030624891725355,
+    0.024368057676800,
+    0.015997432032024,
+    0.007698301815602,
+    -0.000632060497488,
+    0.001751134301193,
+    0.016465839189576,
+    0.004839033540485,
+    0.025804906534650,
+    0.008471091054441,
+    0.018354914106280,
+    0.000704404677908,
+    0.010112684927462,
+    0.003573909385950
+  };
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_xyz[0+s*3] = suborder_xy_rule_20[0+s*3];
+    suborder_xyz[1+s*3] = suborder_xy_rule_20[1+s*3];
+    suborder_xyz[2+s*3] = suborder_xy_rule_20[2+s*3];
+  }
+
+  for (s = 0; s < suborder_num; s++)
+  {
+    suborder_w[s] = suborder_w_rule_20[s];
+  }
+
+  return;
+}
+//****************************************************************************80
+
+int SimplexQuadrature::i4_modp(int i, int j)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    I4_MODP returns the nonnegative remainder of I4 division.
+//
+//  Formula:
+//
+//    If
+//      NREM = I4_MODP(I, J)
+//      NMULT = (I - NREM) / J
+//    then
+//      I = J * NMULT + NREM
+//    where NREM is always nonnegative.
+//
+//  Discussion:
+//
+//    The MOD function computes a result with the same sign as the
+//    quantity being divided.  Thus, suppose you had an angle A,
+//    and you wanted to ensure that it was between 0 and 360.
+//    Then mod(A,360) would do, if A was positive, but if A
+//    was negative, your result would be between -360 and 0.
+//
+//    On the other hand, I4_MODP(A,360) is between 0 and 360, always.
+//
+//  Example:
+//
+//        I         J     MOD  I4_MODP   I4_MODP Factorization
+//
+//      107        50       7       7    107 =  2 *  50 + 7
+//      107       -50       7       7    107 = -2 * -50 + 7
+//     -107        50      -7      43   -107 = -3 *  50 + 43
+//     -107       -50      -7      43   -107 =  3 * -50 + 43
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    26 May 1999
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, int I, the number to be divided.
+//
+//    Input, int J, the number that divides I.
+//
+//    Output, int I4_MODP, the nonnegative remainder when I is
+//    divided by J.
+//
+{
+  int value;
+
+  if (j == 0)
+  {
+    dolfin_error("SimplexQuadrature.cpp",
+                 "compute quadrature rule for triangle",
+                 "i4_modp must have non-zero j, which is here ", j);
+  }
+
+  value = i % j;
+
+  if (value < 0)
+  {
+    value = value + abs(j);
+  }
+
+  return value;
+}
+//****************************************************************************80*
+
+int SimplexQuadrature::i4_wrap(int ival, int ilo, int ihi)
+
+//****************************************************************************80*
+//
+//  Purpose:
+//
+//    I4_WRAP forces an integer to lie between given limits by wrapping.
+//
+//  Example:
+//
+//    ILO = 4, IHI = 8
+//
+//    I   Value
+//
+//    -2     8
+//    -1     4
+//     0     5
+//     1     6
+//     2     7
+//     3     8
+//     4     4
+//     5     5
+//     6     6
+//     7     7
+//     8     8
+//     9     4
+//    10     5
+//    11     6
+//    12     7
+//    13     8
+//    14     4
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    19 August 2003
+//
+//  Author:
+//
+//    John Burkardt
+//
+//  Parameters:
+//
+//    Input, int IVAL, an integer value.
+//
+//    Input, int ILO, IHI, the desired bounds for the integer value.
+//
+//    Output, int I4_WRAP, a "wrapped" version of IVAL.
+//
+{
+  int jhi;
+  int jlo;
+  int value;
+  int wide;
+
+  jlo = std::min(ilo, ihi);
+  jhi = std::max(ilo, ihi);
+
+  wide = jhi + 1 - jlo;
+
+  if (wide == 1)
+  {
+    value = jlo;
+  }
+  else
+  {
+    value = jlo + i4_modp(ival - jlo, wide);
+  }
+
+  return value;
+}
+//-----------------------------------------------------------------------------
+void SimplexQuadrature::legendre_compute_glr(std::size_t n,
+					     std::vector<double>& x,
+					     std::vector<double>& w)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    LEGENDRE_COMPUTE_GLR: Legendre quadrature by the Glaser-Liu-Rokhlin method.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    20 October 2009
+//
+//  Author:
+//
+//    Original C++ version by Nick Hale.
+//    This C++ version by John Burkardt.
+//
+//  Reference:
+//
+//    Andreas Glaser, Xiangtao Liu, Vladimir Rokhlin,
+//    A fast algorithm for the calculation of the roots of special functions,
+//    SIAM Journal on Scientific Computing,
+//    Volume 29, Number 4, pages 1420-1438, 2007.
+//
+//  Parameters:
+//
+//    Input, int N, the order.
+//
+//    Output, double X[N], the abscissas.
+//
+//    Output, double W[N], the weights.
+//
+{
+  x.resize(n);
+  w.resize(n);
+
+  std::size_t i;
+  double p;
+  double pp;
+  double w_sum;
+  //
+  //  Get the value and derivative of the N-th Legendre polynomial at 0.
+  //
+  legendre_compute_glr0(n, p, pp);
+  //
+  //  If N is odd, then zero is a root.
+  //
+  if (n % 2 == 1)
+  {
+    x[(n-1)/2] = p;
+    w[(n-1)/2] = pp;
+  }
+  //
+  //  If N is even, we have to call a function to find the first root.
+  //
+  else
+  {
+    legendre_compute_glr2(p, n, x[n/2], w[n/2]);
+  }
+  //
+  //  Get the complete set of roots and derivatives.
+  //
+  legendre_compute_glr1(n, x, w);
+  //
+  //  Compute the W.
+  //
+  for (i = 0; i < n; i++)
+  {
+    w[i] = 2.0 /(1.0 - x[i]) /(1.0 + x[i]) / w[i] / w[i];
+  }
+  w_sum = 0.0;
+  for (i = 0; i < n; i++)
+  {
+    w_sum = w_sum + w[i];
+  }
+  for (i = 0; i < n; i++)
+  {
+    w[i] = 2.0 * w[i] / w_sum;
+  }
+  return;
+}
+//****************************************************************************80
+
+void SimplexQuadrature::legendre_compute_glr0(std::size_t n, double& p, double& pp)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    LEGENDRE_COMPUTE_GLR0 gets a starting value for the fast algorithm.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    19 October 2009
+//
+//  Author:
+//
+//    Original C++ version by Nick Hale.
+//    This C++ version by John Burkardt.
+//
+//  Reference:
+//
+//    Andreas Glaser, Xiangtao Liu, Vladimir Rokhlin,
+//    A fast algorithm for the calculation of the roots of special functions,
+//    SIAM Journal on Scientific Computing,
+//    Volume 29, Number 4, pages 1420-1438, 2007.
+//
+//  Parameters:
+//
+//    Input, int N, the order of the Legendre polynomial.
+//
+//    Output, double *P, *PP, the value of the N-th Legendre polynomial
+//    and its derivative at 0.
+//
+{
+  double dk;
+  std::size_t k;
+  double pm1;
+  double pm2;
+  double ppm1;
+  double ppm2;
+
+  pm2 = 0.0;
+  pm1 = 1.0;
+  ppm2 = 0.0;
+  ppm1 = 0.0;
+
+  for (k = 0; k < n; k++)
+  {
+    dk = static_cast<double>(k);
+    p = - dk * pm2 /(dk + 1.0);
+    pp = (( 2.0 * dk + 1.0) * pm1 - dk * ppm2) /(dk + 1.0);
+    pm2 = pm1;
+    pm1 = p;
+    ppm2 = ppm1;
+    ppm1 = pp;
+  }
+  return;
+}
+//****************************************************************************80
+
+void SimplexQuadrature::legendre_compute_glr1(std::size_t n_,
+					      std::vector<double>& x,
+					      std::vector<double>& w)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    LEGENDRE_COMPUTE_GLR1 gets the complete set of Legendre points and weights.
+//
+//  Discussion:
+//
+//    This routine requires that a starting estimate be provided for one
+//    root and its derivative.  This information will be stored in entry
+//    (N+1)/2 if N is odd, or N/2 if N is even, of X and W.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    19 October 2009
+//
+//  Author:
+//
+//    Original C++ version by Nick Hale.
+//    This C++ version by John Burkardt.
+//
+//  Reference:
+//
+//    Andreas Glaser, Xiangtao Liu, Vladimir Rokhlin,
+//    A fast algorithm for the calculation of the roots of special functions,
+//    SIAM Journal on Scientific Computing,
+//    Volume 29, Number 4, pages 1420-1438, 2007.
+//
+//  Parameters:
+//
+//    Input, int N, the order of the Legendre polynomial.
+//
+//    Input/output, double X[N].  On input, a starting value
+//    has been set in one entry.  On output, the roots of the Legendre
+//    polynomial.
+//
+//    Input/output, double W[N].  On input, a starting value
+//    has been set in one entry.  On output, the derivatives of the Legendre
+//    polynomial at the zeros.
+//
+//  Local Parameters:
+//
+//    Local, int M, the number of terms in the Taylor expansion.
+//
+{
+  double dk;
+  double dn;
+  double h;
+  int j;
+  int k;
+  int l;
+  int m = 30;
+  int n2;
+  int s;
+  // double *u;
+  // double *up;
+  double xp;
+
+  int n = static_cast<int>(n_);
+
+  if (n % 2 == 1)
+  {
+    n2 = (n - 1) / 2 - 1;
+    s = 1;
+  }
+  else
+  {
+    n2 = n / 2 - 1;
+    s = 0;
+  }
+
+  // u = new double[m+2];
+  // up = new double[m+1];
+  std::vector<double> u(m+2);
+  std::vector<double> up(m+1);
+
+  dn = static_cast<double>(n);
+
+  for (j = n2 + 1; j < n - 1; j++)
+  {
+    xp = x[j];
+
+    h = rk2_leg(DOLFIN_PI/2.0, -DOLFIN_PI/2.0, xp, n) - xp;
+
+    u[0] = 0.0;
+    u[1] = 0.0;
+    u[2] = w[j];
+
+    up[0] = 0.0;
+    up[1] = u[2];
+
+    for (k = 0; k <= m - 2; k++)
+    {
+      dk = static_cast<double>(k);
+
+      u[k+3] =
+	(
+	 2.0 * xp *(dk + 1.0) * u[k+2]
+	 +(dk *(dk + 1.0) - dn *(dn + 1.0)) * u[k+1] /(dk + 1.0)
+	 ) /(1.0 - xp) /(1.0 + xp) /(dk + 2.0);
+
+      up[k+2] = (dk + 2.0) * u[k+3];
+    }
+
+    for (l = 0; l < 5; l++)
+    {
+      h = h - ts_mult(u, h, m) / ts_mult(up, h, m-1);
+    }
+
+    x[j+1] = xp + h;
+    w[j+1] = ts_mult(up, h, m - 1);
+  }
+
+  for (k = 0; k <= n2 + s; k++)
+  {
+    x[k] = - x[n-1-k];
+    w[k] = w[n-1-k];
+  }
+  return;
+}
+//****************************************************************************80
+
+void SimplexQuadrature::legendre_compute_glr2(double pn0, int n, double& x1, double& d1)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    LEGENDRE_COMPUTE_GLR2 finds the first real root.
+//
+//  Discussion:
+//
+//    This function is only called if N is even.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    19 October 2009
+//
+//  Author:
+//
+//    Original C++ version by Nick Hale.
+//    This C++ version by John Burkardt.
+//
+//  Reference:
+//
+//    Andreas Glaser, Xiangtao Liu, Vladimir Rokhlin,
+//    A fast algorithm for the calculation of the roots of special functions,
+//    SIAM Journal on Scientific Computing,
+//    Volume 29, Number 4, pages 1420-1438, 2007.
+//
+//  Parameters:
+//
+//    Input, double PN0, the value of the N-th Legendre polynomial
+//    at 0.
+//
+//    Input, int N, the order of the Legendre polynomial.
+//
+//    Output, double *X1, the first real root.
+//
+//    Output, double *D1, the derivative at X1.
+//
+//  Local Parameters:
+//
+//    Local, int M, the number of terms in the Taylor expansion.
+//
+{
+  double dk;
+  double dn;
+  int k;
+  int l;
+  int m = 30;
+  double t;
+  // double *u;
+  // double *up;
+
+  t = 0.0;
+  x1 = rk2_leg(t, -DOLFIN_PI/2.0, 0.0, n);
+
+  // u = new double[m+2];
+  // up = new double[m+1];
+  std::vector<double> u(m+2);
+  std::vector<double> up(m+1);
+
+  dn = static_cast<double>(n);
+  //
+  //  U[0] and UP[0] are never used.
+  //  U[M+1] is set, but not used, and UP[M] is set and not used.
+  //  What gives?
+  //
+  u[0] = 0.0;
+  u[1] = pn0;
+
+  up[0] = 0.0;
+
+  for (k = 0; k <= m - 2; k = k + 2)
+  {
+    dk = static_cast<double>(k);
+
+    u[k+2] = 0.0;
+    u[k+3] = (dk *(dk + 1.0) - dn *(dn + 1.0)) * u[k+1]
+      / (dk + 1.0) / (dk + 2.0);
+
+    up[k+1] = 0.0;
+    up[k+2] = (dk + 2.0) * u[k+3];
+  }
+
+  for (l = 0; l < 5; l++)
+  {
+    x1 = x1 - ts_mult(u, x1, m) / ts_mult(up, x1, m-1);
+  }
+  d1 = ts_mult(up, x1, m-1);
+
+  return;
+}
+//****************************************************************************80
+
+double SimplexQuadrature::rk2_leg(double t1, double t2, double x, int n)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    RK2_LEG advances the value of X(T) using a Runge-Kutta method.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    22 October 2009
+//
+//  Author:
+//
+//    Original C++ version by Nick Hale.
+//    This C++ version by John Burkardt.
+//
+//  Parameters:
+//
+//    Input, double T1, T2, the range of the integration interval.
+//
+//    Input, double X, the value of X at T1.
+//
+//    Input, int N, the number of steps to take.
+//
+//    Output, double RK2_LEG, the value of X at T2.
+//
+{
+  double f;
+  double h;
+  int j;
+  double k1;
+  double k2;
+  int m = 10;
+  double snn1;
+  double t;
+
+  h = (t2 - t1) / static_cast<double>(m);
+  snn1 = sqrt(static_cast<double>(n *(n + 1)));
+  t = t1;
+
+  for (j = 0; j < m; j++)
+  {
+    f = (1.0 - x) *(1.0 + x);
+    k1 = - h * f /(snn1 * sqrt(f) - 0.5 * x * sin(2.0 * t));
+    x = x + k1;
+
+    t = t + h;
+
+    f = (1.0 - x) *(1.0 + x);
+    k2 = - h * f /(snn1 * sqrt(f) - 0.5 * x * sin(2.0 * t));
+    x = x + 0.5 *(k2 - k1);
+  }
+  return x;
+}
+//****************************************************************************80
+
+double SimplexQuadrature::ts_mult(std::vector<double>& u, double h, int n)
+
+//****************************************************************************80
+//
+//  Purpose:
+//
+//    TS_MULT evaluates a polynomial.
+//
+//  Licensing:
+//
+//    This code is distributed under the GNU LGPL license.
+//
+//  Modified:
+//
+//    17 May 2013
+//
+//  Author:
+//
+//    Original C++ version by Nick Hale.
+//    This C++ version by John Burkardt.
+//
+//  Parameters:
+//
+//    Input, double U[N+1], the polynomial coefficients.
+//    U[0] is ignored.
+//
+//    Input, double H, the polynomial argument.
+//
+//    Input, int N, the number of terms to compute.
+//
+//    Output, double TS_MULT, the value of the polynomial.
+//
+{
+  double hk;
+  int k;
+  double ts;
+
+  ts = 0.0;
+  hk = 1.0;
+  for (k = 1; k<= n; k++)
+  {
+    ts = ts + u[k] * hk;
+    hk = hk * h;
+  }
+  return ts;
 }
 //-----------------------------------------------------------------------------
diff --git a/dolfin/geometry/SimplexQuadrature.h b/dolfin/geometry/SimplexQuadrature.h
index aafaa9f..be36ce3 100644
--- a/dolfin/geometry/SimplexQuadrature.h
+++ b/dolfin/geometry/SimplexQuadrature.h
@@ -16,12 +16,13 @@
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 //
 // First added:  2014-02-24
-// Last changed: 2014-04-28
+// Last changed: 2017-09-22
 
 #ifndef __SIMPLEX_QUADRATURE_H
 #define __SIMPLEX_QUADRATURE_H
 
 #include <vector>
+#include <Eigen/Dense>
 #include "Point.h"
 
 namespace dolfin
@@ -30,12 +31,22 @@ namespace dolfin
   // Forward declarations
   class Cell;
 
-  /// Quadrature on simplices
+  /// This class defines quadrature rules for simplices.
 
   class SimplexQuadrature
   {
   public:
 
+    /// Create SimplexQuadrature rules for reference simplex
+    ///
+    /// *Arguments*
+    ///     tdim (std::size_t)
+    ///         The topological dimension of the simplex.
+    ///     order (std::size_t)
+    ///         The order of convergence of the quadrature rule.
+    ///
+    SimplexQuadrature(std::size_t tdim, std::size_t order);
+
     /// Compute quadrature rule for cell.
     ///
     /// *Arguments*
@@ -45,18 +56,18 @@ namespace dolfin
     ///         The order of convergence of the quadrature rule.
     ///
     /// *Returns*
-    ///     std::pair<std::vector<double>, std::vector<double> >
+    ///     std::pair<std::vector<double>, std::vector<double>>
     ///         A flattened array of quadrature points and a
     ///         corresponding array of quadrature weights.
-    static std::pair<std::vector<double>, std::vector<double> >
-    compute_quadrature_rule(const Cell& cell, std::size_t order);
+    std::pair<std::vector<double>, std::vector<double>>
+    compute_quadrature_rule(const Cell& cell,
+			    std::size_t order) const;
 
     /// Compute quadrature rule for simplex.
     ///
     /// *Arguments*
-    ///     coordinates (double *)
-    ///         A flattened array of simplex coordinates of
-    ///         dimension num_vertices x gdim = (tdim + 1)*gdim.
+    ///     coordinates (std::vector<Point>)
+    ///         Vertex coordinates for the simplex
     ///     tdim (std::size_t)
     ///         The topological dimension of the simplex.
     ///     gdim (std::size_t)
@@ -65,75 +76,225 @@ namespace dolfin
     ///         The order of convergence of the quadrature rule.
     ///
     /// *Returns*
-    ///     std::pair<std::vector<double>, std::vector<double> >
+    ///     std::pair<std::vector<double>, std::vector<double>>
     ///         A flattened array of quadrature points and a
     ///         corresponding array of quadrature weights.
-    static std::pair<std::vector<double>, std::vector<double> >
-    compute_quadrature_rule(const double* coordinates,
-                            std::size_t tdim,
-                            std::size_t gdim,
-                            std::size_t order);
+    std::pair<std::vector<double>, std::vector<double>>
+    compute_quadrature_rule(const std::vector<Point>& coordinates,
+			    std::size_t gdim,
+                            std::size_t order) const;
 
     /// Compute quadrature rule for interval.
     ///
     /// *Arguments*
-    ///     coordinates (double *)
-    ///         A flattened array of simplex coordinates of
-    ///         dimension num_vertices x gdim = 2*gdim.
+    ///     coordinates (std::vector<Point>)
+    ///         Vertex coordinates for the simplex
     ///     gdim (std::size_t)
     ///         The geometric dimension.
     ///     order (std::size_t)
     ///         The order of convergence of the quadrature rule.
     ///
     /// *Returns*
-    ///     std::pair<std::vector<double>, std::vector<double> >
+    ///     std::pair<std::vector<double>, std::vector<double>>
     ///         A flattened array of quadrature points and a
     ///         corresponding array of quadrature weights.
-    static std::pair<std::vector<double>, std::vector<double> >
-    compute_quadrature_rule_interval(const double* coordinates,
-                                     std::size_t gdim,
-                                     std::size_t order);
+    std::pair<std::vector<double>, std::vector<double>>
+    compute_quadrature_rule_interval(const std::vector<Point>& coordinates,
+				     std::size_t gdim,
+                                     std::size_t order) const;
 
     /// Compute quadrature rule for triangle.
     ///
     /// *Arguments*
-    ///     coordinates (double *)
-    ///         A flattened array of simplex coordinates of
-    ///         dimension num_vertices x gdim = 3*gdim.
+    ///     coordinates (std::vector<Point>)
+    ///         Vertex coordinates for the simplex
     ///     gdim (std::size_t)
     ///         The geometric dimension.
     ///     order (std::size_t)
     ///         The order of convergence of the quadrature rule.
     ///
     /// *Returns*
-    ///     std::pair<std::vector<double>, std::vector<double> >
+    ///     std::pair<std::vector<double>, std::vector<double>>
     ///         A flattened array of quadrature points and a
     ///         corresponding array of quadrature weights.
-    static std::pair<std::vector<double>, std::vector<double> >
-    compute_quadrature_rule_triangle(const double* coordinates,
+    std::pair<std::vector<double>, std::vector<double>>
+    compute_quadrature_rule_triangle(const std::vector<Point>& coordinates,
                                      std::size_t gdim,
-                                     std::size_t order);
-
+				     std::size_t order) const;
+    
     /// Compute quadrature rule for tetrahedron.
     ///
     /// *Arguments*
-    ///     coordinates (double *)
-    ///         A flattened array of simplex coordinates of
-    ///         dimension num_vertices x gdim = 4*gdim.
+    ///     coordinates (std::vector<Point>)
+    ///         Vertex coordinates for the simplex
     ///     gdim (std::size_t)
     ///         The geometric dimension.
     ///     order (std::size_t)
     ///         The order of convergence of the quadrature rule.
     ///
     /// *Returns*
-    ///     std::pair<std::vector<double>, std::vector<double> >
+    ///     std::pair<std::vector<double>, std::vector<double>>
     ///         A flattened array of quadrature points and a
     ///         corresponding array of quadrature weights.
+    std::pair<std::vector<double>, std::vector<double>>
+    compute_quadrature_rule_tetrahedron(const std::vector<Point>& coordinates,
+					std::size_t gdim,
+					std::size_t order) const;
+    
+    /// Compress a quadrature rule using algorithms from
+    ///     Compression of multivariate discrete measures and applications
+    ///     A. Sommariva, M. Vianello
+    ///     Numerical Functional Analysis and Optimization
+    ///     Volume 36, 2015 - Issue 9
+    ///
+    /// *Arguments*
+    ///     qr (std::pair<std::vector<double>, std::vector<double>>)
+    ///         The quadrature rule to be compressed
+    ///     gdim (std::size_t)
+    ///         The geometric dimension
+    ///     quadrature_order (std::size_t)
+    ///         The order of the quadrature rule
+    ///
+    /// *Returns*
+    ///     std::vector<std::size_t>
+    ///         The indices of the points that were kept (empty
+    ///         if no compression was made)
+    static std::vector<std::size_t>
+    compress(std::pair<std::vector<double>, std::vector<double>>& qr,
+	     std::size_t gdim,
+	     std::size_t quadrature_order);
+
+  private:
+
+    // Setup quadrature rule on a reference simplex
+    void setup_qr_reference_interval(std::size_t order);
+    void setup_qr_reference_triangle(std::size_t order);
+    void setup_qr_reference_tetrahedron(std::size_t order);
+
+    // Utility function for computing a Vandermonde type matrix in a
+    // Chebyshev basis
+    static Eigen::MatrixXd
+      Chebyshev_Vandermonde_matrix
+      (const std::pair<std::vector<double>, std::vector<double>>& qr,
+       std::size_t gdim, std::size_t N);
+    
+    // Utility function for computing a Chebyshev basis
+    static std::vector<Eigen::VectorXd>
+      Chebyshev_polynomial(const Eigen::VectorXd& x, std::size_t N);
+    
+    // Utility function for creating a matrix with coefficients in
+    // graded lexicographic order
+    static std::vector<std::vector<std::size_t>>
+      grlex(std::size_t gdim, std::size_t N);
+    
+    // Utility function for calculating all combinations (n over k)
+    static std::size_t choose(std::size_t n, std::size_t k);
+    
+    // The following code has been copied from
+    //
+    // https://people.sc.fsu.edu/~jburkardt/cpp_src/triangle_dunavant_rule/triangle_dunavant_rule.cpp
+    //
+    // License: LGPL
+
+    // Compute Duanvant quadrature rules for triangle
+
+    static void dunavant_rule(std::size_t order,
+			      std::vector<std::vector<double> >& p,
+			      std::vector<double>& w);
+    static std::size_t dunavant_order_num(std::size_t rule);
+    static std::vector<std::size_t> dunavant_suborder(int rule, int suborder_num);
+    static std::size_t dunavant_suborder_num(int rule);
+    static void dunavant_subrule(std::size_t rule,
+				 std::size_t suborder_num,
+				 std::vector<double>& suborder_xyz,
+				 std::vector<double>& w);
+    static void dunavant_subrule_01(int suborder_num,
+				    std::vector<double>& suborder_xyz,
+				    std::vector<double>& suborder_w);
+    static void dunavant_subrule_02(int suborder_num,
+				    std::vector<double>& suborder_xyz,
+				    std::vector<double>& suborder_w);
+    static void dunavant_subrule_03(int suborder_num,
+				    std::vector<double>& suborder_xyz,
+				    std::vector<double>& suborder_w);
+    static void dunavant_subrule_04(int suborder_num,
+				    std::vector<double>& suborder_xyz,
+				    std::vector<double>& suborder_w);
+    static void dunavant_subrule_05(int suborder_num,
+				    std::vector<double>& suborder_xyz,
+				    std::vector<double>& suborder_w);
+    static void dunavant_subrule_06(int suborder_num,
+				    std::vector<double>& suborder_xyz,
+				    std::vector<double>& suborder_w);
+    static void dunavant_subrule_07(int suborder_num,
+				    std::vector<double>& suborder_xyz,
+				    std::vector<double>& suborder_w);
+    static void dunavant_subrule_08(int suborder_num,
+				    std::vector<double>& suborder_xyz,
+				    std::vector<double>& suborder_w);
+    static void dunavant_subrule_09(int suborder_num,
+				    std::vector<double>& suborder_xyz,
+				    std::vector<double>& suborder_w);
+    static void dunavant_subrule_10(int suborder_num,
+				    std::vector<double>& suborder_xyz,
+				    std::vector<double>& suborder_w);
+    static void dunavant_subrule_11(int suborder_num,
+				    std::vector<double>& suborder_xyz,
+				    std::vector<double>& suborder_w);
+    static void dunavant_subrule_12(int suborder_num,
+				    std::vector<double>& suborder_xyz,
+				    std::vector<double>& suborder_w);
+    static void dunavant_subrule_13(int suborder_num,
+				    std::vector<double>& suborder_xyz,
+				    std::vector<double>& suborder_w);
+    static void dunavant_subrule_14(int suborder_num,
+				    std::vector<double>& suborder_xyz,
+				    std::vector<double>& suborder_w);
+    static void dunavant_subrule_15(int suborder_num,
+				    std::vector<double>& suborder_xyz,
+				    std::vector<double>& suborder_w);
+    static void dunavant_subrule_16(int suborder_num,
+				    std::vector<double>& suborder_xyz,
+				    std::vector<double>& suborder_w);
+    static void dunavant_subrule_17(int suborder_num,
+				    std::vector<double>& suborder_xyz,
+				    std::vector<double>& suborder_w);
+    static void dunavant_subrule_18(int suborder_num,
+				    std::vector<double>& suborder_xyz,
+				    std::vector<double>& suborder_w);
+    static void dunavant_subrule_19(int suborder_num,
+				    std::vector<double>& suborder_xyz,
+				    std::vector<double>& suborder_w);
+    static void dunavant_subrule_20(int suborder_num,
+				    std::vector<double>& suborder_xyz,
+				    std::vector<double>& suborder_w);
+    static int i4_modp(int i, int j);
+    static int i4_wrap(int ival, int ilo, int ihi);
+
+    // The following code has been copied from
+    //
+    // https://people.sc.fsu.edu/~jburkardt/cpp_src/legendre_rule_fast/legendre_rule_fast.cpp
+    //
+    // License: LGPL
+
+    // Compute Gauss-Legendre quadrature rules for line
+
+    static void legendre_compute_glr(std::size_t n,
+				     std::vector<double>& x,
+				     std::vector<double>& w);
+    static void legendre_compute_glr0(std::size_t n,
+				      double& p,
+				      double& pp);
+    static void legendre_compute_glr1(std::size_t n,
+				      std::vector<double>& x,
+				      std::vector<double>& w);
+    static void legendre_compute_glr2(double pn0, int n, double& x1, double& d1);
+    static double ts_mult(std::vector<double>& u, double h, int n);
+    static double rk2_leg(double t1, double t2, double x, int n);
 
-    static std::pair<std::vector<double>, std::vector<double> >
-    compute_quadrature_rule_tetrahedron(const double* coordinates,
-                                        std::size_t gdim,
-                                        std::size_t order);
+    // Quadrature rule on reference simplex (points and weights)
+    std::vector<std::vector<double> > _p;
+    std::vector<double> _w;
 
   };
 
diff --git a/dolfin/geometry/dolfin_geometry.h b/dolfin/geometry/dolfin_geometry.h
index 8efeaf5..d679c55 100644
--- a/dolfin/geometry/dolfin_geometry.h
+++ b/dolfin/geometry/dolfin_geometry.h
@@ -8,6 +8,7 @@
 #include <dolfin/geometry/GenericBoundingBoxTree.h>
 #include <dolfin/geometry/BoundingBoxTree3D.h>
 #include <dolfin/geometry/MeshPointIntersection.h>
+#include <dolfin/geometry/CollisionPredicates.h>
 #include <dolfin/geometry/intersect.h>
 
 #endif
diff --git a/dolfin/geometry/intersect.cpp b/dolfin/geometry/intersect.cpp
index bc7364f..d67a197 100644
--- a/dolfin/geometry/intersect.cpp
+++ b/dolfin/geometry/intersect.cpp
@@ -16,9 +16,11 @@
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 //
 // First added:  2013-05-30
-// Last changed: 2013-05-30
+// Last changed: 2017-09-25
 
 #include "MeshPointIntersection.h"
+#include <dolfin/mesh/CellType.h>
+#include <dolfin/mesh/Mesh.h>
 #include "intersect.h"
 
 using namespace dolfin;
@@ -27,6 +29,14 @@ using namespace dolfin;
 std::shared_ptr<const MeshPointIntersection>
 dolfin::intersect(const Mesh& mesh, const Point& point)
 {
+  // Intersection is only implemented for simplex meshes
+  if (!mesh.type().is_simplex())
+  {
+    dolfin_error("intersect.cpp",
+		 "intersect mesh and point",
+		 "Intersection is only implemented for simplex meshes");
+  }
+
   return std::shared_ptr<const MeshPointIntersection>
     (new MeshPointIntersection(mesh, point));
 }
diff --git a/dolfin/geometry/predicates.cpp b/dolfin/geometry/predicates.cpp
new file mode 100644
index 0000000..6b4be8c
--- /dev/null
+++ b/dolfin/geometry/predicates.cpp
@@ -0,0 +1,2372 @@
+#include <dolfin/geometry/Point.h>
+#include "predicates.h"
+
+//-----------------------------------------------------------------------------
+double dolfin::orient1d(double a, double b, double x)
+{
+  if (x > std::max(a, b)) return 1.0;
+  if (x < std::min(a, b)) return -1.0;
+  return 0.0;
+}
+//-----------------------------------------------------------------------------
+double dolfin::orient2d(const Point& a, const Point& b, const Point& c)
+{
+  return dolfin::_orient2d(a.coordinates(),
+                           b.coordinates(),
+                           c.coordinates());
+}
+//-----------------------------------------------------------------------------
+double dolfin::orient3d(const Point& a, const Point& b, const Point& c, const Point& d)
+{
+  return dolfin::_orient3d(a.coordinates(),
+                           b.coordinates(),
+                           c.coordinates(),
+                           d.coordinates());
+}
+//-----------------------------------------------------------------------------
+
+/*****************************************************************************/
+/*                                                                           */
+/*  Routines for Arbitrary Precision Floating-point Arithmetic               */
+/*  and Fast Robust Geometric Predicates                                     */
+/*  (predicates.c)                                                           */
+/*                                                                           */
+/*  May 18, 1996                                                             */
+/*                                                                           */
+/*  Placed in the public domain by                                           */
+/*  Jonathan Richard Shewchuk                                                */
+/*  School of Computer Science                                               */
+/*  Carnegie Mellon University                                               */
+/*  5000 Forbes Avenue                                                       */
+/*  Pittsburgh, Pennsylvania  15213-3891                                     */
+/*  jrs at cs.cmu.edu                                                           */
+/*                                                                           */
+/*  This file contains C implementation of algorithms for exact addition     */
+/*    and multiplication of floating-point numbers, and predicates for       */
+/*    robustly performing the orientation and incircle tests used in         */
+/*    computational geometry.  The algorithms and underlying theory are      */
+/*    described in Jonathan Richard Shewchuk.  "Adaptive Precision Floating- */
+/*    Point Arithmetic and Fast Robust Geometric Predicates."  Technical     */
+/*    Report CMU-CS-96-140, School of Computer Science, Carnegie Mellon      */
+/*    University, Pittsburgh, Pennsylvania, May 1996.  (Submitted to         */
+/*    Discrete & Computational Geometry.)                                    */
+/*                                                                           */
+/*  This file, the paper listed above, and other information are available   */
+/*    from the Web page http://www.cs.cmu.edu/~quake/robust.html .           */
+/*                                                                           */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/*                                                                           */
+/*  Using this code:                                                         */
+/*                                                                           */
+/*  First, read the short or long version of the paper (from the Web page    */
+/*    above).                                                                */
+/*                                                                           */
+/*  Be sure to call exactinit() once, before calling any of the arithmetic   */
+/*    functions or geometric predicates.  Also be sure to turn on the        */
+/*    optimizer when compiling this file.                                    */
+/*                                                                           */
+/*                                                                           */
+/*  Several geometric predicates are defined.  Their parameters are all      */
+/*    points.  Each point is an array of two or three floating-point         */
+/*    numbers.  The geometric predicates, described in the papers, are       */
+/*                                                                           */
+/*    orient2d(pa, pb, pc)                                                   */
+/*    orient2dfast(pa, pb, pc)                                               */
+/*    orient3d(pa, pb, pc, pd)                                               */
+/*    orient3dfast(pa, pb, pc, pd)                                           */
+/*    incircle(pa, pb, pc, pd)                                               */
+/*    incirclefast(pa, pb, pc, pd)                                           */
+/*    insphere(pa, pb, pc, pd, pe)                                           */
+/*    inspherefast(pa, pb, pc, pd, pe)                                       */
+/*                                                                           */
+/*  Those with suffix "fast" are approximate, non-robust versions.  Those    */
+/*    without the suffix are adaptive precision, robust versions.  There     */
+/*    are also versions with the suffices "exact" and "slow", which are      */
+/*    non-adaptive, exact arithmetic versions, which I use only for timings  */
+/*    in my arithmetic papers.                                               */
+/*                                                                           */
+/*                                                                           */
+/*  An expansion is represented by an array of floating-point numbers,       */
+/*    sorted from smallest to largest magnitude (possibly with interspersed  */
+/*    zeros).  The length of each expansion is stored as a separate integer, */
+/*    and each arithmetic function returns an integer which is the length    */
+/*    of the expansion it created.                                           */
+/*                                                                           */
+/*  Several arithmetic functions are defined.  Their parameters are          */
+/*                                                                           */
+/*    e, f           Input expansions                                        */
+/*    elen, flen     Lengths of input expansions (must be >= 1)              */
+/*    h              Output expansion                                        */
+/*    b              Input scalar                                            */
+/*                                                                           */
+/*  The arithmetic functions are                                             */
+/*                                                                           */
+/*    grow_expansion(elen, e, b, h)                                          */
+/*    grow_expansion_zeroelim(elen, e, b, h)                                 */
+/*    expansion_sum(elen, e, flen, f, h)                                     */
+/*    expansion_sum_zeroelim1(elen, e, flen, f, h)                           */
+/*    expansion_sum_zeroelim2(elen, e, flen, f, h)                           */
+/*    fast_expansion_sum(elen, e, flen, f, h)                                */
+/*    fast_expansion_sum_zeroelim(elen, e, flen, f, h)                       */
+/*    linear_expansion_sum(elen, e, flen, f, h)                              */
+/*    linear_expansion_sum_zeroelim(elen, e, flen, f, h)                     */
+/*    scale_expansion(elen, e, b, h)                                         */
+/*    scale_expansion_zeroelim(elen, e, b, h)                                */
+/*    compress(elen, e, h)                                                   */
+/*                                                                           */
+/*  All of these are described in the long version of the paper; some are    */
+/*    described in the short version.  All return an integer that is the     */
+/*    length of h.  Those with suffix _zeroelim perform zero elimination,    */
+/*    and are recommended over their counterparts.  The procedure            */
+/*    fast_expansion_sum_zeroelim() (or linear_expansion_sum_zeroelim() on   */
+/*    processors that do not use the round-to-even tiebreaking rule) is      */
+/*    recommended over expansion_sum_zeroelim().  Each procedure has a       */
+/*    little note next to it (in the code below) that tells you whether or   */
+/*    not the output expansion may be the same array as one of the input     */
+/*    expansions.                                                            */
+/*                                                                           */
+/*                                                                           */
+/*  If you look around below, you'll also find macros for a bunch of         */
+/*    simple unrolled arithmetic operations, and procedures for printing     */
+/*    expansions (commented out because they don't work with all C           */
+/*    compilers) and for generating random floating-point numbers whose      */
+/*    significand bits are all random.  Most of the macros have undocumented */
+/*    requirements that certain of their parameters should not be the same   */
+/*    variable; for safety, better to make sure all the parameters are       */
+/*    distinct variables.  Feel free to send email to jrs at cs.cmu.edu if you  */
+/*    have questions.                                                        */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <sys/time.h>
+
+/* On some machines, the exact arithmetic routines might be defeated by the  */
+/*   use of internal extended precision floating-point registers.  Sometimes */
+/*   this problem can be fixed by defining certain values to be volatile,    */
+/*   thus forcing them to be stored to memory and rounded off.  This isn't   */
+/*   a great solution, though, as it slows the arithmetic down.              */
+/*                                                                           */
+/* To try this out, write "#define INEXACT volatile" below.  Normally,       */
+/*   however, INEXACT should be defined to be nothing.  ("#define INEXACT".) */
+
+#define INEXACT                          /* Nothing */
+/* #define INEXACT volatile */
+
+#define REAL double                      /* float or double */
+#define REALPRINT doubleprint
+#define REALRAND doublerand
+#define NARROWRAND narrowdoublerand
+#define UNIFORMRAND uniformdoublerand
+
+/* Which of the following two methods of finding the absolute values is      */
+/*   fastest is compiler-dependent.  A few compilers can inline and optimize */
+/*   the fabs() call; but most will incur the overhead of a function call,   */
+/*   which is disastrously slow.  A faster way on IEEE machines might be to  */
+/*   mask the appropriate bit, but that's difficult to do in C.              */
+
+#define Absolute(a)  ((a) >= 0.0 ? (a) : -(a))
+/* #define Absolute(a)  fabs(a) */
+
+/* Many of the operations are broken up into two pieces, a main part that    */
+/*   performs an approximate operation, and a "tail" that computes the       */
+/*   roundoff error of that operation.                                       */
+/*                                                                           */
+/* The operations Fast_Two_Sum(), Fast_Two_Diff(), Two_Sum(), Two_Diff(),    */
+/*   Split(), and Two_Product() are all implemented as described in the      */
+/*   reference.  Each of these macros requires certain variables to be       */
+/*   defined in the calling routine.  The variables `bvirt', `c', `abig',    */
+/*   `_i', `_j', `_k', `_l', `_m', and `_n' are declared `INEXACT' because   */
+/*   they store the result of an operation that may incur roundoff error.    */
+/*   The input parameter `x' (or the highest numbered `x_' parameter) must   */
+/*   also be declared `INEXACT'.                                             */
+
+#define Fast_Two_Sum_Tail(a, b, x, y) \
+  bvirt = x - a; \
+  y = b - bvirt
+
+#define Fast_Two_Sum(a, b, x, y) \
+  x = (REAL) (a + b); \
+  Fast_Two_Sum_Tail(a, b, x, y)
+
+#define Fast_Two_Diff_Tail(a, b, x, y) \
+  bvirt = a - x; \
+  y = bvirt - b
+
+#define Fast_Two_Diff(a, b, x, y) \
+  x = (REAL) (a - b); \
+  Fast_Two_Diff_Tail(a, b, x, y)
+
+#define Two_Sum_Tail(a, b, x, y) \
+  bvirt = (REAL) (x - a); \
+  avirt = x - bvirt; \
+  bround = b - bvirt; \
+  around = a - avirt; \
+  y = around + bround
+
+#define Two_Sum(a, b, x, y) \
+  x = (REAL) (a + b); \
+  Two_Sum_Tail(a, b, x, y)
+
+#define Two_Diff_Tail(a, b, x, y) \
+  bvirt = (REAL) (a - x); \
+  avirt = x + bvirt; \
+  bround = bvirt - b; \
+  around = a - avirt; \
+  y = around + bround
+
+#define Two_Diff(a, b, x, y) \
+  x = (REAL) (a - b); \
+  Two_Diff_Tail(a, b, x, y)
+
+#define Split(a, ahi, alo) \
+  c = (REAL) (splitter * a); \
+  abig = (REAL) (c - a); \
+  ahi = c - abig; \
+  alo = a - ahi
+
+#define Two_Product_Tail(a, b, x, y) \
+  Split(a, ahi, alo); \
+  Split(b, bhi, blo); \
+  err1 = x - (ahi * bhi); \
+  err2 = err1 - (alo * bhi); \
+  err3 = err2 - (ahi * blo); \
+  y = (alo * blo) - err3
+
+#define Two_Product(a, b, x, y) \
+  x = (REAL) (a * b); \
+  Two_Product_Tail(a, b, x, y)
+
+/* Two_Product_Presplit() is Two_Product() where one of the inputs has       */
+/*   already been split.  Avoids redundant splitting.                        */
+
+#define Two_Product_Presplit(a, b, bhi, blo, x, y) \
+  x = (REAL) (a * b); \
+  Split(a, ahi, alo); \
+  err1 = x - (ahi * bhi); \
+  err2 = err1 - (alo * bhi); \
+  err3 = err2 - (ahi * blo); \
+  y = (alo * blo) - err3
+
+/* Two_Product_2Presplit() is Two_Product() where both of the inputs have    */
+/*   already been split.  Avoids redundant splitting.                        */
+
+#define Two_Product_2Presplit(a, ahi, alo, b, bhi, blo, x, y) \
+  x = (REAL) (a * b); \
+  err1 = x - (ahi * bhi); \
+  err2 = err1 - (alo * bhi); \
+  err3 = err2 - (ahi * blo); \
+  y = (alo * blo) - err3
+
+/* Square() can be done more quickly than Two_Product().                     */
+
+#define Square_Tail(a, x, y) \
+  Split(a, ahi, alo); \
+  err1 = x - (ahi * ahi); \
+  err3 = err1 - ((ahi + ahi) * alo); \
+  y = (alo * alo) - err3
+
+#define Square(a, x, y) \
+  x = (REAL) (a * a); \
+  Square_Tail(a, x, y)
+
+/* Macros for summing expansions of various fixed lengths.  These are all    */
+/*   unrolled versions of Expansion_Sum().                                   */
+
+#define Two_One_Sum(a1, a0, b, x2, x1, x0) \
+  Two_Sum(a0, b , _i, x0); \
+  Two_Sum(a1, _i, x2, x1)
+
+#define Two_One_Diff(a1, a0, b, x2, x1, x0) \
+  Two_Diff(a0, b , _i, x0); \
+  Two_Sum( a1, _i, x2, x1)
+
+#define Two_Two_Sum(a1, a0, b1, b0, x3, x2, x1, x0) \
+  Two_One_Sum(a1, a0, b0, _j, _0, x0); \
+  Two_One_Sum(_j, _0, b1, x3, x2, x1)
+
+#define Two_Two_Diff(a1, a0, b1, b0, x3, x2, x1, x0) \
+  Two_One_Diff(a1, a0, b0, _j, _0, x0); \
+  Two_One_Diff(_j, _0, b1, x3, x2, x1)
+
+#define Four_One_Sum(a3, a2, a1, a0, b, x4, x3, x2, x1, x0) \
+  Two_One_Sum(a1, a0, b , _j, x1, x0); \
+  Two_One_Sum(a3, a2, _j, x4, x3, x2)
+
+#define Four_Two_Sum(a3, a2, a1, a0, b1, b0, x5, x4, x3, x2, x1, x0) \
+  Four_One_Sum(a3, a2, a1, a0, b0, _k, _2, _1, _0, x0); \
+  Four_One_Sum(_k, _2, _1, _0, b1, x5, x4, x3, x2, x1)
+
+#define Four_Four_Sum(a3, a2, a1, a0, b4, b3, b1, b0, x7, x6, x5, x4, x3, x2, \
+                      x1, x0) \
+  Four_Two_Sum(a3, a2, a1, a0, b1, b0, _l, _2, _1, _0, x1, x0); \
+  Four_Two_Sum(_l, _2, _1, _0, b4, b3, x7, x6, x5, x4, x3, x2)
+
+#define Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b, x8, x7, x6, x5, x4, \
+                      x3, x2, x1, x0) \
+  Four_One_Sum(a3, a2, a1, a0, b , _j, x3, x2, x1, x0); \
+  Four_One_Sum(a7, a6, a5, a4, _j, x8, x7, x6, x5, x4)
+
+#define Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, x9, x8, x7, \
+                      x6, x5, x4, x3, x2, x1, x0) \
+  Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b0, _k, _6, _5, _4, _3, _2, \
+                _1, _0, x0); \
+  Eight_One_Sum(_k, _6, _5, _4, _3, _2, _1, _0, b1, x9, x8, x7, x6, x5, x4, \
+                x3, x2, x1)
+
+#define Eight_Four_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b4, b3, b1, b0, x11, \
+                       x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0) \
+  Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, _l, _6, _5, _4, _3, \
+                _2, _1, _0, x1, x0); \
+  Eight_Two_Sum(_l, _6, _5, _4, _3, _2, _1, _0, b4, b3, x11, x10, x9, x8, \
+                x7, x6, x5, x4, x3, x2)
+
+/* Macros for multiplying expansions of various fixed lengths.               */
+
+#define Two_One_Product(a1, a0, b, x3, x2, x1, x0) \
+  Split(b, bhi, blo); \
+  Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \
+  Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \
+  Two_Sum(_i, _0, _k, x1); \
+  Fast_Two_Sum(_j, _k, x3, x2)
+
+#define Four_One_Product(a3, a2, a1, a0, b, x7, x6, x5, x4, x3, x2, x1, x0) \
+  Split(b, bhi, blo); \
+  Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \
+  Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \
+  Two_Sum(_i, _0, _k, x1); \
+  Fast_Two_Sum(_j, _k, _i, x2); \
+  Two_Product_Presplit(a2, b, bhi, blo, _j, _0); \
+  Two_Sum(_i, _0, _k, x3); \
+  Fast_Two_Sum(_j, _k, _i, x4); \
+  Two_Product_Presplit(a3, b, bhi, blo, _j, _0); \
+  Two_Sum(_i, _0, _k, x5); \
+  Fast_Two_Sum(_j, _k, x7, x6)
+
+#define Two_Two_Product(a1, a0, b1, b0, x7, x6, x5, x4, x3, x2, x1, x0) \
+  Split(a0, a0hi, a0lo); \
+  Split(b0, bhi, blo); \
+  Two_Product_2Presplit(a0, a0hi, a0lo, b0, bhi, blo, _i, x0); \
+  Split(a1, a1hi, a1lo); \
+  Two_Product_2Presplit(a1, a1hi, a1lo, b0, bhi, blo, _j, _0); \
+  Two_Sum(_i, _0, _k, _1); \
+  Fast_Two_Sum(_j, _k, _l, _2); \
+  Split(b1, bhi, blo); \
+  Two_Product_2Presplit(a0, a0hi, a0lo, b1, bhi, blo, _i, _0); \
+  Two_Sum(_1, _0, _k, x1); \
+  Two_Sum(_2, _k, _j, _1); \
+  Two_Sum(_l, _j, _m, _2); \
+  Two_Product_2Presplit(a1, a1hi, a1lo, b1, bhi, blo, _j, _0); \
+  Two_Sum(_i, _0, _n, _0); \
+  Two_Sum(_1, _0, _i, x2); \
+  Two_Sum(_2, _i, _k, _1); \
+  Two_Sum(_m, _k, _l, _2); \
+  Two_Sum(_j, _n, _k, _0); \
+  Two_Sum(_1, _0, _j, x3); \
+  Two_Sum(_2, _j, _i, _1); \
+  Two_Sum(_l, _i, _m, _2); \
+  Two_Sum(_1, _k, _i, x4); \
+  Two_Sum(_2, _i, _k, x5); \
+  Two_Sum(_m, _k, x7, x6)
+
+/* An expansion of length two can be squared more quickly than finding the   */
+/*   product of two different expansions of length two, and the result is    */
+/*   guaranteed to have no more than six (rather than eight) components.     */
+
+#define Two_Square(a1, a0, x5, x4, x3, x2, x1, x0) \
+  Square(a0, _j, x0); \
+  _0 = a0 + a0; \
+  Two_Product(a1, _0, _k, _1); \
+  Two_One_Sum(_k, _1, _j, _l, _2, x1); \
+  Square(a1, _j, _1); \
+  Two_Two_Sum(_j, _1, _l, _2, x5, x4, x3, x2)
+
+REAL splitter;     /* = 2^ceiling(p / 2) + 1.  Used to split floats in half. */
+REAL epsilon;                /* = 2^(-p).  Used to estimate roundoff errors. */
+/* A set of coefficients used to calculate maximum roundoff errors.          */
+REAL resulterrbound;
+REAL ccwerrboundA, ccwerrboundB, ccwerrboundC;
+REAL o3derrboundA, o3derrboundB, o3derrboundC;
+REAL iccerrboundA, iccerrboundB, iccerrboundC;
+REAL isperrboundA, isperrboundB, isperrboundC;
+
+/*****************************************************************************/
+/*                                                                           */
+/*  doubleprint()   Print the bit representation of a double.                */
+/*                                                                           */
+/*  Useful for debugging exact arithmetic routines.                          */
+/*                                                                           */
+/*****************************************************************************/
+
+/*
+void doubleprint(number)
+double number;
+{
+  unsigned long long no;
+  unsigned long long sign, expo;
+  int exponent;
+  int i, bottomi;
+
+  no = *(unsigned long long *) &number;
+  sign = no & 0x8000000000000000ll;
+  expo = (no >> 52) & 0x7ffll;
+  exponent = (int) expo;
+  exponent = exponent - 1023;
+  if (sign) {
+    printf("-");
+  } else {
+    printf(" ");
+  }
+  if (exponent == -1023) {
+    printf(
+      "0.0000000000000000000000000000000000000000000000000000_     (   )");
+  } else {
+    printf("1.");
+    bottomi = -1;
+    for (i = 0; i < 52; i++) {
+      if (no & 0x0008000000000000ll) {
+        printf("1");
+        bottomi = i;
+      } else {
+        printf("0");
+      }
+      no <<= 1;
+    }
+    printf("_%d  (%d)", exponent, exponent - 1 - bottomi);
+  }
+}
+*/
+
+/*****************************************************************************/
+/*                                                                           */
+/*  floatprint()   Print the bit representation of a float.                  */
+/*                                                                           */
+/*  Useful for debugging exact arithmetic routines.                          */
+/*                                                                           */
+/*****************************************************************************/
+
+/*
+void floatprint(number)
+float number;
+{
+  unsigned no;
+  unsigned sign, expo;
+  int exponent;
+  int i, bottomi;
+
+  no = *(unsigned *) &number;
+  sign = no & 0x80000000;
+  expo = (no >> 23) & 0xff;
+  exponent = (int) expo;
+  exponent = exponent - 127;
+  if (sign) {
+    printf("-");
+  } else {
+    printf(" ");
+  }
+  if (exponent == -127) {
+    printf("0.00000000000000000000000_     (   )");
+  } else {
+    printf("1.");
+    bottomi = -1;
+    for (i = 0; i < 23; i++) {
+      if (no & 0x00400000) {
+        printf("1");
+        bottomi = i;
+      } else {
+        printf("0");
+      }
+      no <<= 1;
+    }
+    printf("_%3d  (%3d)", exponent, exponent - 1 - bottomi);
+  }
+}
+*/
+
+/*****************************************************************************/
+/*                                                                           */
+/*  expansion_print()   Print the bit representation of an expansion.        */
+/*                                                                           */
+/*  Useful for debugging exact arithmetic routines.                          */
+/*                                                                           */
+/*****************************************************************************/
+
+/*
+void expansion_print(elen, e)
+int elen;
+REAL *e;
+{
+  int i;
+
+  for (i = elen - 1; i >= 0; i--) {
+    REALPRINT(e[i]);
+    if (i > 0) {
+      printf(" +\n");
+    } else {
+      printf("\n");
+    }
+  }
+}
+*/
+
+/*****************************************************************************/
+/*                                                                           */
+/*  doublerand()   Generate a double with random 53-bit significand and a    */
+/*                 random exponent in [0, 511].                              */
+/*                                                                           */
+/*****************************************************************************/
+
+double doublerand()
+{
+  double result;
+  double expo;
+  long a, b, c;
+  long i;
+
+  a = random();
+  b = random();
+  c = random();
+  result = (double) (a - 1073741824) * 8388608.0 + (double) (b >> 8);
+  for (i = 512, expo = 2; i <= 131072; i *= 2, expo = expo * expo) {
+    if (c & i) {
+      result *= expo;
+    }
+  }
+  return result;
+}
+
+/*****************************************************************************/
+/*                                                                           */
+/*  narrowdoublerand()   Generate a double with random 53-bit significand    */
+/*                       and a random exponent in [0, 7].                    */
+/*                                                                           */
+/*****************************************************************************/
+
+double narrowdoublerand()
+{
+  double result;
+  double expo;
+  long a, b, c;
+  long i;
+
+  a = random();
+  b = random();
+  c = random();
+  result = (double) (a - 1073741824) * 8388608.0 + (double) (b >> 8);
+  for (i = 512, expo = 2; i <= 2048; i *= 2, expo = expo * expo) {
+    if (c & i) {
+      result *= expo;
+    }
+  }
+  return result;
+}
+
+/*****************************************************************************/
+/*                                                                           */
+/*  uniformdoublerand()   Generate a double with random 53-bit significand.  */
+/*                                                                           */
+/*****************************************************************************/
+
+double uniformdoublerand()
+{
+  double result;
+  long a, b;
+
+  a = random();
+  b = random();
+  result = (double) (a - 1073741824) * 8388608.0 + (double) (b >> 8);
+  return result;
+}
+
+/*****************************************************************************/
+/*                                                                           */
+/*  floatrand()   Generate a float with random 24-bit significand and a      */
+/*                random exponent in [0, 63].                                */
+/*                                                                           */
+/*****************************************************************************/
+
+float floatrand()
+{
+  float result;
+  float expo;
+  long a, c;
+  long i;
+
+  a = random();
+  c = random();
+  result = (float) ((a - 1073741824) >> 6);
+  for (i = 512, expo = 2; i <= 16384; i *= 2, expo = expo * expo) {
+    if (c & i) {
+      result *= expo;
+    }
+  }
+  return result;
+}
+
+/*****************************************************************************/
+/*                                                                           */
+/*  narrowfloatrand()   Generate a float with random 24-bit significand and  */
+/*                      a random exponent in [0, 7].                         */
+/*                                                                           */
+/*****************************************************************************/
+
+float narrowfloatrand()
+{
+  float result;
+  float expo;
+  long a, c;
+  long i;
+
+  a = random();
+  c = random();
+  result = (float) ((a - 1073741824) >> 6);
+  for (i = 512, expo = 2; i <= 2048; i *= 2, expo = expo * expo) {
+    if (c & i) {
+      result *= expo;
+    }
+  }
+  return result;
+}
+
+/*****************************************************************************/
+/*                                                                           */
+/*  uniformfloatrand()   Generate a float with random 24-bit significand.    */
+/*                                                                           */
+/*****************************************************************************/
+
+float uniformfloatrand()
+{
+  float result;
+  long a;
+
+  a = random();
+  result = (float) ((a - 1073741824) >> 6);
+  return result;
+}
+
+/*****************************************************************************/
+/*                                                                           */
+/*  exactinit()   Initialize the variables used for exact arithmetic.        */
+/*                                                                           */
+/*  `epsilon' is the largest power of two such that 1.0 + epsilon = 1.0 in   */
+/*  floating-point arithmetic.  `epsilon' bounds the relative roundoff       */
+/*  error.  It is used for floating-point error analysis.                    */
+/*                                                                           */
+/*  `splitter' is used to split floating-point numbers into two half-        */
+/*  length significands for exact multiplication.                            */
+/*                                                                           */
+/*  I imagine that a highly optimizing compiler might be too smart for its   */
+/*  own good, and somehow cause this routine to fail, if it pretends that    */
+/*  floating-point arithmetic is too much like real arithmetic.              */
+/*                                                                           */
+/*  Don't change this routine unless you fully understand it.                */
+/*                                                                           */
+/*****************************************************************************/
+
+void dolfin::exactinit()
+{
+  REAL half;
+  REAL check, lastcheck;
+  int every_other;
+
+  every_other = 1;
+  half = 0.5;
+  epsilon = 1.0;
+  splitter = 1.0;
+  check = 1.0;
+  /* Repeatedly divide `epsilon' by two until it is too small to add to    */
+  /*   one without causing roundoff.  (Also check if the sum is equal to   */
+  /*   the previous sum, for machines that round up instead of using exact */
+  /*   rounding.  Not that this library will work on such machines anyway. */
+  do {
+    lastcheck = check;
+    epsilon *= half;
+    if (every_other) {
+      splitter *= 2.0;
+    }
+    every_other = !every_other;
+    check = 1.0 + epsilon;
+  } while ((check != 1.0) && (check != lastcheck));
+  splitter += 1.0;
+
+  /* Error bounds for orientation and incircle tests. */
+  resulterrbound = (3.0 + 8.0 * epsilon) * epsilon;
+  ccwerrboundA = (3.0 + 16.0 * epsilon) * epsilon;
+  ccwerrboundB = (2.0 + 12.0 * epsilon) * epsilon;
+  ccwerrboundC = (9.0 + 64.0 * epsilon) * epsilon * epsilon;
+  o3derrboundA = (7.0 + 56.0 * epsilon) * epsilon;
+  o3derrboundB = (3.0 + 28.0 * epsilon) * epsilon;
+  o3derrboundC = (26.0 + 288.0 * epsilon) * epsilon * epsilon;
+  iccerrboundA = (10.0 + 96.0 * epsilon) * epsilon;
+  iccerrboundB = (4.0 + 48.0 * epsilon) * epsilon;
+  iccerrboundC = (44.0 + 576.0 * epsilon) * epsilon * epsilon;
+  isperrboundA = (16.0 + 224.0 * epsilon) * epsilon;
+  isperrboundB = (5.0 + 72.0 * epsilon) * epsilon;
+  isperrboundC = (71.0 + 1408.0 * epsilon) * epsilon * epsilon;
+}
+
+/*****************************************************************************/
+/*                                                                           */
+/*  grow_expansion()   Add a scalar to an expansion.                         */
+/*                                                                           */
+/*  Sets h = e + b.  See the long version of my paper for details.           */
+/*                                                                           */
+/*  Maintains the nonoverlapping property.  If round-to-even is used (as     */
+/*  with IEEE 754), maintains the strongly nonoverlapping and nonadjacent    */
+/*  properties as well.  (That is, if e has one of these properties, so      */
+/*  will h.)                                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+int grow_expansion(int elen, REAL *e, REAL b, REAL *h)                /* e and h can be the same. */
+/* int elen; */
+/* REAL *e; */
+/* REAL b; */
+/* REAL *h; */
+{
+  REAL Q;
+  INEXACT REAL Qnew;
+  int eindex;
+  REAL enow;
+  INEXACT REAL bvirt;
+  REAL avirt, bround, around;
+
+  Q = b;
+  for (eindex = 0; eindex < elen; eindex++) {
+    enow = e[eindex];
+    Two_Sum(Q, enow, Qnew, h[eindex]);
+    Q = Qnew;
+  }
+  h[eindex] = Q;
+  return eindex + 1;
+}
+
+/*****************************************************************************/
+/*                                                                           */
+/*  grow_expansion_zeroelim()   Add a scalar to an expansion, eliminating    */
+/*                              zero components from the output expansion.   */
+/*                                                                           */
+/*  Sets h = e + b.  See the long version of my paper for details.           */
+/*                                                                           */
+/*  Maintains the nonoverlapping property.  If round-to-even is used (as     */
+/*  with IEEE 754), maintains the strongly nonoverlapping and nonadjacent    */
+/*  properties as well.  (That is, if e has one of these properties, so      */
+/*  will h.)                                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+int grow_expansion_zeroelim(int elen, REAL *e, REAL b, REAL *h)       /* e and h can be the same. */
+/* int elen; */
+/* REAL *e; */
+/* REAL b; */
+/* REAL *h; */
+{
+  REAL Q, hh;
+  INEXACT REAL Qnew;
+  int eindex, hindex;
+  REAL enow;
+  INEXACT REAL bvirt;
+  REAL avirt, bround, around;
+
+  hindex = 0;
+  Q = b;
+  for (eindex = 0; eindex < elen; eindex++) {
+    enow = e[eindex];
+    Two_Sum(Q, enow, Qnew, hh);
+    Q = Qnew;
+    if (hh != 0.0) {
+      h[hindex++] = hh;
+    }
+  }
+  if ((Q != 0.0) || (hindex == 0)) {
+    h[hindex++] = Q;
+  }
+  return hindex;
+}
+
+/*****************************************************************************/
+/*                                                                           */
+/*  expansion_sum()   Sum two expansions.                                    */
+/*                                                                           */
+/*  Sets h = e + f.  See the long version of my paper for details.           */
+/*                                                                           */
+/*  Maintains the nonoverlapping property.  If round-to-even is used (as     */
+/*  with IEEE 754), maintains the nonadjacent property as well.  (That is,   */
+/*  if e has one of these properties, so will h.)  Does NOT maintain the     */
+/*  strongly nonoverlapping property.                                        */
+/*                                                                           */
+/*****************************************************************************/
+
+int expansion_sum(int elen, REAL *e, int flen, REAL *f, REAL *h)
+/* e and h can be the same, but f and h cannot. */
+/* int elen; */
+/* REAL *e; */
+/* int flen; */
+/* REAL *f; */
+/* REAL *h; */
+{
+  REAL Q;
+  INEXACT REAL Qnew;
+  int findex, hindex, hlast;
+  REAL hnow;
+  INEXACT REAL bvirt;
+  REAL avirt, bround, around;
+
+  Q = f[0];
+  for (hindex = 0; hindex < elen; hindex++) {
+    hnow = e[hindex];
+    Two_Sum(Q, hnow, Qnew, h[hindex]);
+    Q = Qnew;
+  }
+  h[hindex] = Q;
+  hlast = hindex;
+  for (findex = 1; findex < flen; findex++) {
+    Q = f[findex];
+    for (hindex = findex; hindex <= hlast; hindex++) {
+      hnow = h[hindex];
+      Two_Sum(Q, hnow, Qnew, h[hindex]);
+      Q = Qnew;
+    }
+    h[++hlast] = Q;
+  }
+  return hlast + 1;
+}
+
+/*****************************************************************************/
+/*                                                                           */
+/*  expansion_sum_zeroelim1()   Sum two expansions, eliminating zero         */
+/*                              components from the output expansion.        */
+/*                                                                           */
+/*  Sets h = e + f.  See the long version of my paper for details.           */
+/*                                                                           */
+/*  Maintains the nonoverlapping property.  If round-to-even is used (as     */
+/*  with IEEE 754), maintains the nonadjacent property as well.  (That is,   */
+/*  if e has one of these properties, so will h.)  Does NOT maintain the     */
+/*  strongly nonoverlapping property.                                        */
+/*                                                                           */
+/*****************************************************************************/
+
+int expansion_sum_zeroelim1(int elen, REAL *e, int flen, REAL *f, REAL *h)
+/* e and h can be the same, but f and h cannot. */
+/* int elen; */
+/* REAL *e; */
+/* int flen; */
+/* REAL *f; */
+/* REAL *h; */
+{
+  REAL Q;
+  INEXACT REAL Qnew;
+  int index, findex, hindex, hlast;
+  REAL hnow;
+  INEXACT REAL bvirt;
+  REAL avirt, bround, around;
+
+  Q = f[0];
+  for (hindex = 0; hindex < elen; hindex++) {
+    hnow = e[hindex];
+    Two_Sum(Q, hnow, Qnew, h[hindex]);
+    Q = Qnew;
+  }
+  h[hindex] = Q;
+  hlast = hindex;
+  for (findex = 1; findex < flen; findex++) {
+    Q = f[findex];
+    for (hindex = findex; hindex <= hlast; hindex++) {
+      hnow = h[hindex];
+      Two_Sum(Q, hnow, Qnew, h[hindex]);
+      Q = Qnew;
+    }
+    h[++hlast] = Q;
+  }
+  hindex = -1;
+  for (index = 0; index <= hlast; index++) {
+    hnow = h[index];
+    if (hnow != 0.0) {
+      h[++hindex] = hnow;
+    }
+  }
+  if (hindex == -1) {
+    return 1;
+  } else {
+    return hindex + 1;
+  }
+}
+
+/*****************************************************************************/
+/*                                                                           */
+/*  expansion_sum_zeroelim2()   Sum two expansions, eliminating zero         */
+/*                              components from the output expansion.        */
+/*                                                                           */
+/*  Sets h = e + f.  See the long version of my paper for details.           */
+/*                                                                           */
+/*  Maintains the nonoverlapping property.  If round-to-even is used (as     */
+/*  with IEEE 754), maintains the nonadjacent property as well.  (That is,   */
+/*  if e has one of these properties, so will h.)  Does NOT maintain the     */
+/*  strongly nonoverlapping property.                                        */
+/*                                                                           */
+/*****************************************************************************/
+
+int expansion_sum_zeroelim2(int elen, REAL *e, int flen, REAL *f, REAL *h)
+/* e and h can be the same, but f and h cannot. */
+/* int elen; */
+/* REAL *e; */
+/* int flen; */
+/* REAL *f; */
+/* REAL *h; */
+{
+  REAL Q, hh;
+  INEXACT REAL Qnew;
+  int eindex, findex, hindex, hlast;
+  REAL enow;
+  INEXACT REAL bvirt;
+  REAL avirt, bround, around;
+
+  hindex = 0;
+  Q = f[0];
+  for (eindex = 0; eindex < elen; eindex++) {
+    enow = e[eindex];
+    Two_Sum(Q, enow, Qnew, hh);
+    Q = Qnew;
+    if (hh != 0.0) {
+      h[hindex++] = hh;
+    }
+  }
+  h[hindex] = Q;
+  hlast = hindex;
+  for (findex = 1; findex < flen; findex++) {
+    hindex = 0;
+    Q = f[findex];
+    for (eindex = 0; eindex <= hlast; eindex++) {
+      enow = h[eindex];
+      Two_Sum(Q, enow, Qnew, hh);
+      Q = Qnew;
+      if (hh != 0) {
+        h[hindex++] = hh;
+      }
+    }
+    h[hindex] = Q;
+    hlast = hindex;
+  }
+  return hlast + 1;
+}
+
+/*****************************************************************************/
+/*                                                                           */
+/*  fast_expansion_sum()   Sum two expansions.                               */
+/*                                                                           */
+/*  Sets h = e + f.  See the long version of my paper for details.           */
+/*                                                                           */
+/*  If round-to-even is used (as with IEEE 754), maintains the strongly      */
+/*  nonoverlapping property.  (That is, if e is strongly nonoverlapping, h   */
+/*  will be also.)  Does NOT maintain the nonoverlapping or nonadjacent      */
+/*  properties.                                                              */
+/*                                                                           */
+/*****************************************************************************/
+
+int fast_expansion_sum(int elen, REAL *e, int flen, REAL *f, REAL *h)           /* h cannot be e or f. */
+/* int elen; */
+/* REAL *e; */
+/* int flen; */
+/* REAL *f; */
+/* REAL *h; */
+{
+  REAL Q;
+  INEXACT REAL Qnew;
+  INEXACT REAL bvirt;
+  REAL avirt, bround, around;
+  int eindex, findex, hindex;
+  REAL enow, fnow;
+
+  enow = e[0];
+  fnow = f[0];
+  eindex = findex = 0;
+  if ((fnow > enow) == (fnow > -enow)) {
+    Q = enow;
+    enow = e[++eindex];
+  } else {
+    Q = fnow;
+    fnow = f[++findex];
+  }
+  hindex = 0;
+  if ((eindex < elen) && (findex < flen)) {
+    if ((fnow > enow) == (fnow > -enow)) {
+      Fast_Two_Sum(enow, Q, Qnew, h[0]);
+      enow = e[++eindex];
+    } else {
+      Fast_Two_Sum(fnow, Q, Qnew, h[0]);
+      fnow = f[++findex];
+    }
+    Q = Qnew;
+    hindex = 1;
+    while ((eindex < elen) && (findex < flen)) {
+      if ((fnow > enow) == (fnow > -enow)) {
+        Two_Sum(Q, enow, Qnew, h[hindex]);
+        enow = e[++eindex];
+      } else {
+        Two_Sum(Q, fnow, Qnew, h[hindex]);
+        fnow = f[++findex];
+      }
+      Q = Qnew;
+      hindex++;
+    }
+  }
+  while (eindex < elen) {
+    Two_Sum(Q, enow, Qnew, h[hindex]);
+    enow = e[++eindex];
+    Q = Qnew;
+    hindex++;
+  }
+  while (findex < flen) {
+    Two_Sum(Q, fnow, Qnew, h[hindex]);
+    fnow = f[++findex];
+    Q = Qnew;
+    hindex++;
+  }
+  h[hindex] = Q;
+  return hindex + 1;
+}
+
+/*****************************************************************************/
+/*                                                                           */
+/*  fast_expansion_sum_zeroelim()   Sum two expansions, eliminating zero     */
+/*                                  components from the output expansion.    */
+/*                                                                           */
+/*  Sets h = e + f.  See the long version of my paper for details.           */
+/*                                                                           */
+/*  If round-to-even is used (as with IEEE 754), maintains the strongly      */
+/*  nonoverlapping property.  (That is, if e is strongly nonoverlapping, h   */
+/*  will be also.)  Does NOT maintain the nonoverlapping or nonadjacent      */
+/*  properties.                                                              */
+/*                                                                           */
+/*****************************************************************************/
+
+int fast_expansion_sum_zeroelim(int elen, REAL *e, int flen, REAL *f, REAL *h)  /* h cannot be e or f. */
+/* int elen; */
+/* REAL *e; */
+/* int flen; */
+/* REAL *f; */
+/* REAL *h; */
+{
+  REAL Q;
+  INEXACT REAL Qnew;
+  INEXACT REAL hh;
+  INEXACT REAL bvirt;
+  REAL avirt, bround, around;
+  int eindex, findex, hindex;
+  REAL enow, fnow;
+
+  enow = e[0];
+  fnow = f[0];
+  eindex = findex = 0;
+  if ((fnow > enow) == (fnow > -enow)) {
+    Q = enow;
+    enow = e[++eindex];
+  } else {
+    Q = fnow;
+    fnow = f[++findex];
+  }
+  hindex = 0;
+  if ((eindex < elen) && (findex < flen)) {
+    if ((fnow > enow) == (fnow > -enow)) {
+      Fast_Two_Sum(enow, Q, Qnew, hh);
+      enow = e[++eindex];
+    } else {
+      Fast_Two_Sum(fnow, Q, Qnew, hh);
+      fnow = f[++findex];
+    }
+    Q = Qnew;
+    if (hh != 0.0) {
+      h[hindex++] = hh;
+    }
+    while ((eindex < elen) && (findex < flen)) {
+      if ((fnow > enow) == (fnow > -enow)) {
+        Two_Sum(Q, enow, Qnew, hh);
+        enow = e[++eindex];
+      } else {
+        Two_Sum(Q, fnow, Qnew, hh);
+        fnow = f[++findex];
+      }
+      Q = Qnew;
+      if (hh != 0.0) {
+        h[hindex++] = hh;
+      }
+    }
+  }
+  while (eindex < elen) {
+    Two_Sum(Q, enow, Qnew, hh);
+    enow = e[++eindex];
+    Q = Qnew;
+    if (hh != 0.0) {
+      h[hindex++] = hh;
+    }
+  }
+  while (findex < flen) {
+    Two_Sum(Q, fnow, Qnew, hh);
+    fnow = f[++findex];
+    Q = Qnew;
+    if (hh != 0.0) {
+      h[hindex++] = hh;
+    }
+  }
+  if ((Q != 0.0) || (hindex == 0)) {
+    h[hindex++] = Q;
+  }
+  return hindex;
+}
+
+/*****************************************************************************/
+/*                                                                           */
+/*  linear_expansion_sum()   Sum two expansions.                             */
+/*                                                                           */
+/*  Sets h = e + f.  See either version of my paper for details.             */
+/*                                                                           */
+/*  Maintains the nonoverlapping property.  (That is, if e is                */
+/*  nonoverlapping, h will be also.)                                         */
+/*                                                                           */
+/*****************************************************************************/
+
+int linear_expansion_sum(int elen, REAL *e, int flen, REAL *f, REAL *h)         /* h cannot be e or f. */
+/* int elen; */
+/* REAL *e; */
+/* int flen; */
+/* REAL *f; */
+/* REAL *h; */
+{
+  REAL Q, q;
+  INEXACT REAL Qnew;
+  INEXACT REAL R;
+  INEXACT REAL bvirt;
+  REAL avirt, bround, around;
+  int eindex, findex, hindex;
+  REAL enow, fnow;
+  REAL g0;
+
+  enow = e[0];
+  fnow = f[0];
+  eindex = findex = 0;
+  if ((fnow > enow) == (fnow > -enow)) {
+    g0 = enow;
+    enow = e[++eindex];
+  } else {
+    g0 = fnow;
+    fnow = f[++findex];
+  }
+  if ((eindex < elen) && ((findex >= flen)
+                          || ((fnow > enow) == (fnow > -enow)))) {
+    Fast_Two_Sum(enow, g0, Qnew, q);
+    enow = e[++eindex];
+  } else {
+    Fast_Two_Sum(fnow, g0, Qnew, q);
+    fnow = f[++findex];
+  }
+  Q = Qnew;
+  for (hindex = 0; hindex < elen + flen - 2; hindex++) {
+    if ((eindex < elen) && ((findex >= flen)
+                            || ((fnow > enow) == (fnow > -enow)))) {
+      Fast_Two_Sum(enow, q, R, h[hindex]);
+      enow = e[++eindex];
+    } else {
+      Fast_Two_Sum(fnow, q, R, h[hindex]);
+      fnow = f[++findex];
+    }
+    Two_Sum(Q, R, Qnew, q);
+    Q = Qnew;
+  }
+  h[hindex] = q;
+  h[hindex + 1] = Q;
+  return hindex + 2;
+}
+
+/*****************************************************************************/
+/*                                                                           */
+/*  linear_expansion_sum_zeroelim()   Sum two expansions, eliminating zero   */
+/*                                    components from the output expansion.  */
+/*                                                                           */
+/*  Sets h = e + f.  See either version of my paper for details.             */
+/*                                                                           */
+/*  Maintains the nonoverlapping property.  (That is, if e is                */
+/*  nonoverlapping, h will be also.)                                         */
+/*                                                                           */
+/*****************************************************************************/
+
+int linear_expansion_sum_zeroelim(int elen, REAL *e, int flen, REAL *f, REAL *h)/* h cannot be e or f. */
+/* int elen; */
+/* REAL *e; */
+/* int flen; */
+/* REAL *f; */
+/* REAL *h; */
+{
+  REAL Q, q, hh;
+  INEXACT REAL Qnew;
+  INEXACT REAL R;
+  INEXACT REAL bvirt;
+  REAL avirt, bround, around;
+  int eindex, findex, hindex;
+  int count;
+  REAL enow, fnow;
+  REAL g0;
+
+  enow = e[0];
+  fnow = f[0];
+  eindex = findex = 0;
+  hindex = 0;
+  if ((fnow > enow) == (fnow > -enow)) {
+    g0 = enow;
+    enow = e[++eindex];
+  } else {
+    g0 = fnow;
+    fnow = f[++findex];
+  }
+  if ((eindex < elen) && ((findex >= flen)
+                          || ((fnow > enow) == (fnow > -enow)))) {
+    Fast_Two_Sum(enow, g0, Qnew, q);
+    enow = e[++eindex];
+  } else {
+    Fast_Two_Sum(fnow, g0, Qnew, q);
+    fnow = f[++findex];
+  }
+  Q = Qnew;
+  for (count = 2; count < elen + flen; count++) {
+    if ((eindex < elen) && ((findex >= flen)
+                            || ((fnow > enow) == (fnow > -enow)))) {
+      Fast_Two_Sum(enow, q, R, hh);
+      enow = e[++eindex];
+    } else {
+      Fast_Two_Sum(fnow, q, R, hh);
+      fnow = f[++findex];
+    }
+    Two_Sum(Q, R, Qnew, q);
+    Q = Qnew;
+    if (hh != 0) {
+      h[hindex++] = hh;
+    }
+  }
+  if (q != 0) {
+    h[hindex++] = q;
+  }
+  if ((Q != 0.0) || (hindex == 0)) {
+    h[hindex++] = Q;
+  }
+  return hindex;
+}
+
+/*****************************************************************************/
+/*                                                                           */
+/*  scale_expansion()   Multiply an expansion by a scalar.                   */
+/*                                                                           */
+/*  Sets h = be.  See either version of my paper for details.                */
+/*                                                                           */
+/*  Maintains the nonoverlapping property.  If round-to-even is used (as     */
+/*  with IEEE 754), maintains the strongly nonoverlapping and nonadjacent    */
+/*  properties as well.  (That is, if e has one of these properties, so      */
+/*  will h.)                                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+int scale_expansion(int elen, REAL *e, REAL b, REAL *h)            /* e and h cannot be the same. */
+/* int elen; */
+/* REAL *e; */
+/* REAL b; */
+/* REAL *h; */
+{
+  INEXACT REAL Q;
+  INEXACT REAL sum;
+  INEXACT REAL product1;
+  REAL product0;
+  int eindex, hindex;
+  REAL enow;
+  INEXACT REAL bvirt;
+  REAL avirt, bround, around;
+  INEXACT REAL c;
+  INEXACT REAL abig;
+  REAL ahi, alo, bhi, blo;
+  REAL err1, err2, err3;
+
+  Split(b, bhi, blo);
+  Two_Product_Presplit(e[0], b, bhi, blo, Q, h[0]);
+  hindex = 1;
+  for (eindex = 1; eindex < elen; eindex++) {
+    enow = e[eindex];
+    Two_Product_Presplit(enow, b, bhi, blo, product1, product0);
+    Two_Sum(Q, product0, sum, h[hindex]);
+    hindex++;
+    Two_Sum(product1, sum, Q, h[hindex]);
+    hindex++;
+  }
+  h[hindex] = Q;
+  return elen + elen;
+}
+
+/*****************************************************************************/
+/*                                                                           */
+/*  scale_expansion_zeroelim()   Multiply an expansion by a scalar,          */
+/*                               eliminating zero components from the        */
+/*                               output expansion.                           */
+/*                                                                           */
+/*  Sets h = be.  See either version of my paper for details.                */
+/*                                                                           */
+/*  Maintains the nonoverlapping property.  If round-to-even is used (as     */
+/*  with IEEE 754), maintains the strongly nonoverlapping and nonadjacent    */
+/*  properties as well.  (That is, if e has one of these properties, so      */
+/*  will h.)                                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+int scale_expansion_zeroelim(int elen, REAL *e, REAL b, REAL *h)   /* e and h cannot be the same. */
+/* int elen; */
+/* REAL *e; */
+/* REAL b; */
+/* REAL *h; */
+{
+  INEXACT REAL Q, sum;
+  REAL hh;
+  INEXACT REAL product1;
+  REAL product0;
+  int eindex, hindex;
+  REAL enow;
+  INEXACT REAL bvirt;
+  REAL avirt, bround, around;
+  INEXACT REAL c;
+  INEXACT REAL abig;
+  REAL ahi, alo, bhi, blo;
+  REAL err1, err2, err3;
+
+  Split(b, bhi, blo);
+  Two_Product_Presplit(e[0], b, bhi, blo, Q, hh);
+  hindex = 0;
+  if (hh != 0) {
+    h[hindex++] = hh;
+  }
+  for (eindex = 1; eindex < elen; eindex++) {
+    enow = e[eindex];
+    Two_Product_Presplit(enow, b, bhi, blo, product1, product0);
+    Two_Sum(Q, product0, sum, hh);
+    if (hh != 0) {
+      h[hindex++] = hh;
+    }
+    Fast_Two_Sum(product1, sum, Q, hh);
+    if (hh != 0) {
+      h[hindex++] = hh;
+    }
+  }
+  if ((Q != 0.0) || (hindex == 0)) {
+    h[hindex++] = Q;
+  }
+  return hindex;
+}
+
+/*****************************************************************************/
+/*                                                                           */
+/*  compress()   Compress an expansion.                                      */
+/*                                                                           */
+/*  See the long version of my paper for details.                            */
+/*                                                                           */
+/*  Maintains the nonoverlapping property.  If round-to-even is used (as     */
+/*  with IEEE 754), then any nonoverlapping expansion is converted to a      */
+/*  nonadjacent expansion.                                                   */
+/*                                                                           */
+/*****************************************************************************/
+
+int compress(int elen, REAL *e, REAL *h)                         /* e and h may be the same. */
+/* int elen; */
+/* REAL *e; */
+/* REAL *h; */
+{
+  REAL Q, q;
+  INEXACT REAL Qnew;
+  int eindex, hindex;
+  INEXACT REAL bvirt;
+  REAL enow, hnow;
+  int top, bottom;
+
+  bottom = elen - 1;
+  Q = e[bottom];
+  for (eindex = elen - 2; eindex >= 0; eindex--) {
+    enow = e[eindex];
+    Fast_Two_Sum(Q, enow, Qnew, q);
+    if (q != 0) {
+      h[bottom--] = Qnew;
+      Q = q;
+    } else {
+      Q = Qnew;
+    }
+  }
+  top = 0;
+  for (hindex = bottom + 1; hindex < elen; hindex++) {
+    hnow = h[hindex];
+    Fast_Two_Sum(hnow, Q, Qnew, q);
+    if (q != 0) {
+      h[top++] = q;
+    }
+    Q = Qnew;
+  }
+  h[top] = Q;
+  return top + 1;
+}
+
+/*****************************************************************************/
+/*                                                                           */
+/*  estimate()   Produce a one-word estimate of an expansion's value.        */
+/*                                                                           */
+/*  See either version of my paper for details.                              */
+/*                                                                           */
+/*****************************************************************************/
+
+REAL estimate(int elen, REAL *e)
+/* int elen; */
+/* REAL *e; */
+{
+  REAL Q;
+  int eindex;
+
+  Q = e[0];
+  for (eindex = 1; eindex < elen; eindex++) {
+    Q += e[eindex];
+  }
+  return Q;
+}
+
+/*****************************************************************************/
+/*                                                                           */
+/*  orient2dfast()   Approximate 2D orientation test.  Nonrobust.            */
+/*  orient2dexact()   Exact 2D orientation test.  Robust.                    */
+/*  orient2dslow()   Another exact 2D orientation test.  Robust.             */
+/*  orient2d()   Adaptive exact 2D orientation test.  Robust.                */
+/*                                                                           */
+/*               Return a positive value if the points pa, pb, and pc occur  */
+/*               in counterclockwise order; a negative value if they occur   */
+/*               in clockwise order; and zero if they are collinear.  The    */
+/*               result is also a rough approximation of twice the signed    */
+/*               area of the triangle defined by the three points.           */
+/*                                                                           */
+/*  Only the first and last routine should be used; the middle two are for   */
+/*  timings.                                                                 */
+/*                                                                           */
+/*  The last three use exact arithmetic to ensure a correct answer.  The     */
+/*  result returned is the determinant of a matrix.  In orient2d() only,     */
+/*  this determinant is computed adaptively, in the sense that exact         */
+/*  arithmetic is used only to the degree it is needed to ensure that the    */
+/*  returned value has the correct sign.  Hence, orient2d() is usually quite */
+/*  fast, but will run more slowly when the input points are collinear or    */
+/*  nearly so.                                                               */
+/*                                                                           */
+/*****************************************************************************/
+
+REAL orient2dfast(REAL *pa, REAL *pb, REAL *pc)
+/* REAL *pa; */
+/* REAL *pb; */
+/* REAL *pc; */
+{
+  REAL acx, bcx, acy, bcy;
+
+  acx = pa[0] - pc[0];
+  bcx = pb[0] - pc[0];
+  acy = pa[1] - pc[1];
+  bcy = pb[1] - pc[1];
+  return acx * bcy - acy * bcx;
+}
+
+REAL orient2dexact(REAL *pa, REAL *pb, REAL *pc)
+/* REAL *pa; */
+/* REAL *pb; */
+/* REAL *pc; */
+{
+  INEXACT REAL axby1, axcy1, bxcy1, bxay1, cxay1, cxby1;
+  REAL axby0, axcy0, bxcy0, bxay0, cxay0, cxby0;
+  REAL aterms[4], bterms[4], cterms[4];
+  INEXACT REAL aterms3, bterms3, cterms3;
+  REAL v[8], w[12];
+  int vlength, wlength;
+
+  INEXACT REAL bvirt;
+  REAL avirt, bround, around;
+  INEXACT REAL c;
+  INEXACT REAL abig;
+  REAL ahi, alo, bhi, blo;
+  REAL err1, err2, err3;
+  INEXACT REAL _i, _j;
+  REAL _0;
+
+  Two_Product(pa[0], pb[1], axby1, axby0);
+  Two_Product(pa[0], pc[1], axcy1, axcy0);
+  Two_Two_Diff(axby1, axby0, axcy1, axcy0,
+               aterms3, aterms[2], aterms[1], aterms[0]);
+  aterms[3] = aterms3;
+
+  Two_Product(pb[0], pc[1], bxcy1, bxcy0);
+  Two_Product(pb[0], pa[1], bxay1, bxay0);
+  Two_Two_Diff(bxcy1, bxcy0, bxay1, bxay0,
+               bterms3, bterms[2], bterms[1], bterms[0]);
+  bterms[3] = bterms3;
+
+  Two_Product(pc[0], pa[1], cxay1, cxay0);
+  Two_Product(pc[0], pb[1], cxby1, cxby0);
+  Two_Two_Diff(cxay1, cxay0, cxby1, cxby0,
+               cterms3, cterms[2], cterms[1], cterms[0]);
+  cterms[3] = cterms3;
+
+  vlength = fast_expansion_sum_zeroelim(4, aterms, 4, bterms, v);
+  wlength = fast_expansion_sum_zeroelim(vlength, v, 4, cterms, w);
+
+  return w[wlength - 1];
+}
+
+REAL orient2dslow(REAL *pa, REAL *pb, REAL *pc)
+/* REAL *pa; */
+/* REAL *pb; */
+/* REAL *pc; */
+{
+  INEXACT REAL acx, acy, bcx, bcy;
+  REAL acxtail, acytail;
+  REAL bcxtail, bcytail;
+  REAL negate, negatetail;
+  REAL axby[8], bxay[8];
+  INEXACT REAL axby7, bxay7;
+  REAL deter[16];
+  int deterlen;
+
+  INEXACT REAL bvirt;
+  REAL avirt, bround, around;
+  INEXACT REAL c;
+  INEXACT REAL abig;
+  REAL a0hi, a0lo, a1hi, a1lo, bhi, blo;
+  REAL err1, err2, err3;
+  INEXACT REAL _i, _j, _k, _l, _m, _n;
+  REAL _0, _1, _2;
+
+  Two_Diff(pa[0], pc[0], acx, acxtail);
+  Two_Diff(pa[1], pc[1], acy, acytail);
+  Two_Diff(pb[0], pc[0], bcx, bcxtail);
+  Two_Diff(pb[1], pc[1], bcy, bcytail);
+
+  Two_Two_Product(acx, acxtail, bcy, bcytail,
+                  axby7, axby[6], axby[5], axby[4],
+                  axby[3], axby[2], axby[1], axby[0]);
+  axby[7] = axby7;
+  negate = -acy;
+  negatetail = -acytail;
+  Two_Two_Product(bcx, bcxtail, negate, negatetail,
+                  bxay7, bxay[6], bxay[5], bxay[4],
+                  bxay[3], bxay[2], bxay[1], bxay[0]);
+  bxay[7] = bxay7;
+
+  deterlen = fast_expansion_sum_zeroelim(8, axby, 8, bxay, deter);
+
+  return deter[deterlen - 1];
+}
+
+REAL orient2dadapt(const REAL *pa, const REAL *pb, const REAL *pc, const REAL detsum)
+/* REAL *pa; */
+/* REAL *pb; */
+/* REAL *pc; */
+/* REAL detsum; */
+{
+  INEXACT REAL acx, acy, bcx, bcy;
+  REAL acxtail, acytail, bcxtail, bcytail;
+  INEXACT REAL detleft, detright;
+  REAL detlefttail, detrighttail;
+  REAL det, errbound;
+  REAL B[4], C1[8], C2[12], D[16];
+  INEXACT REAL B3;
+  int C1length, C2length, Dlength;
+  REAL u[4];
+  INEXACT REAL u3;
+  INEXACT REAL s1, t1;
+  REAL s0, t0;
+
+  INEXACT REAL bvirt;
+  REAL avirt, bround, around;
+  INEXACT REAL c;
+  INEXACT REAL abig;
+  REAL ahi, alo, bhi, blo;
+  REAL err1, err2, err3;
+  INEXACT REAL _i, _j;
+  REAL _0;
+
+  acx = (REAL) (pa[0] - pc[0]);
+  bcx = (REAL) (pb[0] - pc[0]);
+  acy = (REAL) (pa[1] - pc[1]);
+  bcy = (REAL) (pb[1] - pc[1]);
+
+  Two_Product(acx, bcy, detleft, detlefttail);
+  Two_Product(acy, bcx, detright, detrighttail);
+
+  Two_Two_Diff(detleft, detlefttail, detright, detrighttail,
+               B3, B[2], B[1], B[0]);
+  B[3] = B3;
+
+  det = estimate(4, B);
+  errbound = ccwerrboundB * detsum;
+  if ((det >= errbound) || (-det >= errbound)) {
+    return det;
+  }
+
+  Two_Diff_Tail(pa[0], pc[0], acx, acxtail);
+  Two_Diff_Tail(pb[0], pc[0], bcx, bcxtail);
+  Two_Diff_Tail(pa[1], pc[1], acy, acytail);
+  Two_Diff_Tail(pb[1], pc[1], bcy, bcytail);
+
+  if ((acxtail == 0.0) && (acytail == 0.0)
+      && (bcxtail == 0.0) && (bcytail == 0.0)) {
+    return det;
+  }
+
+  errbound = ccwerrboundC * detsum + resulterrbound * Absolute(det);
+  det += (acx * bcytail + bcy * acxtail)
+       - (acy * bcxtail + bcx * acytail);
+  if ((det >= errbound) || (-det >= errbound)) {
+    return det;
+  }
+
+  Two_Product(acxtail, bcy, s1, s0);
+  Two_Product(acytail, bcx, t1, t0);
+  Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
+  u[3] = u3;
+  C1length = fast_expansion_sum_zeroelim(4, B, 4, u, C1);
+
+  Two_Product(acx, bcytail, s1, s0);
+  Two_Product(acy, bcxtail, t1, t0);
+  Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
+  u[3] = u3;
+  C2length = fast_expansion_sum_zeroelim(C1length, C1, 4, u, C2);
+
+  Two_Product(acxtail, bcytail, s1, s0);
+  Two_Product(acytail, bcxtail, t1, t0);
+  Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
+  u[3] = u3;
+  Dlength = fast_expansion_sum_zeroelim(C2length, C2, 4, u, D);
+
+  return(D[Dlength - 1]);
+}
+
+REAL dolfin::_orient2d(const REAL *pa, const REAL *pb, const REAL *pc)
+/* REAL *pa; */
+/* REAL *pb; */
+/* REAL *pc; */
+{
+  REAL detleft, detright, det;
+  REAL detsum, errbound;
+
+  detleft = (pa[0] - pc[0]) * (pb[1] - pc[1]);
+  detright = (pa[1] - pc[1]) * (pb[0] - pc[0]);
+  det = detleft - detright;
+
+  if (detleft > 0.0) {
+    if (detright <= 0.0) {
+      return det;
+    } else {
+      detsum = detleft + detright;
+    }
+  } else if (detleft < 0.0) {
+    if (detright >= 0.0) {
+      return det;
+    } else {
+      detsum = -detleft - detright;
+    }
+  } else {
+    return det;
+  }
+
+  errbound = ccwerrboundA * detsum;
+  if ((det >= errbound) || (-det >= errbound)) {
+    return det;
+  }
+
+  return orient2dadapt(pa, pb, pc, detsum);
+}
+
+/*****************************************************************************/
+/*                                                                           */
+/*  orient3dfast()   Approximate 3D orientation test.  Nonrobust.            */
+/*  orient3dexact()   Exact 3D orientation test.  Robust.                    */
+/*  orient3dslow()   Another exact 3D orientation test.  Robust.             */
+/*  orient3d()   Adaptive exact 3D orientation test.  Robust.                */
+/*                                                                           */
+/*               Return a positive value if the point pd lies below the      */
+/*               plane passing through pa, pb, and pc; "below" is defined so */
+/*               that pa, pb, and pc appear in counterclockwise order when   */
+/*               viewed from above the plane.  Returns a negative value if   */
+/*               pd lies above the plane.  Returns zero if the points are    */
+/*               coplanar.  The result is also a rough approximation of six  */
+/*               times the signed volume of the tetrahedron defined by the   */
+/*               four points.                                                */
+/*                                                                           */
+/*  Only the first and last routine should be used; the middle two are for   */
+/*  timings.                                                                 */
+/*                                                                           */
+/*  The last three use exact arithmetic to ensure a correct answer.  The     */
+/*  result returned is the determinant of a matrix.  In orient3d() only,     */
+/*  this determinant is computed adaptively, in the sense that exact         */
+/*  arithmetic is used only to the degree it is needed to ensure that the    */
+/*  returned value has the correct sign.  Hence, orient3d() is usually quite */
+/*  fast, but will run more slowly when the input points are coplanar or     */
+/*  nearly so.                                                               */
+/*                                                                           */
+/*****************************************************************************/
+
+REAL orient3dfast(REAL *pa, REAL *pb, REAL *pc, REAL *pd)
+/* REAL *pa; */
+/* REAL *pb; */
+/* REAL *pc; */
+/* REAL *pd; */
+{
+  REAL adx, bdx, cdx;
+  REAL ady, bdy, cdy;
+  REAL adz, bdz, cdz;
+
+  adx = pa[0] - pd[0];
+  bdx = pb[0] - pd[0];
+  cdx = pc[0] - pd[0];
+  ady = pa[1] - pd[1];
+  bdy = pb[1] - pd[1];
+  cdy = pc[1] - pd[1];
+  adz = pa[2] - pd[2];
+  bdz = pb[2] - pd[2];
+  cdz = pc[2] - pd[2];
+
+  return adx * (bdy * cdz - bdz * cdy)
+       + bdx * (cdy * adz - cdz * ady)
+       + cdx * (ady * bdz - adz * bdy);
+}
+
+REAL orient3dexact(REAL *pa, REAL *pb, REAL *pc, REAL *pd)
+/* REAL *pa; */
+/* REAL *pb; */
+/* REAL *pc; */
+/* REAL *pd; */
+{
+  INEXACT REAL axby1, bxcy1, cxdy1, dxay1, axcy1, bxdy1;
+  INEXACT REAL bxay1, cxby1, dxcy1, axdy1, cxay1, dxby1;
+  REAL axby0, bxcy0, cxdy0, dxay0, axcy0, bxdy0;
+  REAL bxay0, cxby0, dxcy0, axdy0, cxay0, dxby0;
+  REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4];
+  REAL temp8[8];
+  int templen;
+  REAL abc[12], bcd[12], cda[12], dab[12];
+  int abclen, bcdlen, cdalen, dablen;
+  REAL adet[24], bdet[24], cdet[24], ddet[24];
+  int alen, blen, clen, dlen;
+  REAL abdet[48], cddet[48];
+  int ablen, cdlen;
+  REAL deter[96];
+  int deterlen;
+  int i;
+
+  INEXACT REAL bvirt;
+  REAL avirt, bround, around;
+  INEXACT REAL c;
+  INEXACT REAL abig;
+  REAL ahi, alo, bhi, blo;
+  REAL err1, err2, err3;
+  INEXACT REAL _i, _j;
+  REAL _0;
+
+  Two_Product(pa[0], pb[1], axby1, axby0);
+  Two_Product(pb[0], pa[1], bxay1, bxay0);
+  Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]);
+
+  Two_Product(pb[0], pc[1], bxcy1, bxcy0);
+  Two_Product(pc[0], pb[1], cxby1, cxby0);
+  Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]);
+
+  Two_Product(pc[0], pd[1], cxdy1, cxdy0);
+  Two_Product(pd[0], pc[1], dxcy1, dxcy0);
+  Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]);
+
+  Two_Product(pd[0], pa[1], dxay1, dxay0);
+  Two_Product(pa[0], pd[1], axdy1, axdy0);
+  Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]);
+
+  Two_Product(pa[0], pc[1], axcy1, axcy0);
+  Two_Product(pc[0], pa[1], cxay1, cxay0);
+  Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]);
+
+  Two_Product(pb[0], pd[1], bxdy1, bxdy0);
+  Two_Product(pd[0], pb[1], dxby1, dxby0);
+  Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]);
+
+  templen = fast_expansion_sum_zeroelim(4, cd, 4, da, temp8);
+  cdalen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, cda);
+  templen = fast_expansion_sum_zeroelim(4, da, 4, ab, temp8);
+  dablen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, dab);
+  for (i = 0; i < 4; i++) {
+    bd[i] = -bd[i];
+    ac[i] = -ac[i];
+  }
+  templen = fast_expansion_sum_zeroelim(4, ab, 4, bc, temp8);
+  abclen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, abc);
+  templen = fast_expansion_sum_zeroelim(4, bc, 4, cd, temp8);
+  bcdlen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, bcd);
+
+  alen = scale_expansion_zeroelim(bcdlen, bcd, pa[2], adet);
+  blen = scale_expansion_zeroelim(cdalen, cda, -pb[2], bdet);
+  clen = scale_expansion_zeroelim(dablen, dab, pc[2], cdet);
+  dlen = scale_expansion_zeroelim(abclen, abc, -pd[2], ddet);
+
+  ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
+  cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet);
+  deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, deter);
+
+  return deter[deterlen - 1];
+}
+
+REAL orient3dslow(REAL *pa, REAL *pb, REAL *pc, REAL *pd)
+/* REAL *pa; */
+/* REAL *pb; */
+/* REAL *pc; */
+/* REAL *pd; */
+{
+  INEXACT REAL adx, ady, adz, bdx, bdy, bdz, cdx, cdy, cdz;
+  REAL adxtail, adytail, adztail;
+  REAL bdxtail, bdytail, bdztail;
+  REAL cdxtail, cdytail, cdztail;
+  REAL negate, negatetail;
+  INEXACT REAL axby7, bxcy7, axcy7, bxay7, cxby7, cxay7;
+  REAL axby[8], bxcy[8], axcy[8], bxay[8], cxby[8], cxay[8];
+  REAL temp16[16], temp32[32], temp32t[32];
+  int temp16len, temp32len, temp32tlen;
+  REAL adet[64], bdet[64], cdet[64];
+  int alen, blen, clen;
+  REAL abdet[128];
+  int ablen;
+  REAL deter[192];
+  int deterlen;
+
+  INEXACT REAL bvirt;
+  REAL avirt, bround, around;
+  INEXACT REAL c;
+  INEXACT REAL abig;
+  REAL a0hi, a0lo, a1hi, a1lo, bhi, blo;
+  REAL err1, err2, err3;
+  INEXACT REAL _i, _j, _k, _l, _m, _n;
+  REAL _0, _1, _2;
+
+  Two_Diff(pa[0], pd[0], adx, adxtail);
+  Two_Diff(pa[1], pd[1], ady, adytail);
+  Two_Diff(pa[2], pd[2], adz, adztail);
+  Two_Diff(pb[0], pd[0], bdx, bdxtail);
+  Two_Diff(pb[1], pd[1], bdy, bdytail);
+  Two_Diff(pb[2], pd[2], bdz, bdztail);
+  Two_Diff(pc[0], pd[0], cdx, cdxtail);
+  Two_Diff(pc[1], pd[1], cdy, cdytail);
+  Two_Diff(pc[2], pd[2], cdz, cdztail);
+
+  Two_Two_Product(adx, adxtail, bdy, bdytail,
+                  axby7, axby[6], axby[5], axby[4],
+                  axby[3], axby[2], axby[1], axby[0]);
+  axby[7] = axby7;
+  negate = -ady;
+  negatetail = -adytail;
+  Two_Two_Product(bdx, bdxtail, negate, negatetail,
+                  bxay7, bxay[6], bxay[5], bxay[4],
+                  bxay[3], bxay[2], bxay[1], bxay[0]);
+  bxay[7] = bxay7;
+  Two_Two_Product(bdx, bdxtail, cdy, cdytail,
+                  bxcy7, bxcy[6], bxcy[5], bxcy[4],
+                  bxcy[3], bxcy[2], bxcy[1], bxcy[0]);
+  bxcy[7] = bxcy7;
+  negate = -bdy;
+  negatetail = -bdytail;
+  Two_Two_Product(cdx, cdxtail, negate, negatetail,
+                  cxby7, cxby[6], cxby[5], cxby[4],
+                  cxby[3], cxby[2], cxby[1], cxby[0]);
+  cxby[7] = cxby7;
+  Two_Two_Product(cdx, cdxtail, ady, adytail,
+                  cxay7, cxay[6], cxay[5], cxay[4],
+                  cxay[3], cxay[2], cxay[1], cxay[0]);
+  cxay[7] = cxay7;
+  negate = -cdy;
+  negatetail = -cdytail;
+  Two_Two_Product(adx, adxtail, negate, negatetail,
+                  axcy7, axcy[6], axcy[5], axcy[4],
+                  axcy[3], axcy[2], axcy[1], axcy[0]);
+  axcy[7] = axcy7;
+
+  temp16len = fast_expansion_sum_zeroelim(8, bxcy, 8, cxby, temp16);
+  temp32len = scale_expansion_zeroelim(temp16len, temp16, adz, temp32);
+  temp32tlen = scale_expansion_zeroelim(temp16len, temp16, adztail, temp32t);
+  alen = fast_expansion_sum_zeroelim(temp32len, temp32, temp32tlen, temp32t,
+                                     adet);
+
+  temp16len = fast_expansion_sum_zeroelim(8, cxay, 8, axcy, temp16);
+  temp32len = scale_expansion_zeroelim(temp16len, temp16, bdz, temp32);
+  temp32tlen = scale_expansion_zeroelim(temp16len, temp16, bdztail, temp32t);
+  blen = fast_expansion_sum_zeroelim(temp32len, temp32, temp32tlen, temp32t,
+                                     bdet);
+
+  temp16len = fast_expansion_sum_zeroelim(8, axby, 8, bxay, temp16);
+  temp32len = scale_expansion_zeroelim(temp16len, temp16, cdz, temp32);
+  temp32tlen = scale_expansion_zeroelim(temp16len, temp16, cdztail, temp32t);
+  clen = fast_expansion_sum_zeroelim(temp32len, temp32, temp32tlen, temp32t,
+                                     cdet);
+
+  ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
+  deterlen = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, deter);
+
+  return deter[deterlen - 1];
+}
+
+REAL orient3dadapt(const REAL *pa, const REAL *pb, const REAL *pc, const REAL *pd, REAL permanent)
+/* REAL *pa; */
+/* REAL *pb; */
+/* REAL *pc; */
+/* REAL *pd; */
+/* REAL permanent; */
+{
+  INEXACT REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz;
+  REAL det, errbound;
+
+  INEXACT REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1;
+  REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0;
+  REAL bc[4], ca[4], ab[4];
+  INEXACT REAL bc3, ca3, ab3;
+  REAL adet[8], bdet[8], cdet[8];
+  int alen, blen, clen;
+  REAL abdet[16];
+  int ablen;
+  REAL *finnow, *finother, *finswap;
+  REAL fin1[192], fin2[192];
+  int finlength;
+
+  REAL adxtail, bdxtail, cdxtail;
+  REAL adytail, bdytail, cdytail;
+  REAL adztail, bdztail, cdztail;
+  INEXACT REAL at_blarge, at_clarge;
+  INEXACT REAL bt_clarge, bt_alarge;
+  INEXACT REAL ct_alarge, ct_blarge;
+  REAL at_b[4], at_c[4], bt_c[4], bt_a[4], ct_a[4], ct_b[4];
+  int at_blen, at_clen, bt_clen, bt_alen, ct_alen, ct_blen;
+  INEXACT REAL bdxt_cdy1, cdxt_bdy1, cdxt_ady1;
+  INEXACT REAL adxt_cdy1, adxt_bdy1, bdxt_ady1;
+  REAL bdxt_cdy0, cdxt_bdy0, cdxt_ady0;
+  REAL adxt_cdy0, adxt_bdy0, bdxt_ady0;
+  INEXACT REAL bdyt_cdx1, cdyt_bdx1, cdyt_adx1;
+  INEXACT REAL adyt_cdx1, adyt_bdx1, bdyt_adx1;
+  REAL bdyt_cdx0, cdyt_bdx0, cdyt_adx0;
+  REAL adyt_cdx0, adyt_bdx0, bdyt_adx0;
+  REAL bct[8], cat[8], abt[8];
+  int bctlen, catlen, abtlen;
+  INEXACT REAL bdxt_cdyt1, cdxt_bdyt1, cdxt_adyt1;
+  INEXACT REAL adxt_cdyt1, adxt_bdyt1, bdxt_adyt1;
+  REAL bdxt_cdyt0, cdxt_bdyt0, cdxt_adyt0;
+  REAL adxt_cdyt0, adxt_bdyt0, bdxt_adyt0;
+  REAL u[4], v[12], w[16];
+  INEXACT REAL u3;
+  int vlength, wlength;
+  REAL negate;
+
+  INEXACT REAL bvirt;
+  REAL avirt, bround, around;
+  INEXACT REAL c;
+  INEXACT REAL abig;
+  REAL ahi, alo, bhi, blo;
+  REAL err1, err2, err3;
+  INEXACT REAL _i, _j, _k;
+  REAL _0;
+
+  adx = (REAL) (pa[0] - pd[0]);
+  bdx = (REAL) (pb[0] - pd[0]);
+  cdx = (REAL) (pc[0] - pd[0]);
+  ady = (REAL) (pa[1] - pd[1]);
+  bdy = (REAL) (pb[1] - pd[1]);
+  cdy = (REAL) (pc[1] - pd[1]);
+  adz = (REAL) (pa[2] - pd[2]);
+  bdz = (REAL) (pb[2] - pd[2]);
+  cdz = (REAL) (pc[2] - pd[2]);
+
+  Two_Product(bdx, cdy, bdxcdy1, bdxcdy0);
+  Two_Product(cdx, bdy, cdxbdy1, cdxbdy0);
+  Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]);
+  bc[3] = bc3;
+  alen = scale_expansion_zeroelim(4, bc, adz, adet);
+
+  Two_Product(cdx, ady, cdxady1, cdxady0);
+  Two_Product(adx, cdy, adxcdy1, adxcdy0);
+  Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]);
+  ca[3] = ca3;
+  blen = scale_expansion_zeroelim(4, ca, bdz, bdet);
+
+  Two_Product(adx, bdy, adxbdy1, adxbdy0);
+  Two_Product(bdx, ady, bdxady1, bdxady0);
+  Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]);
+  ab[3] = ab3;
+  clen = scale_expansion_zeroelim(4, ab, cdz, cdet);
+
+  ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
+  finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1);
+
+  det = estimate(finlength, fin1);
+  errbound = o3derrboundB * permanent;
+  if ((det >= errbound) || (-det >= errbound)) {
+    return det;
+  }
+
+  Two_Diff_Tail(pa[0], pd[0], adx, adxtail);
+  Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail);
+  Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail);
+  Two_Diff_Tail(pa[1], pd[1], ady, adytail);
+  Two_Diff_Tail(pb[1], pd[1], bdy, bdytail);
+  Two_Diff_Tail(pc[1], pd[1], cdy, cdytail);
+  Two_Diff_Tail(pa[2], pd[2], adz, adztail);
+  Two_Diff_Tail(pb[2], pd[2], bdz, bdztail);
+  Two_Diff_Tail(pc[2], pd[2], cdz, cdztail);
+
+  if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0)
+      && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0)
+      && (adztail == 0.0) && (bdztail == 0.0) && (cdztail == 0.0)) {
+    return det;
+  }
+
+  errbound = o3derrboundC * permanent + resulterrbound * Absolute(det);
+  det += (adz * ((bdx * cdytail + cdy * bdxtail)
+                 - (bdy * cdxtail + cdx * bdytail))
+          + adztail * (bdx * cdy - bdy * cdx))
+       + (bdz * ((cdx * adytail + ady * cdxtail)
+                 - (cdy * adxtail + adx * cdytail))
+          + bdztail * (cdx * ady - cdy * adx))
+       + (cdz * ((adx * bdytail + bdy * adxtail)
+                 - (ady * bdxtail + bdx * adytail))
+          + cdztail * (adx * bdy - ady * bdx));
+  if ((det >= errbound) || (-det >= errbound)) {
+    return det;
+  }
+
+  finnow = fin1;
+  finother = fin2;
+
+  if (adxtail == 0.0) {
+    if (adytail == 0.0) {
+      at_b[0] = 0.0;
+      at_blen = 1;
+      at_c[0] = 0.0;
+      at_clen = 1;
+    } else {
+      negate = -adytail;
+      Two_Product(negate, bdx, at_blarge, at_b[0]);
+      at_b[1] = at_blarge;
+      at_blen = 2;
+      Two_Product(adytail, cdx, at_clarge, at_c[0]);
+      at_c[1] = at_clarge;
+      at_clen = 2;
+    }
+  } else {
+    if (adytail == 0.0) {
+      Two_Product(adxtail, bdy, at_blarge, at_b[0]);
+      at_b[1] = at_blarge;
+      at_blen = 2;
+      negate = -adxtail;
+      Two_Product(negate, cdy, at_clarge, at_c[0]);
+      at_c[1] = at_clarge;
+      at_clen = 2;
+    } else {
+      Two_Product(adxtail, bdy, adxt_bdy1, adxt_bdy0);
+      Two_Product(adytail, bdx, adyt_bdx1, adyt_bdx0);
+      Two_Two_Diff(adxt_bdy1, adxt_bdy0, adyt_bdx1, adyt_bdx0,
+                   at_blarge, at_b[2], at_b[1], at_b[0]);
+      at_b[3] = at_blarge;
+      at_blen = 4;
+      Two_Product(adytail, cdx, adyt_cdx1, adyt_cdx0);
+      Two_Product(adxtail, cdy, adxt_cdy1, adxt_cdy0);
+      Two_Two_Diff(adyt_cdx1, adyt_cdx0, adxt_cdy1, adxt_cdy0,
+                   at_clarge, at_c[2], at_c[1], at_c[0]);
+      at_c[3] = at_clarge;
+      at_clen = 4;
+    }
+  }
+  if (bdxtail == 0.0) {
+    if (bdytail == 0.0) {
+      bt_c[0] = 0.0;
+      bt_clen = 1;
+      bt_a[0] = 0.0;
+      bt_alen = 1;
+    } else {
+      negate = -bdytail;
+      Two_Product(negate, cdx, bt_clarge, bt_c[0]);
+      bt_c[1] = bt_clarge;
+      bt_clen = 2;
+      Two_Product(bdytail, adx, bt_alarge, bt_a[0]);
+      bt_a[1] = bt_alarge;
+      bt_alen = 2;
+    }
+  } else {
+    if (bdytail == 0.0) {
+      Two_Product(bdxtail, cdy, bt_clarge, bt_c[0]);
+      bt_c[1] = bt_clarge;
+      bt_clen = 2;
+      negate = -bdxtail;
+      Two_Product(negate, ady, bt_alarge, bt_a[0]);
+      bt_a[1] = bt_alarge;
+      bt_alen = 2;
+    } else {
+      Two_Product(bdxtail, cdy, bdxt_cdy1, bdxt_cdy0);
+      Two_Product(bdytail, cdx, bdyt_cdx1, bdyt_cdx0);
+      Two_Two_Diff(bdxt_cdy1, bdxt_cdy0, bdyt_cdx1, bdyt_cdx0,
+                   bt_clarge, bt_c[2], bt_c[1], bt_c[0]);
+      bt_c[3] = bt_clarge;
+      bt_clen = 4;
+      Two_Product(bdytail, adx, bdyt_adx1, bdyt_adx0);
+      Two_Product(bdxtail, ady, bdxt_ady1, bdxt_ady0);
+      Two_Two_Diff(bdyt_adx1, bdyt_adx0, bdxt_ady1, bdxt_ady0,
+                  bt_alarge, bt_a[2], bt_a[1], bt_a[0]);
+      bt_a[3] = bt_alarge;
+      bt_alen = 4;
+    }
+  }
+  if (cdxtail == 0.0) {
+    if (cdytail == 0.0) {
+      ct_a[0] = 0.0;
+      ct_alen = 1;
+      ct_b[0] = 0.0;
+      ct_blen = 1;
+    } else {
+      negate = -cdytail;
+      Two_Product(negate, adx, ct_alarge, ct_a[0]);
+      ct_a[1] = ct_alarge;
+      ct_alen = 2;
+      Two_Product(cdytail, bdx, ct_blarge, ct_b[0]);
+      ct_b[1] = ct_blarge;
+      ct_blen = 2;
+    }
+  } else {
+    if (cdytail == 0.0) {
+      Two_Product(cdxtail, ady, ct_alarge, ct_a[0]);
+      ct_a[1] = ct_alarge;
+      ct_alen = 2;
+      negate = -cdxtail;
+      Two_Product(negate, bdy, ct_blarge, ct_b[0]);
+      ct_b[1] = ct_blarge;
+      ct_blen = 2;
+    } else {
+      Two_Product(cdxtail, ady, cdxt_ady1, cdxt_ady0);
+      Two_Product(cdytail, adx, cdyt_adx1, cdyt_adx0);
+      Two_Two_Diff(cdxt_ady1, cdxt_ady0, cdyt_adx1, cdyt_adx0,
+                   ct_alarge, ct_a[2], ct_a[1], ct_a[0]);
+      ct_a[3] = ct_alarge;
+      ct_alen = 4;
+      Two_Product(cdytail, bdx, cdyt_bdx1, cdyt_bdx0);
+      Two_Product(cdxtail, bdy, cdxt_bdy1, cdxt_bdy0);
+      Two_Two_Diff(cdyt_bdx1, cdyt_bdx0, cdxt_bdy1, cdxt_bdy0,
+                   ct_blarge, ct_b[2], ct_b[1], ct_b[0]);
+      ct_b[3] = ct_blarge;
+      ct_blen = 4;
+    }
+  }
+
+  bctlen = fast_expansion_sum_zeroelim(bt_clen, bt_c, ct_blen, ct_b, bct);
+  wlength = scale_expansion_zeroelim(bctlen, bct, adz, w);
+  finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
+                                          finother);
+  finswap = finnow; finnow = finother; finother = finswap;
+
+  catlen = fast_expansion_sum_zeroelim(ct_alen, ct_a, at_clen, at_c, cat);
+  wlength = scale_expansion_zeroelim(catlen, cat, bdz, w);
+  finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
+                                          finother);
+  finswap = finnow; finnow = finother; finother = finswap;
+
+  abtlen = fast_expansion_sum_zeroelim(at_blen, at_b, bt_alen, bt_a, abt);
+  wlength = scale_expansion_zeroelim(abtlen, abt, cdz, w);
+  finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
+                                          finother);
+  finswap = finnow; finnow = finother; finother = finswap;
+
+  if (adztail != 0.0) {
+    vlength = scale_expansion_zeroelim(4, bc, adztail, v);
+    finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v,
+                                            finother);
+    finswap = finnow; finnow = finother; finother = finswap;
+  }
+  if (bdztail != 0.0) {
+    vlength = scale_expansion_zeroelim(4, ca, bdztail, v);
+    finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v,
+                                            finother);
+    finswap = finnow; finnow = finother; finother = finswap;
+  }
+  if (cdztail != 0.0) {
+    vlength = scale_expansion_zeroelim(4, ab, cdztail, v);
+    finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v,
+                                            finother);
+    finswap = finnow; finnow = finother; finother = finswap;
+  }
+
+  if (adxtail != 0.0) {
+    if (bdytail != 0.0) {
+      Two_Product(adxtail, bdytail, adxt_bdyt1, adxt_bdyt0);
+      Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdz, u3, u[2], u[1], u[0]);
+      u[3] = u3;
+      finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+                                              finother);
+      finswap = finnow; finnow = finother; finother = finswap;
+      if (cdztail != 0.0) {
+        Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdztail, u3, u[2], u[1], u[0]);
+        u[3] = u3;
+        finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+                                                finother);
+        finswap = finnow; finnow = finother; finother = finswap;
+      }
+    }
+    if (cdytail != 0.0) {
+      negate = -adxtail;
+      Two_Product(negate, cdytail, adxt_cdyt1, adxt_cdyt0);
+      Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdz, u3, u[2], u[1], u[0]);
+      u[3] = u3;
+      finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+                                              finother);
+      finswap = finnow; finnow = finother; finother = finswap;
+      if (bdztail != 0.0) {
+        Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdztail, u3, u[2], u[1], u[0]);
+        u[3] = u3;
+        finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+                                                finother);
+        finswap = finnow; finnow = finother; finother = finswap;
+      }
+    }
+  }
+  if (bdxtail != 0.0) {
+    if (cdytail != 0.0) {
+      Two_Product(bdxtail, cdytail, bdxt_cdyt1, bdxt_cdyt0);
+      Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adz, u3, u[2], u[1], u[0]);
+      u[3] = u3;
+      finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+                                              finother);
+      finswap = finnow; finnow = finother; finother = finswap;
+      if (adztail != 0.0) {
+        Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adztail, u3, u[2], u[1], u[0]);
+        u[3] = u3;
+        finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+                                                finother);
+        finswap = finnow; finnow = finother; finother = finswap;
+      }
+    }
+    if (adytail != 0.0) {
+      negate = -bdxtail;
+      Two_Product(negate, adytail, bdxt_adyt1, bdxt_adyt0);
+      Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdz, u3, u[2], u[1], u[0]);
+      u[3] = u3;
+      finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+                                              finother);
+      finswap = finnow; finnow = finother; finother = finswap;
+      if (cdztail != 0.0) {
+        Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdztail, u3, u[2], u[1], u[0]);
+        u[3] = u3;
+        finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+                                                finother);
+        finswap = finnow; finnow = finother; finother = finswap;
+      }
+    }
+  }
+  if (cdxtail != 0.0) {
+    if (adytail != 0.0) {
+      Two_Product(cdxtail, adytail, cdxt_adyt1, cdxt_adyt0);
+      Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdz, u3, u[2], u[1], u[0]);
+      u[3] = u3;
+      finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+                                              finother);
+      finswap = finnow; finnow = finother; finother = finswap;
+      if (bdztail != 0.0) {
+        Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdztail, u3, u[2], u[1], u[0]);
+        u[3] = u3;
+        finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+                                                finother);
+        finswap = finnow; finnow = finother; finother = finswap;
+      }
+    }
+    if (bdytail != 0.0) {
+      negate = -cdxtail;
+      Two_Product(negate, bdytail, cdxt_bdyt1, cdxt_bdyt0);
+      Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adz, u3, u[2], u[1], u[0]);
+      u[3] = u3;
+      finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+                                              finother);
+      finswap = finnow; finnow = finother; finother = finswap;
+      if (adztail != 0.0) {
+        Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adztail, u3, u[2], u[1], u[0]);
+        u[3] = u3;
+        finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
+                                                finother);
+        finswap = finnow; finnow = finother; finother = finswap;
+      }
+    }
+  }
+
+  if (adztail != 0.0) {
+    wlength = scale_expansion_zeroelim(bctlen, bct, adztail, w);
+    finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
+                                            finother);
+    finswap = finnow; finnow = finother; finother = finswap;
+  }
+  if (bdztail != 0.0) {
+    wlength = scale_expansion_zeroelim(catlen, cat, bdztail, w);
+    finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
+                                            finother);
+    finswap = finnow; finnow = finother; finother = finswap;
+  }
+  if (cdztail != 0.0) {
+    wlength = scale_expansion_zeroelim(abtlen, abt, cdztail, w);
+    finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
+                                            finother);
+    finswap = finnow; finnow = finother; finother = finswap;
+  }
+
+  return finnow[finlength - 1];
+}
+
+REAL dolfin::_orient3d(const REAL *pa, const REAL *pb, const REAL *pc, const REAL *pd)
+/* REAL *pa; */
+/* REAL *pb; */
+/* REAL *pc; */
+/* REAL *pd; */
+{
+  REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz;
+  REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady;
+  REAL det;
+  REAL permanent, errbound;
+
+  adx = pa[0] - pd[0];
+  bdx = pb[0] - pd[0];
+  cdx = pc[0] - pd[0];
+  ady = pa[1] - pd[1];
+  bdy = pb[1] - pd[1];
+  cdy = pc[1] - pd[1];
+  adz = pa[2] - pd[2];
+  bdz = pb[2] - pd[2];
+  cdz = pc[2] - pd[2];
+
+  bdxcdy = bdx * cdy;
+  cdxbdy = cdx * bdy;
+
+  cdxady = cdx * ady;
+  adxcdy = adx * cdy;
+
+  adxbdy = adx * bdy;
+  bdxady = bdx * ady;
+
+  det = adz * (bdxcdy - cdxbdy)
+      + bdz * (cdxady - adxcdy)
+      + cdz * (adxbdy - bdxady);
+
+  permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * Absolute(adz)
+            + (Absolute(cdxady) + Absolute(adxcdy)) * Absolute(bdz)
+            + (Absolute(adxbdy) + Absolute(bdxady)) * Absolute(cdz);
+  errbound = o3derrboundA * permanent;
+  if ((det > errbound) || (-det > errbound)) {
+    return det;
+  }
+
+  return orient3dadapt(pa, pb, pc, pd, permanent);
+}
+
+
+//--- DOLFIN-specific additions ---
+
+#include "predicates.h"
+
+namespace dolfin
+{
+  /// Initialize the predicate
+  PredicateInitialization predicate_initialization;
+}
diff --git a/dolfin/geometry/predicates.h b/dolfin/geometry/predicates.h
new file mode 100644
index 0000000..fa7f248
--- /dev/null
+++ b/dolfin/geometry/predicates.h
@@ -0,0 +1,59 @@
+// This is a DOLFIN header file for predicates.cpp which provides
+//
+//   Routines for Arbitrary Precision Floating-point Arithmetic
+//   and Fast Robust Geometric Predicates
+//
+// by
+//
+//   Jonathan Richard Shewchuk
+//
+// Code is placed in the public domain.
+
+#ifndef __PREDICATES_H
+#define __PREDICATES_H
+
+namespace dolfin
+{
+
+  class Point;
+
+  /// Initialize tolerances for exact arithmetic
+  void exactinit();
+
+  /// Compute relative orientation of point x wrt segment [a, b]
+  double orient1d(double a, double b, double x);
+
+  /// Compute relative orientation of points a, b, c. The orientation
+  /// is such that orient2d(a, b, c) > 0 if a, b, c are ordered
+  /// counter-clockwise.
+  double _orient2d(const double* a, const double* b, const double* c);
+
+  /// Convenience function using dolfin::Point
+  double orient2d(const Point& a, const Point& b, const Point& c);
+
+  /// Compute relative orientation of points a, b, c, d. The
+  /// orientation is such that orient3d(a, b, c, d) > 0 if a, b, c, d
+  /// are oriented according to the left hand rule.
+  double _orient3d(const double* a, const double* b, const double* c, const double* d);
+
+  /// Convenience function using dolfin::Point
+  double orient3d(const Point& a, const Point& b, const Point& c, const Point& d);
+
+  /// Class used for automatic initialization of tolerances at startup.
+  /// A global instance is defined inside predicates.cpp to ensure that
+  /// the constructor and thus exactinit() is called.
+
+  class PredicateInitialization
+  {
+  public:
+
+    PredicateInitialization()
+    {
+      exactinit();
+    }
+
+  };
+
+}
+
+#endif
diff --git a/dolfin/io/HDF5File.cpp b/dolfin/io/HDF5File.cpp
index 252c7ac..5462bd5 100644
--- a/dolfin/io/HDF5File.cpp
+++ b/dolfin/io/HDF5File.cpp
@@ -444,7 +444,7 @@ void HDF5File::write(const Mesh& mesh, std::size_t cell_dim,
     global_size[1] = num_cell_points;
 
     const std::int64_t num_cells
-      = mpi_io ? mesh.size_global(cell_dim) : mesh.size(cell_dim);
+      = mpi_io ? mesh.num_entities_global(cell_dim) : mesh.num_entities(cell_dim);
     dolfin_assert(global_size[0] == num_cells);
     const bool mpi_io = _mpi_comm.size() > 1 ? true : false;
     write_data(topology_dataset, topological_data, global_size, mpi_io);
@@ -608,10 +608,10 @@ void HDF5File::read_mesh_function(MeshFunction<T>& meshfunction,
                  "Cell dimension mismatch");
   }
 
-  // Ensure size_global(cell_dim) is set
+  // Ensure num_entities_global(cell_dim) is set
   DistributedMeshTools::number_entities(*mesh, cell_dim);
 
-  if (num_global_cells != mesh->size_global(cell_dim))
+  if (num_global_cells != mesh->num_entities_global(cell_dim))
   {
     dolfin_error("HDF5File.cpp",
                  "read meshfunction topology",
@@ -641,7 +641,7 @@ void HDF5File::read_mesh_function(MeshFunction<T>& meshfunction,
   // Now send the read data to each process on the basis of the first
   // vertex of the entity, since we do not know the global_index
   const std::size_t num_processes = _mpi_comm.size();
-  const std::size_t max_vertex = mesh->size_global(0);
+  const std::size_t max_vertex = mesh->num_entities_global(0);
 
   std::vector<std::vector<std::size_t>> send_topology(num_processes);
   std::vector<std::vector<T>> send_values(num_processes);
@@ -785,7 +785,7 @@ void HDF5File::write_mesh_function(const MeshFunction<T>& meshfunction,
   else
   {
     // In parallel and not CellFunction
-    data_values.reserve(mesh.size(cell_dim));
+    data_values.reserve(mesh.num_entities(cell_dim));
 
     // Drop duplicate data
     const std::size_t tdim = mesh.topology().dim();
@@ -925,14 +925,14 @@ void HDF5File::write(const Function& u, const std::string name)
   write_data(name + "/cell_dofs", cell_dofs, global_size, mpi_io);
   if (_mpi_comm.rank() == _mpi_comm.size() - 1)
     x_cell_dofs.push_back(global_size[0]);
-  global_size[0] = mesh.size_global(tdim) + 1;
+  global_size[0] = mesh.num_entities_global(tdim) + 1;
   write_data(name + "/x_cell_dofs", x_cell_dofs, global_size, mpi_io);
 
   // Save cell ordering - copy to local vector and cut off ghosts
   std::vector<std::size_t> cells(mesh.topology().global_indices(tdim).begin(),
                        mesh.topology().global_indices(tdim).begin() + n_cells);
 
-  global_size[0] = mesh.size_global(tdim);
+  global_size[0] = mesh.num_entities_global(tdim);
   write_data(name + "/cells", cells, global_size, mpi_io);
 
   HDF5Interface::add_attribute(_hdf5_file_id, name, "signature",
@@ -1030,7 +1030,7 @@ void HDF5File::read(Function& u, const std::string name)
   const std::vector<std::int64_t> dataset_shape =
     HDF5Interface::get_dataset_shape(_hdf5_file_id, cells_dataset_name);
   const std::size_t num_global_cells = dataset_shape[0];
-  if (mesh.size_global(mesh.topology().dim()) != num_global_cells)
+  if (mesh.num_entities_global(mesh.topology().dim()) != num_global_cells)
   {
     dolfin_error("HDF5File.cpp",
                  "read Function from file",
@@ -1310,7 +1310,7 @@ void HDF5File::read_mesh_value_collection(MeshValueCollection<T>& mesh_vc,
 
   // Ensure the mesh dimension is initialised
   mesh->init(dim);
-  std::size_t global_vertex_range = mesh->size_global(0);
+  std::size_t global_vertex_range = mesh->num_entities_global(0);
   std::vector<std::size_t> v(num_verts_per_entity);
   const std::size_t num_processes = _mpi_comm.size();
 
diff --git a/dolfin/io/HDF5Utility.cpp b/dolfin/io/HDF5Utility.cpp
index b73e45d..b005fdf 100644
--- a/dolfin/io/HDF5Utility.cpp
+++ b/dolfin/io/HDF5Utility.cpp
@@ -190,7 +190,7 @@ std::vector<std::pair<std::size_t, std::size_t>>
 
   const std::size_t num_processes = MPI::size(mpi_comm);
   const std::size_t num_global_cells
-    = mesh.size_global(mesh.topology().dim());
+    = mesh.num_entities_global(mesh.topology().dim());
   const std::pair<std::size_t, std::size_t> cell_range
     = MPI::local_range(mpi_comm, num_global_cells);
 
@@ -258,7 +258,7 @@ void HDF5Utility::cell_owners_in_range(std::vector<std::pair<std::size_t,
   // MPI communicator
   const MPI_Comm mpi_comm = mesh.mpi_comm();
 
-  const std::size_t n_global_cells = mesh.size_global(mesh.topology().dim());
+  const std::size_t n_global_cells = mesh.num_entities_global(mesh.topology().dim());
   const std::size_t num_processes = MPI::size(mpi_comm);
 
   // Communicate global ownership of cells to matching process
diff --git a/dolfin/io/VTKWriter.cpp b/dolfin/io/VTKWriter.cpp
index ea84367..eff6934 100644
--- a/dolfin/io/VTKWriter.cpp
+++ b/dolfin/io/VTKWriter.cpp
@@ -388,17 +388,17 @@ std::uint8_t VTKWriter::vtk_cell_type(const Mesh& mesh,
 
   // Determine VTK cell type
   std::uint8_t vtk_cell_type = 0;
-  if (cell_type == CellType::tetrahedron)
+  if (cell_type == CellType::Type::tetrahedron)
     vtk_cell_type = 10;
-  else if (cell_type == CellType::hexahedron)
+  else if (cell_type == CellType::Type::hexahedron)
     vtk_cell_type = 12;
-  else if (cell_type == CellType::quadrilateral)
+  else if (cell_type == CellType::Type::quadrilateral)
     vtk_cell_type = 9;
-  else if (cell_type == CellType::triangle)
+  else if (cell_type == CellType::Type::triangle)
     vtk_cell_type = 5;
-  else if (cell_type == CellType::interval)
+  else if (cell_type == CellType::Type::interval)
     vtk_cell_type = 3;
-  else if (cell_type == CellType::point)
+  else if (cell_type == CellType::Type::point)
     vtk_cell_type = 1;
   else
   {
diff --git a/dolfin/io/X3DFile.cpp b/dolfin/io/X3DFile.cpp
index 9578249..aa7dc8c 100644
--- a/dolfin/io/X3DFile.cpp
+++ b/dolfin/io/X3DFile.cpp
@@ -153,7 +153,7 @@ void X3DFile::write_meshfunction(const MeshFunction<std::size_t>& meshfunction)
   {
     dolfin_error("X3DFile.cpp",
                  "output meshfunction",
-                 "Can only output CellFunction at present");
+                 "Can only output MeshFunction on cells at present");
   }
 
   // Check that X3D type is appropriate
@@ -161,7 +161,7 @@ void X3DFile::write_meshfunction(const MeshFunction<std::size_t>& meshfunction)
   {
     dolfin_error("X3DFile.cpp",
                  "output meshfunction",
-                 "Cannot output CellFunction with Edge mesh");
+                 "Cannot output MeshFunction on cells with Edge mesh");
   }
 
   // Check that mesh is in 2D or 3D
diff --git a/dolfin/io/XDMFFile.cpp b/dolfin/io/XDMFFile.cpp
index 6ffc0fe..494dd3d 100644
--- a/dolfin/io/XDMFFile.cpp
+++ b/dolfin/io/XDMFFile.cpp
@@ -369,9 +369,9 @@ void XDMFFile::write(const Function& u, const Encoding encoding)
   dolfin_assert(data_values.size()%width == 0);
 
   const std::int64_t num_points = (degree == 2) ?
-    (mesh.size(0) + mesh.size(1)) : mesh.size_global(0);
+    (mesh.num_entities(0) + mesh.num_entities(1)) : mesh.num_entities_global(0);
   const std::int64_t num_values =  cell_centred ?
-    mesh.size_global(mesh.topology().dim()) : num_points;
+    mesh.num_entities_global(mesh.topology().dim()) : num_points;
 
   add_data_item(_mpi_comm.comm(), attribute_node, h5_id,
                 "/VisualisationVector/0", data_values, {num_values, width});
@@ -513,7 +513,7 @@ void XDMFFile::write(const Function& u, double time_step,
   std::int64_t width = get_padded_width(u);
   dolfin_assert(data_values.size()%width == 0);
   std::int64_t num_values =  cell_centred ?
-    mesh.size_global(mesh.topology().dim()) : mesh.size_global(0);
+    mesh.num_entities_global(mesh.topology().dim()) : mesh.num_entities_global(0);
 
   const std::string dataset_name = "/VisualisationVector/"
                                    + std::to_string(_counter);
@@ -673,7 +673,7 @@ void XDMFFile::write_mesh_value_collection(const MeshValueCollection<T>& mvc,
     const std::string dims_str = geometry_data_node.attribute("Dimensions").as_string();
     std::vector<std::string> dims_list;
     boost::split(dims_list, dims_str, boost::is_any_of(" "));
-    const std::int64_t npoints = mesh->size_global(0);
+    const std::int64_t npoints = mesh->num_entities_global(0);
     if (boost::lexical_cast<std::int64_t>(dims_list[0]) != npoints
         or boost::lexical_cast<std::int64_t>(dims_list[1]) != (int)gdim)
     {
@@ -847,7 +847,7 @@ void XDMFFile::read_mesh_value_collection
 
   // Ensure the mesh dimension is initialised
   mesh->init(cell_dim);
-  const std::size_t global_vertex_range = mesh->size_global(0);
+  const std::size_t global_vertex_range = mesh->num_entities_global(0);
   const std::int32_t num_processes = _mpi_comm.size();
 
   // Send entities to processes based on the lowest vertex index
@@ -1136,7 +1136,7 @@ void XDMFFile::add_mesh(MPI_Comm comm, pugi::xml_node& xml_node,
 
   // Add topology node and attributes (including writing data)
   const int tdim = mesh.topology().dim();
-  const std::int64_t num_global_cells = mesh.size_global(tdim);
+  const std::int64_t num_global_cells = mesh.num_entities_global(tdim);
   if (num_global_cells < 1e9)
     add_topology_data<std::int32_t>(comm, grid_node, h5_id, path_prefix,
                                     mesh, tdim);
@@ -1272,7 +1272,7 @@ void XDMFFile::add_function(MPI_Comm mpi_comm, pugi::xml_node& xml_node,
   if (MPI::rank(mpi_comm) == MPI::size(mpi_comm) - 1)
     x_cell_dofs.push_back(num_cell_dofs_global);
 
-  const std::int64_t num_x_cell_dofs_global = mesh.size_global(tdim) + 1;
+  const std::int64_t num_x_cell_dofs_global = mesh.num_entities_global(tdim) + 1;
 
   // Write number of dofs per cell
   add_data_item(mpi_comm, fe_attribute_node, h5_id,
@@ -1284,7 +1284,7 @@ void XDMFFile::add_function(MPI_Comm mpi_comm, pugi::xml_node& xml_node,
     mesh.topology().global_indices(tdim).begin(),
     mesh.topology().global_indices(tdim).begin() + n_cells);
 
-  const std::int64_t num_cells_global = mesh.size_global(tdim);
+  const std::int64_t num_cells_global = mesh.num_entities_global(tdim);
 
   add_data_item(mpi_comm, fe_attribute_node, h5_id,
                 h5_path + "/cells", cells,
@@ -1545,7 +1545,7 @@ void XDMFFile::build_mesh_quadratic(Mesh& mesh, const CellType& cell_type,
   std::vector<std::int32_t> topology_data
     = get_dataset<std::int32_t>(mesh.mpi_comm(), topology_dataset_node,
                                 relative_path);
-  dolfin_assert(topology_data.size()%num_cells == 0);
+  dolfin_assert(topology_data.size() % num_cells == 0);
   const int num_points_per_cell = topology_data.size()/num_cells;
   const int num_vertices_per_cell = cell_type.num_entities(0);
   const int num_edges_per_cell = cell_type.num_entities(1);
@@ -1825,7 +1825,7 @@ void XDMFFile::add_geometry_data(MPI_Comm comm, pugi::xml_node& xml_node,
   const int degree = mesh_geometry.degree();
   dolfin_assert(degree == 1 or degree == 2);
   const std::int64_t num_points
-    = (degree == 1) ? mesh.size_global(0) : (mesh.size(0) + mesh.size(1));
+    = (degree == 1) ? mesh.num_entities_global(0) : (mesh.num_entities(0) + mesh.num_entities(1));
 
   // Add geometry node and attributes
   pugi::xml_node geometry_node = xml_node.append_child("Geometry");
@@ -2082,7 +2082,7 @@ std::vector<T> XDMFFile::compute_quadratic_topology(const Mesh& mesh)
   const CellType& celltype = mesh.type();
   std::size_t npoint = celltype.num_entities(0) + celltype.num_entities(1);
   std::vector<T> topology_data;
-  topology_data.reserve(npoint*mesh.size(tdim));
+  topology_data.reserve(npoint*mesh.num_entities(tdim));
 
   for (CellIterator c(mesh); !c.end(); ++c)
   {
@@ -2486,9 +2486,9 @@ void XDMFFile::read_mesh_function(MeshFunction<T>& meshfunction,
   dolfin_assert(cell_dim == meshfunction.dim());
   const std::size_t num_entities_global = get_num_cells(topology_node);
 
-  // Ensure size_global(cell_dim) is set and check dataset matches
+  // Ensure num_entities_global(cell_dim) is set and check dataset matches
   DistributedMeshTools::number_entities(*mesh, cell_dim);
-  dolfin_assert(mesh->size_global(cell_dim) == num_entities_global);
+  dolfin_assert(mesh->num_entities_global(cell_dim) == num_entities_global);
 
   boost::filesystem::path xdmf_filename(_filename);
   const boost::filesystem::path parent_path = xdmf_filename.parent_path();
@@ -2533,7 +2533,7 @@ void XDMFFile::remap_meshfunction_data(MeshFunction<T>& meshfunction,
   // determined by the lowest global vertex index of the entity
   std::vector<std::vector<std::int64_t>> send_topology(num_processes);
   std::vector<std::vector<T>> send_values(num_processes);
-  const std::size_t max_vertex = mesh->size_global(0);
+  const std::size_t max_vertex = mesh->num_entities_global(0);
   for (std::size_t i = 0; i < num_entities ; ++i)
   {
     std::vector<std::int64_t>
@@ -2719,7 +2719,8 @@ void XDMFFile::write_mesh_function(const MeshFunction<T>& meshfunction,
 
   const std::string mf_name = "/MeshFunction/" + std::to_string(_counter);
 
-  // If adding a CellFunction to an existing Mesh, do not rewrite Mesh
+  // If adding a MeshFunction of topology dimension dim() to an existing Mesh, 
+  // do not rewrite Mesh
   // FIXME: do some checks on the existing Mesh to make sure it is the same
   // as the meshfunction's mesh.
   pugi::xml_node grid_node = domain_node.child("Grid");
@@ -2753,7 +2754,7 @@ void XDMFFile::write_mesh_function(const MeshFunction<T>& meshfunction,
     // FIXME: remove this once Edge in 3D in parallel works properly
     DistributedMeshTools::number_entities(*mesh, cell_dim);
 
-    const std::int64_t num_global_cells = mesh->size_global(cell_dim);
+    const std::int64_t num_global_cells = mesh->num_entities_global(cell_dim);
     if (num_global_cells < 1e9)
       add_topology_data<std::int32_t>(_mpi_comm.comm(), grid_node, h5_id, mf_name,
                                       *mesh, cell_dim);
@@ -2782,7 +2783,7 @@ void XDMFFile::write_mesh_function(const MeshFunction<T>& meshfunction,
   attribute_node.append_attribute("AttributeType") = "Scalar";
   attribute_node.append_attribute("Center") = "Cell";
 
-  const std::int64_t num_values = mesh->size_global(cell_dim);
+  const std::int64_t num_values = mesh->num_entities_global(cell_dim);
   // Add attribute DataItem node and write data
 
   // Copy values to vector, removing duplicates
@@ -2890,7 +2891,7 @@ std::vector<double> XDMFFile::get_point_data_values(const Function& u)
   if (u.value_rank() > 0)
   {
     // Transpose vector/tensor data arrays
-    const std::size_t num_local_vertices = mesh->size(0);
+    const std::size_t num_local_vertices = mesh->num_entities(0);
     const std::size_t value_size = u.value_size();
     std::vector<double> _data_values(width*num_local_vertices, 0.0);
     for (std::size_t i = 0; i < num_local_vertices; i++)
@@ -2922,7 +2923,7 @@ std::vector<double> XDMFFile::get_p2_data_values(const Function& u)
 
   const std::size_t value_size = u.value_size();
   const std::size_t value_rank = u.value_rank();
-  const std::size_t num_local_points = mesh->size(0) + mesh->size(1);
+  const std::size_t num_local_points = mesh->num_entities(0) + mesh->num_entities(1);
   const std::size_t width = get_padded_width(u);
   std::vector<double> data_values(width*num_local_points);
   std::vector<dolfin::la_index> data_dofs(data_values.size(), 0);
@@ -2958,7 +2959,7 @@ std::vector<double> XDMFFile::get_p2_data_values(const Function& u)
     {
       const std::size_t v0 = e->entities(0)[0];
       const std::size_t v1 = e->entities(0)[1];
-      const std::size_t e0 = (e->index() + mesh->size(0))*width;
+      const std::size_t e0 = (e->index() + mesh->num_entities(0))*width;
       for (std::size_t i = 0; i != value_size; ++i)
         data_values[e0 + i] = (data_values[v0 + i] + data_values[v1 + i])/2.0;
     }
@@ -2982,7 +2983,7 @@ std::vector<double> XDMFFile::get_p2_data_values(const Function& u)
         }
         for (EdgeIterator e(*cell); !e.end(); ++e)
         {
-          const std::size_t e0 = (e->index() + mesh->size(0))*width;
+          const std::size_t e0 = (e->index() + mesh->num_entities(0))*width;
           data_dofs[e0 + i] = dofs[c];
           ++c;
         }
diff --git a/dolfin/io/XMLMesh.cpp b/dolfin/io/XMLMesh.cpp
index b76e3b5..085bded 100644
--- a/dolfin/io/XMLMesh.cpp
+++ b/dolfin/io/XMLMesh.cpp
@@ -483,16 +483,16 @@ void XMLMesh::write_mesh(const Mesh& mesh, pugi::xml_node mesh_node)
 
     switch (_cell_type)
     {
-    case CellType::interval:
+    case CellType::Type::interval:
       cell_node.append_attribute("v0") = (unsigned int) vertices[0];
       cell_node.append_attribute("v1") = (unsigned int) vertices[1];
       break;
-    case CellType::triangle:
+    case CellType::Type::triangle:
       cell_node.append_attribute("v0") = (unsigned int) vertices[0];
       cell_node.append_attribute("v1") = (unsigned int) vertices[1];
       cell_node.append_attribute("v2") = (unsigned int) vertices[2];
       break;
-    case CellType::tetrahedron:
+    case CellType::Type::tetrahedron:
       cell_node.append_attribute("v0") = (unsigned int) vertices[0];
       cell_node.append_attribute("v1") = (unsigned int) vertices[1];
       cell_node.append_attribute("v2") = (unsigned int) vertices[2];
diff --git a/dolfin/la/EigenVector.cpp b/dolfin/la/EigenVector.cpp
index c4493ef..0925cd3 100644
--- a/dolfin/la/EigenVector.cpp
+++ b/dolfin/la/EigenVector.cpp
@@ -112,23 +112,21 @@ void EigenVector::get_local(double* block, std::size_t m,
 //-----------------------------------------------------------------------------
 void EigenVector::get_local(std::vector<double>& values) const
 {
-  values.resize(size());
-  for (std::size_t i = 0; i < size(); i++)
-    values[i] = (*_x)(i);
+  values.assign(_x->data(), _x->data() + _x->size());
 }
 //-----------------------------------------------------------------------------
 void EigenVector::set_local(const std::vector<double>& values)
 {
   dolfin_assert(values.size() == size());
-  for (std::size_t i = 0; i < size(); i++)
-    (*_x)(i) = values[i];
+  Eigen::Map<const Eigen::VectorXd> _values(values.data(), values.size());
+  *_x = _values;
 }
 //-----------------------------------------------------------------------------
 void EigenVector::add_local(const Array<double>& values)
 {
   dolfin_assert(values.size() == size());
-  for (std::size_t i = 0; i < size(); i++)
-    (*_x)(i) += values[i];
+  Eigen::Map<const Eigen::VectorXd> _values(values.data(), values.size());
+  *_x += _values;
 }
 //-----------------------------------------------------------------------------
 void EigenVector::gather(GenericVector& x,
diff --git a/dolfin/la/GenericMatrix.cpp b/dolfin/la/GenericMatrix.cpp
index 8befa07..8c7e905 100644
--- a/dolfin/la/GenericMatrix.cpp
+++ b/dolfin/la/GenericMatrix.cpp
@@ -27,7 +27,7 @@
 using namespace dolfin;
 
 //-----------------------------------------------------------------------------
-void GenericMatrix::ident_zeros()
+void GenericMatrix::ident_zeros(double tol)
 {
   // Check size of system
   if (size(0) != size(1))
@@ -58,7 +58,7 @@ void GenericMatrix::ident_zeros()
       max = std::max(max, std::abs(values[k]));
 
     // Check if row is zero
-    if (max < DOLFIN_EPS)
+    if (max < tol)
       zero_rows.push_back(global_row);
   }
 
diff --git a/dolfin/la/GenericMatrix.h b/dolfin/la/GenericMatrix.h
index e0c3ae6..4347557 100644
--- a/dolfin/la/GenericMatrix.h
+++ b/dolfin/la/GenericMatrix.h
@@ -30,9 +30,11 @@
 
 #include <tuple>
 #include <vector>
+#include <dolfin/common/constants.h>
 #include "GenericTensor.h"
 #include "GenericLinearOperator.h"
 
+
 namespace dolfin
 {
 
@@ -250,8 +252,7 @@ namespace dolfin
     {  set(&value, 1, &ij.first, 1, &ij.second); }
 
     /// Insert one on the diagonal for all zero rows
-    virtual void ident_zeros();
-
+    virtual void ident_zeros(double tol=DOLFIN_EPS);
   };
 
 }
diff --git a/dolfin/la/PETScObject.h b/dolfin/la/PETScObject.h
index 08df1d7..22868c8 100644
--- a/dolfin/la/PETScObject.h
+++ b/dolfin/la/PETScObject.h
@@ -44,6 +44,7 @@ namespace dolfin
     static void petsc_error(int error_code,
                             std::string filename,
                             std::string petsc_function);
+
   };
 }
 
diff --git a/dolfin/la/SLEPcEigenSolver.cpp b/dolfin/la/SLEPcEigenSolver.cpp
index 1f84040..b301625 100644
--- a/dolfin/la/SLEPcEigenSolver.cpp
+++ b/dolfin/la/SLEPcEigenSolver.cpp
@@ -77,7 +77,7 @@ SLEPcEigenSolver::SLEPcEigenSolver(MPI_Comm comm,
 //-----------------------------------------------------------------------------
 SLEPcEigenSolver::SLEPcEigenSolver(std::shared_ptr<const PETScMatrix> A,
                                    std::shared_ptr<const PETScMatrix> B)
-  : _matA(A), _matB(B), _eps(nullptr)
+  : _eps(nullptr)
 
 {
   // TODO: deprecate
@@ -96,9 +96,9 @@ SLEPcEigenSolver::SLEPcEigenSolver(std::shared_ptr<const PETScMatrix> A,
   // Set operators
   dolfin_assert(_eps);
   if (B)
-    EPSSetOperators(_eps, _matA->mat(), _matB->mat());
+    EPSSetOperators(_eps, A->mat(), B->mat());
   else
-    EPSSetOperators(_eps, _matA->mat(), NULL);
+    EPSSetOperators(_eps, A->mat(), NULL);
 
   // Set default parameter values
   parameters = default_parameters();
@@ -107,7 +107,7 @@ SLEPcEigenSolver::SLEPcEigenSolver(std::shared_ptr<const PETScMatrix> A,
 SLEPcEigenSolver::SLEPcEigenSolver(MPI_Comm comm,
                                    std::shared_ptr<const PETScMatrix> A,
                                    std::shared_ptr<const PETScMatrix> B)
-  : _matA(A), _matB(B), _eps(nullptr)
+  : _eps(nullptr)
 {
   // TODO: deprecate
 
@@ -127,9 +127,9 @@ SLEPcEigenSolver::SLEPcEigenSolver(MPI_Comm comm,
 
   // Set operators
   if (B)
-    EPSSetOperators(_eps, _matA->mat(), _matB->mat());
+    EPSSetOperators(_eps, A->mat(), B->mat());
   else
-    EPSSetOperators(_eps, _matA->mat(), NULL);
+    EPSSetOperators(_eps, A->mat(), NULL);
 }
 //-----------------------------------------------------------------------------
 SLEPcEigenSolver::~SLEPcEigenSolver()
@@ -145,9 +145,9 @@ void SLEPcEigenSolver::set_operators(std::shared_ptr<const PETScMatrix> A,
   // Set operators
   dolfin_assert(_eps);
   if (B)
-     EPSSetOperators(_eps, _matA->mat(), _matB->mat());
+     EPSSetOperators(_eps, A->mat(), B->mat());
   else
-    EPSSetOperators(_eps, _matA->mat(), NULL);
+    EPSSetOperators(_eps, A->mat(), NULL);
 }
 //-----------------------------------------------------------------------------
 void SLEPcEigenSolver::solve()
@@ -164,9 +164,18 @@ void SLEPcEigenSolver::solve()
 //-----------------------------------------------------------------------------
 void SLEPcEigenSolver::solve(std::size_t n)
 {
+#ifdef DEBUG
+  // Get operators
+  Mat A, B;
+  dolfin_assert(_eps);
+  EPSGetOperators(_eps, &A, &B);
+  
+  // Wrap operator as short-cut to get size
+  PETScMatrix A_wrapped(A);
+  dolfin_assert(n <= A_wrapped.size(0));
+#endif
+  
   // Set number of eigenpairs to compute
-  dolfin_assert(_matA);
-  dolfin_assert(n <= _matA->size(0));
   dolfin_assert(_eps);
   EPSSetDimensions(_eps, n, PETSC_DECIDE, PETSC_DECIDE);
 
@@ -250,9 +259,15 @@ void SLEPcEigenSolver::get_eigenpair(double& lr, double& lc,
 
   if (ii < num_computed_eigenvalues)
   {
-    dolfin_assert(_matA);
-    _matA->init_vector(r, 0);
-    _matA->init_vector(c, 0);
+    // Get operators
+    Mat A, B;
+    dolfin_assert(_eps);
+    EPSGetOperators(_eps, &A, &B);
+
+    // Wrap operator and initialize r and c
+    PETScMatrix A_wrapped(A);
+    A_wrapped.init_vector(r, 0);
+    A_wrapped.init_vector(c, 0);
 
     // Get eigen pairs
     EPSGetEigenpair(_eps, ii, &lr, &lc, r.vec(), c.vec());
diff --git a/dolfin/la/SLEPcEigenSolver.h b/dolfin/la/SLEPcEigenSolver.h
index cee36a0..bb1f93c 100644
--- a/dolfin/la/SLEPcEigenSolver.h
+++ b/dolfin/la/SLEPcEigenSolver.h
@@ -228,9 +228,6 @@ namespace dolfin
     // Set tolerance
     void set_tolerance(double tolerance, int maxiter);
 
-    // Operators (A x = \lambda x or Ax = \lambda B x)
-    std::shared_ptr<const PETScMatrix> _matA, _matB;
-
     // SLEPc solver pointer
     EPS _eps;
 
diff --git a/dolfin/log/Logger.cpp b/dolfin/log/Logger.cpp
index f70b34b..2c99c07 100644
--- a/dolfin/log/Logger.cpp
+++ b/dolfin/log/Logger.cpp
@@ -92,7 +92,7 @@ void _monitor_memory_usage(dolfin::Logger* logger)
 #endif
 
 //-----------------------------------------------------------------------------
-Logger::Logger() : _active(true), _log_level(INFO), indentation_level(0),
+Logger::Logger() : _active(true), _log_level(INFO), _indentation_level(0),
                    logstream(&std::cout), _maximum_memory_usage(-1),
                    _mpi_comm(MPI_COMM_WORLD)
 {
@@ -119,7 +119,7 @@ void Logger::log_underline(std::string msg, int log_level) const
   std::stringstream s;
   s << msg;
   s << "\n";
-  for (int i = 0; i < indentation_level; i++)
+  for (int i = 0; i < _indentation_level; i++)
     s << "  ";
   for (std::size_t i = 0; i < msg.size(); i++)
     s << "-";
@@ -213,12 +213,12 @@ void Logger::begin(std::string msg, int log_level)
 {
   // Write a message
   log(msg, log_level);
-  indentation_level++;
+  _indentation_level++;
 }
 //-----------------------------------------------------------------------------
 void Logger::end()
 {
-  indentation_level--;
+  _indentation_level--;
 }
 //-----------------------------------------------------------------------------
 void Logger::progress(std::string title, double p) const
@@ -226,7 +226,7 @@ void Logger::progress(std::string title, double p) const
   std::stringstream line;
   line << title << " [";
 
-  const int N = DOLFIN_TERM_WIDTH - title.size() - 12 - 2*indentation_level;
+  const int N = DOLFIN_TERM_WIDTH - title.size() - 12 - 2*_indentation_level;
   const int n = static_cast<int>(p*static_cast<double>(N));
 
   for (int i = 0; i < n; i++)
@@ -258,6 +258,11 @@ void Logger::set_log_level(int log_level)
   _log_level = log_level;
 }
 //-----------------------------------------------------------------------------
+void Logger::set_indentation_level(std::size_t indentation_level)
+{
+  _indentation_level = indentation_level;
+}
+//-----------------------------------------------------------------------------
 void Logger::register_timing(std::string task,
                              std::tuple<double, double, double> elapsed)
 {
@@ -455,7 +460,7 @@ void Logger::write(int log_level, std::string msg) const
   }
 
   // Add indentation
-  for (int i = 0; i < indentation_level; i++)
+  for (int i = 0; i < _indentation_level; i++)
     msg = "  " + msg;
 
   // Write to stream
diff --git a/dolfin/log/Logger.h b/dolfin/log/Logger.h
index 6c5d4de..b531286 100644
--- a/dolfin/log/Logger.h
+++ b/dolfin/log/Logger.h
@@ -101,6 +101,9 @@ namespace dolfin
     /// Get log level
     inline int get_log_level() const { return _log_level; }
 
+    /// Set indentation level
+    void set_indentation_level(std::size_t indentation_level);
+
     /// Register timing (for later summary)
     void register_timing(std::string task,
                          std::tuple<double, double, double> elapsed);
@@ -157,7 +160,7 @@ namespace dolfin
     int _log_level;
 
     // Current indentation level
-    int indentation_level;
+    int _indentation_level;
 
     // Optional stream for logging
     std::ostream* logstream;
diff --git a/dolfin/log/log.cpp b/dolfin/log/log.cpp
index a8c9f3c..b33568a 100644
--- a/dolfin/log/log.cpp
+++ b/dolfin/log/log.cpp
@@ -182,6 +182,11 @@ void dolfin::set_log_level(int level)
   LogManager::logger().set_log_level(level);
 }
 //-----------------------------------------------------------------------------
+void dolfin::set_indentation_level(std::size_t indentation_level)
+{
+  LogManager::logger().set_indentation_level(indentation_level);
+}
+//-----------------------------------------------------------------------------
 void dolfin::set_output_stream(std::ostream& out)
 {
   LogManager::logger().set_output_stream(out);
diff --git a/dolfin/log/log.h b/dolfin/log/log.h
index 8f3e707..68e9eb5 100644
--- a/dolfin/log/log.h
+++ b/dolfin/log/log.h
@@ -117,6 +117,9 @@ namespace dolfin
   /// Set log level
   void set_log_level(int level);
 
+  /// Set indentation level
+  void set_indentation_level(std::size_t indentation_level);
+
   /// Set output stream
   void set_output_stream(std::ostream& out);
 
diff --git a/dolfin/mesh/BoundaryComputation.cpp b/dolfin/mesh/BoundaryComputation.cpp
index addd772..313cf9b 100644
--- a/dolfin/mesh/BoundaryComputation.cpp
+++ b/dolfin/mesh/BoundaryComputation.cpp
@@ -419,10 +419,10 @@ void BoundaryComputation::reorder(std::vector<std::size_t>& vertices,
   // Check orientation
   switch (mesh.type().cell_type())
   {
-  case CellType::interval:
+  case CellType::Type::interval:
     // Do nothing
     break;
-  case CellType::triangle:
+  case CellType::Type::triangle:
     {
       dolfin_assert(facet.num_entities(0) == 2);
 
@@ -439,7 +439,7 @@ void BoundaryComputation::reorder(std::vector<std::size_t>& vertices,
       }
     }
     break;
-  case CellType::tetrahedron:
+  case CellType::Type::tetrahedron:
     {
       dolfin_assert(facet.num_entities(0) == 3);
 
diff --git a/dolfin/mesh/CMakeLists.txt b/dolfin/mesh/CMakeLists.txt
index cd9a864..d100530 100644
--- a/dolfin/mesh/CMakeLists.txt
+++ b/dolfin/mesh/CMakeLists.txt
@@ -52,6 +52,7 @@ set(HEADERS
 set(SOURCES
   BoundaryComputation.cpp
   BoundaryMesh.cpp
+  Cell.cpp
   CellType.cpp
   DistributedMeshTools.cpp
   DynamicMeshEditor.cpp
diff --git a/dolfin/geometry/intersect.cpp b/dolfin/mesh/Cell.cpp
similarity index 50%
copy from dolfin/geometry/intersect.cpp
copy to dolfin/mesh/Cell.cpp
index bc7364f..a5d8924 100644
--- a/dolfin/geometry/intersect.cpp
+++ b/dolfin/mesh/Cell.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2013 Anders Logg
+// Copyright (C) 2016 Anders Logg
 //
 // This file is part of DOLFIN.
 //
@@ -14,20 +14,32 @@
 //
 // You should have received a copy of the GNU Lesser General Public License
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
-//
-// First added:  2013-05-30
-// Last changed: 2013-05-30
 
-#include "MeshPointIntersection.h"
-#include "intersect.h"
+#include <dolfin/geometry/IntersectionConstruction.h>
+#include <dolfin/geometry/CollisionPredicates.h>
+#include "Cell.h"
 
 using namespace dolfin;
 
 //-----------------------------------------------------------------------------
-std::shared_ptr<const MeshPointIntersection>
-dolfin::intersect(const Mesh& mesh, const Point& point)
+bool Cell::contains(const Point& point) const
+{
+  return CollisionPredicates::collides(*this, point);
+}
+//-----------------------------------------------------------------------------
+bool Cell::collides(const Point& point) const
+{
+  return CollisionPredicates::collides(*this, point);
+}
+//-----------------------------------------------------------------------------
+bool Cell::collides(const MeshEntity& entity) const
+{
+  return CollisionPredicates::collides(*this, entity);
+}
+//-----------------------------------------------------------------------------
+std::vector<Point>
+Cell::intersection(const MeshEntity& entity) const
 {
-  return std::shared_ptr<const MeshPointIntersection>
-    (new MeshPointIntersection(mesh, point));
+  return IntersectionConstruction::intersection(*this, entity);
 }
 //-----------------------------------------------------------------------------
diff --git a/dolfin/mesh/Cell.h b/dolfin/mesh/Cell.h
index fee4ead..da7bda9 100644
--- a/dolfin/mesh/Cell.h
+++ b/dolfin/mesh/Cell.h
@@ -26,14 +26,13 @@
 
 #include <memory>
 
-#include <dolfin/geometry/Point.h>
 #include "CellType.h"
 #include "Mesh.h"
 #include "MeshEntity.h"
 #include "MeshEntityIteratorBase.h"
 #include "MeshFunction.h"
-#include <dolfin/geometry/CollisionDetection.h>
-#include <dolfin/geometry/IntersectionTriangulation.h>
+#include <ufc.h>
+#include <dolfin/geometry/Point.h>
 
 namespace dolfin
 {
@@ -257,8 +256,7 @@ namespace dolfin
     ///
     /// @return     bool
     ///         True iff point is contained in cell.
-    bool contains(const Point& point) const
-    { return _mesh->type().collides(*this, point); }
+    bool contains(const Point& point) const;
 
     /// Check whether given point collides with cell
     ///
@@ -267,8 +265,7 @@ namespace dolfin
     ///
     /// @return     bool
     ///         True iff point collides with cell.
-    bool collides(const Point& point) const
-    { return _mesh->type().collides(*this, point); }
+    bool collides(const Point& point) const;
 
     /// Check whether given entity collides with cell
     ///
@@ -277,21 +274,19 @@ namespace dolfin
     ///
     /// @return     bool
     ///         True iff entity collides with cell.
-    bool collides(const MeshEntity& entity) const
-    { return _mesh->type().collides(*this, entity); }
+    bool collides(const MeshEntity& entity) const;
 
     /// Compute triangulation of intersection with given entity
     ///
     /// @param    entity
     ///         The entity with which to intersect.
     ///
-    /// @return      std::vector<double>
+    /// @return      std::vector<Point>
     ///         A flattened array of simplices of dimension
     ///         num_simplices x num_vertices x gdim =
     ///         num_simplices x (tdim + 1) x gdim
-    std::vector<double>
-    triangulate_intersection(const MeshEntity& entity) const
-    { return _mesh->type().triangulate_intersection(*this, entity); }
+    std::vector<Point>
+    intersection(const MeshEntity& entity) const;
 
     // FIXME: This function is part of a UFC transition
     /// Get cell coordinate dofs (not vertex coordinates)
@@ -425,11 +420,19 @@ namespace dolfin
 
     /// Constructor on Mesh
     CellFunction(std::shared_ptr<const Mesh> mesh)
-      : MeshFunction<T>(mesh, mesh->topology().dim()) {}
+      : MeshFunction<T>(mesh, mesh->topology().dim()) {
+        deprecation("CellFunction<T>(mesh)",
+                    "2017.2.0",
+                    "Use MeshFunction<T>(mesh, mesh->topology().dim())");     
+      }
 
     /// Constructor on Mesh and value
     CellFunction(std::shared_ptr<const Mesh> mesh, const T& value)
-      : MeshFunction<T>(mesh, mesh->topology().dim(), value) {}
+      : MeshFunction<T>(mesh, mesh->topology().dim(), value) {
+        deprecation("CellFunction<T>(mesh, value)",
+                    "2017.2.0",
+                    "Use MeshFunction<T>(mesh, mesh->topology().dim(), value)");
+      }
   };
 
 }
diff --git a/dolfin/mesh/CellType.cpp b/dolfin/mesh/CellType.cpp
index 8a55ebf..e21f7e5 100644
--- a/dolfin/mesh/CellType.cpp
+++ b/dolfin/mesh/CellType.cpp
@@ -56,17 +56,17 @@ CellType* CellType::create(Type type)
 {
   switch ( type )
   {
-  case point:
+  case Type::point:
     return new PointCell();
-  case interval:
+  case Type::interval:
     return new IntervalCell();
-  case triangle:
+  case Type::triangle:
     return new TriangleCell();
-  case tetrahedron:
+  case Type::tetrahedron:
     return new TetrahedronCell();
-  case quadrilateral:
+  case Type::quadrilateral:
     return new QuadrilateralCell();
-  case hexahedron:
+  case Type::hexahedron:
     return new HexahedronCell();
   default:
     dolfin_error("CellType.cpp",
@@ -85,17 +85,17 @@ CellType* CellType::create(std::string type)
 CellType::Type CellType::string2type(std::string type)
 {
   if (type == "point")
-    return point;
+    return Type::point;
   else if (type == "interval")
-    return interval;
+    return Type::interval;
   else if (type == "triangle")
-    return triangle;
+    return Type::triangle;
   else if (type == "tetrahedron")
-    return tetrahedron;
+    return Type::tetrahedron;
   else if (type == "quadrilateral")
-    return quadrilateral;
+    return Type::quadrilateral;
   else if (type == "hexahedron")
-    return hexahedron;
+    return Type::hexahedron;
   else
   {
     dolfin_error("CellType.cpp",
@@ -103,24 +103,24 @@ CellType::Type CellType::string2type(std::string type)
                  "Unknown cell type (\"%s\")", type.c_str());
   }
 
-  return interval;
+  return Type::interval;
 }
 //-----------------------------------------------------------------------------
 std::string CellType::type2string(Type type)
 {
   switch (type)
   {
-  case point:
+  case Type::point:
     return "point";
-  case interval:
+  case Type::interval:
     return "interval";
-  case triangle:
+  case Type::triangle:
    return "triangle";
-  case tetrahedron:
+  case Type::tetrahedron:
     return "tetrahedron";
-  case quadrilateral:
+  case Type::quadrilateral:
     return "quadrilateral";
-  case hexahedron:
+  case Type::hexahedron:
     return "hexahedron";
   default:
     dolfin_error("CellType.cpp",
@@ -159,8 +159,8 @@ double CellType::h(const MeshEntity& entity) const
   // Get the coordinates (Points) of the vertices
   const unsigned int* vertices = entity.entities(0);
   dolfin_assert(vertices);
-  std::array<Point, 4> points;
-  dolfin_assert(num_vertices <= 4);
+  std::array<Point, 8> points;
+  dolfin_assert(num_vertices <= 8);
   for (int i = 0; i < num_vertices; ++i)
     points[i] = geometry.point(vertices[i]);
 
@@ -178,8 +178,8 @@ double CellType::h(const MeshEntity& entity) const
 double CellType::inradius(const Cell& cell) const
 {
   // Check cell type
-  if (_cell_type != interval && _cell_type != triangle
-      && _cell_type != tetrahedron)
+  if (_cell_type != Type::interval && _cell_type != Type::triangle
+      && _cell_type != Type::tetrahedron)
   {
     dolfin_error("Cell.h",
                  "compute cell inradius",
diff --git a/dolfin/mesh/CellType.h b/dolfin/mesh/CellType.h
index 4f40eb2..4d3d0aa 100644
--- a/dolfin/mesh/CellType.h
+++ b/dolfin/mesh/CellType.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2006-2013 Anders Logg
+// Copyright (C) 2006-2017 Anders Logg
 //
 // This file is part of DOLFIN.
 //
@@ -20,7 +20,7 @@
 // Modified by Jan Blechta 2013
 //
 // First added:  2006-06-05
-// Last changed: 2014-04-24
+// Last changed: 2017-09-26
 
 #ifndef __CELL_TYPE_H
 #define __CELL_TYPE_H
@@ -48,7 +48,7 @@ namespace dolfin
   public:
 
     /// Enum for different cell types
-    enum Type { point, interval, triangle, quadrilateral, tetrahedron, hexahedron };
+    enum class Type : int { point, interval, triangle, quadrilateral, tetrahedron, hexahedron };
 
     /// Constructor
     CellType(Type cell_type, Type facet_type);
@@ -79,6 +79,9 @@ namespace dolfin
     /// Return type of cell for entity of dimension i
     Type entity_type(std::size_t i) const;
 
+    /// Check if cell is a simplex
+    virtual bool is_simplex() const = 0;
+
     /// Return topological dimension of cell
     virtual std::size_t dim() const = 0;
 
@@ -153,14 +156,6 @@ namespace dolfin
     /// Check whether given entity collides with cell
     virtual bool collides(const Cell& cell, const MeshEntity& entity) const = 0;
 
-    /// Compute triangulation of intersection of two cells
-    virtual std::vector<double>
-    triangulate_intersection(const Cell& c0, const Cell& c1) const = 0;
-
-    /// Compute triangulation of intersection with given entity
-    virtual std::vector<double>
-    triangulate_intersection(const Cell& cell, const MeshEntity& entity) const = 0;
-
     /// Return description of cell type
     virtual std::string description(bool plural) const = 0;
 
diff --git a/dolfin/mesh/DistributedMeshTools.cpp b/dolfin/mesh/DistributedMeshTools.cpp
index 12ffe7d..03c345b 100644
--- a/dolfin/mesh/DistributedMeshTools.cpp
+++ b/dolfin/mesh/DistributedMeshTools.cpp
@@ -113,7 +113,7 @@ std::size_t DistributedMeshTools::number_entities(
   {
     shared_entities.clear();
     global_entity_indices = mesh.topology().global_indices(d);
-    return mesh.size_global(d);
+    return mesh.num_entities_global(d);
 
     /*
     dolfin_error("MeshPartitioning.cpp",
@@ -196,7 +196,7 @@ std::size_t DistributedMeshTools::number_entities(
   // Prepare list of global entity numbers. Check later that nothing
   // is equal to -1
   global_entity_indices
-    = std::vector<std::int64_t>(mesh.size(d), -1);
+    = std::vector<std::int64_t>(mesh.num_entities(d), -1);
 
   std::map<Entity, EntityData>::const_iterator it;
 
diff --git a/dolfin/mesh/DynamicMeshEditor.cpp b/dolfin/mesh/DynamicMeshEditor.cpp
index 59c8ee7..4627ccc 100644
--- a/dolfin/mesh/DynamicMeshEditor.cpp
+++ b/dolfin/mesh/DynamicMeshEditor.cpp
@@ -62,22 +62,22 @@ void DynamicMeshEditor::open(Mesh& mesh, std::string type, std::size_t tdim,
 {
   if (type == "point")
   {
-    open(mesh, CellType::point, tdim, gdim, num_global_vertices,
+    open(mesh, CellType::Type::point, tdim, gdim, num_global_vertices,
          num_global_cells);
   }
   else if (type == "interval")
   {
-    open(mesh, CellType::interval, tdim, gdim, num_global_vertices,
+    open(mesh, CellType::Type::interval, tdim, gdim, num_global_vertices,
          num_global_cells);
   }
   else if (type == "triangle")
   {
-    open(mesh, CellType::triangle, tdim, gdim, num_global_vertices,
+    open(mesh, CellType::Type::triangle, tdim, gdim, num_global_vertices,
          num_global_cells);
   }
   else if (type == "tetrahedron")
   {
-    open(mesh, CellType::tetrahedron, tdim, gdim, num_global_vertices,
+    open(mesh, CellType::Type::tetrahedron, tdim, gdim, num_global_vertices,
          num_global_cells);
   }
   else
diff --git a/dolfin/mesh/Edge.h b/dolfin/mesh/Edge.h
index 5ee3a03..94f6f60 100644
--- a/dolfin/mesh/Edge.h
+++ b/dolfin/mesh/Edge.h
@@ -101,11 +101,19 @@ namespace dolfin
 
     /// Constructor on Mesh
     EdgeFunction(std::shared_ptr<const Mesh> mesh)
-      : MeshFunction<T>(mesh, 1) {}
+      : MeshFunction<T>(mesh, 1) {
+        deprecation("EdgeFunction<T>(mesh)",
+                    "2017.2.0",
+                    "Use MeshFunction<T>(mesh, 1)");
+      }
 
     /// Constructor on Mesh and value
     EdgeFunction(std::shared_ptr<const Mesh> mesh, const T& value)
-      : MeshFunction<T>(mesh, 1, value) {}
+      : MeshFunction<T>(mesh, 1, value) {
+        deprecation("EdgeFunction<T>(mesh, value)",
+                    "2017.2.0",
+                    "Use MeshFunction<T>(mesh, 1, value)");
+      }
 
   };
 
diff --git a/dolfin/mesh/Face.h b/dolfin/mesh/Face.h
index c25c1d7..e078352 100644
--- a/dolfin/mesh/Face.h
+++ b/dolfin/mesh/Face.h
@@ -68,11 +68,19 @@ namespace dolfin
 
     /// Constructor on Mesh
     FaceFunction(std::shared_ptr<const Mesh> mesh)
-      : MeshFunction<T>(mesh, 2) {}
+      : MeshFunction<T>(mesh, 2) {
+        deprecation("FaceFunction<T>(mesh)",
+                    "2017.2.0",
+                    "Use MeshFunction<T>(mesh, 2)");
+      }
 
     /// Constructor on Mesh and value
     FaceFunction(std::shared_ptr<const Mesh> mesh, const T& value)
-      : MeshFunction<T>(mesh, 2, value) {}
+      : MeshFunction<T>(mesh, 2, value) {
+        deprecation("FaceFunction<T>(mesh, value)",
+                    "2017.2.0",
+                    "Use MeshFunction<T>(mesh, 2, value)");
+      }
 
   };
 
diff --git a/dolfin/mesh/Facet.h b/dolfin/mesh/Facet.h
index c42e184..21ebf19 100644
--- a/dolfin/mesh/Facet.h
+++ b/dolfin/mesh/Facet.h
@@ -91,11 +91,19 @@ namespace dolfin
 
     /// Constructor on Mesh
     FacetFunction(std::shared_ptr<const Mesh> mesh)
-      : MeshFunction<T>(mesh, mesh->topology().dim() - 1) {}
+      : MeshFunction<T>(mesh, mesh->topology().dim() - 1) {
+        deprecation("FacetFunction<T>(mesh)",
+                    "2017.2.0",
+                    "Use MeshFunction<T>(mesh, mesh->topology().dim() - 1)");
+      }
 
     /// Constructor on Mesh and value
     FacetFunction(std::shared_ptr<const Mesh> mesh, const T& value)
-      : MeshFunction<T>(mesh, mesh->topology().dim() - 1, value) {}
+      : MeshFunction<T>(mesh, mesh->topology().dim() - 1, value) {
+        deprecation("FacetFunction<T>(mesh, value)",
+                    "2017.2.0",
+                    "Use MeshFunction<T>(mesh, mesh->topology().dim() - 1, value)");
+      }
 
   };
 
diff --git a/dolfin/mesh/HexahedronCell.cpp b/dolfin/mesh/HexahedronCell.cpp
index 526f584..94b8559 100644
--- a/dolfin/mesh/HexahedronCell.cpp
+++ b/dolfin/mesh/HexahedronCell.cpp
@@ -241,20 +241,6 @@ bool HexahedronCell::collides(const Cell& cell, const MeshEntity& entity) const
   return false;
 }
 //-----------------------------------------------------------------------------
-std::vector<double>
-HexahedronCell::triangulate_intersection(const Cell& c0, const Cell& c1) const
-{
-  dolfin_not_implemented();
-  return std::vector<double>();
-}
-//-----------------------------------------------------------------------------
-std::vector<double>
-HexahedronCell::triangulate_intersection(const Cell& cell, const MeshEntity& entity) const
-{
-  dolfin_not_implemented();
-  return std::vector<double>();
-}
-//-----------------------------------------------------------------------------
 std::string HexahedronCell::description(bool plural) const
 {
   if (plural)
diff --git a/dolfin/mesh/HexahedronCell.h b/dolfin/mesh/HexahedronCell.h
index 1830470..4fa8b89 100644
--- a/dolfin/mesh/HexahedronCell.h
+++ b/dolfin/mesh/HexahedronCell.h
@@ -14,7 +14,6 @@
 //
 // You should have received a copy of the GNU Lesser General Public License
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
-//
 
 #ifndef __HEXAHEDRON_CELL_H
 #define __HEXAHEDRON_CELL_H
@@ -25,14 +24,18 @@
 namespace dolfin
 {
 
-  /// This class implements functionality for triangular meshes.
+  /// This class implements functionality for hexahedral cell  meshes.
 
   class HexahedronCell : public CellType
   {
   public:
 
     /// Specify cell type and facet type
-    HexahedronCell() : CellType(hexahedron, quadrilateral) {}
+     HexahedronCell() : CellType(Type::hexahedron, Type::quadrilateral) {}
+
+    /// Check if cell is a simplex
+    bool is_simplex() const
+    { return false; }
 
     /// Return topological dimension of cell
     std::size_t dim() const;
@@ -82,14 +85,6 @@ namespace dolfin
     /// Check whether given entity collides with cell
     bool collides(const Cell& cell, const MeshEntity& entity) const;
 
-    /// Compute triangulation of intersection of two cells
-    std::vector<double>
-    triangulate_intersection(const Cell& c0, const Cell& c1) const;
-
-    /// Compute triangulation of intersection with given entity
-    std::vector<double>
-    triangulate_intersection(const Cell& cell, const MeshEntity& entity) const;
-
     /// Return description of cell type
     std::string description(bool plural) const;
 
diff --git a/dolfin/mesh/IntervalCell.cpp b/dolfin/mesh/IntervalCell.cpp
index 35e0d99..71c5bee 100644
--- a/dolfin/mesh/IntervalCell.cpp
+++ b/dolfin/mesh/IntervalCell.cpp
@@ -21,10 +21,11 @@
 // Modified by August Johansson 2014
 //
 // First added:  2006-06-05
-// Last changed: 2014-05-22
+// Last changed: 2016-05-05
 
 #include <algorithm>
 #include <dolfin/log/log.h>
+#include <dolfin/geometry/CollisionPredicates.h>
 #include "Cell.h"
 #include "MeshEditor.h"
 #include "MeshEntity.h"
@@ -240,24 +241,12 @@ void IntervalCell::order(Cell& cell,
 //-----------------------------------------------------------------------------
 bool IntervalCell::collides(const Cell& cell, const Point& point) const
 {
-  return CollisionDetection::collides(cell, point);
+  return CollisionPredicates::collides(cell, point);
 }
 //-----------------------------------------------------------------------------
 bool IntervalCell::collides(const Cell& cell, const MeshEntity& entity) const
 {
-  return CollisionDetection::collides(cell, entity);
-}
-//-----------------------------------------------------------------------------
-std::vector<double>
-IntervalCell::triangulate_intersection(const Cell& c0, const Cell& c1) const
-{
-  return IntersectionTriangulation::triangulate_intersection(c0, c1);
-}
-//-----------------------------------------------------------------------------
-std::vector<double>
-IntervalCell::triangulate_intersection(const Cell& cell, const MeshEntity& entity) const
-{
-  return IntersectionTriangulation::triangulate_intersection(cell, entity);
+  return CollisionPredicates::collides(cell, entity);
 }
 //-----------------------------------------------------------------------------
 std::string IntervalCell::description(bool plural) const
diff --git a/dolfin/mesh/IntervalCell.h b/dolfin/mesh/IntervalCell.h
index c23162a..1197d65 100644
--- a/dolfin/mesh/IntervalCell.h
+++ b/dolfin/mesh/IntervalCell.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2006-2013 Anders Logg
+// Copyright (C) 2006-2017 Anders Logg
 //
 // This file is part of DOLFIN.
 //
@@ -18,7 +18,7 @@
 // Modified by Kristoffer Selim 2008
 //
 // First added:  2006-06-05
-// Last changed: 2014-05-22
+// Last changed: 2017-09-26
 
 #ifndef __INTERVAL_CELL_H
 #define __INTERVAL_CELL_H
@@ -36,14 +36,18 @@ namespace dolfin
   class MeshEntity;
   template<typename T> class MeshFunction;
 
-  /// This class implements functionality for interval meshes.
+  /// This class implements functionality for interval cell meshes.
 
   class IntervalCell : public CellType
   {
   public:
 
     /// Specify cell type and facet type
-    IntervalCell() : CellType(interval, point) {}
+    IntervalCell() : CellType(Type::interval, Type::point) {}
+
+    /// Check if cell is a simplex
+    bool is_simplex() const
+    { return true; }
 
     /// Return topological dimension of cell
     std::size_t dim() const;
@@ -105,14 +109,6 @@ namespace dolfin
     virtual
     bool collides(const Cell& cell, const MeshEntity& entity) const;
 
-    /// Compute triangulation of intersection of two cells
-    virtual std::vector<double>
-    triangulate_intersection(const Cell& c0, const Cell& c1) const;
-
-    /// Compute triangulation of intersection of two cells
-    virtual std::vector<double>
-    triangulate_intersection(const Cell& cell, const MeshEntity& entity) const;
-
     /// Return description of cell type
     std::string description(bool plural) const;
 
diff --git a/dolfin/mesh/LocalMeshData.cpp b/dolfin/mesh/LocalMeshData.cpp
index c7375c8..f35f42c 100644
--- a/dolfin/mesh/LocalMeshData.cpp
+++ b/dolfin/mesh/LocalMeshData.cpp
@@ -181,7 +181,7 @@ void LocalMeshData::broadcast_mesh_data(const MPI_Comm mpi_comm)
     values.push_back(geometry.num_global_vertices);
     values.push_back(topology.num_global_cells);
     values.push_back(topology.num_vertices_per_cell);
-    values.push_back(topology.cell_type);
+    values.push_back(static_cast<int>(topology.cell_type));
     MPI::broadcast(mpi_comm, values);
   }
 
diff --git a/dolfin/mesh/Mesh.cpp b/dolfin/mesh/Mesh.cpp
index 647d4ff..3bb1e4d 100644
--- a/dolfin/mesh/Mesh.cpp
+++ b/dolfin/mesh/Mesh.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2006-2014 Anders Logg
+// Copyright (C) 2006-2016 Anders Logg
 //
 // This file is part of DOLFIN.
 //
@@ -26,7 +26,7 @@
 // Modified by Jan Blechta 2013
 //
 // First added:  2006-05-09
-// Last changed: 2014-08-11
+// Last changed: 2016-05-05
 
 #include <dolfin/ale/ALE.h>
 #include <dolfin/common/Array.h>
@@ -273,6 +273,11 @@ dolfin::Mesh Mesh::renumber_by_color() const
   return MeshRenumbering::renumber_by_color(*this, coloring_type);
 }
 //-----------------------------------------------------------------------------
+void Mesh::scale(double factor)
+{
+  MeshTransformation::scale(*this, factor);
+}
+//-----------------------------------------------------------------------------
 void Mesh::translate(const Point& point)
 {
   MeshTransformation::translate(*this, point);
diff --git a/dolfin/mesh/Mesh.h b/dolfin/mesh/Mesh.h
index cbd61e7..fd92593 100644
--- a/dolfin/mesh/Mesh.h
+++ b/dolfin/mesh/Mesh.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2006-2013 Anders Logg
+// Copyright (C) 2006-2016 Anders Logg
 //
 // This file is part of DOLFIN.
 //
@@ -32,7 +32,6 @@
 #include <string>
 #include <utility>
 
-#include <dolfin/ale/MeshDisplacement.h>
 #include <dolfin/common/Hierarchical.h>
 #include <dolfin/common/MPI.h>
 #include <dolfin/common/Variable.h>
@@ -202,17 +201,6 @@ namespace dolfin
     const std::vector<unsigned int>& cells() const
     { return _topology(_topology.dim(), 0)(); }
 
-    /// Get number of local entities of given topological dimension.
-    ///
-    /// @param  dim (std::size_t)
-    ///         Topological dimension.
-    ///
-    /// @return std::size_t
-    ///         Number of local entities of topological dimension d.
-    ///
-    std::size_t size(std::size_t dim) const
-    { return _topology.size(dim); }
-
     /// Get global number of entities of given topological dimension.
     ///
     /// @param dim (std::size_t)
@@ -221,7 +209,7 @@ namespace dolfin
     /// @return std::size_t
     ///         Global number of entities of topological dimension d.
     ///
-    std::size_t size_global(std::size_t dim) const
+    std::size_t num_entities_global(std::size_t dim) const
     { return _topology.size_global(dim); }
 
     /// Get mesh topology.
@@ -348,6 +336,13 @@ namespace dolfin
     /// @return Mesh
     Mesh renumber_by_color() const;
 
+    /// Scale mesh coordinates with given factor.
+    ///
+    /// *Arguments*
+    ///     factor (double)
+    ///         The factor defining the scaling.
+    void scale(double factor);
+
     /// Translate mesh according to a given vector.
     ///
     /// @param  point (Point)
@@ -405,7 +400,7 @@ namespace dolfin
 
     /// Color the cells of the mesh such that no two neighboring cells
     /// share the same color. A colored mesh keeps a
-    /// CellFunction<std::size_t> named "cell colors" as mesh data which
+    /// MeshFunction<std::size_t> named "cell colors" as mesh data which
     /// holds the colors of the mesh.
     ///
     /// @param coloring_type (std::string)
@@ -419,7 +414,7 @@ namespace dolfin
 
     /// Color the cells of the mesh such that no two neighboring cells
     /// share the same color. A colored mesh keeps a
-    /// CellFunction<std::size_t> named "cell colors" as mesh data which
+    /// MeshFunction<std::size_t> named "cell colors" as mesh data which
     /// holds the colors of the mesh.
     ///
     /// @param coloring_type (std::vector<std::size_t>&)
diff --git a/dolfin/mesh/MeshColoring.cpp b/dolfin/mesh/MeshColoring.cpp
index 4303121..1fe101e 100644
--- a/dolfin/mesh/MeshColoring.cpp
+++ b/dolfin/mesh/MeshColoring.cpp
@@ -120,7 +120,7 @@ MeshColoring::compute_colors(const Mesh& mesh,
   return GraphColoring::compute_local_vertex_coloring(graph, colors);
 }
 //-----------------------------------------------------------------------------
-CellFunction<std::size_t>
+MeshFunction<std::size_t>
 MeshColoring::cell_colors(std::shared_ptr<const Mesh> mesh,
                           std::string coloring_type)
 {
@@ -136,7 +136,7 @@ MeshColoring::cell_colors(std::shared_ptr<const Mesh> mesh,
   return cell_colors(mesh, _coloring_type);
 }
 //-----------------------------------------------------------------------------
-CellFunction<std::size_t>
+MeshFunction<std::size_t>
 MeshColoring::cell_colors(std::shared_ptr<const Mesh> mesh,
                           std::vector<std::size_t> coloring_type)
 {
@@ -159,7 +159,7 @@ MeshColoring::cell_colors(std::shared_ptr<const Mesh> mesh,
   // Colors
   const std::vector<std::size_t>& colors = coloring_data->second.first;
 
-  CellFunction<std::size_t> mf(mesh);
+  MeshFunction<std::size_t> mf(mesh, mesh->topology().dim());
   dolfin_assert(colors.size() == mesh->num_entities(coloring_type[0]));
   for (CellIterator cell(*mesh); !cell.end(); ++cell)
     mf[*cell] = colors[cell->index()];
diff --git a/dolfin/mesh/MeshColoring.h b/dolfin/mesh/MeshColoring.h
index 7f4b6aa..9a69e57 100644
--- a/dolfin/mesh/MeshColoring.h
+++ b/dolfin/mesh/MeshColoring.h
@@ -60,12 +60,12 @@ namespace dolfin
 
     /// Return a MeshFunction with the cell colors (used for
     /// visualisation)
-    static CellFunction<std::size_t>
+    static MeshFunction<std::size_t>
       cell_colors(std::shared_ptr<const Mesh> mesh,
                   std::string coloring_type);
 
     /// Return a MeshFunction with the cell colors (used for visualisation)
-    static CellFunction<std::size_t>
+    static MeshFunction<std::size_t>
       cell_colors(std::shared_ptr<const Mesh> mesh,
                   std::vector<std::size_t> coloring_type);
 
diff --git a/dolfin/mesh/MeshEditor.cpp b/dolfin/mesh/MeshEditor.cpp
index 2b10f7e..f8efe76 100644
--- a/dolfin/mesh/MeshEditor.cpp
+++ b/dolfin/mesh/MeshEditor.cpp
@@ -41,36 +41,6 @@ MeshEditor::~MeshEditor()
   // Do nothing
 }
 //-----------------------------------------------------------------------------
-void MeshEditor::open(Mesh& mesh, std::size_t tdim,
-                      std::size_t gdim, std::size_t degree)
-{
-  switch (tdim)
-  {
-  case 0:
-    open(mesh, CellType::point, tdim, gdim, degree);
-    break;
-  case 1:
-    open(mesh, CellType::interval, tdim, gdim, degree);
-    break;
-  case 2:
-    open(mesh, CellType::triangle, tdim, gdim, degree);
-    break;
-  case 3:
-    open(mesh, CellType::tetrahedron, tdim, gdim, degree);
-    break;
-  case 4:
-    open(mesh, CellType::quadrilateral, tdim, gdim, degree);
-    break;
-  case 5:
-    open(mesh, CellType::hexahedron, tdim, gdim, degree);
-    break;
-  default:
-    dolfin_error("MeshEditor.cpp",
-                 "open mesh for editing",
-                 "Unknown cell type of topological dimension %d", tdim);
-  }
-}
-//-----------------------------------------------------------------------------
 void MeshEditor::open(Mesh& mesh, CellType::Type type, std::size_t tdim,
                       std::size_t gdim, std::size_t degree)
 {
@@ -107,17 +77,17 @@ void MeshEditor::open(Mesh& mesh, std::string type, std::size_t tdim,
                       std::size_t gdim, std::size_t degree)
 {
   if (type == "point")
-    open(mesh, CellType::point, tdim, gdim, degree);
+    open(mesh, CellType::Type::point, tdim, gdim, degree);
   else if (type == "interval")
-    open(mesh, CellType::interval, tdim, gdim, degree);
+    open(mesh, CellType::Type::interval, tdim, gdim, degree);
   else if (type == "triangle")
-    open(mesh, CellType::triangle, tdim, gdim, degree);
+    open(mesh, CellType::Type::triangle, tdim, gdim, degree);
   else if (type == "tetrahedron")
-    open(mesh, CellType::tetrahedron, tdim, gdim, degree);
+    open(mesh, CellType::Type::tetrahedron, tdim, gdim, degree);
   else if (type == "quadrilateral")
-    open(mesh, CellType::quadrilateral, tdim, gdim, degree);
+    open(mesh, CellType::Type::quadrilateral, tdim, gdim, degree);
   else if (type == "hexahedron")
-    open(mesh, CellType::hexahedron, tdim, gdim, degree);
+    open(mesh, CellType::Type::hexahedron, tdim, gdim, degree);
   else
   {
     dolfin_error("MeshEditor.cpp",
diff --git a/dolfin/mesh/MeshEditor.h b/dolfin/mesh/MeshEditor.h
index fe69b82..74436d9 100644
--- a/dolfin/mesh/MeshEditor.h
+++ b/dolfin/mesh/MeshEditor.h
@@ -43,24 +43,6 @@ namespace dolfin
     /// Destructor
     ~MeshEditor();
 
-    /// Open mesh of given topological and geometrical dimension
-    ///
-    /// @param    mesh (_Mesh_)
-    ///         The mesh to open.
-    /// @param     tdim (std::size_t)
-    ///         The topological dimension.
-    /// @param     gdim (std::size_t)
-    ///         The geometrical dimension.
-    /// @param     degree (std::size_t)
-    ///         The polynomial degree.
-    /// @code{.cpp}
-    ///
-    ///         Mesh mesh;
-    ///         MeshEditor editor;
-    ///         editor.open(mesh, 2, 2, 1);
-    /// @endcode
-    void open(Mesh& mesh, std::size_t tdim, std::size_t gdim, std::size_t degree=1);
-
     /// Open mesh of given cell type, topological and geometrical dimension
     ///
     /// @param    mesh (_Mesh_)
diff --git a/dolfin/mesh/MeshFunction.h b/dolfin/mesh/MeshFunction.h
index db32263..08cbc82 100644
--- a/dolfin/mesh/MeshFunction.h
+++ b/dolfin/mesh/MeshFunction.h
@@ -579,7 +579,7 @@ namespace dolfin
 
     }
     _mesh->init(dim);
-    init(_mesh, dim, _mesh->size(dim));
+    init(_mesh, dim, _mesh->num_entities(dim));
   }
   //---------------------------------------------------------------------------
   template <typename T>
@@ -601,7 +601,7 @@ namespace dolfin
   {
     dolfin_assert(mesh);
     mesh->init(dim);
-    init(mesh, dim, mesh->size(dim));
+    init(mesh, dim, mesh->num_entities(dim));
   }
   //---------------------------------------------------------------------------
   template <typename T>
@@ -612,7 +612,7 @@ namespace dolfin
 
     // Initialize mesh for entities of given dimension
     mesh->init(dim);
-    dolfin_assert(mesh->size(dim) == size);
+    dolfin_assert(mesh->num_entities(dim) == size);
 
     // Initialize data
     if (_size != size)
@@ -652,7 +652,7 @@ namespace dolfin
     std::size_t n = std::count(_values.get(), _values.get() + _size, value);
     std::vector<std::size_t> indices;
     indices.reserve(n);
-    for (int i = 0; i < size(); ++i)
+    for (std::size_t i = 0; i < size(); ++i)
     {
       if (_values[i] == value)
         indices.push_back(i);
diff --git a/dolfin/mesh/MeshHierarchy.cpp b/dolfin/mesh/MeshHierarchy.cpp
index fe8a44d..d0fd378 100644
--- a/dolfin/mesh/MeshHierarchy.cpp
+++ b/dolfin/mesh/MeshHierarchy.cpp
@@ -98,7 +98,7 @@ MeshHierarchy::coarsen(const MeshFunction<bool>& coarsen_markers) const
   }
 
   // Set up refinement markers to re-refine the parent mesh
-  EdgeFunction<bool> edge_markers(parent_mesh, false);
+  MeshFunction<bool> edge_markers(parent_mesh, 1, false);
   const std::map<std::size_t, std::size_t>& edge_to_vertex
     = *(_relation->edge_to_global_vertex);
 
@@ -191,8 +191,8 @@ std::shared_ptr<Mesh> MeshHierarchy::rebalance() const
 
   // Cells
 
-  local_mesh_data.topology.num_global_cells = coarse_mesh.size_global(tdim);
-  const std::size_t num_local_cells = coarse_mesh.size(tdim);
+  local_mesh_data.topology.num_global_cells = coarse_mesh.num_entities_global(tdim);
+  const std::size_t num_local_cells = coarse_mesh.num_entities(tdim);
   local_mesh_data.topology.global_cell_indices.resize(num_local_cells);
   local_mesh_data.topology.cell_vertices.resize(boost::extents[num_local_cells][local_mesh_data.topology.num_vertices_per_cell]);
 
@@ -206,8 +206,8 @@ std::shared_ptr<Mesh> MeshHierarchy::rebalance() const
 
   // Vertices - must be reordered into global order
 
-  const std::size_t num_local_vertices = coarse_mesh.size(0);
-  local_mesh_data.geometry.num_global_vertices = coarse_mesh.size_global(0);
+  const std::size_t num_local_vertices = coarse_mesh.num_entities(0);
+  local_mesh_data.geometry.num_global_vertices = coarse_mesh.num_entities_global(0);
   local_mesh_data.geometry.vertex_indices.resize(num_local_vertices);
   for (VertexIterator v(coarse_mesh); !v.end(); ++v)
     local_mesh_data.geometry.vertex_indices[v->index()] = v->global_index();
diff --git a/dolfin/mesh/MeshQuality.cpp b/dolfin/mesh/MeshQuality.cpp
index ba03139..408f035 100644
--- a/dolfin/mesh/MeshQuality.cpp
+++ b/dolfin/mesh/MeshQuality.cpp
@@ -29,11 +29,11 @@
 using namespace dolfin;
 
 //-----------------------------------------------------------------------------
-dolfin::CellFunction<double>
+dolfin::MeshFunction<double>
 MeshQuality::radius_ratios(std::shared_ptr<const Mesh> mesh)
 {
-  // Create CellFunction
-  CellFunction<double> cf(mesh, 0.0);
+  // Create MeshFunction
+  MeshFunction<double> cf(mesh, mesh->topology().dim(), 0.0);
 
   // Compute radius ration
   for (CellIterator cell(*mesh); !cell.end(); ++cell)
@@ -143,14 +143,12 @@ MeshQuality::radius_ratio_matplotlib_histogram(const Mesh& mesh,
 //-----------------------------------------------------------------------------
 void MeshQuality::dihedral_angles(const Cell& cell, std::vector<double>& dh_angle)
 {
-  if (cell.type() < 4)
+  if (cell.dim() != 3)
   {
       dolfin_error("MeshQuality.cpp",
                  "calculate dihedral angles",
                  "Only works for 3D cells");
   }
-  // Check cell type
-  // dolfin_assert(cell.type()>=4);
 
   static const std::size_t edges[6][2] = {{2, 3},
                                           {1, 3},
diff --git a/dolfin/mesh/MeshQuality.h b/dolfin/mesh/MeshQuality.h
index cce04ac..c2f164d 100644
--- a/dolfin/mesh/MeshQuality.h
+++ b/dolfin/mesh/MeshQuality.h
@@ -41,13 +41,13 @@ namespace dolfin
 
     /// Compute the radius ratio for all cells.
     /// @param mesh (std::shared_ptr<const Mesh>)
-    /// @return     CellFunction<double>
+    /// @return     MeshFunction<double>
     ///         The cell radius ratio radius ratio geometric_dimension *
     ///         * inradius / circumradius (geometric_dimension
     ///         is normalization factor). It has range zero to one.
     ///         Zero indicates a degenerate element.
     ///
-    static CellFunction<double>
+    static MeshFunction<double>
       radius_ratios(std::shared_ptr<const Mesh> mesh);
 
 
diff --git a/dolfin/mesh/MeshRenumbering.cpp b/dolfin/mesh/MeshRenumbering.cpp
index dfd67fd..8fb88ae 100644
--- a/dolfin/mesh/MeshRenumbering.cpp
+++ b/dolfin/mesh/MeshRenumbering.cpp
@@ -45,10 +45,10 @@ dolfin::Mesh MeshRenumbering::renumber_by_color(const Mesh& mesh,
   // Get some some mesh
   const std::size_t tdim = mesh.topology().dim();
   const std::size_t gdim = mesh.geometry().dim();
-  const std::size_t num_local_vertices  = mesh.size(0);
-  const std::size_t num_global_vertices = mesh.size_global(0);
-  const std::size_t num_local_cells     = mesh.size(tdim);
-  const std::size_t num_global_cells    = mesh.size_global(tdim);
+  const std::size_t num_local_vertices  = mesh.num_entities(0);
+  const std::size_t num_global_vertices = mesh.num_entities_global(0);
+  const std::size_t num_local_cells     = mesh.num_entities(tdim);
+  const std::size_t num_global_cells    = mesh.num_entities_global(tdim);
 
   // Check that requested coloring is a cell coloring
   if (coloring_type[0] != tdim)
diff --git a/dolfin/mesh/MeshTopology.cpp b/dolfin/mesh/MeshTopology.cpp
index cb6de76..9b061bd 100644
--- a/dolfin/mesh/MeshTopology.cpp
+++ b/dolfin/mesh/MeshTopology.cpp
@@ -28,13 +28,14 @@
 using namespace dolfin;
 
 //-----------------------------------------------------------------------------
-MeshTopology::MeshTopology()
+MeshTopology::MeshTopology() : Variable("topology", "mesh topology")
 {
   // Do nothing
 }
 //-----------------------------------------------------------------------------
 MeshTopology::MeshTopology(const MeshTopology& topology)
-  : coloring(topology.coloring), num_entities(topology.num_entities),
+  : Variable("topology", "mesh topology"),
+    coloring(topology.coloring), num_entities(topology.num_entities),
     ghost_offset_index(topology.ghost_offset_index),
     global_num_entities(topology.global_num_entities),
     _global_indices(topology._global_indices),
diff --git a/dolfin/mesh/MeshTopology.h b/dolfin/mesh/MeshTopology.h
index 364ab8e..bf87c90 100644
--- a/dolfin/mesh/MeshTopology.h
+++ b/dolfin/mesh/MeshTopology.h
@@ -25,6 +25,8 @@
 #include <map>
 #include <utility>
 #include <vector>
+
+#include <dolfin/common/Variable.h>
 #include "MeshConnectivity.h"
 
 namespace dolfin
@@ -41,7 +43,7 @@ namespace dolfin
   /// i), where dim is the topological dimension and i is the index of
   /// the entity within that topological dimension.
 
-  class MeshTopology
+  class MeshTopology : public Variable
   {
   public:
 
diff --git a/dolfin/mesh/MeshTransformation.cpp b/dolfin/mesh/MeshTransformation.cpp
index 7475974..1fb4c35 100644
--- a/dolfin/mesh/MeshTransformation.cpp
+++ b/dolfin/mesh/MeshTransformation.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2012-2013 Anders Logg
+// Copyright (C) 2012-2016 Anders Logg
 //
 // This file is part of DOLFIN.
 //
@@ -25,6 +25,22 @@
 using namespace dolfin;
 
 //-----------------------------------------------------------------------------
+void MeshTransformation::scale(Mesh& mesh, double factor)
+{
+ // Get mesh geometry
+  MeshGeometry& geometry = mesh.geometry();
+  const std::size_t gdim = geometry.dim();
+
+  // Scale all points
+  std::vector<double> x0(gdim);
+  for (std::size_t i = 0; i < geometry.num_vertices(); i++)
+  {
+    for (std::size_t j = 0; j < gdim; j++)
+      x0[j] = factor*geometry.x(i, j);
+    geometry.set(i, x0.data());
+  }
+}
+//-----------------------------------------------------------------------------
 void MeshTransformation::translate(Mesh& mesh, const Point& point)
 {
   // Get mesh geometry
diff --git a/dolfin/mesh/MeshTransformation.h b/dolfin/mesh/MeshTransformation.h
index 75c1ee3..3892d4a 100644
--- a/dolfin/mesh/MeshTransformation.h
+++ b/dolfin/mesh/MeshTransformation.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2012-2013 Anders Logg
+// Copyright (C) 2012-2016 Anders Logg
 //
 // This file is part of DOLFIN.
 //
@@ -16,7 +16,7 @@
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 //
 // First added:  2012-01-16
-// Last changed: 2013-06-27
+// Last changed: 2016-05-03
 
 #ifndef __MESH_TRANSFORMATION_H
 #define __MESH_TRANSFORMATION_H
@@ -34,6 +34,15 @@ class MeshTransformation
 {
 public:
 
+  /// Scale mesh coordinates with given factor.
+  ///
+  /// *Arguments*
+  ///     mesh (_Mesh_)
+  ///         The mesh
+  ///     factor (double)
+  ///         The factor defining the scaling.
+  static void scale(Mesh& mesh, double factor);
+
   /// Translate mesh according to a given vector.
   ///
   /// @param mesh (Mesh)
diff --git a/dolfin/mesh/MultiMesh.cpp b/dolfin/mesh/MultiMesh.cpp
index ef2b0e7..575a8cb 100644
--- a/dolfin/mesh/MultiMesh.cpp
+++ b/dolfin/mesh/MultiMesh.cpp
@@ -15,19 +15,24 @@
 // You should have received a copy of the GNU Lesser General Public License
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 //
-// Modified by August Johansson 2014
+// Modified by August Johansson 2016
+// Modified by Benjamin Kehlet 2016
 //
 // First added:  2013-08-05
-// Last changed: 2016-03-02
+// Last changed: 2017-10-09
 
 #include <cmath>
-
 #include <dolfin/log/log.h>
 #include <dolfin/common/NoDeleter.h>
 #include <dolfin/geometry/BoundingBoxTree.h>
 #include <dolfin/geometry/SimplexQuadrature.h>
+#include <dolfin/geometry/IntersectionConstruction.h>
+#include <dolfin/geometry/ConvexTriangulation.h>
+#include <dolfin/geometry/GeometryPredicates.h>
+
 #include "Cell.h"
 #include "Facet.h"
+#include "Vertex.h"
 #include "BoundaryMesh.h"
 #include "MeshFunction.h"
 #include "MultiMesh.h"
@@ -35,14 +40,18 @@
 using namespace dolfin;
 
 //-----------------------------------------------------------------------------
-MultiMesh::MultiMesh()
+MultiMesh::MultiMesh() : _is_built(false)
 {
-  // Do nothing
+  // Set parameters
+  parameters = default_parameters();
 }
 //-----------------------------------------------------------------------------
 MultiMesh::MultiMesh(std::vector<std::shared_ptr<const Mesh>> meshes,
-                     std::size_t quadrature_order)
+                     std::size_t quadrature_order) : _is_built(false)
 {
+  // Set parameters
+  parameters = default_parameters();
+
   // Add and build
   for (auto mesh : meshes)
     add(mesh);
@@ -50,8 +59,11 @@ MultiMesh::MultiMesh(std::vector<std::shared_ptr<const Mesh>> meshes,
 }
 //-----------------------------------------------------------------------------
 MultiMesh::MultiMesh(std::shared_ptr<const Mesh> mesh_0,
-                     std::size_t quadrature_order)
+                     std::size_t quadrature_order) : _is_built(false)
 {
+  // Set parameters
+  parameters = default_parameters();
+
   // Add and build
   add(mesh_0);
   build(quadrature_order);
@@ -59,8 +71,11 @@ MultiMesh::MultiMesh(std::shared_ptr<const Mesh> mesh_0,
 //-----------------------------------------------------------------------------
 MultiMesh::MultiMesh(std::shared_ptr<const Mesh> mesh_0,
                      std::shared_ptr<const Mesh> mesh_1,
-                     std::size_t quadrature_order)
+                     std::size_t quadrature_order) : _is_built(false)
 {
+  // Set parameters
+  parameters = default_parameters();
+
   // Add and build
   add(mesh_0);
   add(mesh_1);
@@ -70,8 +85,11 @@ MultiMesh::MultiMesh(std::shared_ptr<const Mesh> mesh_0,
 MultiMesh::MultiMesh(std::shared_ptr<const Mesh> mesh_0,
                      std::shared_ptr<const Mesh> mesh_1,
                      std::shared_ptr<const Mesh> mesh_2,
-                     std::size_t quadrature_order)
+                     std::size_t quadrature_order) : _is_built(false)
 {
+  // Set parameters
+  parameters = default_parameters();
+
   // Add and build
   add(mesh_0);
   add(mesh_1);
@@ -102,11 +120,24 @@ MultiMesh::uncut_cells(std::size_t part) const
   return _uncut_cells[part];
 }
 //-----------------------------------------------------------------------------
-const std::vector<unsigned int>&
+const std::vector<unsigned int>
 MultiMesh::cut_cells(std::size_t part) const
 {
   dolfin_assert(part < num_parts());
-  return _cut_cells[part];
+
+  // Extract keys from collision map
+  const std::map<unsigned int,std::vector<std::pair<std::size_t,unsigned int>>>&
+    cm = collision_map_cut_cells(part);
+
+  // Vector to store cut cell IDs
+  std::vector<unsigned int> _cut_cells;
+  _cut_cells.reserve(cm.size());
+
+  // Add cell ID if it has any collisions
+  for (const auto& it : cm)
+    if (it.second.size() > 0)
+      _cut_cells.push_back(it.first);
+  return _cut_cells;
 }
 //-----------------------------------------------------------------------------
 const std::vector<unsigned int>&
@@ -118,42 +149,61 @@ MultiMesh::covered_cells(std::size_t part) const
 //-----------------------------------------------------------------------------
 const std::map<unsigned int,
                std::vector<std::pair<std::size_t, unsigned int>>>&
-MultiMesh::collision_map_cut_cells(std::size_t part) const
+  MultiMesh::collision_map_cut_cells(std::size_t part) const
 {
   dolfin_assert(part < num_parts());
   return _collision_maps_cut_cells[part];
 }
 //-----------------------------------------------------------------------------
-const std::map<unsigned int, quadrature_rule> &
-MultiMesh::quadrature_rule_cut_cells(std::size_t part) const
+const std::map<unsigned int, MultiMesh::quadrature_rule> &
+MultiMesh::quadrature_rules_cut_cells(std::size_t part) const
 
 {
   dolfin_assert(part < num_parts());
   return _quadrature_rules_cut_cells[part];
 }
 //-----------------------------------------------------------------------------
-quadrature_rule
-MultiMesh::quadrature_rule_cut_cell(std::size_t part,
-                                    unsigned int cell_index) const
+const MultiMesh::quadrature_rule
+MultiMesh::quadrature_rules_cut_cells(std::size_t part,
+                                      unsigned int cell_index) const
 {
-  auto q = quadrature_rule_cut_cells(part);
+  auto q = quadrature_rules_cut_cells(part);
+  dolfin_assert(cell_index < this->part(part)->num_cells());
   return q[cell_index];
 }
 //-----------------------------------------------------------------------------
-const std::map<unsigned int, std::vector<quadrature_rule>>&
-  MultiMesh::quadrature_rule_overlap(std::size_t part) const
+const std::map<unsigned int, std::vector<MultiMesh::quadrature_rule>>&
+  MultiMesh::quadrature_rules_overlap(std::size_t part) const
 {
   dolfin_assert(part < num_parts());
   return _quadrature_rules_overlap[part];
 }
 //-----------------------------------------------------------------------------
-const std::map<unsigned int, std::vector<quadrature_rule>>&
-  MultiMesh::quadrature_rule_interface(std::size_t part) const
+const std::vector<MultiMesh::quadrature_rule>
+MultiMesh::quadrature_rules_overlap(std::size_t part,
+				    unsigned int cell_index) const
+{
+  auto q = quadrature_rules_overlap(part);
+  dolfin_assert(cell_index < this->part(part)->num_cells());
+  return q[cell_index];
+}
+//-----------------------------------------------------------------------------
+const std::map<unsigned int, std::vector<MultiMesh::quadrature_rule>>&
+  MultiMesh::quadrature_rules_interface(std::size_t part) const
 {
   dolfin_assert(part < num_parts());
   return _quadrature_rules_interface[part];
 }
 //-----------------------------------------------------------------------------
+const std::vector<MultiMesh::quadrature_rule>
+MultiMesh::quadrature_rules_interface(std::size_t part,
+				      unsigned int cell_index) const
+{
+  auto q = quadrature_rules_interface(part);
+  dolfin_assert(cell_index < this->part(part)->num_cells());
+  return q[cell_index];
+}
+//-----------------------------------------------------------------------------
 const std::map<unsigned int, std::vector<std::vector<double>>>&
   MultiMesh::facet_normals(std::size_t part) const
 {
@@ -192,12 +242,12 @@ void MultiMesh::build(std::size_t quadrature_order)
   // Build bounding box trees
   _build_bounding_box_trees();
 
-  // Build collision maps
+  // Build collision maps, i.e. classify cut, uncut and covered cells
   _build_collision_maps();
 
-  // FIXME: For collisions with meshes of same type we get three types
-  // of quadrature rules: the cut cell qr, qr of the overlap part and
-  // qr of the interface.
+  // For collisions with meshes of same type we get three types of
+  // quadrature rules: the cut cell qr, qr of the overlap part and qr
+  // of the interface.
 
   // Build quadrature rules of the cut cells' overlap. Do this before
   // we build the quadrature rules of the cut cells
@@ -206,6 +256,17 @@ void MultiMesh::build(std::size_t quadrature_order)
   // Build quadrature rules of the cut cells
   _build_quadrature_rules_cut_cells(quadrature_order);
 
+  // Build quadrature rules and normals of the interface
+  _build_quadrature_rules_interface(quadrature_order);
+
+  // Make sure that cut cells are actually cut
+  // TODO: Check if this needed
+  // TODO: Maybe also keep track of interface cells
+  // _impose_cut_cell_consistency();
+
+  // Mark space as built
+  _is_built = true;
+
   end();
 }
 //-----------------------------------------------------------------------------
@@ -215,7 +276,6 @@ void MultiMesh::clear()
   _trees.clear();
   _boundary_trees.clear();
   _uncut_cells.clear();
-  _cut_cells.clear();
   _covered_cells.clear();
   _collision_maps_cut_cells.clear();
   _collision_maps_cut_cells_boundary.clear();
@@ -224,6 +284,156 @@ void MultiMesh::clear()
   _quadrature_rules_interface.clear();
 }
 //-----------------------------------------------------------------------------
+double MultiMesh::compute_area() const
+{
+  // Total area
+  double area = 0.0;
+
+  // Compute contribution from all parts
+  for (std::size_t p = 0; p < num_parts(); p++)
+  {
+    // Get the quadrature rules
+    const auto& quadrature_rules = quadrature_rules_interface(p);
+
+    // Get the collision map
+    const auto& cmap = collision_map_cut_cells(p);
+
+    for (auto it = cmap.begin(); it != cmap.end(); ++it)
+    {
+      // Get the cells that intersect the cut cell. These are the
+      // cutting cells
+      const unsigned int cut_cell_index = it->first;
+      const auto& cutting_cells = it->second;
+
+      // Iterate over cutting cells
+      for (auto jt = cutting_cells.begin(); jt != cutting_cells.end(); jt++)
+      {
+	// Get the quadrature rule for the interface part defined by
+	// the intersection of the cut and cutting cell
+	const std::size_t k = jt - cutting_cells.begin();
+	dolfin_assert(k < quadrature_rules.at(cut_cell_index).size());
+	const auto& qr = quadrature_rules.at(cut_cell_index)[k];
+
+	// Sum over all qr weights
+	for (std::size_t i = 0; i < qr.second.size(); ++i)
+	{
+	  area += qr.second[i];
+	}
+      }
+    }
+  }
+
+  return area;
+}
+
+//-----------------------------------------------------------------------------
+double MultiMesh::compute_volume() const
+{
+  // Total volume
+  double volume = 0.0;
+
+  // Compute contribution from all parts
+  for (std::size_t p = 0; p < num_parts(); p++)
+  {
+    // Sum volume of uncut cells (from cell.volume)
+    {
+      const auto& cells = uncut_cells(p);
+      for (auto it = cells.begin(); it != cells.end(); ++it)
+      {
+        const Cell cell(*part(p), *it);
+        volume += cell.volume();
+      }
+    }
+
+    // Sum volume of cut cells (from quadrature rules)
+    {
+      const auto& cells = cut_cells(p);
+      for (auto it = cells.begin(); it != cells.end(); ++it)
+      {
+        const auto& qr = quadrature_rules_cut_cells(p, *it);
+        for (std::size_t i = 0; i < qr.second.size(); ++i)
+          volume += qr.second[i];
+      }
+    }
+  }
+
+  return volume;
+}
+//-----------------------------------------------------------------------------
+std::string MultiMesh::plot_matplotlib(double delta_z,
+				       const std::string& filename) const
+{
+  if (num_parts() == 0)
+    dolfin_error("MultiMesh.cpp",
+		 "plotting multimesh with matplotlib",
+		 "Multimesh is empty. Call MultiMesh.add(mesh) before plotting");
+
+  if (part(0)->geometry().dim() != 2)
+    dolfin_error("MultiMesh.cpp",
+		 "plotting multimesh with matplotlib",
+		 "Plotting is only implemented in 2D");
+
+  const bool do_3d = delta_z != 0.;
+  std::stringstream ss;
+
+  ss << "def plot_multimesh() :\n";
+  ss << "    from mpl_toolkits.mplot3d import Axes3D\n";
+  ss << "    from matplotlib import cm\n";
+  ss << "    import matplotlib.pyplot as plt\n";
+  ss << "    import numpy as np\n";
+  ss << "    fig = plt.figure()\n";
+  if (do_3d)
+    ss << "    ax = fig.gca(projection='3d')\n";
+  else
+    ss << "    ax = fig.gca()\n";
+  ss << "    alpha = " << (do_3d ? 0.4 : 1.0) << "\n";
+
+  for (std::size_t p = 0; p < num_parts(); p++)
+  {
+    std::shared_ptr<const Mesh> current = part(p);
+    std::stringstream x, y;
+    x << "    x = np.array((";
+    y << "    y = np.array((";
+    for (std::size_t i = 0; i < current->num_vertices(); i++)
+    {
+      x << current->coordinates()[i*2] << ", ";
+      y << current->coordinates()[i*2 + 1] << ",";
+    }
+    x << "))\n";
+    y << "))\n";
+    ss << x.str() << y.str();
+
+    ss << "    facets = np.array((";
+    for (CellIterator cit(*current); !cit.end(); ++cit)
+    {
+      const unsigned int* vertices = cit->entities(0);
+      ss << "(" << vertices[0] << ", " << vertices[1] << ", " << vertices[2] << "), ";
+    }
+
+    ss << "), dtype=int)\n";
+    if (do_3d)
+    {
+      ss << "    z = np.zeros(x.shape) + " << (p*delta_z) << "\n";
+      ss << "    ax.plot_trisurf(x, y, z, triangles=facets, alpha=alpha)\n";
+    }
+    else
+    {
+      ss << "    z = " << p<< "*np.ones(int(facets.size / 3))\n"
+	 << "    ax.tripcolor(x, y, facets, facecolors = z, edgecolors = 'k', alpha = alpha, vmin = 0, vmax = " << num_parts()-1 << ")\n";
+    }
+  }
+
+  if (!do_3d)
+  {
+    ss << "    ax.axis('tight')\n"
+       << "    ax.axis('square')\n";
+    if (!filename.empty())
+      ss << "    plt.savefig('" << filename << "')\n";
+  }
+  ss << "    plt.show()\n";
+  return ss.str();
+}
+//-----------------------------------------------------------------------------
 void MultiMesh::_build_boundary_meshes()
 {
   begin(PROGRESS, "Building boundary meshes.");
@@ -262,6 +472,7 @@ void MultiMesh::_build_bounding_box_trees()
     std::shared_ptr<BoundingBoxTree> boundary_tree(new BoundingBoxTree());
 
     // FIXME: what if the boundary mesh is empty?
+    dolfin_assert(_boundary_meshes[i]->num_vertices()>0);
     if (_boundary_meshes[i]->num_vertices()>0)
       boundary_tree->build(*_boundary_meshes[i]);
     _boundary_trees.push_back(boundary_tree);
@@ -276,7 +487,6 @@ void MultiMesh::_build_collision_maps()
 
   // Clear collision maps
   _uncut_cells.clear();
-  _cut_cells.clear();
   _covered_cells.clear();
   _collision_maps_cut_cells.clear();
   _collision_maps_cut_cells_boundary.clear();
@@ -293,11 +503,12 @@ void MultiMesh::_build_collision_maps()
     // Create vector of markers for cells in part `i` (0, 1, or 2)
     std::vector<char> markers(_meshes[i]->num_cells(), 0);
 
-    // Create local array for marking boundary collisions for cells in
-    // part `i`. Note that in contrast to the markers above which are
-    // global to part `i`, these markers are local to the collision
-    // between part `i` and part `j`.
+    // Create local arrays for marking domain and boundary collisions
+    // for cells in part `i`. Note that in contrast to the markers
+    // above which are global to part `i`, these markers are local to
+    // the collision between part `i` and part `j`.
     std::vector<bool> collides_with_boundary(_meshes[i]->num_cells());
+    std::vector<bool> collides_with_domain(_meshes[i]->num_cells());
 
     // Create empty collision map for cut cells in part `i`
     std::map<unsigned int, std::vector<std::pair<std::size_t, unsigned int>>>
@@ -308,30 +519,37 @@ void MultiMesh::_build_collision_maps()
     {
       log(PROGRESS, "Computing collisions for mesh %d overlapped by mesh %d.", i, j);
 
-      // Reset boundary collision markers
-      std::fill(collides_with_boundary.begin(), collides_with_boundary.end(), false);
-
       // Compute domain-boundary collisions
       const auto& boundary_collisions = _trees[i]->compute_collisions(*_boundary_trees[j]);
 
-      // Iterate over boundary collisions
-      for (auto it = boundary_collisions.first.begin();
-           it != boundary_collisions.first.end(); ++it)
-      {
-        // Mark that cell collides with boundary
-        collides_with_boundary[*it] = true;
-
-        // Mark as cut cell if not previously covered
-        if (markers[*it] != 2)
-        {
-          // Mark as cut cell
-          markers[*it] = 1;
+      // Reset boundary collision markers
+      std::fill(collides_with_boundary.begin(), collides_with_boundary.end(), false);
 
-          // Add empty list of collisions into map if it does not exist
-          if (collision_map_cut_cells.find(*it) == collision_map_cut_cells.end())
-          {
+      // Iterate over boundary collisions.
+      for (std::size_t k = 0; k < boundary_collisions.first.size(); ++k)
+      {
+	// Get the colliding cell
+	const std::size_t cell_i = boundary_collisions.first[k];
+
+	// Do a careful check if not already marked as colliding
+	if (!collides_with_boundary[cell_i])
+	{
+	  const Cell cell(*_meshes[i], cell_i);
+	  const Cell boundary_cell(*_boundary_meshes[j], boundary_collisions.second[k]);
+	  collides_with_boundary[cell_i] = cell.collides(boundary_cell);
+	}
+
+	// Mark as cut cell if not previously covered
+	if (collides_with_boundary[cell_i] and markers[cell_i] != 2)
+	{
+	  // Mark as cut cell
+	  markers[cell_i] = 1;
+
+	  // Add empty list of collisions into map if it does not exist
+	  if (collision_map_cut_cells.find(cell_i) == collision_map_cut_cells.end())
+	  {
             std::vector<std::pair<std::size_t, unsigned int>> collisions;
-            collision_map_cut_cells[*it] = collisions;
+            collision_map_cut_cells[cell_i] = collisions;
           }
         }
       }
@@ -339,34 +557,55 @@ void MultiMesh::_build_collision_maps()
       // Compute domain-domain collisions
       const auto& domain_collisions = _trees[i]->compute_collisions(*_trees[j]);
 
+      // Reset domain collision markers
+      std::fill(collides_with_domain.begin(), collides_with_domain.end(), false);
+
       // Iterate over domain collisions
       dolfin_assert(domain_collisions.first.size() == domain_collisions.second.size());
       for (std::size_t k = 0; k < domain_collisions.first.size(); k++)
       {
         // Get the two colliding cells
-        auto cell_i = domain_collisions.first[k];
-        auto cell_j = domain_collisions.second[k];
+        const std::size_t cell_i = domain_collisions.first[k];
+	const std::size_t cell_j = domain_collisions.second[k];
 
         // Store collision in collision map if we have a cut cell
         if (markers[cell_i] == 1)
         {
-          auto it = collision_map_cut_cells.find(cell_i);
-          dolfin_assert(it != collision_map_cut_cells.end());
-          it->second.push_back(std::make_pair(j, cell_j));
+	  const Cell cell(*_meshes[i], cell_i);
+	  const Cell other_cell(*_meshes[j], cell_j);
+	  if (cell.collides(other_cell))
+	  {
+	    collides_with_domain[cell_i] = true;
+	    auto it = collision_map_cut_cells.find(cell_i);
+	    dolfin_assert(it != collision_map_cut_cells.end());
+	    it->second.emplace_back(j, cell_j);
+	  }
         }
 
-        // Mark cell as covered if it does not collide with boundary
+        // Possibility to cell as covered if it does not collide with boundary
         if (!collides_with_boundary[cell_i])
         {
-          // Remove from collision map if previously marked as as cut cell
-          if (markers[cell_i] == 1)
-          {
-            dolfin_assert(collision_map_cut_cells.find(cell_i) != collision_map_cut_cells.end());
-            collision_map_cut_cells.erase(cell_i);
-          }
+	  // Detailed check if it is not marked as colliding with domain
+	  if (!collides_with_domain[cell_i])
+	  {
+	    const Cell cell(*_meshes[i], cell_i);
+	    const Cell other_cell(*_meshes[j], cell_j);
+	    collides_with_domain[cell_i] = cell.collides(other_cell);
+	  }
+
+	  if (collides_with_domain[cell_i])
+	  {
+	    // Remove from collision map if previously marked as as cut cell
+	    if (markers[cell_i] == 1)
+	    {
+	      dolfin_assert(collision_map_cut_cells.find(cell_i) != collision_map_cut_cells.end());
+	      collision_map_cut_cells.erase(cell_i);
+	    }
+
+	    // Mark as covered cell (may already be marked)
+	    markers[cell_i] = 2;
+	  }
 
-          // Mark as covered cell (may already be marked)
-          markers[cell_i] = 2;
         }
       }
     }
@@ -392,7 +631,7 @@ void MultiMesh::_build_collision_maps()
 
     // Store data for this mesh
     _uncut_cells.push_back(uncut_cells);
-    _cut_cells.push_back(cut_cells);
+    //_cut_cells.push_back(cut_cells);
     _covered_cells.push_back(covered_cells);
     _collision_maps_cut_cells.push_back(collision_map_cut_cells);
 
@@ -410,297 +649,94 @@ void MultiMesh::_build_quadrature_rules_overlap(std::size_t quadrature_order)
 
   // Clear quadrature rules
   _quadrature_rules_overlap.clear();
-  _quadrature_rules_interface.clear();
 
   // Resize quadrature rules
   _quadrature_rules_overlap.resize(num_parts());
-  _quadrature_rules_interface.resize(num_parts());
-
-  // Clear and resize facet normals
-  _facet_normals.clear();
-  _facet_normals.resize(num_parts());
-
-  // FIXME: test prebuild map from boundary facets to full mesh cells
-  // for all meshes: Loop over all boundary mesh facets to find the
-  // full mesh cell which contains the facet. This is done in two
-  // steps: Since the facet is on the boundary mesh, we first map this
-  // facet to a facet in the full mesh using the
-  // boundary_cell_map. Then we use the full_facet_cell_map to find
-  // the corresponding cell in the full mesh. This cell is to match
-  // the cutting_cell_no.
-
-  // Build map from boundary facets to full mesh
-  std::vector<std::vector<std::vector<std::pair<std::size_t, std::size_t>>>>
-    full_to_bdry(num_parts());
-  for (std::size_t part = 0; part < num_parts(); ++part)
-  {
-    full_to_bdry[part].resize(_meshes[part]->num_cells());
-
-    // Get map from boundary mesh to facets of full mesh
-    const std::size_t tdim_boundary
-      = _boundary_meshes[part]->topology().dim();
-    const auto& boundary_cell_map
-      = _boundary_meshes[part]->entity_map(tdim_boundary);
-
-    // Generate facet to cell connectivity for full mesh
-    const std::size_t tdim = _meshes[part]->topology().dim();
-    _meshes[part]->init(tdim_boundary, tdim);
-    const MeshConnectivity& full_facet_cell_map
-      = _meshes[part]->topology()(tdim_boundary, tdim);
-
-    for (std::size_t boundary_facet = 0;
-         boundary_facet < boundary_cell_map.size(); ++boundary_facet)
-    {
-      // Find the facet in the full mesh
-      const std::size_t full_mesh_facet = boundary_cell_map[boundary_facet];
-
-      // Find the cells in the full mesh (for interior facets we
-      // can have 2 facets, but here we should only have 1)
-      dolfin_assert(full_facet_cell_map.size(full_mesh_facet) == 1);
-      const auto& full_cells = full_facet_cell_map(full_mesh_facet);
-      full_to_bdry[part][full_cells[0]].push_back(std::make_pair(boundary_facet,
-                                                                 full_mesh_facet));
-    }
-  }
 
   // Iterate over all parts
   for (std::size_t cut_part = 0; cut_part < num_parts(); cut_part++)
   {
+    // Construct quadrature rules on reference simplex
+    const std::size_t tdim = _meshes[cut_part]->topology().dim();
+    const std::size_t gdim = _meshes[cut_part]->geometry().dim();
+    const SimplexQuadrature sq(tdim, quadrature_order);
+
     // Iterate over cut cells for current part
-    const auto& cmap = collision_map_cut_cells(cut_part);
-    for (auto it = cmap.begin(); it != cmap.end(); ++it)
+    for (const auto& c : collision_map_cut_cells(cut_part))
     {
       // Get cut cell
-      const unsigned int cut_cell_index = it->first;
+      const unsigned int cut_cell_index = c.first;
       const Cell cut_cell(*(_meshes[cut_part]), cut_cell_index);
 
-      // Get dimensions
-      const std::size_t tdim = cut_cell.mesh().topology().dim();
-      const std::size_t gdim = cut_cell.mesh().geometry().dim();
+      // Data structure for the first intersections (this is the first
+      // stage in the inclusion exclusion principle). These are the
+      // polyhedra to be used in the exlusion inclusion.
+      std::vector<std::pair<std::size_t, Polyhedron>> initial_polyhedra;
 
-      // Data structure for the volume triangulation of the cut_cell
-      std::vector<double> volume_triangulation;
+      // Get the cutting cells
+      const std::vector<std::pair<std::size_t, unsigned int>>& cutting_cells = c.second;
 
       // Data structure for the overlap quadrature rule
-      std::vector<quadrature_rule> overlap_qr;
-
-      // Data structure for the interface quadrature rule
-      std::vector<quadrature_rule> interface_qr;
-
-      // Data structure for the facet normals of the interface. The
-      // numbering matches the numbering of interface_qr. This means
-      // we have one normal for each quadrature point, since this is
-      // how the data are grouped during assembly: for each pair of
-      // colliding cells, we build a list of quadrature points and a
-      // corresponding list of facet normals.
-      std::vector<std::vector<double>> interface_n;
+      std::vector<quadrature_rule> overlap_qr(cutting_cells.size());
 
-      // Data structure for the interface triangulation
-      std::vector<double> interface_triangulation;
-
-      // Data structure for normals to the interface. The numbering
-      // should match the numbering of interface_triangulation.
-      std::vector<Point> triangulation_normals;
-
-      // Iterate over cutting cells
-      const auto& cutting_cells = it->second;
-      for (auto jt = cutting_cells.begin(); jt != cutting_cells.end(); jt++)
+      // Loop over all cutting cells to construct the polyhedra to be
+      // used in the inclusion-exclusion principle
+      for (const std::pair<std::size_t, unsigned int> cutting : cutting_cells)
       {
-        // Get cutting part and cutting cell
-        const std::size_t cutting_part = jt->first;
-        const std::size_t cutting_cell_index = jt->second;
+	// Get cutting part and cutting cell
+        const std::size_t cutting_part = cutting.first;
+        const std::size_t cutting_cell_index = cutting.second;
         const Cell cutting_cell(*(_meshes[cutting_part]), cutting_cell_index);
 
-        // Topology of this cut part
-        const std::size_t tdim_boundary = _boundary_meshes[cutting_part]->topology().dim();
-
-        // Must have the same topology at the moment (FIXME)
-        dolfin_assert(cutting_cell.mesh().topology().dim() == tdim);
+  	// Only allow same type of cell for now
+      	dolfin_assert(cutting_cell.mesh().topology().dim() == tdim);
+      	dolfin_assert(cutting_cell.mesh().geometry().dim() == gdim);
 
-        // Data structure for local interface triangulation
-        std::vector<double> local_interface_triangulation;
+        // Compute the intersection (a polyhedron)
+        // const Polyhedron polyhedron
+        //   = IntersectionTriangulation::triangulate(cut_cell, cutting_cell);
+        const Polyhedron polyhedron =
+          ConvexTriangulation::triangulate(IntersectionConstruction::intersection(cut_cell, cutting_cell), gdim, tdim);
 
-        // Data structure for the local interface normals. The
-        // numbering should match the numbering of
-        // local_interface_triangulation.
-        std::vector<Point> local_triangulation_normals;
+	// dolfin_assert(!ConvexTriangulation::selfintersects(polyhedron));
 
-        // Data structure for the overlap part quadrature rule
-        quadrature_rule overlap_part_qr;
+	// FIXME: Flip triangles in polyhedron to maximize minimum angle here?
+	// FIXME: only include large polyhedra
 
-        // Data structure for the interface part quadrature rule
-        quadrature_rule interface_part_qr;
+	// Store key and polyhedron but only use polyhedron of same tdim
+	Polyhedron polyhedron_same_tdim;
+	for (const Simplex& s: polyhedron)
+	  if (s.size() == tdim + 1 and
+	      !GeometryPredicates::is_degenerate(s, gdim))
+	    polyhedron_same_tdim.push_back(s);
 
-        // Data structure for the interface part facet normals. The
-        // numbering matches the numbering of interface_part_qr.
-        std::vector<double> interface_part_n;
-
-        // Iterate over boundary cells
-        for (auto boundary_cell_index : full_to_bdry[cutting_part][cutting_cell_index])
-        {
-          // Get the boundary facet as a cell in the boundary mesh
-          const Cell boundary_cell(*_boundary_meshes[cutting_part],
-                                   boundary_cell_index.first);
-
-          // Get the boundary facet as a facet in the full mesh
-          const Facet boundary_facet(*_meshes[cutting_part],
-                                     boundary_cell_index.second);
-
-          // Triangulate intersection of cut cell and boundary cell
-          const auto triangulation_cut_boundary
-            = cut_cell.triangulate_intersection(boundary_cell);
-
-          // The normals to triangulation_cut_boundary
-          std::vector<Point> normals_cut_boundary;
-
-          // Add quadrature rule and normals for triangulation
-          if (triangulation_cut_boundary.size())
-          {
-            dolfin_assert(interface_part_n.size() == interface_part_qr.first.size());
-
-            const auto num_qr_points
-              = _add_quadrature_rule(interface_part_qr,
-                                     triangulation_cut_boundary,
-                                     tdim_boundary, gdim,
-                                     quadrature_order, 1);
-
-            const std::size_t local_facet_index = cutting_cell.index(boundary_facet);
-            const Point n = -cutting_cell.normal(local_facet_index);
-            for (std::size_t i = 0; i < num_qr_points.size(); ++i)
-            {
-              _add_normal(interface_part_n,
-                          n,
-                          num_qr_points[i],
-                          gdim);
-              normals_cut_boundary.push_back(n);
-            }
-
-            dolfin_assert(interface_part_n.size() == interface_part_qr.first.size());
-          }
+	// Note that this can be empty
+	initial_polyhedra.emplace_back(initial_polyhedra.size(),
+				       polyhedron_same_tdim);
+      }
 
-          // Triangulate intersection of boundary cell and previous volume triangulation
-          const auto triangulation_boundary_prev_volume
-            = IntersectionTriangulation::triangulate_intersection(boundary_cell,
-                                                                  volume_triangulation,
-                                                                  tdim);
-
-          // Add quadrature rule and normals for triangulation
-          if (triangulation_boundary_prev_volume.size())
-          {
-            dolfin_assert(interface_part_n.size() == interface_part_qr.first.size());
-
-            const auto num_qr_points
-              = _add_quadrature_rule(interface_part_qr,
-                                     triangulation_boundary_prev_volume,
-                                     tdim_boundary, gdim,
-                                     quadrature_order, -1);
-
-            const std::size_t local_facet_index = cutting_cell.index(boundary_facet);
-            const Point n = -cutting_cell.normal(local_facet_index);
-            for (std::size_t i = 0; i < num_qr_points.size(); ++i)
-              _add_normal(interface_part_n,
-                          n,
-                          num_qr_points[i],
-                          gdim);
-
-            dolfin_assert(interface_part_n.size() == interface_part_qr.first.size());
-          }
+      if (cutting_cells.size() > 0)
+	_inclusion_exclusion_overlap(overlap_qr, sq, initial_polyhedra,
+				     tdim, gdim, quadrature_order);
 
-          // Update triangulation
-          local_interface_triangulation.insert(local_interface_triangulation.end(),
-                                               triangulation_cut_boundary.begin(),
-                                               triangulation_cut_boundary.end());
+      // Remove any near-trival quadrature rules
+      // TODO: The tolerance here appears to work ok in 2D with few meshes
+      // TODO: It might not be accurate in 3D or a large number of meshes
 
-          // Update interface facet normals
-          local_triangulation_normals.insert(local_triangulation_normals.end(),
-                                             normals_cut_boundary.begin(),
-                                             normals_cut_boundary.end());
-        }
+      //const double tolerance = DOLFIN_EPS * cut_cell.volume();
+      //for (std::size_t i = 0; i < overlap_qr.size(); i++)
+      //	remove_quadrature_rule(overlap_qr[i], tolerance);
 
-        // Triangulate the intersection of the previous interface
-        // triangulation and the cutting cell (to remove)
-        std::vector<double> triangulation_prev_cutting;
-        std::vector<Point> normals_prev_cutting;
-        IntersectionTriangulation::triangulate_intersection(cutting_cell,
-                                                            interface_triangulation,
-                                                            triangulation_normals,
-                                                            triangulation_prev_cutting,
-                                                            normals_prev_cutting,
-                                                            tdim_boundary);
-
-        // Add quadrature rule for triangulation
-        if (triangulation_prev_cutting.size())
+      if (parameters["compress_volume_quadrature"])
+      {
+      	for (std::size_t i = 0; i < overlap_qr.size(); ++i)
         {
-          dolfin_assert(interface_part_n.size() == interface_part_qr.first.size());
-
-          const auto num_qr_points
-            = _add_quadrature_rule(interface_part_qr,
-                                   triangulation_prev_cutting,
-                                   tdim_boundary, gdim,
-                                   quadrature_order, -1);
-
-          for (std::size_t i = 0; i < num_qr_points.size(); ++i)
-            _add_normal(interface_part_n,
-                        normals_prev_cutting[i],
-                        num_qr_points[i],
-                        gdim);
-
-          dolfin_assert(interface_part_n.size() == interface_part_qr.first.size());
+      	  SimplexQuadrature::compress(overlap_qr[i], gdim, quadrature_order);
         }
-
-        // Update triangulation
-        interface_triangulation.insert(interface_triangulation.end(),
-                                       local_interface_triangulation.begin(),
-                                       local_interface_triangulation.end());
-
-        // Update normals
-        triangulation_normals.insert(triangulation_normals.end(),
-                                     local_triangulation_normals.begin(),
-                                     local_triangulation_normals.end());
-
-        // Do the volume segmentation
-
-        // Compute volume triangulation of intersection of cut and cutting cells
-        const auto triangulation_cut_cutting
-          = cut_cell.triangulate_intersection(cutting_cell);
-
-        // Compute triangulation of intersection of cutting cell and
-        // the (previous) volume triangulation
-        const auto triangulation_cutting_prev
-          = IntersectionTriangulation::triangulate_intersection(cutting_cell,
-                                                                volume_triangulation,
-                                                                tdim);
-
-        // Add these new triangulations
-        volume_triangulation.insert(volume_triangulation.end(),
-                                    triangulation_cut_cutting.begin(),
-                                    triangulation_cut_cutting.end());
-
-        // Add quadrature rule with weights corresponding to the two
-        // triangulations
-        _add_quadrature_rule(overlap_part_qr,
-                             triangulation_cut_cutting,
-                             tdim, gdim, quadrature_order, 1);
-        _add_quadrature_rule(overlap_part_qr,
-                             triangulation_cutting_prev,
-                             tdim, gdim, quadrature_order, -1);
-
-        // Add quadrature rule for overlap part
-        overlap_qr.push_back(overlap_part_qr);
-
-        // Add quadrature rule for interface part
-        interface_qr.push_back(interface_part_qr);
-
-        // Add facet normal for interface part
-        interface_n.push_back(interface_part_n);
       }
 
       // Store quadrature rules for cut cell
       _quadrature_rules_overlap[cut_part][cut_cell_index] = overlap_qr;
-      _quadrature_rules_interface[cut_part][cut_cell_index] = interface_qr;
-
-      // Store facet normals for cut cell
-      _facet_normals[cut_part][cut_cell_index] = interface_n;
     }
   }
 
@@ -718,6 +754,11 @@ void MultiMesh::_build_quadrature_rules_cut_cells(std::size_t quadrature_order)
   // Iterate over all parts
   for (std::size_t cut_part = 0; cut_part < num_parts(); cut_part++)
   {
+    // Construct quadrature rules on reference simplex
+    const std::size_t tdim = _meshes[cut_part]->topology().dim();
+    const std::size_t gdim = _meshes[cut_part]->geometry().dim();
+    const SimplexQuadrature sq(tdim, quadrature_order);
+
     // Iterate over cut cells for current part
     const auto& cmap = collision_map_cut_cells(cut_part);
     for (auto it = cmap.begin(); it != cmap.end(); ++it)
@@ -726,12 +767,8 @@ void MultiMesh::_build_quadrature_rules_cut_cells(std::size_t quadrature_order)
       const unsigned int cut_cell_index = it->first;
       const Cell cut_cell(*(_meshes[cut_part]), cut_cell_index);
 
-      // Get dimension
-      const std::size_t gdim = cut_cell.mesh().geometry().dim();
-
       // Compute quadrature rule for the cell itself.
-      auto qr = SimplexQuadrature::compute_quadrature_rule(cut_cell,
-                                                           quadrature_order);
+      auto qr = sq.compute_quadrature_rule(cut_cell, quadrature_order);
 
       // Get the quadrature rule for the overlapping part
       const auto& qr_overlap = _quadrature_rules_overlap[cut_part][cut_cell_index];
@@ -741,6 +778,12 @@ void MultiMesh::_build_quadrature_rules_cut_cells(std::size_t quadrature_order)
       for (std::size_t k = 0; k < qr_overlap.size(); k++)
         _add_quadrature_rule(qr, qr_overlap[k], gdim, -1);
 
+      if (parameters["compress_volume_quadrature"])
+      {
+      	// Compress
+      	SimplexQuadrature::compress(qr, gdim, quadrature_order);
+      }
+
       // Store quadrature rule for cut cell
       _quadrature_rules_cut_cells[cut_part][cut_cell_index] = qr;
     }
@@ -748,36 +791,299 @@ void MultiMesh::_build_quadrature_rules_cut_cells(std::size_t quadrature_order)
 
   end();
 }
-//-----------------------------------------------------------------------------
-std::vector<std::size_t>
-MultiMesh::_add_quadrature_rule(quadrature_rule& qr,
-                                const std::vector<double>& triangulation,
-                                std::size_t tdim,
-                                std::size_t gdim,
-                                std::size_t quadrature_order,
-                                double factor) const
+//------------------------------------------------------------------------------
+void MultiMesh::_build_quadrature_rules_interface(std::size_t quadrature_order)
 {
-  // Iterate over simplices in triangulation
-  const std::size_t offset = (tdim + 1)*gdim; // coordinates per simplex
-  const std::size_t num_simplices = triangulation.size() / offset;
-  std::vector<std::size_t> num_points(num_simplices);
+  begin(PROGRESS, "Building quadrature rules of interface.");
+
+  // This is similar to _build_quadrature_rules_overlap, except
+  // - For the edge E_ij, i<j, we only intersect with triangles T_k
+  //   where k>i and k!=j
+  // - We note that the sign change is opposite of the other inc exc:
+  //   |E_ij \ U_k T_k| = |E_ij| - |E_ij \cap U_k T_k|
+  //                    = |E_ij| - |U_k E_ij \cap T_k|
+
+  // Clear and resize quadrature rules and normals
+  _quadrature_rules_interface.clear();
+  _quadrature_rules_interface.resize(num_parts());
+  _facet_normals.clear();
+  _facet_normals.resize(num_parts());
+
+  // First we prebuild a map from the boundary facets to full mesh
+  // cells for all meshes: Loop over all boundary mesh facets to find
+  // the full mesh cell which contains the facet. This is done in two
+  // steps: Since the facet is on the boundary mesh, we first map this
+  // facet to a facet in the full mesh using the
+  // boundary_cell_map. Then we use the full_facet_cell_map to find
+  // the corresponding cell in the full mesh. This cell is to match
+  // the cutting_cell_no.
+
+  // Build map from boundary facets to full mesh
+  std::vector<std::vector<std::vector<std::pair<std::size_t, std::size_t>>>>
+    full_to_bdry(num_parts());
+  for (std::size_t part = 0; part < num_parts(); ++part)
+    full_to_bdry[part] = _boundary_facets_to_full_mesh(part);
 
-  for (std::size_t k = 0; k < num_simplices; k++)
+  // Iterate over all parts
+  for (std::size_t cut_part = 0; cut_part < num_parts(); cut_part++)
   {
-    // Get coordinates for current simplex in triangulation
-    const double* x = &triangulation[0] + k*offset;
+    // Topological dimension of bulk
+    const std::size_t tdim_bulk = _meshes[cut_part]->topology().dim();
 
-    // Compute quadrature rule for simplex
-    const auto dqr = SimplexQuadrature::compute_quadrature_rule(x,
-                                                               tdim,
-                                                               gdim,
-                                                               quadrature_order);
+    // Construct quadrature rules on reference simplex on interface
+    const std::size_t tdim_interface = tdim_bulk - 1;
+    const std::size_t gdim = _meshes[cut_part]->geometry().dim();
+    const SimplexQuadrature sq(tdim_interface, quadrature_order);
 
-    // Add quadrature rule
-    num_points[k] = _add_quadrature_rule(qr, dqr, gdim, factor);
+    // Iterate over cut cells for current part
+    const std::map<unsigned int,
+                   std::vector<std::pair<std::size_t,
+                                         unsigned int>>>&
+      cmap = collision_map_cut_cells(cut_part);
+    for (const auto cut_i: cmap)
+    {
+      // Get cut cell
+      const std::size_t cut_cell_index_i = cut_i.first;
+      const Cell cut_cell_i(*(_meshes[cut_part]), cut_cell_index_i);
+
+      // Get the cutting cells
+      const auto& cutting_cells_j = cut_i.second;
+
+      // Data structures for the interface quadrature rule and the normals
+      const std::size_t num_cutting_cells
+	= std::distance(cutting_cells_j.begin(), cutting_cells_j.end());
+      std::vector<quadrature_rule> interface_qr(num_cutting_cells);
+      std::vector<std::vector<double>> interface_normals(num_cutting_cells);
+
+      // Loop over all cutting cells to construct the polyhedra to be
+      // used in the inclusion-exclusion principle
+      for (std::vector<std::pair<std::size_t, unsigned int>>::const_iterator
+	     cutting_j = cutting_cells_j.begin();
+	   cutting_j != cutting_cells_j.end(); ++cutting_j)
+      {
+	// Get cutting part and cutting cell
+        const std::size_t cutting_part_j = cutting_j->first;
+        const std::size_t cutting_cell_index_j = cutting_j->second;
+        const Cell cutting_cell_j(*(_meshes[cutting_part_j]), cutting_cell_index_j);
+	const std::size_t local_cutting_cell_j_index = cutting_j - cutting_cells_j.begin();
+	dolfin_assert(cutting_part_j > cut_part);
+
+	// Find and store the cutting cells Tk. These are fed into the
+	// inc exc together with the edge Eij.
+	std::vector<std::pair<std::size_t, Polyhedron> > initial_polygons;
+
+	// Find and save all cutting cells with part number > i
+	// (this is always true), and part number != j.
+	for (const std::pair<size_t, unsigned int>& cutting_k: cut_i.second)
+	{
+	  const std::size_t cutting_part_k = cutting_k.first;
+	  if (cutting_part_k != cutting_part_j)
+	  {
+	    const std::size_t cutting_cell_index_k = cutting_k.second;
+	    const Cell cutting_cell_k(*(_meshes[cutting_part_k]),
+				      cutting_cell_index_k);
+
+	    // Store key and the cutting cell as a polygon (this
+	    // is really a Simplex, but store as polyhedron to
+	    // minimize interface change to inc exc).
+	    const MeshGeometry& geometry = _meshes[cutting_part_k]->geometry();
+	    const unsigned int* vertices = cutting_cell_k.entities(0);
+	    Simplex cutting_cell_k_simplex(tdim_bulk + 1);
+	    for (std::size_t i = 0; i < cutting_cell_k_simplex.size(); ++i)
+	      cutting_cell_k_simplex[i] = geometry.point(vertices[i]);
+	    const Polyhedron cutting_cell_k_polyhedron(1, cutting_cell_k_simplex);
+
+	    initial_polygons.emplace_back(initial_polygons.size(),
+					  cutting_cell_k_polyhedron);
+	  }
+	}
+
+	// Iterate over boundary cells of this cutting cell (for
+	// triangles we have one or two sides that cut). Here we can
+	// optionally use a full (polygon) E_ij used in the E_ij \cap
+	// T_k, or we can only take a part (a simplex) of the Eij.
+
+	// Loop over all Eij parts (i.e. boundary parts of T_j)
+	for (const auto boundary_cell_index_j: full_to_bdry[cutting_part_j][cutting_cell_index_j])
+        {
+          // Get the boundary facet as a cell in the boundary mesh
+          // (remember that this is of one less topological dimension)
+          const Cell boundary_cell_j(*_boundary_meshes[cutting_part_j],
+				     boundary_cell_index_j.first);
+	  dolfin_assert(boundary_cell_j.mesh().topology().dim() == tdim_interface);
+
+	  // Get the normal by constructing a Facet using the full_to_bdry data
+	  const Facet boundary_facet_j(*_meshes[cutting_part_j],
+				       boundary_cell_index_j.second);
+	  const std::size_t local_facet_index = cutting_cell_j.index(boundary_facet_j);
+	  const Point facet_normal = cutting_cell_j.normal(local_facet_index);
+
+	  // Triangulate intersection of cut cell and boundary cell
+	  const std::vector<Point> Eij_part_points
+	    = IntersectionConstruction::intersection(cut_cell_i, boundary_cell_j);
+
+	  // Check that the triangulation is not part of the cut cell boundary
+	  // FIXME: How can we avoid is_degenerate warnings in
+	  // _is_overlapped_interface by checking the input?
+	  if (Eij_part_points.size() < tdim_interface + 1 or
+	      _is_overlapped_interface(Eij_part_points, cut_cell_i, facet_normal))
+	    continue;
+
+	  const Polyhedron Eij_part =
+            ConvexTriangulation::triangulate(Eij_part_points, gdim, tdim_interface);
+
+	  // The intersection should be either empty or one simplex
+	  dolfin_assert(Eij_part.size() <= 1);
+
+	  if (Eij_part.size())
+	  {
+	    // Do not include if the point (or line) is degenerate,
+	    // neither here nor below
+	    if (Eij_part[0].size() == tdim_interface + 1 and
+		!GeometryPredicates::is_degenerate(Eij_part[0], gdim))
+	    {
+	      const Simplex& Eij = Eij_part[0];
+
+	      // Store the |Eij| and normals
+	      const std::size_t num_pts
+		= _add_quadrature_rule(interface_qr[local_cutting_cell_j_index],
+				       sq, Eij, gdim, quadrature_order, 1.);
+	      _add_normal(interface_normals[local_cutting_cell_j_index],
+			  facet_normal, num_pts, gdim);
+
+	      // No need to run inc exc if there are no cutting cells
+	      if (initial_polygons.size())
+	      {
+		// Call inclusion exclusion
+		_inclusion_exclusion_interface
+		  (interface_qr[local_cutting_cell_j_index],
+		   interface_normals[local_cutting_cell_j_index],
+		   sq, Eij, facet_normal, initial_polygons,
+		   tdim_interface, gdim, quadrature_order);
+	      }
+
+	      // // Remove any near-trival quadrature rules
+	      // // TODO: Investigate the tolerance
+              // double cut_size;
+              // if  (Eij.size() == 2)
+              //   cut_size = (Eij[1] - Eij[0]).norm();
+              // else if (Eij.size() == 3)
+              //   cut_size = (Eij[1] - Eij[0]).cross(Eij[2] - Eij[0]).norm() / 2;
+              //const double tolerance = DOLFIN_EPS * cut_size;
+	      //remove_quadrature_rule(interface_qr[local_cutting_cell_j_index], tolerance);
+
+	      // TODO: Investigate if we should compress here or below
+	      if (parameters["compress_interface_quadrature"])
+	      {
+		const std::vector<std::size_t> indices
+		  = SimplexQuadrature::compress(interface_qr[local_cutting_cell_j_index], gdim, quadrature_order);
+		if (indices.size())
+		{
+		  // Reorder the normals
+		  std::vector<double> normals(gdim*indices.size());
+		  for (std::size_t j = 0; j < indices.size(); ++j)
+		    for (std::size_t d = 0; d < gdim; ++d)
+		      normals[gdim*j + d] = interface_normals[local_cutting_cell_j_index][gdim*indices[j] + d];
+		  interface_normals[local_cutting_cell_j_index] = normals;
+		}
+	      }
+	    }
+	  }
+	} // end loop over boundary_cell_j
+      } // end loop over cutting_j
+
+      // // TODO: Investigate if we should compress here or below
+      // if (parameters["compress_interface_quadrature"])
+      // {
+      // 	for (std::size_t i = 0; i < interface_qr.size(); ++i)
+      // 	{
+      // 	  const std::size_t sz = interface_qr[i].second.size();
+      // 	  const std::vector<std::size_t> indices
+      // 	    = SimplexQuadrature::compress(interface_qr[i], gdim, quadrature_order);
+
+      // 	  if (indices.size())
+      // 	  {
+      // 	    // Reorder the normals
+      // 	    std::vector<double> normals(gdim*indices.size());
+      // 	    for (std::size_t j = 0; j < indices.size(); ++j)
+      // 	      for (std::size_t d = 0; d < gdim; ++d)
+      // 		normals[gdim*j + d] = interface_normals[i][gdim*indices[j] + d];
+      // 	    interface_normals[i] = normals;
+      // 	    // std::cout<<__FUNCTION__<<" compress " << sz<<' '<<indices.size() << std::endl;
+      // 	  }
+      // 	}
+      // }
+
+      _quadrature_rules_interface[cut_part][cut_cell_index_i] = interface_qr;
+      _facet_normals[cut_part][cut_cell_index_i] = interface_normals;
+
+    } // end loop over cut_i
+  } // end loop over parts
+
+  end();
+}
+//------------------------------------------------------------------------------
+bool
+MultiMesh::_is_overlapped_interface(std::vector<Point> simplex,
+				    const Cell cut_cell,
+				    Point simplex_normal) const
+{
+  // Returns true if an interface intersection is overlapped by the cutting cell.
+  // The criterion for the edge being overlapped should be that
+  //  (1) The intersection is contained within the cell facets
+  //  (2) The (outwards) normals of the cut and the cutting cutting cell are equal.
+
+  // First, use inner products with a tolerance
+  // TODO: Maybe faster to call orient2dfast instead
+  Point simplex_midpoint(0.0, 0.0, 0.0);
+  for (Point p : simplex)
+    simplex_midpoint += p;
+  simplex_midpoint /= simplex.size();
+
+  const unsigned int* vertex_indices = cut_cell.entities(0);
+  for (std::size_t j = 0; j < cut_cell.num_entities(0); j++)
+  {
+    Vertex vertex_j(cut_cell.mesh(), vertex_indices[j]);
+    double c = simplex_normal.dot(vertex_j.point() - simplex_midpoint);
+    if (c > DOLFIN_EPS_LARGE)
+      return false;
+  }
+  // Identify a facet being cut, if any
+  std::size_t tdim = cut_cell.dim();
+  const unsigned int* facet_indices = cut_cell.entities(tdim - 1);
+  for (std::size_t j = 0; j < cut_cell.num_entities(tdim - 1); j++)
+  {
+    Facet facet_j(cut_cell.mesh(), facet_indices[j]);
+    simplex.push_back(facet_j.midpoint());
+    if (GeometryPredicates::is_degenerate(simplex, tdim))
+    {
+      // then we have found the right facet
+      simplex.pop_back();
+      return (simplex_normal.dot(cut_cell.normal(j)) > 0);
+    }
+    simplex.pop_back();
   }
+  return false;
+}
+//------------------------------------------------------------------------------
+std::size_t
+MultiMesh::_add_quadrature_rule(quadrature_rule& qr,
+				const SimplexQuadrature& sq,
+                                const Simplex& simplex,
+                                std::size_t gdim,
+                                std::size_t quadrature_order,
+                                double factor) const
+{
+  // Compute quadrature rule for simplex
+  const auto dqr = sq.compute_quadrature_rule(simplex,
+						 gdim,
+						 quadrature_order);
+  // Add quadrature rule
+  const std::size_t num_points = _add_quadrature_rule(qr, dqr, gdim, factor);
+
   return num_points;
 }
+
 //-----------------------------------------------------------------------------
 std::size_t MultiMesh::_add_quadrature_rule(quadrature_rule& qr,
                                             const quadrature_rule& dqr,
@@ -788,13 +1094,6 @@ std::size_t MultiMesh::_add_quadrature_rule(quadrature_rule& qr,
   dolfin_assert(dqr.first.size() == gdim*dqr.second.size());
   const std::size_t num_points = dqr.second.size();
 
-  // Skip if sum of weights is too small
-  double wsum = 0.0;
-    for (std::size_t i = 0; i < num_points; i++)
-    wsum += std::abs(dqr.second[i]);
-  if (wsum < DOLFIN_EPS)
-    return 0;
-
   // Append points and weights
   for (std::size_t i = 0; i < num_points; i++)
   {
@@ -810,12 +1109,482 @@ std::size_t MultiMesh::_add_quadrature_rule(quadrature_rule& qr,
 }
 //-----------------------------------------------------------------------------
 void MultiMesh::_add_normal(std::vector<double>& normals,
-                         const Point& normal,
-                         const std::size_t npts,
-                         const std::size_t gdim) const
+			    const Point& normal,
+			    std::size_t npts,
+			    std::size_t gdim) const
+{
+  for (std::size_t i = 0; i < npts; ++i)
+    for (std::size_t j = 0; j < gdim; ++j)
+      normals.push_back(-normal[j]);
+}
+//-----------------------------------------------------------------------------
+void MultiMesh::_inclusion_exclusion_overlap
+(std::vector<quadrature_rule>& qr,
+ const SimplexQuadrature& sq,
+ const std::vector<std::pair<std::size_t, Polyhedron> >& initial_polyhedra,
+ std::size_t tdim,
+ std::size_t gdim,
+ std::size_t quadrature_order) const
+{
+  begin(PROGRESS, "The inclusion exclusion principle.");
+
+  // Exclusion-inclusion principle. There are N stages in the
+  // principle, where N = polyhedra.size(). The first stage is
+  // simply the polyhedra themselves A, B, C, ... etc. The second
+  // stage is for the pairwise intersections A \cap B, A \cap C, B
+  // \cap C, etc, with different sign. There are
+  // n_choose_k(N,stage) intersections for each stage.
+
+  // Data structure for storing the previous intersections: the key
+  // and the intersections.
+  const std::size_t N = initial_polyhedra.size();
+  std::vector<std::pair<IncExcKey, Polyhedron> > previous_intersections(N);
+  for (std::size_t i = 0; i < N; ++i)
+    previous_intersections[i]
+      = std::make_pair(IncExcKey(1, initial_polyhedra[i].first),
+		       initial_polyhedra[i].second);
+
+  // Do stage = 1 up to stage = polyhedra.size in the
+  // principle. Recall that stage 1 is the pairwise
+  // intersections. There are up to n_choose_k(N,stage)
+  // intersections in each stage (there may be less). The
+  // intersections are found using the polyhedra data and the
+  // previous_intersections data. We only have to intersect if the
+  // key doesn't contain the polyhedron.
+
+  // Add quadrature rules for stage 0
+  for (const std::pair<IncExcKey, Polyhedron>& pol_pair: previous_intersections)
+    for (const Simplex& simplex: pol_pair.second)
+      if (simplex.size() == tdim + 1)
+      {
+	_add_quadrature_rule(qr[pol_pair.first[0]], sq, simplex, gdim,
+			     quadrature_order, 1.);
+      }
+
+  // Add quadrature rules for overlap part
+  for (std::size_t stage = 1; stage < N; ++stage)
+  {
+    // Structure for storing new intersections
+    std::vector<std::pair<IncExcKey, Polyhedron> > new_intersections;
+
+    // Loop over all intersections from the previous stage
+    for (const std::pair<IncExcKey, Polyhedron>& previous_polyhedron: previous_intersections)
+    {
+      // Loop over all initial polyhedra.
+      for (const std::pair<std::size_t, Polyhedron>& initial_polyhedron: initial_polyhedra)
+      {
+	// Only check if initial_polyhedron key < previous_polyhedron
+	// key[0]
+	if (initial_polyhedron.first < previous_polyhedron.first[0])
+	{
+	  // We want to save the intersection of the previous
+	  // polyhedron and the initial polyhedron in one single
+	  // polyhedron.
+	  Polyhedron new_polyhedron;
+	  IncExcKey new_keys;
+
+	  // Loop over all simplices in the initial_polyhedron and
+	  // the previous_polyhedron and append the intersection of
+	  // these to the new_polyhedron
+	  bool any_intersections = false;
+
+	  for (const Simplex& previous_simplex: previous_polyhedron.second)
+	  {
+	    for (const Simplex& initial_simplex: initial_polyhedron.second)
+	    {
+	      // Compute the intersection (a polyhedron)
+	      // To save all intersections as a single polyhedron,
+	      // we don't call this a polyhedron yet, but rather a
+	      // std::vector<Simplex> since we are still filling
+	      // the polyhedron with simplices
+
+	      // Only allow same types for now
+	      if (previous_simplex.size() == tdim + 1 &&
+		  initial_simplex.size() == tdim + 1)
+	      {
+		const std::vector<Point> intersection_points
+		  = IntersectionConstruction::intersection(initial_simplex,
+							   previous_simplex,
+							   gdim);
+
+                if (!GeometryPredicates::convex_hull_is_degenerate(intersection_points,
+                                                                   gdim))
+                {
+
+                  const Polyhedron intersection
+                    = ConvexTriangulation::triangulate(intersection_points,
+                                                       gdim,
+                                                       tdim);
+
+		  // To save all intersections as a single
+		  // polyhedron, we don't call this a polyhedron
+		  // yet, but rather a std::vector<Simplex> since we
+		  // are still filling the polyhedron with simplices
+
+		  // FIXME: We could add only if area is sufficiently
+		  // large
+		  for (const Simplex& simplex: intersection)
+                  {
+		    if (simplex.size() == tdim + 1 and
+			!GeometryPredicates::is_degenerate(simplex, gdim))
+		    {
+		      new_polyhedron.push_back(simplex);
+		      any_intersections = true;
+		    }
+                  }
+		}
+	      }
+	    }
+	  }
+
+	  if (any_intersections)
+	  {
+	    new_keys.push_back(initial_polyhedron.first);
+	    new_keys.insert(new_keys.end(),
+			    previous_polyhedron.first.begin(),
+			    previous_polyhedron.first.end());
+
+	    // FIXME: Test improve quality
+	    //maximize_minimum_angle(new_polyhedron);
+
+	    // Save data
+	    new_intersections.emplace_back(new_keys, new_polyhedron);
+	  }
+	}
+      }
+    }
+
+    // Update before next stage
+    previous_intersections = new_intersections;
+
+    // Add quadrature rule with correct sign
+    const double sign = std::pow(-1, stage);
+
+    for (const std::pair<IncExcKey, Polyhedron>& polyhedron: new_intersections)
+      for (const Simplex& simplex: polyhedron.second)
+	if (simplex.size() == tdim + 1)
+	{
+	  _add_quadrature_rule(qr[polyhedron.first[0]], sq, simplex, gdim,
+			       quadrature_order, sign);
+	}
+
+  } // end loop over stages
+
+  end();
+}
+//------------------------------------------------------------------------------
+void MultiMesh::_inclusion_exclusion_interface
+(quadrature_rule& qr,
+ std::vector<double>& normals,
+ const SimplexQuadrature& sq,
+ const Simplex& Eij,
+ const Point& facet_normal,
+ const std::vector<std::pair<std::size_t, Polyhedron> >& initial_polyhedra,
+ std::size_t tdim_interface,
+ std::size_t gdim,
+ std::size_t quadrature_order) const
+{
+  begin(PROGRESS, "The inclusion exclusion principle for the interface.");
+
+  dolfin_assert(Eij.size() == tdim_interface + 1);
+  const std::size_t tdim_bulk = tdim_interface + 1;
+
+  // Exclusion-inclusion principle. There are N stages in the
+  // principle, where N = polyhedra.size(). The first stage is simply
+  // the polyhedra themselves A, B, C, ... etc. The second stage is
+  // for the pairwise intersections A \cap B, A \cap C, B \cap C, etc,
+  // with different sign. There are n_choose_k(N,stage) intersections
+  // for each stage.
+
+  // Note that for each qr we have a normal.
+
+  // Data structure for storing the previous intersections: the key
+  // and the intersections.
+  const std::size_t N = initial_polyhedra.size();
+  std::vector<std::pair<IncExcKey, Polyhedron> > previous_intersections(N);
+  for (std::size_t i = 0; i < N; ++i)
+    previous_intersections[i]
+      = std::make_pair(IncExcKey(1, initial_polyhedra[i].first),
+		       initial_polyhedra[i].second);
+
+  // Do stage = 1 up to stage = polyhedra.size in the
+  // principle. Recall that stage 1 is the pairwise
+  // intersections. There are up to n_choose_k(N,stage) intersections
+  // in each stage (there may be less). The intersections are found
+  // using the polyhedra data and the previous_intersections data. We
+  // only have to intersect if the key doesn't contain the polyhedron.
+
+  // FIXME: We also only have to intersect if the polyhedron and the
+  // previous_intersections are from different meshes.
+
+  // Add quadrature rule for stage 0 and save normals
+  quadrature_rule qr_stage0;
+  std::vector<double> normals_stage0;
+
+  for (const std::pair<IncExcKey, Polyhedron>& pol_pair: previous_intersections)
+  {
+    for (const Simplex& simplex: pol_pair.second)
+    {
+      if (simplex.size() == tdim_bulk + 1 and
+	  !GeometryPredicates::is_degenerate(simplex, gdim))
+      {
+
+	const std::vector<Point> Eij_cap_Tk_points
+	  = IntersectionConstruction::intersection(Eij, simplex, gdim);
+
+	if (Eij_cap_Tk_points.size())
+	{
+	  const Polyhedron Eij_cap_Tk
+	    = ConvexTriangulation::triangulate(Eij_cap_Tk_points, gdim, tdim_interface);
+
+	  for (const Simplex& s: Eij_cap_Tk)
+	  {
+	    if (s.size() == tdim_interface + 1 and
+		!GeometryPredicates::is_degenerate(s, gdim))
+	    {
+	      const std::size_t num_pts
+		= _add_quadrature_rule(qr_stage0, sq, s, gdim,
+				       quadrature_order, -1.); // Stage 0 is negative
+	      _add_normal(normals_stage0, facet_normal, num_pts, gdim);
+	    }
+	  }
+	}
+      }
+    }
+  }
+  dolfin_assert(normals_stage0.size() == qr_stage0.first.size());
+
+  // Add quadrature rule and normals
+  qr.first.insert(qr.first.end(), qr_stage0.first.begin(), qr_stage0.first.end());
+  qr.second.insert(qr.second.end(), qr_stage0.second.begin(), qr_stage0.second.end());
+  normals.insert(normals.end(), normals_stage0.begin(), normals_stage0.end());
+
+  for (std::size_t stage = 1; stage < N; ++stage)
+  {
+    // Data structure for storing new intersections
+    std::vector<std::pair<IncExcKey, Polyhedron> > new_intersections;
+
+    // Loop over all intersections from the previous stage
+    for (const std::pair<IncExcKey, Polyhedron>& previous_polyhedron: previous_intersections)
+    {
+      // Loop over all initial polyhedra.
+      for (const std::pair<std::size_t, Polyhedron>& initial_polyhedron: initial_polyhedra)
+      {
+
+	// Check if the initial_polyhedron's key < previous_polyhedron
+	// key[0]
+	if (initial_polyhedron.first < previous_polyhedron.first[0])
+	{
+	  // We want to save the intersection of the previous
+	  // polyhedron and the initial polyhedron in one single
+	  // polyhedron.
+	  Polyhedron new_polyhedron;
+	  IncExcKey new_keys;
+
+	  // Loop over all simplices in the initial_polyhedron and
+	  // the previous_polyhedron and append the intersection of
+	  // these to the new_polyhedron
+	  bool any_intersections = false;
+
+	  for (const Simplex& previous_simplex: previous_polyhedron.second)
+	  {
+	    for (const Simplex& initial_simplex: initial_polyhedron.second)
+	    {
+	      // Compute the intersection (a polyhedron).
+	      // FIXME: Only allow same types for now.
+	      if (previous_simplex.size() == tdim_bulk + 1 &&
+		  initial_simplex.size() == tdim_bulk + 1)
+	      {
+		const std::vector<Point> intersection_points
+		  = IntersectionConstruction::intersection(initial_simplex,
+							   previous_simplex,
+							   gdim);
+		// FIXME: Should we avoid this if statement and let
+		// ConvexTriangulation deal with empty input?
+		if (intersection_points.size())
+		{
+		  const Polyhedron intersection
+		    = ConvexTriangulation::triangulate(intersection_points,
+						       gdim,
+						       tdim_bulk);
+
+		  if (intersection.size())
+		  {
+		    // To save all intersections as a single
+		    // polyhedron, we don't call this a polyhedron
+		    // yet, but rather a std::vector<Simplex> since we
+		    // are still filling the polyhedron with simplices
+
+		    // FIXME: We could add only if area is sufficiently large
+		    for (const Simplex& simplex: intersection)
+		    {
+		      if (simplex.size() == tdim_bulk + 1 and
+			  !GeometryPredicates::is_degenerate(simplex, gdim))
+		      {
+			new_polyhedron.push_back(simplex);
+			any_intersections = true;
+		      }
+		    }
+		  }
+		}
+	      }
+	    }
+	  }
+
+
+	  if (any_intersections)
+	  {
+	    new_keys.push_back(initial_polyhedron.first);
+	    new_keys.insert(new_keys.end(),
+			    previous_polyhedron.first.begin(),
+			    previous_polyhedron.first.end());
+
+	    // FIXME: Test improve quality by edge flips
+
+	    // Save data
+	    new_intersections.emplace_back(new_keys, new_polyhedron);
+	  }
+	}
+      }
+    }
+
+    // Update before next stage
+    previous_intersections = new_intersections;
+
+    // Add quadrature rule with correct sign and save normals
+    const double sign = -std::pow(-1, stage);
+    quadrature_rule qr_stage;
+    std::vector<double> normals_stage;
+
+    for (const std::pair<IncExcKey, Polyhedron>& polyhedron: new_intersections)
+    {
+      for (const Simplex& simplex: polyhedron.second)
+      {
+	if (simplex.size() == tdim_bulk + 1)
+	{
+	  const std::vector<Point> Eij_cap_Tk_points
+	    = IntersectionConstruction::intersection(Eij, simplex, gdim);
+	  const Polyhedron Eij_cap_Tk
+	    = ConvexTriangulation::triangulate(Eij_cap_Tk_points,
+					       gdim,
+					       tdim_interface);
+	  for (const Simplex& s: Eij_cap_Tk)
+	  {
+	    if (s.size() == tdim_interface + 1 and
+		!GeometryPredicates::is_degenerate(s, gdim))
+	    {
+	      const std::size_t num_pts
+		= _add_quadrature_rule(qr_stage, sq, s, gdim,
+				       quadrature_order, sign);
+	      _add_normal(normals_stage, facet_normal, num_pts, gdim);
+	    }
+	  }
+	}
+      }
+    }
+    dolfin_assert(normals_stage.size() == qr_stage.first.size());
+
+    // Add quadrature rule and normals
+    qr.first.insert(qr.first.end(), qr_stage.first.begin(), qr_stage.first.end());
+    qr.second.insert(qr.second.end(), qr_stage.second.begin(), qr_stage.second.end());
+    normals.insert(normals.end(), normals_stage.begin(), normals_stage.end());
+  } // end loop over stages
+
+  end();
+}
+//------------------------------------------------------------------------------
+std::vector<std::vector<std::pair<std::size_t, std::size_t>>>
+MultiMesh::_boundary_facets_to_full_mesh(std::size_t part) const
+{
+  std::vector<std::vector<std::pair<std::size_t, std::size_t>>>
+    full_to_bdry(_meshes[part]->num_cells());
+
+  // Get map from boundary mesh to facets of full mesh
+  const std::size_t tdim_boundary
+    = _boundary_meshes[part]->topology().dim();
+  const auto& boundary_cell_map
+    = _boundary_meshes[part]->entity_map(tdim_boundary);
+
+  // Generate facet to cell connectivity for full mesh
+  const std::size_t tdim = _meshes[part]->topology().dim();
+  _meshes[part]->init(tdim_boundary, tdim);
+  const MeshConnectivity& full_facet_cell_map
+    = _meshes[part]->topology()(tdim_boundary, tdim);
+
+  for (std::size_t boundary_facet = 0;
+       boundary_facet < boundary_cell_map.size(); ++boundary_facet)
+  {
+    // Find the facet in the full mesh
+    const std::size_t full_mesh_facet = boundary_cell_map[boundary_facet];
+
+    // Find the cells in the full mesh (for interior facets we
+    // can have 2 facets, but here we should only have 1)
+    dolfin_assert(full_facet_cell_map.size(full_mesh_facet) == 1);
+    const auto& full_cells = full_facet_cell_map(full_mesh_facet);
+    full_to_bdry[full_cells[0]].emplace_back(boundary_facet,
+					     full_mesh_facet);
+  }
+
+  return full_to_bdry;
+}
+//-----------------------------------------------------------------------------
+void MultiMesh::_impose_cut_cell_consistency()
+{
+  for (std::size_t part_id = 0; part_id < num_parts(); part_id++)
+  {
+    for (auto cell : cut_cells(part_id))
+    {
+      auto cell_quadrature_rules = _quadrature_rules_interface[part_id][cell];
+      bool has_no_qr = true;
+      for (quadrature_rule qr : cell_quadrature_rules)
+      {
+        if (qr.first.size() > 0)
+        {
+          has_no_qr = false;
+          break;
+        }
+      }
+      if (has_no_qr)
+      {
+        // Decide if cell is overlapped or uncut
+        // TODO: Implement decision to allow update before generating all the quadrature rules
+        // For now, we use cut cell and overlap quadrature
+        double overlap_area = 0;
+        for (auto _qr : _quadrature_rules_overlap[part_id][cell])
+          for (double w : _qr.second)
+            overlap_area += w;
+
+        double cut_cell_area = 0;
+        for (double w : _quadrature_rules_cut_cells[part_id][cell].second)
+          cut_cell_area += w;
+
+        // Append to _cut_cells or _overlapped_cells
+        // One of cut cell area and overlapped cell area should be zero
+        if (overlap_area > cut_cell_area)
+          _covered_cells[part_id].push_back(cell);
+        else
+        {
+          _uncut_cells[part_id].push_back(cell);
+          // Clear collision map
+          _collision_maps_cut_cells[part_id][cell].clear();
+        }
+      }
+    }
+  }
+}
+//-----------------------------------------------------------------------------
+void MultiMesh::remove_quadrature_rule(quadrature_rule& qr,
+				       double tolerance)
 {
-for (std::size_t i = 0; i < npts; ++i)
- for (std::size_t j = 0; j < gdim; ++j)
-   normals.push_back(normal[j]);
+  //const double sum = std::accumulate(qr.second.begin(),
+  // 				       qr.second.end(), 0.0);
+
+  const double sum_of_weights = std::accumulate(qr.second.begin(),
+                                                qr.second.end(), 0.0);
+  if (std::abs(sum_of_weights) < tolerance)
+  {
+    qr.first.clear();
+    qr.second.clear();
+  }
 }
 //-----------------------------------------------------------------------------
diff --git a/dolfin/mesh/MultiMesh.h b/dolfin/mesh/MultiMesh.h
index 8403c8a..61e0015 100644
--- a/dolfin/mesh/MultiMesh.h
+++ b/dolfin/mesh/MultiMesh.h
@@ -16,7 +16,7 @@
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 //
 // First added:  2014-03-03
-// Last changed: 2016-03-02
+// Last changed: 2017-09-22
 
 #ifndef __MULTI_MESH_H
 #define __MULTI_MESH_H
@@ -24,6 +24,7 @@
 #include <memory>
 #include <vector>
 #include <map>
+#include <deque>
 
 #include <dolfin/common/Variable.h>
 #include <dolfin/geometry/Point.h>
@@ -36,9 +37,7 @@ namespace dolfin
   class Mesh;
   class BoundaryMesh;
   class BoundingBoxTree;
-
-  /// Typedefs
-  typedef std::pair<std::vector<double>, std::vector<double> > quadrature_rule;
+  class SimplexQuadrature;
 
   /// This class represents a collection of meshes with arbitrary
   /// overlaps. A multimesh may be created from a set of standard
@@ -50,6 +49,18 @@ namespace dolfin
   {
   public:
 
+    /// Structure storing a quadrature rule
+    typedef std::pair<std::vector<double>, std::vector<double> > quadrature_rule;
+
+    /// A simplex is a list of points
+    typedef std::vector<Point> Simplex;
+
+    /// A polyhedron is a list of simplices
+    typedef std::vector<Simplex> Polyhedron;
+
+    /// Key to identify polyhedra
+    typedef std::vector<std::size_t> IncExcKey;
+
     /// Create empty multimesh
     MultiMesh();
 
@@ -125,7 +136,7 @@ namespace dolfin
     /// *Returns*
     ///     std::vector<unsigned int>
     ///         List of cut cell indices for given part
-    const std::vector<unsigned int>& cut_cells(std::size_t part) const;
+    const std::vector<unsigned int> cut_cells(std::size_t part) const;
 
     /// Return the list of covered cells for given part. The covered
     /// cells are defined as all cells that collide with the domain of
@@ -170,7 +181,7 @@ namespace dolfin
     ///         of a flattened array of quadrature points and a
     ///         corresponding array of quadrature weights.
     const std::map<unsigned int, quadrature_rule >&
-    quadrature_rule_cut_cells(std::size_t part) const;
+    quadrature_rules_cut_cells(std::size_t part) const;
 
     /// Return quadrature rule for a given cut cell on the given part
     ///
@@ -186,12 +197,8 @@ namespace dolfin
     ///         array of quadrature points and a corresponding array
     ///         of quadrature weights. An error is raised if the given
     ///         cell is not in the map.
-    ///
-    /// Developer note: this function is mainly useful from Python and
-    /// could be replaced by a suitable typemap that would make the
-    /// previous more general function accessible from Python.
-    quadrature_rule
-    quadrature_rule_cut_cell(std::size_t part, unsigned int cell_index) const;
+    const quadrature_rule
+    quadrature_rules_cut_cells(std::size_t part, unsigned int cell_index) const;
 
     /// Return quadrature rules for the overlap on the given part.
     ///
@@ -200,7 +207,7 @@ namespace dolfin
     ///         The part number
     ///
     /// *Returns*
-    ///     std::map<unsigned int, std::pair<std::vector<double>, std::vector<double> > >
+    ///     std::map<unsigned int, std::vector<std::pair<std::vector<double>, std::vector<double> > > >
     ///         A map from cell indices of cut cells to quadrature
     ///         rules.  A separate quadrature rule is given for each
     ///         cutting cell and stored in the same order as in the
@@ -208,7 +215,28 @@ namespace dolfin
     ///         a pair of an array of quadrature points and a
     ///         corresponding flattened array of quadrature weights.
     const std::map<unsigned int, std::vector<quadrature_rule> >&
-    quadrature_rule_overlap(std::size_t part) const;
+    quadrature_rules_overlap(std::size_t part) const;
+
+    /// Return quadrature rules for the overlap for a given cell
+    /// on the given part.
+    ///
+    /// *Arguments*
+    ///     part (std::size_t)
+    ///         The part number
+    //      cell (unsigned int)
+    //          The cell index
+    ///
+    /// *Returns*
+    ///     std::vector<std::pair<std::vector<double>, std::vector<double> > >
+    ///         A vector of quadrature rules on the cut cell. A separate
+    ///         quadrature rule is given for each cutting cell and stored
+    ///         in the same order as in the collision map.
+    ///         A quadrature rule represented as a pair of a flattened
+    ///         array of quadrature points and a corresponding array
+    ///         of quadrature weights. An error is raised if the given
+    ///         cell is not in the map.
+    const std::vector<quadrature_rule>
+    quadrature_rules_overlap(std::size_t part, unsigned int cell) const;
 
     /// Return quadrature rules for the interface on the given part
     ///
@@ -217,7 +245,7 @@ namespace dolfin
     ///         The part number
     ///
     /// *Returns*
-    ///     std::map<unsigned int, std::pair<std::vector<double>, std::vector<double> > >
+    ///     std::map<unsigned int, std::vector<std::pair<std::vector<double>, std::vector<double> > > >
     ///         A map from cell indices of cut cells to quadrature
     ///         rules on an interface part cutting through the cell.
     ///         A separate quadrature rule is given for each cutting
@@ -226,7 +254,35 @@ namespace dolfin
     ///         an array of quadrature points and a corresponding
     ///         flattened array of quadrature weights.
     const std::map<unsigned int, std::vector<quadrature_rule> >&
-    quadrature_rule_interface(std::size_t part) const;
+    quadrature_rules_interface(std::size_t part) const;
+
+
+    /// Return quadrature rules for the interface of a given cut cell
+    /// on the given part
+    ///
+    /// *Arguments*
+    ///     part (std::size_t)
+    ///         The part number
+    ///     cell (unsigned int)
+    ///         The cell index
+    ///
+    /// *Returns*
+    ///     std::vector<std::pair<std::vector<double>, std::vector<double> > >
+    ///         A vector of quadrature rules on the cut cell. A separate
+    ///         quadrature rule is given for each cutting cell and stored
+    ///         in the same order as in the collision map.
+    ///         Each quadrature rule represented as a pair of a flattened
+    ///         array of quadrature points and a corresponding array
+    ///         of quadrature weights. An error is raised if the given
+    ///         cell is not in the map.
+    ///
+    /// Developer note: this function is mainly useful from Python and
+    /// could be replaced by a suitable typemap that would make the
+    /// previous more general function accessible from Python.
+    const std::vector<quadrature_rule>
+    quadrature_rules_interface(std::size_t part,
+			       unsigned int cell_index) const;
+
 
     /// Return facet normals for the interface on the given part
     ///
@@ -283,11 +339,44 @@ namespace dolfin
     /// Build multimesh
     void build(std::size_t quadrature_order=2);
 
+    /// Check whether multimesh has been built
+    bool is_built() const { return _is_built; }
+
     /// Clear multimesh
     void clear();
 
+    /// Default parameter values
+    static Parameters default_parameters()
+    {
+      Parameters p("multimesh");
+
+      //p.add("quadrature_order", 1);
+      p.add("compress_volume_quadrature", false);
+      p.add("compress_interface_quadrature", false);
+
+      return p;
+    }
+
+    //--- The functions below are mainly useful for testing/debugging ---
+
+    /// Compute total interface area or the total volume of multimesh
+    /// by summing up quadrature weights.  If the area or volume of
+    /// the domain mesh is known, this is a good test to verify that
+    /// the mesh-mesh intersections and quadrature are correct.
+    double compute_area() const;
+
+    /// Corresponding function for volume
+    double compute_volume() const;
+
+    /// Create matplotlib string to plot 2D multimesh (small meshes only)
+    std::string plot_matplotlib(double delta_z=1,
+				const std::string& filename="") const;
+
   private:
 
+    // Flag for whether multimesh has been built
+    bool _is_built;
+
     // List of meshes
     std::vector<std::shared_ptr<const Mesh> > _meshes;
 
@@ -311,17 +400,6 @@ namespace dolfin
     //     j = the cell number (in the list of uncut cells)
     std::vector<std::vector<unsigned int> > _uncut_cells;
 
-    // Cell indices for all cut cells for all parts. Access data by
-    //
-    //     c = _cut_cells[i][j]
-    //
-    // where
-    //
-    //     c = cell index for a cut cell
-    //     i = the part (mesh) number
-    //     j = the cell number (in the list of cut cells)
-    std::vector<std::vector<unsigned int> > _cut_cells;
-
     // Cell indices for all covered cells for all parts. Access data by
     //
     //     c = _covered_cells[i][j]
@@ -437,15 +515,23 @@ namespace dolfin
     // Build quadrature rules for the overlap
     void _build_quadrature_rules_overlap(std::size_t quadrature_order);
 
-    // Add quadrature rule for simplices in the triangulation
-    // array. Returns the number of points generated for each simplex.
-    std::vector<std::size_t>
-    _add_quadrature_rule(quadrature_rule& qr,
-                         const std::vector<double>& triangulation,
-                         std::size_t tdim,
-                         std::size_t gdim,
-                         std::size_t quadrature_order,
-                         double factor) const;
+    // Build quadrature rules and normals for the interface
+    void _build_quadrature_rules_interface(std::size_t quadrature_order);
+
+    // Help function to determine if interface intersection is
+    // (exactly) overlapped by a cutting cell
+    bool _is_overlapped_interface(std::vector<Point> simplex,
+				  const Cell cut_cell,
+				  Point simplex_normal) const;
+
+    // Add quadrature rule for simplices in polyhedron. Returns the
+    // number of points generated for each simplex.
+    std::size_t _add_quadrature_rule(quadrature_rule& qr,
+				     const SimplexQuadrature& sq,
+				     const Simplex& simplex,
+				     std::size_t gdim,
+				     std::size_t quadrature_order,
+				     double factor) const;
 
     // Add quadrature rule to existing quadrature rule (append dqr to
     // qr). Returns number of points added.
@@ -457,10 +543,50 @@ namespace dolfin
     // Append normal to list of normals npts times
     void _add_normal(std::vector<double>& normals,
                      const Point& normal,
-                     const std::size_t npts,
-                     const std::size_t gdim) const;
+                     std::size_t npts,
+                     std::size_t gdim) const;
+
+    // Plot multimesh
+    void _plot() const;
+
+    // Inclusion-exclusion for overlap
+    void _inclusion_exclusion_overlap
+      (std::vector<quadrature_rule>& qr,
+       const SimplexQuadrature& sq,
+       const std::vector<std::pair<std::size_t, Polyhedron> >& initial_polyhedra,
+       std::size_t tdim,
+       std::size_t gdim,
+       std::size_t quadrature_order) const;
+
+    // Inclusion-exclusion for interface
+    void _inclusion_exclusion_interface
+      (quadrature_rule& qr,
+       std::vector<double>& normals,
+       const SimplexQuadrature& sq,
+       const Simplex& Eij,
+       const Point& facet_normal,
+       const std::vector<std::pair<std::size_t, Polyhedron> >& initial_polygons,
+       std::size_t tdim,
+       std::size_t gdim,
+       std::size_t quadrature_order) const;
+
+    // Construct and return mapping from boundary facets to full mesh
+    std::vector<std::vector<std::pair<std::size_t, std::size_t> > >
+      _boundary_facets_to_full_mesh(std::size_t part) const;
+
+    // Impose consistency of _cut_cells, so that only the cells with
+    // a nontrivial interface quadrature rule are classified as cut.
+    void _impose_cut_cell_consistency();
+
+    // Remove quadrature rule if the sum of the weights is less than a
+    // tolerance
+    static void remove_quadrature_rule(quadrature_rule& qr,
+				       double tolerance);
   };
 
+
+
 }
 
+
 #endif
diff --git a/dolfin/mesh/PointCell.cpp b/dolfin/mesh/PointCell.cpp
index 1c3441b..1449efd 100644
--- a/dolfin/mesh/PointCell.cpp
+++ b/dolfin/mesh/PointCell.cpp
@@ -20,9 +20,10 @@
 // Modified by August Johansson 2014
 //
 // First added:  2007-12-12
-// Last changed: 2014-02-13
+// Last changed: 2016-05-05
 
 #include <dolfin/log/log.h>
+#include <dolfin/geometry/CollisionPredicates.h>
 #include "Cell.h"
 #include "Facet.h"
 #include "MeshEditor.h"
@@ -154,24 +155,12 @@ void PointCell::order(
 //-----------------------------------------------------------------------------
 bool PointCell::collides(const Cell& cell, const Point& point) const
 {
-  return CollisionDetection::collides(cell, point);
+  return CollisionPredicates::collides(cell, point);
 }
 //-----------------------------------------------------------------------------
 bool PointCell::collides(const Cell& cell, const MeshEntity& entity) const
 {
-  return CollisionDetection::collides(cell, entity);
-}
-//-----------------------------------------------------------------------------
-std::vector<double>
-PointCell::triangulate_intersection(const Cell& c0, const Cell& c1) const
-{
-  return IntersectionTriangulation::triangulate_intersection(c0, c1);
-}
-//-----------------------------------------------------------------------------
-std::vector<double>
-PointCell::triangulate_intersection(const Cell& cell, const MeshEntity& entity) const
-{
-  return IntersectionTriangulation::triangulate_intersection(cell, entity);
+  return CollisionPredicates::collides(cell, entity);
 }
 //-----------------------------------------------------------------------------
 std::string PointCell::description(bool plural) const
diff --git a/dolfin/mesh/PointCell.h b/dolfin/mesh/PointCell.h
index b27a52b..2e68b98 100644
--- a/dolfin/mesh/PointCell.h
+++ b/dolfin/mesh/PointCell.h
@@ -19,25 +19,30 @@
 // Modified by Kristoffer Selim 2008
 //
 // First added:  2007-12-12
-// Last changed: 2014-01-06
+// Last changed: 2016-05-05
 
 #ifndef __POINT_CELL_H
 #define __POINT_CELL_H
 
+#include <vector>
 #include <boost/multi_array.hpp>
 #include "CellType.h"
 
 namespace dolfin
 {
 
-  /// This class implements functionality for triangular meshes.
+  /// This class implements functionality for point cell meshes.
 
   class PointCell : public CellType
   {
   public:
 
     /// Specify cell type and facet type
-    PointCell() : CellType(point, point) {}
+    PointCell() : CellType(Type::point, Type::point) {}
+
+    /// Check if cell is a simplex
+    bool is_simplex() const
+    { return true; }
 
     /// Return topological dimension of cell
     std::size_t dim() const;
@@ -92,14 +97,6 @@ namespace dolfin
     /// Check whether given entity collides with cell
     bool collides(const Cell& cell, const MeshEntity& entity) const;
 
-    /// Compute triangulation of intersection of two cells
-    virtual std::vector<double>
-    triangulate_intersection(const Cell& c0, const Cell& c1) const;
-
-    /// Compute triangulation of intersection with given entity
-    virtual std::vector<double>
-    triangulate_intersection(const Cell& cell, const MeshEntity& entity) const;
-
     /// Return description of cell type
     std::string description(bool plural) const;
 
diff --git a/dolfin/mesh/QuadrilateralCell.cpp b/dolfin/mesh/QuadrilateralCell.cpp
index 39bb526..dc03685 100644
--- a/dolfin/mesh/QuadrilateralCell.cpp
+++ b/dolfin/mesh/QuadrilateralCell.cpp
@@ -288,20 +288,6 @@ bool QuadrilateralCell::collides(const Cell& cell, const MeshEntity& entity) con
   return false;
 }
 //-----------------------------------------------------------------------------
-std::vector<double>
-QuadrilateralCell::triangulate_intersection(const Cell& c0, const Cell& c1) const
-{
-  dolfin_not_implemented();
-  return std::vector<double>();
-}
-//-----------------------------------------------------------------------------
-std::vector<double>
-QuadrilateralCell::triangulate_intersection(const Cell& cell, const MeshEntity& entity) const
-{
-  dolfin_not_implemented();
-  return std::vector<double>();
-}
-//-----------------------------------------------------------------------------
 std::string QuadrilateralCell::description(bool plural) const
 {
   if (plural)
diff --git a/dolfin/mesh/QuadrilateralCell.h b/dolfin/mesh/QuadrilateralCell.h
index 8a2f5ad..52fb7b7 100644
--- a/dolfin/mesh/QuadrilateralCell.h
+++ b/dolfin/mesh/QuadrilateralCell.h
@@ -14,7 +14,6 @@
 //
 // You should have received a copy of the GNU Lesser General Public License
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
-//
 
 #ifndef __QUADRILATERAL_CELL_H
 #define __QUADRILATERAL_CELL_H
@@ -25,14 +24,18 @@
 namespace dolfin
 {
 
-  /// This class implements functionality for triangular meshes.
+  /// This class implements functionality for quadrilaterial cells.
 
   class QuadrilateralCell : public CellType
   {
   public:
 
     /// Specify cell type and facet type
-    QuadrilateralCell() : CellType(quadrilateral, interval) {}
+    QuadrilateralCell() : CellType(Type::quadrilateral, Type::interval) {}
+
+    /// Check if cell is a simplex
+    bool is_simplex() const
+    { return false; }
 
     /// Return topological dimension of cell
     std::size_t dim() const;
@@ -82,14 +85,6 @@ namespace dolfin
     /// Check whether given entity collides with cell
     bool collides(const Cell& cell, const MeshEntity& entity) const;
 
-    /// Compute triangulation of intersection of two cells
-    std::vector<double>
-    triangulate_intersection(const Cell& c0, const Cell& c1) const;
-
-    /// Compute triangulation of intersection with given entity
-    std::vector<double>
-    triangulate_intersection(const Cell& cell, const MeshEntity& entity) const;
-
     /// Return description of cell type
     std::string description(bool plural) const;
 
diff --git a/dolfin/mesh/TetrahedronCell.cpp b/dolfin/mesh/TetrahedronCell.cpp
index 58d0e14..4bc192c 100644
--- a/dolfin/mesh/TetrahedronCell.cpp
+++ b/dolfin/mesh/TetrahedronCell.cpp
@@ -22,13 +22,14 @@
 // Modified by August Johansson 2014
 //
 // First added:  2006-06-05
-// Last changed: 2014-02-13
+// Last changed: 2016-05-05
 
 #include <algorithm>
 #include <cmath>
 #include <boost/multi_array.hpp>
 
 #include <dolfin/log/log.h>
+#include <dolfin/geometry/CollisionPredicates.h>
 #include "Cell.h"
 #include "Facet.h"
 #include "MeshEditor.h"
@@ -528,24 +529,12 @@ void TetrahedronCell::order(
 //-----------------------------------------------------------------------------
 bool TetrahedronCell::collides(const Cell& cell, const Point& point) const
 {
-  return CollisionDetection::collides(cell, point);
+  return CollisionPredicates::collides(cell, point);
 }
 //-----------------------------------------------------------------------------
 bool TetrahedronCell::collides(const Cell& cell, const MeshEntity& entity) const
 {
-  return CollisionDetection::collides(cell, entity);
-}
-//-----------------------------------------------------------------------------
-std::vector<double>
-TetrahedronCell::triangulate_intersection(const Cell& c0, const Cell& c1) const
-{
-  return IntersectionTriangulation::triangulate_intersection(c0, c1);
-}
-//-----------------------------------------------------------------------------
-std::vector<double>
-TetrahedronCell::triangulate_intersection(const Cell& cell, const MeshEntity& entity) const
-{
-  return IntersectionTriangulation::triangulate_intersection(cell, entity);
+  return CollisionPredicates::collides(cell, entity);
 }
 //-----------------------------------------------------------------------------
 std::string TetrahedronCell::description(bool plural) const
diff --git a/dolfin/mesh/TetrahedronCell.h b/dolfin/mesh/TetrahedronCell.h
index 0ff2fbb..04acda3 100644
--- a/dolfin/mesh/TetrahedronCell.h
+++ b/dolfin/mesh/TetrahedronCell.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2006-2013 Anders Logg
+// Copyright (C) 2006-2017 Anders Logg
 //
 // This file is part of DOLFIN.
 //
@@ -20,7 +20,7 @@
 // Modified by Kristoffer Selim, 2008.
 //
 // First added:  2006-06-05
-// Last changed: 2014-01-31
+// Last changed: 2017-09-26
 
 #ifndef __TETRAHEDRON_CELL_H
 #define __TETRAHEDRON_CELL_H
@@ -35,14 +35,18 @@ namespace dolfin
 
   class Cell;
 
-  /// This class implements functionality for tetrahedral meshes.
+  /// This class implements functionality for tetrahedral cell meshes.
 
   class TetrahedronCell : public CellType
   {
   public:
 
     /// Specify cell type and facet type
-    TetrahedronCell() : CellType(tetrahedron, triangle) {}
+    TetrahedronCell() : CellType(Type::tetrahedron, Type::triangle) {}
+
+    /// Check if cell is a simplex
+    bool is_simplex() const
+    { return true; }
 
     /// Return topological dimension of cell
     std::size_t dim() const;
@@ -92,14 +96,6 @@ namespace dolfin
     /// Check whether given entity collides with cell
     bool collides(const Cell& cell, const MeshEntity& entity) const;
 
-    /// Compute triangulation of intersection of two cells
-    virtual std::vector<double>
-    triangulate_intersection(const Cell& c0, const Cell& c1) const;
-
-    /// Compute triangulation of intersection with given entity
-    virtual std::vector<double>
-    triangulate_intersection(const Cell& cell, const MeshEntity& entity) const;
-
     /// Return description of cell type
     std::string description(bool plural) const;
 
diff --git a/dolfin/mesh/TopologyComputation.cpp b/dolfin/mesh/TopologyComputation.cpp
index 277e233..39b9c27 100644
--- a/dolfin/mesh/TopologyComputation.cpp
+++ b/dolfin/mesh/TopologyComputation.cpp
@@ -383,12 +383,12 @@ void TopologyComputation::compute_from_map(Mesh& mesh,
                                                        .entity_type(d0)));
 
   MeshConnectivity& connectivity = mesh.topology()(d0, d1);
-  connectivity.init(mesh.size(d0), cell_type->num_entities(d1));
+  connectivity.init(mesh.num_entities(d0), cell_type->num_entities(d1));
 
   // Make a map from the sorted d1 entity vertices to the d1 entity index
   boost::unordered_map<std::vector<unsigned int>, unsigned int>
     entity_to_index;
-  entity_to_index.reserve(mesh.size(d1));
+  entity_to_index.reserve(mesh.num_entities(d1));
 
   const std::size_t num_verts_d1 = mesh.type().num_vertices(d1);
   std::vector<unsigned int> key(num_verts_d1);
diff --git a/dolfin/mesh/TriangleCell.cpp b/dolfin/mesh/TriangleCell.cpp
index 987f9a7..c22f213 100644
--- a/dolfin/mesh/TriangleCell.cpp
+++ b/dolfin/mesh/TriangleCell.cpp
@@ -23,11 +23,12 @@
 // Modified by August Johansson 2014
 //
 // First added:  2006-06-05
-// Last changed: 2014-05-22
+// Last changed: 2016-05-05
 
 #include <algorithm>
 #include <cmath>
 #include <dolfin/log/log.h>
+#include <dolfin/geometry/CollisionPredicates.h>
 #include "Cell.h"
 #include "MeshEditor.h"
 #include "MeshEntity.h"
@@ -449,24 +450,12 @@ void TriangleCell::order(
 //-----------------------------------------------------------------------------
 bool TriangleCell::collides(const Cell& cell, const Point& point) const
 {
-  return CollisionDetection::collides(cell, point);
+  return CollisionPredicates::collides(cell, point);
 }
 //-----------------------------------------------------------------------------
 bool TriangleCell::collides(const Cell& cell, const MeshEntity& entity) const
 {
-  return CollisionDetection::collides(cell, entity);
-}
-//-----------------------------------------------------------------------------
-std::vector<double>
-TriangleCell::triangulate_intersection(const Cell& c0, const Cell& c1) const
-{
-  return IntersectionTriangulation::triangulate_intersection(c0, c1);
-}
-//-----------------------------------------------------------------------------
-std::vector<double>
-TriangleCell::triangulate_intersection(const Cell& cell, const MeshEntity& entity) const
-{
-  return IntersectionTriangulation::triangulate_intersection(cell, entity);
+  return CollisionPredicates::collides(cell, entity);
 }
 //-----------------------------------------------------------------------------
 std::string TriangleCell::description(bool plural) const
diff --git a/dolfin/mesh/TriangleCell.h b/dolfin/mesh/TriangleCell.h
index 57412ca..29879e8 100644
--- a/dolfin/mesh/TriangleCell.h
+++ b/dolfin/mesh/TriangleCell.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2006-2013 Anders Logg
+// Copyright (C) 2006-2017 Anders Logg
 //
 // This file is part of DOLFIN.
 //
@@ -19,7 +19,7 @@
 // Modified by Jan Blechta 2013
 //
 // First added:  2006-06-05
-// Last changed: 2014-05-22
+// Last changed: 2017-09-26
 
 #ifndef __TRIANGLE_CELL_H
 #define __TRIANGLE_CELL_H
@@ -38,7 +38,11 @@ namespace dolfin
   public:
 
     /// Specify cell type and facet type
-    TriangleCell() : CellType(triangle, interval) {}
+    TriangleCell() : CellType(Type::triangle, Type::interval) {}
+
+    /// Check if cell is a simplex
+    bool is_simplex() const
+    { return true; }
 
     /// Return topological dimension of cell
     std::size_t dim() const;
@@ -97,14 +101,6 @@ namespace dolfin
     /// Check whether given entity collides with cell
     bool collides(const Cell& cell, const MeshEntity& entity) const;
 
-    /// Compute triangulation of intersection of two cells
-    std::vector<double>
-    triangulate_intersection(const Cell& c0, const Cell& c1) const;
-
-    /// Compute triangulation of intersection with given entity
-    std::vector<double>
-    triangulate_intersection(const Cell& cell, const MeshEntity& entity) const;
-
     /// Return description of cell type
     std::string description(bool plural) const;
 
diff --git a/dolfin/mesh/Vertex.h b/dolfin/mesh/Vertex.h
index e5befb7..f040a7b 100644
--- a/dolfin/mesh/Vertex.h
+++ b/dolfin/mesh/Vertex.h
@@ -71,11 +71,19 @@ namespace dolfin
 
     /// Constructor on Mesh
     VertexFunction(std::shared_ptr<const Mesh> mesh)
-      : MeshFunction<T>(mesh, 0) {}
+      : MeshFunction<T>(mesh, 0) {
+        deprecation("VertexFunction<T>(mesh)",
+                    "2017.2.0",
+                    "Use MeshFunction<T>(mesh, 0)");
+      }
 
     /// Constructor on Mesh and value
     VertexFunction(std::shared_ptr<const Mesh> mesh, const T& value)
-      : MeshFunction<T>(mesh, 0, value) {}
+      : MeshFunction<T>(mesh, 0, value) {
+        deprecation("VertexFunction<T>(mesh, value)",
+                    "2017.2.0",
+                    "Use MeshFunction<T>(mesh, 0, value)");
+      }
 
   };
 
diff --git a/dolfin/refinement/BisectionRefinement1D.cpp b/dolfin/refinement/BisectionRefinement1D.cpp
index ea24dc7..63fe635 100644
--- a/dolfin/refinement/BisectionRefinement1D.cpp
+++ b/dolfin/refinement/BisectionRefinement1D.cpp
@@ -99,7 +99,7 @@ void BisectionRefinement1D::refine(Mesh& refined_mesh,
                                    const Mesh& mesh, bool redistribute)
 {
   auto _mesh = reference_to_no_delete_pointer(mesh);
-  const CellFunction<bool> cell_markers(_mesh, true);
+  const MeshFunction<bool> cell_markers(_mesh, _mesh->topology().dim(), true);
   BisectionRefinement1D::refine(refined_mesh, mesh, cell_markers, redistribute);
 }
 //-----------------------------------------------------------------------------
diff --git a/dolfin/refinement/LocalMeshCoarsening.cpp b/dolfin/refinement/LocalMeshCoarsening.cpp
index c0bdae7..9becf1f 100644
--- a/dolfin/refinement/LocalMeshCoarsening.cpp
+++ b/dolfin/refinement/LocalMeshCoarsening.cpp
@@ -49,15 +49,16 @@ void LocalMeshCoarsening::coarsen_mesh_by_edge_collapse(Mesh& mesh,
   log(TRACE, "Coarsen simplicial mesh by edge collapse.");
 
   // Get size of old mesh
-  //const std::size_t num_vertices = mesh.size(0);
-  const std::size_t num_cells = mesh.size(mesh.topology().dim());
+  const std::size_t num_cells = mesh.num_entities(mesh.topology().dim());
 
   // Check cell marker
   if ( cell_marker.size() != num_cells )
+  {
     dolfin_error("LocalMeshCoarsening.cpp",
                  "coarsen mesh by collapsing edges",
                  "Number of cell markers (%d) does not match number of cells (%d)",
                  cell_marker.size(), num_cells);
+  }
 
   // Generate cell - edge connectivity if not generated
   mesh.init(mesh.topology().dim(), 1);
@@ -196,11 +197,8 @@ bool LocalMeshCoarsening::coarsen_cell(Mesh& mesh, Mesh& coarse_mesh,
 				      std::vector<int>& old2new_cell,
 				      bool coarsen_boundary)
 {
-  cout << "coarsen_cell: " << cellid << endl;
-  cout << "num_cells: " << mesh.num_cells() << endl;
-
-  const std::size_t num_vertices = mesh.size(0);
-  const std::size_t num_cells = mesh.size(mesh.topology().dim());
+  const std::size_t num_vertices = mesh.num_entities(0);
+  const std::size_t num_cells = mesh.num_entities(mesh.topology().dim());
 
   auto _mesh = reference_to_no_delete_pointer(mesh);
 
diff --git a/dolfin/refinement/ParallelRefinement.cpp b/dolfin/refinement/ParallelRefinement.cpp
index 5ac85c3..9930e9d 100644
--- a/dolfin/refinement/ParallelRefinement.cpp
+++ b/dolfin/refinement/ParallelRefinement.cpp
@@ -138,7 +138,7 @@ void ParallelRefinement::update_logical_edgefunction()
   // Clear marked_for_update vectors
   marked_for_update = std::vector<std::vector<std::size_t>>(mpi_size);
 
-  // Flatten received values and set EdgeFunction true at each index
+  // Flatten received values and set edges MeshFunction true at each index
   // received
   for (auto const &local_index : received_values)
       marked_edges[local_index] = true;
@@ -194,7 +194,7 @@ void ParallelRefinement::create_new_vertices()
   const std::size_t num_new_vertices = n;
   const std::size_t global_offset
     = MPI::global_offset(_mesh.mpi_comm(), num_new_vertices, true)
-    + _mesh.size_global(0);
+    + _mesh.num_entities_global(0);
 
   // If they are shared, then the new global vertex index needs to be
   // sent off-process.  Add offset to map, and collect up any shared
@@ -254,7 +254,15 @@ void ParallelRefinement::build_local(Mesh& new_mesh) const
   dolfin_assert(new_cell_topology.size()%num_cell_vertices == 0);
   const std::size_t num_cells = new_cell_topology.size()/num_cell_vertices;
 
-  ed.open(new_mesh, tdim, gdim);
+  CellType::Type cell_type;
+  if (tdim == 3)
+    cell_type = CellType::Type::tetrahedron;
+  else if (tdim == 2)
+    cell_type = CellType::Type::triangle;
+  else
+    cell_type = CellType::Type::interval;
+
+  ed.open(new_mesh, cell_type, tdim, gdim);
   ed.init_vertices(num_vertices);
   std::size_t i = 0;
   for (auto p = new_vertex_coordinates.begin();
diff --git a/dolfin/refinement/ParallelRefinement.h b/dolfin/refinement/ParallelRefinement.h
index db59156..a89171f 100644
--- a/dolfin/refinement/ParallelRefinement.h
+++ b/dolfin/refinement/ParallelRefinement.h
@@ -29,15 +29,15 @@ namespace dolfin
 
   // Forward declarations
   class Mesh;
-  template<typename T> class EdgeFunction;
   template<typename T> class MeshFunction;
 
   /// Data structure and methods for refining meshes in parallel
 
   /// ParallelRefinement encapsulates two main features:
-  /// a distributed EdgeFunction, which can be updated
-  /// across processes, and storage for local mesh data,
-  /// which can be used to construct the new Mesh
+  /// a distributed MeshFunction defined over the mesh edes, 
+  /// which can be updated across processes, 
+  /// and storage for local mesh data, which can be used 
+  /// to construct the new Mesh
 
   class ParallelRefinement
   {
diff --git a/dolfin/refinement/RegularCutRefinement.cpp b/dolfin/refinement/RegularCutRefinement.cpp
index 475f462..ce17f9f 100644
--- a/dolfin/refinement/RegularCutRefinement.cpp
+++ b/dolfin/refinement/RegularCutRefinement.cpp
@@ -260,7 +260,8 @@ void RegularCutRefinement::refine_marked(Mesh& refined_mesh,
   // Initialize mesh editor
   const std::size_t num_vertices = mesh.num_vertices() + marked_edges.size();
   MeshEditor editor;
-  editor.open(refined_mesh, mesh.topology().dim(), mesh.geometry().dim());
+  editor.open(refined_mesh, mesh.type().cell_type(),
+              mesh.topology().dim(), mesh.geometry().dim());
   editor.init_vertices_global(num_vertices, num_vertices);
   editor.init_cells_global(num_cells, num_cells);
 
diff --git a/dolfin/refinement/refine.cpp b/dolfin/refinement/refine.cpp
index 37c0d0d..263a581 100644
--- a/dolfin/refinement/refine.cpp
+++ b/dolfin/refinement/refine.cpp
@@ -71,8 +71,8 @@ void dolfin::refine(Mesh& refined_mesh, const Mesh& mesh, bool redistribute)
   }
 
   // Report the number of refined cells
-  const std::size_t n0 = mesh.size_global(D);
-  const std::size_t n1 = refined_mesh.size_global(D);
+  const std::size_t n0 = mesh.num_entities_global(D);
+  const std::size_t n1 = refined_mesh.num_entities_global(D);
   log(TRACE,  "Number of cells increased from %d to %d (%.1f%% increase).",
        n0, n1, 100.0 * (static_cast<double>(n1) / static_cast<double>(n0) - 1.0));
 
@@ -114,8 +114,8 @@ void dolfin::refine(Mesh& refined_mesh, const Mesh& mesh,
   }
 
   // Report the number of refined cells
-  const std::size_t n0 = mesh.size_global(D);
-  const std::size_t n1 = refined_mesh.size_global(D);
+  const std::size_t n0 = mesh.num_entities_global(D);
+  const std::size_t n1 = refined_mesh.num_entities_global(D);
   log(TRACE, "Number of cells increased from %d to %d (%.1f%% increase).",
       n0, n1, 100.0 * (static_cast<double>(n1) / static_cast<double>(n0) - 1.0));
 
@@ -138,9 +138,11 @@ void dolfin::p_refine(Mesh& refined_mesh, const Mesh& mesh)
                  "Currently only linear -> quadratic is supported");
   }
 
-  if (mesh.type().cell_type() != CellType::triangle
-      and mesh.type().cell_type() != CellType::tetrahedron
-      and mesh.type().cell_type() != CellType::interval)
+  const CellType::Type cell_type = mesh.type().cell_type();
+
+  if (cell_type != CellType::Type::triangle
+      and cell_type != CellType::Type::tetrahedron
+      and cell_type != CellType::Type::interval)
   {
     dolfin_error("refine.cpp",
                  "increase polynomial degree of mesh",
@@ -150,14 +152,14 @@ void dolfin::p_refine(Mesh& refined_mesh, const Mesh& mesh)
   const std::size_t tdim = mesh.topology().dim();
   const std::size_t gdim = mesh.geometry().dim();
 
-  editor.open(refined_mesh, tdim, gdim, 2);
+  editor.open(refined_mesh, cell_type, tdim, gdim, 2);
 
   // Copy over mesh
-  editor.init_vertices_global(mesh.size(0), mesh.size_global(0));
+  editor.init_vertices_global(mesh.num_entities(0), mesh.num_entities_global(0));
   for (VertexIterator v(mesh); !v.end(); ++v)
     editor.add_vertex(v->index(), v->point());
 
-  editor.init_cells_global(mesh.size(tdim), mesh.size_global(tdim));
+  editor.init_cells_global(mesh.num_entities(tdim), mesh.num_entities_global(tdim));
   std::vector<std::size_t> verts(tdim + 1);
   for (CellIterator c(mesh); !c.end(); ++c)
   {
diff --git a/dolfin/refinement/refine.h b/dolfin/refinement/refine.h
index 46506ca..ab3acbf 100644
--- a/dolfin/refinement/refine.h
+++ b/dolfin/refinement/refine.h
@@ -83,7 +83,7 @@ namespace dolfin
   ///         The locally refined mesh.
   ///
   /// @code{.cpp}
-  ///         CellFunction<bool> cell_markers(mesh);
+  ///         MeshFunction<bool> cell_markers(mesh, mesh->topology().dim());
   ///         cell_markers.set_all(false);
   ///         Point origin(0.0, 0.0, 0.0);
   ///         for (CellIterator cell(mesh); !cell.end(); ++cell)
diff --git a/dolfin/swig/la/post.i b/dolfin/swig/la/post.i
index 9230ea5..e8b6b71 100644
--- a/dolfin/swig/la/post.i
+++ b/dolfin/swig/la/post.i
@@ -149,6 +149,13 @@ def la_index_dtype():
 
     def array(self):
         "Return a numpy array representation of the local part of a Vector"
+        # Annoying deprecation warning that cannot be turned off, sorry! 
+        import warnings
+        with warnings.catch_warnings():
+            # Changes default warning filter inside this context manager only
+            warnings.simplefilter('always')
+            warnings.warn("GenericVector.array() is being deprecated, "
+                          "use GenericVector.get_local()", DeprecationWarning)
         return self.get_local()
 
     def __contains__(self, value):
@@ -349,10 +356,6 @@ def la_index_dtype():
     def __len__(self):
         return self.size()
 
-    def __iter__(self):
-        for i in range(self.size()):
-            yield self[i]
-
     def __add__(self, other):
         """x.__add__(y) <==> x+y"""
         from numpy import isscalar
@@ -466,7 +469,7 @@ def la_index_dtype():
         return NotImplemented
 
     def __iter__(self):
-        return iter(self.array())
+        return iter(self.get_local())
 
     import sys
     if sys.version_info[0] == 2:
diff --git a/dolfin/swig/mesh/post.i b/dolfin/swig/mesh/post.i
index 0bdf613..42928d6 100644
--- a/dolfin/swig/mesh/post.i
+++ b/dolfin/swig/mesh/post.i
@@ -500,6 +500,48 @@ def ufl_domain(self):
 }
 
 //-----------------------------------------------------------------------------
+// Extend MultiMesh interface with some ufl_* methods
+//-----------------------------------------------------------------------------
+%extend dolfin::MultiMesh
+{
+%pythoncode
+%{
+def ufl_id(self):
+    "Returns an id that UFL can use to decide if two objects are the same."
+    return self.id()
+
+def mpi_comm(self):
+    return self.part(0).mpi_comm()
+
+def type(self):
+    return self.part(0).type()
+
+def ufl_cell(self):
+    """Returns the ufl cell of the mesh."""
+    import ufl
+    gdim = self.part(0).geometry().dim()
+    cellname = self.type().description(False)
+    return ufl.Cell(cellname, geometric_dimension=gdim)
+
+def ufl_coordinate_element(self):
+    "Return the finite element of the coordinate vector field of this domain."
+    import ufl
+    cell = self.ufl_cell()
+    degree = self.part(0).geometry().degree()
+    return ufl.VectorElement("Lagrange", cell, degree, dim=cell.geometric_dimension())
+
+def ufl_domain(self):
+    """Returns the ufl domain corresponding to the mesh."""
+    import ufl
+    # Cache object to avoid recreating it a lot
+    if not hasattr(self, "_ufl_domain"):
+        self._ufl_domain = ufl.Mesh(self.ufl_coordinate_element(), ufl_id=self.ufl_id(), cargo=self)
+    return self._ufl_domain
+%}
+}
+
+
+//-----------------------------------------------------------------------------
 // Modifying the interface of Hierarchical
 //-----------------------------------------------------------------------------
 %pythoncode %{
diff --git a/dolfin/swig/mesh/pre.i b/dolfin/swig/mesh/pre.i
index 47c3e97..b2bb413 100644
--- a/dolfin/swig/mesh/pre.i
+++ b/dolfin/swig/mesh/pre.i
@@ -352,3 +352,94 @@ FORWARD_DECLARE_MESHFUNCTIONS(std::size_t, Sizet)
 %ignore dolfin::MeshPartitioning::build_distributed_mesh(Mesh&, const std::vector<std::size_t>&);
 %ignore dolfin::MeshPartitioning::build_distributed_mesh(Mesh&, const LocalMeshData&);
 %ignore dolfin::MeshPartitioning::build_distributed_value_collection;
+
+//-----------------------------------------------------------------------------
+// Ignores for MultiMesh
+//-----------------------------------------------------------------------------
+%ignore dolfin::plot(const MultiMesh&);
+%ignore dolfin::plot(std::shared_ptr<const MultiMesh>);
+
+//-----------------------------------------------------------------------------
+// Add typemap functions for MultiMesh quadrature rules
+//-----------------------------------------------------------------------------
+typedef std::pair<std::vector<double>, std::vector<double> > quadrature_rule;
+%{
+typedef std::pair<std::vector<double>, std::vector<double> > quadrature_rule;
+%}
+%fragment("convert_dolfin_quadrature_rule", "header"){ 
+SWIGINTERNINLINE PyObject * convert_dolfin_quadrature_rule(quadrature_rule qr)
+{
+  // Typemap Function for dolfin::quadrature_rule 
+  npy_intp n0 = qr.first.size();
+  npy_intp n1 = qr.second.size();
+
+  PyArrayObject *x0 = reinterpret_cast<PyArrayObject*>(PyArray_SimpleNew(1, &n0, NPY_DOUBLE));
+  PyArrayObject *x1 = reinterpret_cast<PyArrayObject*>(PyArray_SimpleNew(1, &n1, NPY_DOUBLE));
+
+  double* data0 = static_cast<double*>(PyArray_DATA(x0));
+  double* data1 = static_cast<double*>(PyArray_DATA(x1));
+
+  std::copy(qr.first.begin(),  qr.first.end(),  data0);
+  std::copy(qr.second.begin(), qr.second.end(), data1);
+
+  PyObject * result;
+  result = Py_BuildValue("OO", x0, x1);
+  return result;
+}
+}
+%fragment("convert_dolfin_quadrature_rule_vector", "header"){
+SWIGINTERNINLINE PyObject * convert_dolfin_quadrature_rule(std::vector<quadrature_rule> qr_vector)
+{
+  // Typemap function for std::vec<quadrature_rule>
+  PyObject * result = PyList_New(qr_vector.size());
+  for (std::size_t j = 0; j < qr_vector.size(); j++)
+  {
+     PyObject * py_qr_j = convert_dolfin_quadrature_rule(qr_vector[j]);
+     PyList_SetItem(result, j, py_qr_j);
+  }
+  return result;
+}
+}
+// Force fragments to be instantiated
+%fragment("convert_dolfin_quadrature_rule");
+%fragment("convert_dolfin_quadrature_rule_vector");
+//-----------------------------------------------------------------------------
+// Modifying MultiMesh interface
+//-----------------------------------------------------------------------------
+%define EXTEND_MULTIMESH_QUADRATURE_RULE(cell_type)
+
+%extend dolfin::MultiMesh
+{
+PyObject* quadrature_rules_##cell_type(std::size_t part)
+{
+  PyObject* ret = PyDict_New();
+  auto qr_map = ($self)->quadrature_rules_##cell_type (part);
+  
+  for (auto it = qr_map.begin(); it != qr_map.end(); it++)
+  {
+    PyObject* key = SWIG_From_dec(unsigned int)(it->first);
+    PyObject* val  = convert_dolfin_quadrature_rule(it->second);
+    if (val != Py_None)
+      PyDict_SetItem(ret, key,  val);
+    Py_XDECREF(key);
+    Py_XDECREF(val);
+  }
+  return ret;
+}
+PyObject* quadrature_rules_##cell_type(std::size_t part, unsigned int cell)
+{
+  auto qr_map = ($self)->quadrature_rules_##cell_type(part);
+  auto qr = qr_map[cell];
+  return convert_dolfin_quadrature_rule(qr);
+}
+}
+%ignore dolfin::MultiMesh::quadrature_rules_##cell_type;
+dolfin::MultiMesh::quadrature_rules_##cell_type(std::size_t part);
+
+
+%enddef
+
+EXTEND_MULTIMESH_QUADRATURE_RULE(cut_cells)
+EXTEND_MULTIMESH_QUADRATURE_RULE(interface)
+EXTEND_MULTIMESH_QUADRATURE_RULE(overlap)
+
diff --git a/dolfin/swig/shared_ptr_classes.i b/dolfin/swig/shared_ptr_classes.i
index c347ab5..f63ea48 100644
--- a/dolfin/swig/shared_ptr_classes.i
+++ b/dolfin/swig/shared_ptr_classes.i
@@ -113,6 +113,7 @@
 %shared_ptr(dolfin::Hierarchical<dolfin::Mesh>)
 %shared_ptr(dolfin::BoundaryMesh)
 %shared_ptr(dolfin::Mesh)
+%shared_ptr(dolfin::MeshTopology)
 %shared_ptr(dolfin::SubMesh)
 %shared_ptr(dolfin::UnitTetrahedronMesh)
 %shared_ptr(dolfin::UnitCubeMesh)
diff --git a/dolfin/swig/typemaps/std_map.i b/dolfin/swig/typemaps/std_map.i
index d9f22a1..60626d2 100644
--- a/dolfin/swig/typemaps/std_map.i
+++ b/dolfin/swig/typemaps/std_map.i
@@ -243,3 +243,30 @@ MAP_OUT_TYPEMAPS(int, unsigned int, uint, NPY_UINT)
   // Append the output to $result
   %append_output(ret);
 }
+
+
+// Add 'out' typemap for cut cell collisions (std::map<uint, std::vector<std::pair<size_t, uint>>>)
+%typemap(out) const std::map<unsigned int, std::vector<std::pair<std::size_t, unsigned int> > >& \
+  (std::map<unsigned int, std::vector<std::pair<std::size_t, unsigned int> > >::const_iterator it,
+   std::vector<std::pair<std::size_t, unsigned int> >::const_iterator jt,
+   PyObject* item0, PyObject* item1, PyObject* item2)
+{
+  $result = PyDict_New();
+  int size;
+  for (it=$1->begin(); it!=$1->end(); ++it)
+  {
+    item0 = SWIG_From_dec(unsigned int)(it->first);
+    item1 = PyList_New(it->second.size());
+
+    int j = 0;
+    for (jt = it->second.begin(); jt!= it->second.end(); jt++, j++)
+    {
+      item2 = Py_BuildValue("ii", (*jt).first, (*jt).second);
+      PyList_SetItem(item1, j, item2);
+    }
+    PyDict_SetItem($result, item0, item1);
+    Py_XDECREF(item0);
+    Py_XDECREF(item1);
+  }
+}
+
diff --git a/dolfin/swig/typemaps/std_vector.i b/dolfin/swig/typemaps/std_vector.i
index 0f79e36..210eaba 100644
--- a/dolfin/swig/typemaps/std_vector.i
+++ b/dolfin/swig/typemaps/std_vector.i
@@ -471,6 +471,24 @@ const std::vector<TYPE>&  ARG_NAME
 }
 %enddef
 
+%define OUT_TYPEMAP_STD_VECTOR_OF_SMALL_DOLFIN_TYPES(TYPE)
+%typemap (out) std::vector<TYPE>
+{
+  PyObject* l = PyList_New(0);
+
+  const std::vector<TYPE>& v = $1;
+  for (const TYPE& o : v)
+  {
+    PyObject* resultobj = SWIG_NewPointerObj(new TYPE(o), $descriptor(TYPE*), SWIG_POINTER_OWN );
+    PyList_Append(l, resultobj);
+    // FIXME: Py_DECREF here?
+  }
+
+  $result = l;
+}
+
+%enddef
+
 //-----------------------------------------------------------------------------
 // Macro for defining an in typemap for const std::vector<std::vector<TYPE> >&
 // where TYPE is a primitive
@@ -744,7 +762,9 @@ OUT_TYPEMAP_STD_VECTOR_OF_PRIMITIVES_REFERENCE(std::size_t, size_t)
 // This typemap handles dolfin::la_index, which can be a 32 or 64 bit integer
 OUT_TYPEMAP_STD_VECTOR_OF_PRIMITIVES_REFERENCE(dolfin::la_index, dolfin_index)
 
-IN_TYPEMAP_STD_VECTOR_OF_SMALL_DOLFIN_TYPES(Point)
+IN_TYPEMAP_STD_VECTOR_OF_SMALL_DOLFIN_TYPES(dolfin::Point)
+OUT_TYPEMAP_STD_VECTOR_OF_SMALL_DOLFIN_TYPES(dolfin::Point)
+
 IN_TYPEMAP_STD_VECTOR_OF_SMALL_DOLFIN_TYPES(MeshEntity)
 #if (DOLFIN_SIZE_T==4)
 IN_TYPEMAP_STD_VECTOR_OF_STD_VECTOR_OF_PRIMITIVES(std::size_t, INT32, facets,
diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt
index 7488b98..a5c3cf2 100644
--- a/python/CMakeLists.txt
+++ b/python/CMakeLists.txt
@@ -8,10 +8,12 @@ find_package(pybind11 REQUIRED CONFIG HINTS ${PYBIND11_DIR} ${PYBIND11_ROOT}
 find_package(DOLFIN REQUIRED)
 include(${DOLFIN_USE_FILE})
 
-# Check for mpi4py
-#set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
-#  ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
-#find_package(MPI4PY)
+# Strict compiler flags
+#include(CheckCXXCompilerFlag)
+#CHECK_CXX_COMPILER_FLAG("-Wall -Werror -pedantic" HAVE_PEDANTIC)
+#if (HAVE_PEDANTIC)
+#   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -pedantic")
+#endif()
 
 # Create the binding library
 pybind11_add_module(cpp SHARED
@@ -32,12 +34,26 @@ pybind11_add_module(cpp SHARED
   src/io.cpp
   src/la.cpp
   src/nls.cpp
-  src/refinement.cpp)
-
-#if (MPI4PY_FOUND)
-#  target_include_directories(cpp PRIVATE ${MPI4PY_INCLUDE_DIR})
-#  add_definitions(-DHAS_MPI4PY)
-#endif()
+  src/refinement.cpp
+  src/MPICommWrapper.cpp)
 
 # Add DOLFIN libraries and other config
 target_link_libraries(cpp PRIVATE pybind11::module dolfin)
+
+# Add to CMake search path
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
+  ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
+
+# Check for petsc4py
+find_package(PETSc4py)
+if (PETSC4PY_FOUND)
+  target_include_directories(cpp PRIVATE ${PETSC4PY_INCLUDE_DIRS})
+  target_compile_definitions(cpp PRIVATE HAS_PYBIND11_PETSC4PY)
+endif()
+
+# Check for mpi4py
+find_package(MPI4PY)
+if (MPI4PY_FOUND)
+  target_include_directories(cpp PRIVATE ${MPI4PY_INCLUDE_DIR})
+  target_compile_definitions(cpp PRIVATE HAS_PYBIND11_MPI4PY)
+endif()
diff --git a/python/cmake/FindPETSc4py.cmake b/python/cmake/FindPETSc4py.cmake
new file mode 100644
index 0000000..66dab9a
--- /dev/null
+++ b/python/cmake/FindPETSc4py.cmake
@@ -0,0 +1,112 @@
+# - Try to find petsc4py
+# Once done this will define
+#
+#  PETSC4PY_FOUND        - system has petsc4py
+#  PETSC4PY_INCLUDE_DIRS  - include directories for petsc4py
+#  PETSC4PY_VERSION      - version of petsc4py
+#  PETSC4PY_VERSION_MAJOR - first number in PETSC4PY_VERSION
+#  PETSC4PY_VERSION_MINOR - second number in PETSC4PY_VERSION
+
+# Based on FindNumPy.cmake
+
+#=============================================================================
+# Copyright (C) 2013 Lawrence Mitchell
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. 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.
+#=============================================================================
+
+message(STATUS "Checking for package 'PETSc4Py'")
+
+if(PETSC4PY_INCLUDE_DIRS)
+  # In cache already
+  set(PETSC4PY_FIND_QUIETLY TRUE)
+endif(PETSC4PY_INCLUDE_DIRS)
+
+execute_process(
+  COMMAND ${PYTHON_EXECUTABLE} -c "import petsc4py; print(petsc4py.get_include())"
+  OUTPUT_VARIABLE PETSC4PY_INCLUDE_DIRS
+  RESULT_VARIABLE PETSC4PY_NOT_FOUND
+  ERROR_QUIET
+  OUTPUT_STRIP_TRAILING_WHITESPACE
+  )
+
+if(PETSC4PY_INCLUDE_DIRS)
+  set(PETSC4PY_FOUND TRUE)
+  set(PETSC4PY_INCLUDE_DIRS ${PETSC4PY_INCLUDE_DIRS} CACHE STRING "petsc4py include path")
+else(PETSC4PY_INCLUDE_DIRS)
+  set(PETSC4PY_FOUND FALSE)
+endif(PETSC4PY_INCLUDE_DIRS)
+
+if(PETSC4PY_FOUND)
+  execute_process(
+    COMMAND ${PYTHON_EXECUTABLE} -c "import petsc4py; print(petsc4py.__version__)"
+    OUTPUT_VARIABLE PETSC4PY_VERSION
+    RESULT_VARIABLE PETSC4PY_NOT_FOUND
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+    )
+  string(REPLACE "." ";" PETSC4PY_VERSION_LIST ${PETSC4PY_VERSION})
+  list(GET PETSC4PY_VERSION_LIST 0 PETSC4PY_VERSION_MAJOR)
+  list(GET PETSC4PY_VERSION_LIST 1 PETSC4PY_VERSION_MINOR)
+  if(NOT PETSC4PY_FIND_QUIETLY)
+    message(STATUS "petsc4py version ${PETSC4PY_VERSION} found")
+  endif(NOT PETSC4PY_FIND_QUIETLY)
+else(PETSC4PY_FOUND)
+  if(PETSC4PY_FIND_REQUIRED)
+    message(FATAL_ERROR "petsc4py missing")
+  endif(PETSC4PY_FIND_REQUIRED)
+endif(PETSC4PY_FOUND)
+
+mark_as_advanced(PETSC4PY_INCLUDE_DIRS, PETSC4PY_VERSION, PETSC4PY_VERSION_MAJOR, PETSC4PY_VERSION_MINOR)
+
+if (PETSc4py_FIND_VERSION)
+  # Check if version found is >= required version
+  if (NOT "${PETSC4PY_VERSION}" VERSION_LESS "${PETSc4py_FIND_VERSION}")
+    set(PETSC4PY_VERSION_OK TRUE)
+  endif()
+else()
+  # No specific version requested
+  set(PETSC4PY_VERSION_OK TRUE)
+endif()
+mark_as_advanced(PETSC4PY_VERSION_OK)
+
+# Standard package handling
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(PETSc4py
+  "PETSc4py could not be found. Be sure to set PYTHONPATH appropriately."
+  PETSC4PY_INCLUDE_DIRS PETSC4PY_VERSION PETSC4PY_VERSION_OK)
+
+# Check petsc4py.i for PETSC_INT
+#if(PETSC4PY_INCLUDE_DIRS)
+#  file(STRINGS "${PETSC4PY_INCLUDE_DIRS}/petsc4py/petsc4py.i" PETSC4PY_INT)
+#  string(REGEX MATCH "SWIG_TYPECHECK_INT[0-9]+" PETSC4PY_INT "${PETSC4PY_INT}")
+#  string(REPLACE "SWIG_TYPECHECK_INT" "" PETSC4PY_INT "${PETSC4PY_INT}")
+#  math(EXPR PETSC_INT "${PETSC_INT_SIZE}*8")
+#  if(NOT PETSC_INT STREQUAL PETSC4PY_INT)
+#    message(STATUS "PETSC_INT = ${PETSC4PY_INT} ${PETSC_INT}")
+#    message(STATUS " - does not match")
+#    set(PETSC4PY_FOUND FALSE)
+#  endif()
+#endif()
diff --git a/python/doc/Makefile b/python/doc/Makefile
new file mode 100644
index 0000000..812b55f
--- /dev/null
+++ b/python/doc/Makefile
@@ -0,0 +1,20 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+SPHINXPROJ    = FEniCSProject
+SOURCEDIR     = source
+BUILDDIR      = build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+	@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
\ No newline at end of file
diff --git a/python/doc/source/api.rst b/python/doc/source/api.rst
index 7b40afa..8fb0dce 100644
--- a/python/doc/source/api.rst
+++ b/python/doc/source/api.rst
@@ -4,8 +4,27 @@ Python API reference
 .. autosummary::
    :toctree: _autogenerated
 
+   dolfin.cpp.adaptivity
+   dolfin.cpp.ale
    dolfin.cpp.common
+   dolfin.cpp.fem
    dolfin.cpp.function
+   dolfin.cpp.generation
+   dolfin.cpp.geometry
+   dolfin.cpp.graph
+   dolfin.cpp.io
+   dolfin.cpp.log
+   dolfin.cpp.math
    dolfin.cpp.mesh
-   dolfin.cpp.la
+   dolfin.cpp.multistage
+   dolfin.cpp.parameter
    dolfin.cpp.refinement
+
+   dolfin.common
+   dolfin.fem
+   dolfin.function
+   dolfin.io
+   dolfin.jit
+   dolfin.la
+   dolfin.multistage
+   dolfin.parameter
diff --git a/python/dolfin/__init__.py b/python/dolfin/__init__.py
index a99a85a..e28b5ce 100644
--- a/python/dolfin/__init__.py
+++ b/python/dolfin/__init__.py
@@ -31,12 +31,15 @@ del sys
 # del sys
 
 # Import cpp modules
+from .cpp import __version__
+
 from .cpp.common import (Variable, has_debug, has_hdf5, has_scotch,
-                         has_hdf5_parallel, has_mpi, has_petsc,
-                         has_parmetis, has_slepc, git_commit_hash,
-                         DOLFIN_EPS, DOLFIN_PI, TimingClear,
-                         TimingType, timing, timings, list_timings,
-                         dump_timings_to_xml)
+                         has_hdf5_parallel, has_mpi, has_mpi4py,
+                         has_petsc, has_petsc4py, has_parmetis,
+                         has_slepc, has_slepc4py, git_commit_hash,
+                         DOLFIN_EPS, DOLFIN_PI, TimingClear, TimingType,
+                         timing, timings, list_timings, dump_timings_to_xml,
+                         SubSystemsManager)
 
 if has_hdf5():
     from .cpp.adaptivity import TimeSeries
@@ -46,7 +49,7 @@ from .cpp.ale import ALE
 from .cpp import MPI
 from .cpp.function import (Expression, Constant, FunctionAXPY,
                            LagrangeInterpolator, FunctionAssigner,
-                           assign)
+                           assign, MultiMeshFunction, MultiMeshFunctionSpace)
 from .cpp.fem import (FiniteElement, DofMap, Assembler,
                       get_coordinates, create_mesh, set_coordinates,
                       vertex_to_dof_map, dof_to_vertex_map,
@@ -55,10 +58,12 @@ from .cpp.fem import (FiniteElement, DofMap, Assembler,
                       NonlinearVariationalSolver,
                       SparsityPatternBuilder)
 
-from .cpp.geometry import (BoundingBoxTree, Point,
-                           MeshPointIntersection, intersect)
+from .cpp.geometry import (BoundingBoxTree,
+                           Point,
+                           MeshPointIntersection,
+                           intersect)
 from .cpp.generation import (IntervalMesh, BoxMesh, RectangleMesh,
-                             UnitDiscMesh, UnitQuadMesh, UnitHexMesh,
+                             UnitDiscMesh,
                              UnitTriangleMesh, UnitCubeMesh,
                              UnitSquareMesh, UnitIntervalMesh,
                              SphericalShellMesh)
@@ -97,7 +102,7 @@ from .cpp.mesh import (Mesh, MeshTopology, MeshGeometry, MeshEntity,
                        entities, vertices, SubDomain, BoundaryMesh,
                        MeshEditor, MeshQuality, SubMesh,
                        DomainBoundary, PeriodicBoundaryComputation,
-                       MeshTransformation, SubsetIterator)
+                       MeshTransformation, SubsetIterator, MultiMesh)
 
 from .cpp.nls import (NonlinearProblem, NewtonSolver, OptimisationProblem)
 from .cpp.refinement import refine
@@ -121,8 +126,8 @@ from .fem.norms import norm, errornorm
 from .fem.dirichletbc import DirichletBC, AutoSubDomain
 from .fem.interpolation import interpolate
 from .fem.projection import project
-from .fem.solving import (solve, LocalSolver,
-                          LinearVariationalProblem,
+from .fem.solvers import LocalSolver
+from .fem.solving import (solve, LinearVariationalProblem,
                           NonlinearVariationalProblem)
 from .fem.formmanipulations import (derivative, adjoint, increase_order, tear)
 
@@ -136,11 +141,12 @@ from .function.function import Function
 from .function.argument import (TestFunction, TrialFunction,
                                 TestFunctions, TrialFunctions)
 from .function.constant import Constant
-from .function.specialfunctions import (FacetNormal, CellSize,
-                                        SpatialCoordinate, CellVolume,
-                                        Circumradius, FacetArea,
-                                        MeshCoordinates)
-from .function.expression import Expression, UserExpression
+from .function.specialfunctions import (MeshCoordinates, FacetArea, FacetNormal,
+                                        CellVolume, SpatialCoordinate, CellNormal,
+                                        CellDiameter, Circumradius,
+                                        MinCellEdgeLength, MaxCellEdgeLength,
+                                        MinFacetEdgeLength, MaxFacetEdgeLength)
+from .function.expression import Expression, UserExpression, CompiledExpression
 
 # experimental
 from .jit.pybind11jit import compile_cpp_code
@@ -148,9 +154,7 @@ from .jit.pybind11jit import compile_cpp_code
 from .la import as_backend_type, la_index_dtype
 from .mesh.ale import (compute_vertex_map, compute_edge_map,
                        init_parent_edge_indices)
-from .mesh.meshfunction import (MeshFunction, CellFunction,
-                                FacetFunction, FaceFunction,
-                                EdgeFunction, VertexFunction)
+from .mesh.meshfunction import (MeshFunction)
 from .mesh.meshvaluecollection import MeshValueCollection
 from .mesh.subdomain import CompiledSubDomain
 
@@ -166,7 +170,7 @@ from ufl import (FiniteElement, TensorElement, VectorElement,
                  split, cross, inner, dot, grad, curl, dx, div,
                  Measure, det, pi, sin, cos, tan, acos, asin, atan,
                  ln, exp, sqrt, bessel_I, bessel_J, bessel_K,
-                 bessel_Y, Dx, ds, dS, dP, interval, triangle,
+                 bessel_Y, Dx, ds, dS, dP, dX, dC, interval, triangle,
                  tetrahedron, quadrilateral, hexahedron, avg, jump,
                  sym, tr, Identity, variable, diff, as_vector,
                  as_tensor, as_matrix, system, outer, dev, skew,
@@ -174,11 +178,6 @@ from ufl import (FiniteElement, TensorElement, VectorElement,
 from ufl.formoperators import action
 
 
-# FIXME
-def has_petsc4py():
-    return False
-
-
 # FIXME: remove after transition
 def has_pybind11():
     return True
@@ -193,6 +192,7 @@ def mpi_comm_self():
 def mpi_comm_world():
     return MPI.comm_world
 
+
 # FIXME: remove all these after transition
 TimingClear_clear = TimingClear.clear
 TimingClear_keep = TimingClear.keep
@@ -209,6 +209,12 @@ TensorLayout.Sparsity_SPARSE = TensorLayout.Sparsity.SPARSE
 TensorLayout.Ghosts_GHOSTED = TensorLayout.Ghosts.GHOSTED
 TensorLayout.Ghosts_UNGHOSTED = TensorLayout.Ghosts.UNGHOSTED
 
+CellType.Type_interval = CellType.Type.interval
+CellType.Type_triangle = CellType.Type.triangle
+CellType.Type_tetrahedron = CellType.Type.tetrahedron
+CellType.Type_quadrilateral = CellType.Type.quadrilateral
+CellType.Type_hexahedron = CellType.Type.hexahedron
+
 if has_linear_algebra_backend('PETSc'):
     PETScKrylovSolver.norm_type_default_norm = PETScKrylovSolver.norm_type.default_norm
     PETScKrylovSolver.norm_type_natural = PETScKrylovSolver.norm_type.natural
diff --git a/python/dolfin/common/plotting.py b/python/dolfin/common/plotting.py
index 7b898bd..dddc99b 100644
--- a/python/dolfin/common/plotting.py
+++ b/python/dolfin/common/plotting.py
@@ -17,7 +17,6 @@
 # along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 
 import os
-from distutils.version import StrictVersion
 
 import dolfin
 import dolfin.cpp as cpp
@@ -116,7 +115,7 @@ def mplot_function(ax, f, **kwargs):
 
     if fvec.size() == mesh.num_cells():
         # DG0 cellwise function
-        C = fvec.array()  # NB! Assuming here dof ordering matching cell numbering
+        C = fvec.get_local()  # NB! Assuming here dof ordering matching cell numbering
         if gdim == 2 and tdim == 2:
             return ax.tripcolor(mesh2triang(mesh), C, **kwargs)
         elif gdim == 3 and tdim == 2:  # surface in 3d
@@ -129,13 +128,13 @@ def mplot_function(ax, f, **kwargs):
             x = mesh.coordinates()[:, 0]
             nv = len(x)
             # Insert duplicate points to get piecewise constant plot
-            xp = np.zeros(2*nv-2)
+            xp = np.zeros(2 * nv - 2)
             xp[0] = x[0]
             xp[-1] = x[-1]
-            xp[1:2*nv-3:2] = x[1:-1]
-            xp[2:2*nv-2:2] = x[1:-1]
+            xp[1:2 * nv - 3:2] = x[1:-1]
+            xp[2:2 * nv - 2:2] = x[1:-1]
             Cp = np.zeros(len(xp))
-            Cp[0:len(Cp)-1:2] = C
+            Cp[0:len(Cp) - 1:2] = C
             Cp[1:len(Cp):2] = C
             return ax.plot(xp, Cp, *kwargs)
         # elif tdim == 1:  # FIXME: Plot embedded line
@@ -198,11 +197,11 @@ def mplot_function(ax, f, **kwargs):
         # Vector function, interpolated to vertices
         w0 = f.compute_vertex_values(mesh)
         nv = mesh.num_vertices()
-        if len(w0) != gdim*nv:
+        if len(w0) != gdim * nv:
             raise AttributeError('Vector length must match geometric dimension.')
         X = mesh.coordinates()
         X = [X[:, i] for i in range(gdim)]
-        U = [w0[i*nv: (i + 1)*nv] for i in range(gdim)]
+        U = [w0[i * nv: (i + 1) * nv] for i in range(gdim)]
 
         # Compute magnitude
         C = U[0]**2
@@ -214,14 +213,6 @@ def mplot_function(ax, f, **kwargs):
         if mode == "glyphs":
             args = X + U + [C]
             if gdim == 3:
-                # 3d quiver plot works only since matplotlib 1.4
-                import matplotlib
-                if StrictVersion(matplotlib.__version__) < '1.4':
-                    cpp.warning('Matplotlib version %s does not support 3d '
-                                'quiver plot. Continuing without plotting...'
-                                % matplotlib.__version__)
-                    return
-
                 length = kwargs.pop("length", 0.1)
                 return ax.quiver(*args, length=length, **kwargs)
             else:
@@ -276,7 +267,7 @@ def _plot_matplotlib(obj, mesh, kwargs):
     # Avoid importing pyplot until used
     try:
         import matplotlib.pyplot as plt
-    except:
+    except Exception:
         cpp.warning("matplotlib.pyplot not available, cannot plot.")
         return
 
@@ -436,6 +427,7 @@ def plot(object, *args, **kwargs):
                          "piecewise linears.")
             object = project(object, mesh=mesh)
             mesh = object.function_space().mesh()
+            object = object._cpp_object
         except Exception as e:
             msg = "Don't know how to plot given object:\n  %s\n" \
                   "and projection failed:\n  %s" % (str(object), str(e))
diff --git a/python/dolfin/common/timer.py b/python/dolfin/common/timer.py
index f6f3d2b..1652b4c 100644
--- a/python/dolfin/common/timer.py
+++ b/python/dolfin/common/timer.py
@@ -51,7 +51,7 @@ class Timer(cpp.common.Timer):
     may be printed using functions ``timing``, ``timings``,
     ``list_timings``, ``dump_timings_to_xml``, e.g.::
 
-        list_timings(TimingClear_keep, [TimingType_wall, TimingType_user])
+        list_timings(TimingClear.keep, [TimingType.wall, TimingType.user])
     """
 
     def __enter__(self):
@@ -72,9 +72,9 @@ def timed(task):
 
         do_foo()
 
-        list_timings(TimingClear_keep, [TimingType_wall, TimingType_user])
+        list_timings(TimingClear.keep, [TimingType.wall, TimingType.user])
 
-        t = timing("Do Foo", TimingClear_clear)
+        t = timing("Do Foo", TimingClear.clear)
         print("Do foo wall time: %s" % t[1])
     """
     def decorator(func):
diff --git a/python/dolfin/fem/adaptivesolving.py b/python/dolfin/fem/adaptivesolving.py
index 73d2375..a1782f8 100644
--- a/python/dolfin/fem/adaptivesolving.py
+++ b/python/dolfin/fem/adaptivesolving.py
@@ -21,16 +21,16 @@ Adaptive*VariationalSolver classes
 # You should have received a copy of the GNU Lesser General Public License
 # along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 
-__all__ = ["AdaptiveLinearVariationalSolver",
-           "AdaptiveNonlinearVariationalSolver",
-           "generate_error_control", "generate_error_control_forms"]
-
 import dolfin.cpp as cpp
 from dolfin.fem.form import Form
 from dolfin.fem.solving import LinearVariationalProblem
 from dolfin.fem.solving import NonlinearVariationalProblem
 from dolfin.fem.errorcontrolgenerator import DOLFINErrorControlGenerator
 
+__all__ = ["AdaptiveLinearVariationalSolver",
+           "AdaptiveNonlinearVariationalSolver",
+           "generate_error_control", "generate_error_control_forms"]
+
 
 class AdaptiveLinearVariationalSolver(cpp.adaptivity.AdaptiveLinearVariationalSolver):
 
@@ -207,9 +207,7 @@ def generate_error_control_forms(problem, goal):
             assert len(form.ufl_domains()) == 1, "Error control got as input a form with more than one domain!"
 
     else:
-        cpp.dolfin_error("adaptivesolving.py",
-                         "generate forms required for error control",
-                         "Unknown problem type (\"%s\")" % str(problem))
+        raise RuntimeError("Generate forms required for error control. Unknown problem type (\"{}\")".format(problem))
 
     # Extract unknown Function from problem
     u = problem.u_ufl
diff --git a/python/dolfin/fem/assembling.py b/python/dolfin/fem/assembling.py
index a51a971..ada8b2a 100644
--- a/python/dolfin/fem/assembling.py
+++ b/python/dolfin/fem/assembling.py
@@ -130,7 +130,7 @@ def assemble(form, tensor=None, form_compiler_parameters=None,
         .. code-block:: python
 
             # MeshFunction marking boundary parts
-            boundary_markers = FacetFunction("size_t", mesh)
+            boundary_markers = MeshFunction("size_t", mesh, mesh.topology().dim()-1)
             # ... fill values in boundary_markers
 
             # Measures with references to cell and boundary markers
@@ -161,8 +161,8 @@ def assemble(form, tensor=None, form_compiler_parameters=None,
         .. code-block:: python
 
             # MeshFunctions marking boundary and cell parts
-            boundary_markers = FacetFunction("size_t", mesh)
-            cell_markers = CellFunction("size_t", mesh)
+            boundary_markers = MeshFunction("size_t", mesh, mesh.topology().dim()-1)
+            cell_markers = MeshFunction("size_t", mesh, mesh.topology().dim())
             # ... fill values in boundary_markers
 
             # Measures with references to cell and boundary markers
diff --git a/python/dolfin/fem/form.py b/python/dolfin/fem/form.py
index db44995..936f788 100644
--- a/python/dolfin/fem/form.py
+++ b/python/dolfin/fem/form.py
@@ -8,8 +8,8 @@
 # version.
 
 import ufl
-import ffc
 import dolfin.cpp as cpp
+from dolfin.jit.jit import ffc_jit
 
 
 class Form(cpp.fem.Form):
@@ -41,7 +41,8 @@ class Form(cpp.fem.Form):
             # FIXME: add paths if dict entry already exists
             form_compiler_parameters["external_include_dirs"] = d["include_dirs"]
 
-        ufc_form = ffc.jit(form, form_compiler_parameters)
+        ufc_form = ffc_jit(form, form_compiler_parameters=form_compiler_parameters,
+                           mpi_comm=mesh.mpi_comm())
         ufc_form = cpp.fem.make_ufc_form(ufc_form[0])
 
         function_spaces = [func.function_space()._cpp_object for func in form.arguments()]
diff --git a/python/dolfin/fem/formmanipulations.py b/python/dolfin/fem/formmanipulations.py
index dc7b4cd..f85519f 100644
--- a/python/dolfin/fem/formmanipulations.py
+++ b/python/dolfin/fem/formmanipulations.py
@@ -18,7 +18,6 @@
 
 import ufl
 import ufl.algorithms.elementtransformations
-import dolfin.cpp as cpp
 from dolfin.function.functionspace import FunctionSpace
 from dolfin.function.function import Function
 from dolfin.function.argument import Argument
@@ -35,13 +34,10 @@ def adjoint(form, reordered_arguments=None):
     # Extract form arguments
     arguments = form.arguments()
     if any(arg.part() is not None for arg in arguments):
-        cpp.dolfin_error("formmanipulation.py",
-                         "compute adjoint of form",
-                         "parts not supported")
+        raise RuntimeError("Compute adjoint of form, parts not supported")
+
     if not (len(arguments) == 2):
-        cpp.dolfin_error("formmanipulation.py",
-                         "compute adjoint of form",
-                         "Form is not bilinear")
+        raise RuntimeError("Compute adjoint of form, form is not bilinear")
 
     # Define new Argument(s) in the same spaces (NB: Order does not
     # matter anymore here because number is absolute)
@@ -66,24 +62,16 @@ def derivative(form, u, du=None, coefficient_derivatives=None):
         number = max([-1] + [arg.number() for arg in form_arguments]) + 1
 
         if any(arg.part() is not None for arg in form_arguments):
-            cpp.dolfin_error("formmanipulation.py",
-                             "compute derivative of form",
-                             "Cannot automatically create new Argument using "
-                             "parts, please supply one")
+            raise RuntimeError("Compute derivative of form, cannot automatically create new Argument using parts, please supply one")
         part = None
 
         if isinstance(u, Function):
             V = u.function_space()
             du = Argument(V, number, part)
         elif isinstance(u, (list, tuple)) and all(isinstance(w, Function) for w in u):
-            cpp.dolfin_error("formmanipulation.py",
-                             "take derivative of form w.r.t. a tuple of Coefficients",
-                             "Take derivative w.r.t. a single Coefficient on "
-                             "a mixed space instead.")
+            raise RuntimeError("Taking derivative of form w.r.t. a tuple of Coefficients. Take derivative w.r.t. a single Coefficient on a mixed space instead.")
         else:
-            cpp.dolfin_error("formmanipulation.py",
-                             "compute derivative of form w.r.t. '%s'" % u,
-                             "Supply Function as a Coefficient")
+            raise RuntimeError("Computing derivative of form w.r.t. '{}'. Supply Function as a Coefficient".format(u))
 
     return ufl.derivative(form, u, du, coefficient_derivatives)
 
diff --git a/python/dolfin/fem/norms.py b/python/dolfin/fem/norms.py
index 8ad069b..54869d3 100644
--- a/python/dolfin/fem/norms.py
+++ b/python/dolfin/fem/norms.py
@@ -122,42 +122,26 @@ def norm(v, norm_type="L2", mesh=None):
 
     elif isinstance(v, ufl.Coefficient):
         if norm_type.lower() == "l2":
-            M = v**2*dx
+            M = v**2 * dx
         elif norm_type.lower() == "h1":
-            M = (v**2 + grad(v)**2)*dx
+            M = (v**2 + grad(v)**2) * dx
         elif norm_type.lower() == "h10":
-            M = grad(v)**2*dx
+            M = grad(v)**2 * dx
         elif norm_type.lower() == "hdiv":
-            M = (v**2 + div(v)**2)*dx
+            M = (v**2 + div(v)**2) * dx
         elif norm_type.lower() == "hdiv0":
-            M = div(v)**2*dx
+            M = div(v)**2 * dx
         elif norm_type.lower() == "hcurl":
-            M = (v**2 + curl(v)**2)*dx
+            M = (v**2 + curl(v)**2) * dx
         elif norm_type.lower() == "hcurl0":
-            M = curl(v)**2*dx
-        # else:
-        #     cpp.dolfin_error("norms.py",
-        #                      "compute norm",
-        #                      "Unknown norm type (\"%s\") for functions"
-        #                      % str(norm_type))
-    # else:
-    #     cpp.dolfin_error("norms.py",
-    #                      "compute norm",
-    #                      "Unknown object type. Must be a vector or a function")
-
-    # Assemble value
-    r = assemble(M)
-
-    # Check value
-    if r < 0.0:
-        pass
-        # cpp.dolfin_error("norms.py",
-        #                  "compute norm",
-        #                  "Square of norm is negative, might be a round-off error")
-    elif r == 0.0:
-        return 0.0
+            M = curl(v)**2 * dx
+        else:
+            raise ValueError("Unknown norm type {}".format(str(norm_type)))
     else:
-        return sqrt(r)
+        raise TypeError("Do not know how to compute norm of {}".format(str(v)))
+
+    # Assemble value and return
+    return sqrt(assemble(M))
 
 
 def errornorm(u, uh, norm_type="l2", degree_rise=3, mesh=None):
@@ -230,23 +214,18 @@ def errornorm(u, uh, norm_type="l2", degree_rise=3, mesh=None):
     if hasattr(u, "_cpp_object") and mesh is None:
         mesh = u._cpp_object.function_space().mesh()
     if mesh is None:
-        cpp.dolfin_error("norms.py",
-                         "compute error norm",
-                         "Missing mesh")
+        raise RuntimeError("Cannot compute error norm. Missing mesh.")
 
     # Get rank
     if not u.ufl_shape == uh.ufl_shape:
-        cpp.dolfin_error("norms.py",
-                         "compute error norm",
-                         "Value shapes don't match")
+        raise RuntimeError("Cannot compute error norm. Value shapes do not match.")
+
     shape = u.ufl_shape
     rank = len(shape)
 
     # Check that uh is associated with a finite element
     if uh.ufl_element().degree() is None:
-        cpp.dolfin_error("norms.py",
-                         "compute error norm",
-                         "Function uh must have a finite element")
+        raise RuntimeError("Cannot compute error norm. Function uh must have a finite element.")
 
     # Degree for interpolation space. Raise degree with respect to uh.
     degree = uh.ufl_element().degree() + degree_rise
diff --git a/python/dolfin/fem/problem.py b/python/dolfin/fem/problem.py
new file mode 100644
index 0000000..b8f203e
--- /dev/null
+++ b/python/dolfin/fem/problem.py
@@ -0,0 +1,95 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2011-2017 Anders Logg and Garth N. Wells
+#
+# This file is part of DOLFIN.
+#
+# DOLFIN is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# DOLFIN 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+
+import dolfin.cpp as cpp
+from dolfin.fem.form import Form
+
+
+class LinearVariationalProblem(cpp.fem.LinearVariationalProblem):
+
+    def __init__(self, a, L, u, bcs=None, form_compiler_parameters=None):
+        """Create linear variational problem a(u, v) = L(v).
+
+        An optional argument bcs may be passed to specify boundary
+        conditions.
+
+        Another optional argument form_compiler_parameters may be
+        specified to pass parameters to the form compiler.
+
+        """
+
+        if bcs is None:
+            bcs = []
+        elif not isinstance(bcs, (list, tuple)):
+            bcs = [bcs]
+
+        # Store input UFL forms and solution Function
+        self.a_ufl = a
+        self.L_ufl = L
+        self.u_ufl = u
+
+        # Store form compiler parameters
+        form_compiler_parameters = form_compiler_parameters or {}
+        self.form_compiler_parameters = form_compiler_parameters
+
+        # Wrap forms (and check if linear form L is empty)
+        if L.empty():
+            L = cpp.fem.Form(1, 0)
+        else:
+            L = Form(L, form_compiler_parameters=form_compiler_parameters)
+        a = Form(a, form_compiler_parameters=form_compiler_parameters)
+
+        # Initialize C++ base class
+        cpp.fem.LinearVariationalProblem.__init__(self, a, L, u._cpp_object, bcs)
+
+
+class NonlinearVariationalProblem(cpp.fem.NonlinearVariationalProblem):
+
+    def __init__(self, F, u, bcs=None, J=None, form_compiler_parameters=None):
+        """Create nonlinear variational problem F(u; v) = 0.
+
+        Optional arguments bcs and J may be passed to specify boundary
+        conditions and the Jacobian J = dF/du.
+
+        Another optional argument form_compiler_parameters may be
+        specified to pass parameters to the form compiler.
+
+        """
+
+        if bcs is None:
+            bcs = []
+        elif not isinstance(bcs, (list, tuple)):
+            bcs = [bcs]
+
+        # Store input UFL forms and solution Function
+        self.F_ufl = F
+        self.J_ufl = J
+        self.u_ufl = u
+
+        # Store form compiler parameters
+        form_compiler_parameters = form_compiler_parameters or {}
+        self.form_compiler_parameters = form_compiler_parameters
+
+        # Wrap forms
+        F = Form(F, form_compiler_parameters=form_compiler_parameters)
+        if J is not None:
+            J = Form(J, form_compiler_parameters=form_compiler_parameters)
+
+        # Initialize C++ base class
+        cpp.fem.NonlinearVariationalProblem.__init__(self, F, u._cpp_object, bcs, J)
diff --git a/python/dolfin/fem/projection.py b/python/dolfin/fem/projection.py
index 42f8f76..176b13b 100644
--- a/python/dolfin/fem/projection.py
+++ b/python/dolfin/fem/projection.py
@@ -102,8 +102,8 @@ def project(v, V=None, bcs=None, mesh=None,
     # Define variational problem for projection
     w = TestFunction(V)
     Pv = TrialFunction(V)
-    a = ufl.inner(w, Pv)*dx
-    L = ufl.inner(w, v)*dx
+    a = ufl.inner(w, Pv) * dx
+    L = ufl.inner(w, v) * dx
 
     # Assemble linear system
     A, b = assemble_system(a, L, bcs=bcs,
@@ -142,10 +142,7 @@ def _extract_function_space(expression, mesh):
                     break
 
     if mesh is None:
-        cpp.dolfin_error("projection.py",
-                         "extract function space",
-                         "Unable to project expression, can't find "
-                         "a suitable mesh.")
+        raise RuntimeError("Unable to project expression, cannot find a suitable mesh.")
 
     # Create function space
     shape = expression.ufl_shape
@@ -156,8 +153,6 @@ def _extract_function_space(expression, mesh):
     elif len(shape) == 2:
         V = TensorFunctionSpace(mesh, "Lagrange", 1, shape=shape)
     else:
-        cpp.dolfin_error("projection.py",
-                         "extract function space",
-                         "Unhandled rank, shape is %s." % (shape,))
+        raise RuntimeError("Unhandled rank, shape is {}.".format((shape,)))
 
     return V
diff --git a/python/dolfin/fem/solvers.py b/python/dolfin/fem/solvers.py
new file mode 100644
index 0000000..2638963
--- /dev/null
+++ b/python/dolfin/fem/solvers.py
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2011 Anders Logg
+#
+# This file is part of DOLFIN.
+#
+# DOLFIN is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# DOLFIN 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+
+import dolfin.cpp as cpp
+from dolfin.fem.form import Form
+
+__all__ = ["LocalSolver"]
+
+
+class LocalSolver(cpp.fem.LocalSolver):
+
+    def __init__(self, a, L=None, solver_type=cpp.fem.LocalSolver.SolverType.LU):
+        """Create a local (cell-wise) solver for a linear variational problem
+        a(u, v) = L(v).
+
+        """
+
+        # Store input UFL forms and solution Function
+        self.a_ufl = a
+        self.L_ufl = L
+
+        # Wrap as DOLFIN forms
+        a = Form(a)
+        if L is None:
+            # Initialize C++ base class
+            cpp.fem.LocalSolver.__init__(self, a, solver_type)
+        else:
+            if L.empty():
+                L = cpp.fem.Form(1, 0)
+            else:
+                L = Form(L)
+
+        # Initialize C++ base class
+        cpp.fem.LocalSolver.__init__(self, a, L, solver_type)
diff --git a/python/dolfin/fem/solving.py b/python/dolfin/fem/solving.py
index 0626aba..255a16c 100644
--- a/python/dolfin/fem/solving.py
+++ b/python/dolfin/fem/solving.py
@@ -27,54 +27,22 @@ from dolfin.function.function import Function
 from dolfin.fem.form import Form
 import dolfin.fem.formmanipulations as formmanipulations
 from dolfin.fem.formmanipulations import derivative
+import dolfin.la.solver
+from dolfin.fem.problem import LinearVariationalProblem, NonlinearVariationalProblem
 
 __all__ = ["LinearVariationalProblem",
            "LinearVariationalSolver",
-           "LocalSolver",
            "NonlinearVariationalProblem",
            "NonlinearVariationalSolver",
            "solve"]
 
-# Problem classes need special handling since they involve JIT
-# compilation
-
-
-class LinearVariationalProblem(cpp.fem.LinearVariationalProblem):
-
-    def __init__(self, a, L, u, bcs=None,
-                 form_compiler_parameters=None):
-        """
-        Create linear variational problem a(u, v) = L(v).
-
-        An optional argument bcs may be passed to specify boundary
-        conditions.
-
-        Another optional argument form_compiler_parameters may be
-        specified to pass parameters to the form compiler.
-        """
 
-        # Extract and check arguments
-        u = _extract_u(u)
-        bcs = _extract_bcs(bcs)
+# FIXME: The code is this file is outrageously convolute because one
+# function an do a number of unrelated operations, depending in the
+# arguments passed.
 
-        # Store input UFL forms and solution Function
-        self.a_ufl = a
-        self.L_ufl = L
-        self.u_ufl = u
-
-        # Store form compiler parameters
-        form_compiler_parameters = form_compiler_parameters or {}
-        self.form_compiler_parameters = form_compiler_parameters
-
-        # Wrap forms (and check if linear form L is empty)
-        if L.empty():
-            L = cpp.fem.Form(1, 0)
-        else:
-            L = Form(L, form_compiler_parameters=form_compiler_parameters)
-        a = Form(a, form_compiler_parameters=form_compiler_parameters)
-
-        # Initialize C++ base class
-        cpp.fem.LinearVariationalProblem.__init__(self, a, L, u._cpp_object, bcs)
+# Problem classes need special handling since they involve JIT
+# compilation
 
 
 class LocalSolver(cpp.fem.LocalSolver):
@@ -104,50 +72,12 @@ class LocalSolver(cpp.fem.LocalSolver):
             cpp.fem.LocalSolver.__init__(self, a, L, solver_type)
 
 
-class NonlinearVariationalProblem(cpp.fem.NonlinearVariationalProblem):
-
-    # Reuse C++ doc-string
-    __doc__ = cpp.fem.NonlinearVariationalProblem.__doc__
-
-    def __init__(self, F, u, bcs=None, J=None,
-                 form_compiler_parameters=None):
-        """
-        Create nonlinear variational problem F(u; v) = 0.
-
-        Optional arguments bcs and J may be passed to specify boundary
-        conditions and the Jacobian J = dF/du.
-
-        Another optional argument form_compiler_parameters may be
-        specified to pass parameters to the form compiler.
-        """
-
-        # Extract and check arguments
-        u = _extract_u(u)
-        bcs = _extract_bcs(bcs)
-
-        # Store input UFL forms and solution Function
-        self.F_ufl = F
-        self.J_ufl = J
-        self.u_ufl = u
-
-        # Store form compiler parameters
-        form_compiler_parameters = form_compiler_parameters or {}
-        self.form_compiler_parameters = form_compiler_parameters
-
-        # Wrap forms
-        F = Form(F, form_compiler_parameters=form_compiler_parameters)
-        if J is not None:
-            J = Form(J, form_compiler_parameters=form_compiler_parameters)
-
-        # Initialize C++ base class
-        cpp.fem.NonlinearVariationalProblem.__init__(self, F, u._cpp_object, bcs, J)
-
 # FIXME: The import here are here to avoid a circular dependency
 # (ugly, should fix)
 # Solver classes are imported directly
-from dolfin.cpp.fem import LinearVariationalSolver, NonlinearVariationalSolver
-from dolfin.fem.adaptivesolving import AdaptiveLinearVariationalSolver
-from dolfin.fem.adaptivesolving import AdaptiveNonlinearVariationalSolver
+from dolfin.cpp.fem import LinearVariationalSolver, NonlinearVariationalSolver  # noqa
+from dolfin.fem.adaptivesolving import AdaptiveLinearVariationalSolver  # noqa
+from dolfin.fem.adaptivesolving import AdaptiveNonlinearVariationalSolver  # noqa
 
 
 # Solve function handles both linear systems and variational problems
@@ -292,13 +222,9 @@ def solve(*args, **kwargs):
     # Default case, just call the wrapped C++ solve function
     else:
         if kwargs:
-            raise RuntimeError("Not expecting keyword arguments when solving linear algebra problem")
-            # cpp.dolfin_error("solving.py",
-            #                  "solve linear algebra problem",
-            #                  "Not expecting keyword arguments when solving "
-            #                  "linear algebra problem")
+            raise RuntimeError("Not expecting keyword arguments when solving linear algebra problem.")
 
-        return cpp.la.solve(*args)
+        return dolfin.la.solver.solve(*args)
 
 
 def _solve_varproblem(*args, **kwargs):
@@ -351,9 +277,7 @@ def _solve_varproblem_adaptive(*args, **kwargs):
 
     # Check that we received the goal functional
     if M is None:
-        cpp.dolfin_error("solving.py",
-                         "solve variational problem adaptively",
-                         "Missing goal functional")
+        raise RuntimeError("Cannot solve variational problem adaptively. Missing goal functional")
 
     # Solve linear variational problem
     if isinstance(eq.lhs, ufl.Form) and isinstance(eq.rhs, ufl.Form):
@@ -395,26 +319,14 @@ def _extract_args(*args, **kwargs):
                     "form_compiler_parameters", "solver_parameters"]
     for kwarg in kwargs.keys():
         if kwarg not in valid_kwargs:
-            raise RuntimeError("Illegal keyword argument")
-            # cpp.dolfin_error("solving.py",
-            #                  "solve variational problem",
-            #                  "Illegal keyword argument \"%s\"; valid keywords are %s" %
-            #                  (kwarg,
-            #                   ", ".join("\"%s\"" % kwarg for kwarg in valid_kwargs)))
+            raise RuntimeError("Solve variational problem. Illegal keyword argument \'{}\'.".format(kwarg))
 
     # Extract equation
     if not len(args) >= 2:
-        raise RuntimeError("Missing argument")
-        # cpp.dolfin_error("solving.py",
-        #                  "solve variational problem",
-        #                  "Missing arguments, expecting solve(lhs == rhs, "
-        #                  "u, bcs=bcs), where bcs is optional")
+        raise RuntimeError("Solve variational problem. Missing arguments, expecting solve(lhs == rhs, u, bcs=bcs), where bcs is optional")
+
     if len(args) > 3:
-        raise RuntimeError("Too many arguments")
-        # cpp.dolfin_error("solving.py",
-        #                  "solve variational problem",
-        #                  "Too many arguments, expecting solve(lhs == rhs, "
-        #                  "u, bcs=bcs), where bcs is optional")
+        raise RuntimeError("Solve variational problem. Too many arguments, expecting solve(lhs == rhs, u, bcs=bcs), where bcs is optional")
 
     # Extract equation
     eq = _extract_eq(args[0])
@@ -433,23 +345,17 @@ def _extract_args(*args, **kwargs):
     # Extract Jacobian
     J = kwargs.get("J", None)
     if J is not None and not isinstance(J, ufl.Form):
-        cpp.dolfin_error("solving.py",
-                         "solve variational problem",
-                         "Expecting Jacobian J to be a UFL Form")
+        raise RuntimeError("Solve variational problem. Expecting Jacobian J to be a UFL Form.")
 
     # Extract tolerance
     tol = kwargs.get("tol", None)
     if tol is not None and not (isinstance(tol, (float, int)) and tol >= 0.0):
-        cpp.dolfin_error("solving.py",
-                         "solve variational problem",
-                         "Expecting tolerance tol to be a non-negative number")
+        raise RuntimeError("Solve variational problem. Expecting tolerance tol to be a non-negative number.")
 
     # Extract functional
     M = kwargs.get("M", None)
     if M is not None and not isinstance(M, ufl.Form):
-        cpp.dolfin_error("solving.py",
-                         "solve variational problem",
-                         "Expecting goal functional M to be a UFL Form")
+        raise RuntimeError("Solve variational problem. Expecting goal functional M to be a UFL Form.")
 
     # Extract parameters
     form_compiler_parameters = kwargs.get("form_compiler_parameters", {})
@@ -461,9 +367,8 @@ def _extract_args(*args, **kwargs):
 def _extract_eq(eq):
     "Extract and check argument eq"
     if not isinstance(eq, ufl.classes.Equation):
-        cpp.dolfin_error("solving.py",
-                         "solve variational problem",
-                         "Expecting first argument to be an Equation")
+        raise RuntimeError("Solve variational problem. Expecting first argument to be an Equation.")
+
     return eq
 
 
@@ -477,7 +382,7 @@ def _extract_u(u):
     if isinstance(u, Function):
         return u
 
-    raise RuntimeError("Expecting second argument to be a Function")
+    raise RuntimeError("Expecting second argument to be a Function.")
     # cpp.dolfin_error("solving.py",
     #                      "solve variational problem",
     #                      "Expecting second argument to be a Function")
@@ -492,8 +397,6 @@ def _extract_bcs(bcs):
         bcs = [bcs]
     for bc in bcs:
         if not isinstance(bc, cpp.fem.DirichletBC):
-            raise RuntimeError("Unable to extract boundary condition arguments")
-            # cpp.dolfin_error("solving.py",
-            #                  "solve variational problem",
-            #                  "Unable to extract boundary condition arguments")
+            raise RuntimeError("solve variational problem. Unable to extract boundary condition arguments")
+
     return bcs
diff --git a/python/dolfin/function/argument.py b/python/dolfin/function/argument.py
index ab6b371..5b045ac 100644
--- a/python/dolfin/function/argument.py
+++ b/python/dolfin/function/argument.py
@@ -19,15 +19,13 @@
 # You should have received a copy of the GNU Lesser General Public License
 # along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 
-__all__ = ["TestFunction", "TrialFunction", "Argument",
-           "TestFunctions", "TrialFunctions"]
-
-import types
 import ufl
-import dolfin.cpp as cpp
 from .functionspace import FunctionSpace
 
-#--- Subclassing of ufl.{Basis, Trial, Test}Function ---
+__all__ = ["TestFunction", "TrialFunction", "Argument",
+           "TestFunctions", "TrialFunctions"]
+
+# --- Subclassing of ufl.{Basis, Trial, Test}Function ---
 
 # TODO: Update this message to clarify dolfin.FunctionSpace vs
 # ufl.FunctionSpace
@@ -38,6 +36,7 @@ element space and is only used in standalone .ufl files, while the
 FunctionSpace provides a full discrete function space over a given
 mesh and should be used in dolfin programs in Python.  """
 
+
 class Argument(ufl.Argument):
     """UFL value: Representation of an argument to a form.
 
@@ -93,7 +92,7 @@ def TrialFunction(V, part=None):
     return Argument(V, 1, part)
 
 
-#--- TestFunctions and TrialFunctions ---
+# --- TestFunctions and TrialFunctions ---
 
 def Arguments(V, number):
     """UFL value: Create an Argument in a mixed space, and return a
diff --git a/python/dolfin/function/constant.py b/python/dolfin/function/constant.py
index e50c4d2..2c8e6e0 100644
--- a/python/dolfin/function/constant.py
+++ b/python/dolfin/function/constant.py
@@ -87,6 +87,8 @@ class Constant(ufl.Coefficient):
         self.rename(name, "a Constant")
 
     def assign(self, x):
+        if isinstance(x, Constant):
+            x = x._cpp_object
         return self._cpp_object.assign(x)
 
     def cell(self):
diff --git a/python/dolfin/function/expression.py b/python/dolfin/function/expression.py
index dbc9582..c460970 100644
--- a/python/dolfin/function/expression.py
+++ b/python/dolfin/function/expression.py
@@ -7,11 +7,6 @@
 # either version 3 of the License, or (at your option) any later
 # version.
 
-
-__all__ = ["UserExpression"]
-
-import hashlib
-from functools import reduce
 import types
 import numpy
 import ufl
@@ -21,6 +16,8 @@ from ufl.utils.indexflattening import (flatten_multiindex,
 import dolfin.cpp as cpp
 import dolfin.function.jit as jit
 
+__all__ = ["UserExpression"]
+
 
 def _select_element(family, cell, degree, value_shape):
     """Select finite element type for cases where user has not provided a
@@ -54,6 +51,7 @@ class _InterfaceExpression(cpp.function.Expression):
         # Wrap eval functions
         def wrapped_eval(self, values, x):
             self.user_expression.eval(values, x)
+
         def wrapped_eval_cell(self, values, x, cell):
             self.user_expression.eval_cell(values, x, cell)
 
@@ -97,7 +95,7 @@ class BaseExpression(ufl.Coefficient):
 
     def ufl_evaluate(self, x, component, derivatives):
         """Function used by ufl to evaluate the Expression"""
-        assert derivatives == () # TODO: Handle derivatives
+        assert derivatives == ()  # TODO: Handle derivatives
 
         if component:
             shape = self.ufl_shape
@@ -112,8 +110,8 @@ class BaseExpression(ufl.Coefficient):
             # Scalar evaluation
             return self(*x)
 
-    #def __call__(self, x):
-    #    return self._cpp_object(x)
+    # def __call__(self, x):
+    #     return self._cpp_object(x)
     def __call__(self, *args, **kwargs):
         # GNW: This function is copied from the old DOLFIN Python
         # code. It is far too complicated. There is no need to provide
@@ -143,7 +141,7 @@ class BaseExpression(ufl.Coefficient):
             if not isinstance(values, numpy.ndarray):
                 raise TypeError("expected a NumPy array for 'values'")
             if len(values) != value_size or not numpy.issubdtype(values.dtype, 'd'):
-                raise TypeError("expected a double NumPy array of length"\
+                raise TypeError("expected a double NumPy array of length"
                                 " %d for return values." % value_size)
             values_provided = True
         else:
@@ -171,7 +169,7 @@ class BaseExpression(ufl.Coefficient):
         # Convert it to an 1D numpy array
         try:
             x = numpy.fromiter(x, 'd')
-        except (TypeError, ValueError, AssertionError) as e:
+        except (TypeError, ValueError, AssertionError):
             raise TypeError("expected scalar arguments for the coordinates")
 
         if len(x) == 0:
@@ -186,7 +184,7 @@ class BaseExpression(ufl.Coefficient):
             pass
         else:
             if len(x) != dim:
-                raise TypeError("expected the geometry argument to be of "\
+                raise TypeError("expected the geometry argument to be of "
                                 "length %d" % dim)
 
         # The actual evaluation
@@ -238,7 +236,7 @@ class UserExpression(BaseExpression):
         domain = kwargs.pop("domain", None)
         name = kwargs.pop("name", None)
         label = kwargs.pop("label", None)
-        mpi_comm = kwargs.pop("mpi_comm", None)
+        # mpi_comm = kwargs.pop("mpi_comm", None)
         if (len(kwargs) > 0):
             raise RuntimeError("Invalid keyword argument")
 
@@ -289,9 +287,65 @@ class ExpressionParameters(object):
         return key in self._params
 
     def update(self, params):
-        for k,v in dict(params).items():
+        for k, v in dict(params).items():
             self[k] = v
 
+
+class CompiledExpression(BaseExpression):
+    """Wrap a compiled module of type cpp.Expression"""
+
+    def __init__(self, cpp_module=None, **kwargs):
+
+        # Remove arguments that are used in Expression creation
+        element = kwargs.pop("element", None)
+        degree = kwargs.pop("degree", None)
+        cell = kwargs.pop("cell", None)
+        domain = kwargs.pop("domain", None)
+        name = kwargs.pop("name", None)
+        label = kwargs.pop("label", None)
+        # mpi_comm = kwargs.pop("mpi_comm", None)
+
+        if not isinstance(cpp_module, cpp.function.Expression):
+            raise RuntimeError("Must supply compiled C++ Expression module to CompiledExpression")
+        else:
+            self._cpp_object = cpp_module
+
+            params = kwargs
+            for k, val in params.items():
+                if not isinstance(k, str):
+                    raise KeyError("User Parameter key must be a string")
+                if not hasattr(self._cpp_object, k):
+                    raise AttributeError("Compiled module does not have attribute %s", k)
+                setattr(self._cpp_object, k, val)
+
+        if element and degree:
+            raise RuntimeError("Cannot specify an element and a degree for Expressions.")
+
+        # Deduce element type if not provided
+        if element is None:
+            if degree is None:
+                raise KeyError("Must supply element or degree")
+            value_shape = tuple(self.value_dimension(i)
+                                for i in range(self.value_rank()))
+            if domain is not None and cell is None:
+                cell = domain.ufl_cell()
+            element = _select_element(family=None, cell=cell, degree=degree,
+                                      value_shape=value_shape)
+
+        BaseExpression.__init__(self, cell=cell, element=element, domain=domain,
+                                name=name, label=label)
+
+    def __getattr__(self, name):
+        if hasattr(self._cpp_object, name):
+            return getattr(self._cpp_object, name)
+
+    def __setattr__(self, name, value):
+        if name.startswith("_"):
+            super().__setattr__(name, value)
+        elif hasattr(self._cpp_object, name):
+            setattr(self._cpp_object, name, value)
+
+
 class Expression(BaseExpression):
     """JIT Expressions"""
 
@@ -308,13 +362,17 @@ class Expression(BaseExpression):
         domain = kwargs.pop("domain", None)
         name = kwargs.pop("name", None)
         label = kwargs.pop("label", None)
-        mpi_comm = kwargs.pop("mpi_comm", None)
+        # FIXME: feed mpi_comm through to JIT
+        # mpi_comm = kwargs.pop("mpi_comm", None)
 
-        if cpp_code is not None:
+        if not isinstance(cpp_code, (str, tuple, list)):
+            raise RuntimeError("Must supply C++ code to Expression. You may want to use UserExpression")
+        else:
             params = kwargs
             for k in params:
                 if not isinstance(k, str):
-                    raise KeyError("User Parameter key must be a string")
+                    raise KeyError("User parameter key must be a string")
+
             self._cpp_object = jit.compile_expression(cpp_code, params)
             self._parameters = ExpressionParameters(self._cpp_object, params)
 
diff --git a/python/dolfin/function/function.py b/python/dolfin/function/function.py
index 608e2a2..57a9807 100644
--- a/python/dolfin/function/function.py
+++ b/python/dolfin/function/function.py
@@ -19,10 +19,10 @@
 # You should have received a copy of the GNU Lesser General Public License
 # along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 
-import types
 import numpy as np
 import ufl
 from ufl.classes import ComponentTensor, Sum, Product, Division
+from ufl.utils.indexflattening import shape_to_strides, flatten_multiindex
 import dolfin.cpp as cpp
 import dolfin.la as la
 from dolfin.function.functionspace import FunctionSpace
@@ -33,6 +33,7 @@ from dolfin.function.constant import Constant
 def _assign_error():
     raise RuntimeError("Expected only linear combinations of Functions in the same FunctionSpaces")
 
+
 def _check_mul_and_division(e, linear_comb, scalar_weight=1.0, multi_index=None):
     """
     Utility func for checking division and multiplication of a Function
@@ -41,12 +42,12 @@ def _check_mul_and_division(e, linear_comb, scalar_weight=1.0, multi_index=None)
     from ufl.constantvalue import ScalarValue
     from ufl.classes import ComponentTensor, MultiIndex, Indexed
     from ufl.algebra import Division, Product, Sum
-    #ops = e.ufl_operands
+    # ops = e.ufl_operands
 
     # FIXME: What should be checked!?
     # martinal: This code has never done anything sensible,
     #   but I don't know what it was supposed to do so I can't fix it.
-    #same_multi_index = lambda x, y: (x.ufl_free_indices == y.ufl_free_indices \
+    # same_multi_index = lambda x, y: (x.ufl_free_indices == y.ufl_free_indices \
     #                        and x.ufl_index_dimensions == y.ufl_index_dimensions)
 
     assert isinstance(scalar_weight, float)
@@ -55,9 +56,9 @@ def _check_mul_and_division(e, linear_comb, scalar_weight=1.0, multi_index=None)
     if isinstance(e, Product):
         for i, op in enumerate(e.ufl_operands):
             if isinstance(op, ScalarValue) or \
-                   (isinstance(op, Constant) and op.value_size()==1):
+               (isinstance(op, Constant) and op.value_size() == 1):
                 scalar = op
-                expr = e.ufl_operands[1-i]
+                expr = e.ufl_operands[1 - i]
                 break
         else:
             _assign_error()
@@ -65,8 +66,8 @@ def _check_mul_and_division(e, linear_comb, scalar_weight=1.0, multi_index=None)
         scalar_weight *= float(scalar)
     elif isinstance(e, Division):
         expr, scalar = e.ufl_operands
-        if not (isinstance(scalar, ScalarValue) or \
-                isinstance(scalar, Constant) and scalar.value_rank()==1):
+        if not (isinstance(scalar, ScalarValue) or
+                isinstance(scalar, Constant) and scalar.value_rank() == 1):
             _assign_error()
         scalar_weight /= float(scalar)
     else:
@@ -82,7 +83,7 @@ def _check_mul_and_division(e, linear_comb, scalar_weight=1.0, multi_index=None)
         # Unpack Indexed and check equality with passed multi_index
         expr, multi_index2 = expr.ufl_operands
         assert isinstance(multi_index2, MultiIndex)
-        #if not same_multi_index(multi_index, multi_index2):
+        # if not same_multi_index(multi_index, multi_index2):
         #    _assign_error()
 
     if isinstance(expr, Function):
@@ -92,7 +93,7 @@ def _check_mul_and_division(e, linear_comb, scalar_weight=1.0, multi_index=None)
         # If componentTensor we need to unpack the MultiIndices
         if isinstance(expr, ComponentTensor):
             expr, multi_index = expr.ufl_operands
-            #if not same_multi_index(multi_index, multi_index2):
+            # if not same_multi_index(multi_index, multi_index2):
             #    _error()
 
         if isinstance(expr, (Product, Division)):
@@ -136,7 +137,7 @@ def _check_and_extract_functions(e, linear_comb=None, scalar_weight=1.0,
     # If not Product or Division we expect Sum
     elif isinstance(e, Sum):
         for op in e.ufl_operands:
-            linear_comb = _check_and_extract_functions(op, linear_comb, \
+            linear_comb = _check_and_extract_functions(op, linear_comb,
                                                        scalar_weight, multi_index)
 
     else:
@@ -162,7 +163,7 @@ def _check_and_contract_linear_comb(expr, self, multi_index):
             # Check if the exact same Function is already present
             ind = funcs.index(func)
             weights[ind] += weight
-        except:
+        except Exception:
             funcs.append(func)
             weights.append(weight)
 
@@ -195,7 +196,7 @@ class Function(ufl.Coefficient):
                     raise RuntimeError("No subfunctions to extract")
                 if not i < num_sub_spaces:
                     raise RuntimeError("Can only extract subfunctions "
-                                        "with i = 0..%d"% num_sub_spaces)
+                                       "with i = 0..%d" % num_sub_spaces)
                 self._cpp_object = cpp.function.Function(other._cpp_object, i)
                 ufl.Coefficient.__init__(self, self.function_space().ufl_function_space(),
                                          count=self._cpp_object.id())
@@ -203,7 +204,9 @@ class Function(ufl.Coefficient):
                 raise TypeError("expected one or two arguments when "
                                 "instantiating from another Function")
         elif isinstance(args[0], cpp.function.Function):
-            raise RuntimeError("Construction from a cpp function not implemented yet")
+            self._cpp_object = args[0]
+            ufl.Coefficient.__init__(self, self.function_space().ufl_function_space(),
+                                     count=self._cpp_object.id())
         elif isinstance(args[0], FunctionSpace):
             V = args[0]
 
@@ -251,14 +254,14 @@ class Function(ufl.Coefficient):
         """Function used by ufl to evaluate the Expression"""
         # FIXME: same as dolfin.expression.Expression version. Find
         # way to re-use.
-        assert derivatives == () # TODO: Handle derivatives
+        assert derivatives == ()   # TODO: Handle derivatives
 
         if component:
             shape = self.ufl_shape
             assert len(shape) == len(component)
-            value_size = product(shape)
+            value_size = ufl.product(shape)
             index = flatten_multiindex(component, shape_to_strides(shape))
-            values = numpy.zeros(value_size)
+            values = np.zeros(value_size)
             # FIXME: use a function with a return value
             self(*x, values=values)
             return values[index]
@@ -274,7 +277,7 @@ class Function(ufl.Coefficient):
         # Deprecate as many options as possible, and maybe share with
         # dolfin.expression.Expresssion.
 
-        if len(args)==0:
+        if len(args) == 0:
             raise TypeError("expected at least 1 argument")
 
         # Test for ufl restriction
@@ -295,9 +298,9 @@ class Function(ufl.Coefficient):
             if not isinstance(values, np.ndarray):
                 raise TypeError("expected a NumPy array for 'values'")
             if len(values) != value_size or \
-                   not np.issubdtype(values.dtype, 'd'):
-                raise TypeError("expected a double NumPy array of length"\
-                      " %d for return values."%value_size)
+               not np.issubdtype(values.dtype, 'd'):
+                raise TypeError("expected a double NumPy array of length"
+                                " %d for return values." % value_size)
             values_provided = True
         else:
             values_provided = False
@@ -320,15 +323,15 @@ class Function(ufl.Coefficient):
         # Convert it to an 1D numpy array
         try:
             x = np.fromiter(x, 'd')
-        except (TypeError, ValueError, AssertionError) as e:
+        except (TypeError, ValueError, AssertionError):
             raise TypeError("expected scalar arguments for the coordinates")
 
         if len(x) == 0:
             raise TypeError("coordinate argument too short")
 
         if len(x) != dim:
-            raise TypeError("expected the geometry argument to be of "\
-                  "length %d"%dim)
+            raise TypeError("expected the geometry argument to be of "
+                            "length %d" % dim)
 
         # The actual evaluation
         self._cpp_object.eval(values, x)
@@ -339,7 +342,7 @@ class Function(ufl.Coefficient):
 
         return values
 
-    #def _assign(self, u):
+    # def _assign(self, u):
     #    if isinstance(u, cpp.function.FunctionAXPY):
     #        self._cpp_object._assign(u)
 
@@ -361,8 +364,11 @@ class Function(ufl.Coefficient):
         else:
             self._cpp_object.interpolate(u)
 
-    def compute_vertex_values(self, mesh):
-        return self._cpp_object.compute_vertex_values(mesh)
+    def compute_vertex_values(self, mesh=None):
+        if mesh is not None:
+            return self._cpp_object.compute_vertex_values(mesh)
+        else:
+            return self._cpp_object.compute_vertex_values()
 
     def set_allow_extrapolation(self, value):
         self._cpp_object.set_allow_extrapolation(value)
@@ -492,7 +498,7 @@ class Function(ufl.Coefficient):
         if num_sub_spaces == 1:
             raise RuntimeError("No subfunctions to extract")
         if not i < num_sub_spaces:
-            raise RuntimeError("Can only extract subfunctions with i = 0..%d" \
+            raise RuntimeError("Can only extract subfunctions with i = 0..%d"
                                % num_sub_spaces)
 
         # Create and instantiate the Function
@@ -503,7 +509,6 @@ class Function(ufl.Coefficient):
         else:
             return Function(self, i, name='%s-%d' % (str(self), i))
 
-
     def split(self, deepcopy=False):
         """Extract any sub functions.
 
diff --git a/python/dolfin/function/functionspace.py b/python/dolfin/function/functionspace.py
index aad8f38..0127c8b 100644
--- a/python/dolfin/function/functionspace.py
+++ b/python/dolfin/function/functionspace.py
@@ -1,5 +1,4 @@
 # -*- coding: utf-8 -*-
-"""Main module for DOLFIN"""
 
 # Copyright (C) 2017 Chris N. Richardson and Garth N. Wells
 #
@@ -7,16 +6,14 @@
 # either version 3 of the License, or (at your option) any later
 # version.
 
-import types
-import ffc
 import ufl
 import dolfin.cpp as cpp
-from . import function
+from dolfin.jit.jit import ffc_jit
 
 
 class FunctionSpace(ufl.FunctionSpace):
 
-    def __init__(self,  *args, **kwargs):
+    def __init__(self, *args, **kwargs):
         """Create finite element function space."""
 
         if len(args) == 1:
@@ -25,10 +22,10 @@ class FunctionSpace(ufl.FunctionSpace):
             self._init_from_cpp(*args, **kwargs)
         else:
             if len(args) == 0 or not isinstance(args[0], cpp.mesh.Mesh):
-                #cpp.dolfin_error("functionspace.py",
-                #                 "create function space",
-                #                 "Illegal argument, not a mesh: "
-                #                 + str(args[0]))
+                # cpp.dolfin_error("functionspace.py",
+                #                  "create function space",
+                #                  "Illegal argument, not a mesh: "
+                #                  + str(args[0]))
                 pass
             elif len(args) == 2:
                 self._init_from_ufl(*args, **kwargs)
@@ -42,7 +39,8 @@ class FunctionSpace(ufl.FunctionSpace):
         ufl.FunctionSpace.__init__(self, mesh.ufl_domain(), element)
 
         # Compile dofmap and element
-        ufc_element, ufc_dofmap = ffc.jit(element, parameters=None)
+        ufc_element, ufc_dofmap = ffc_jit(element, form_compiler_parameters=None,
+                                          mpi_comm=mesh.mpi_comm())
         ufc_element = cpp.fem.make_ufc_finite_element(ufc_element)
 
         # Create DOLFIN element and dofmap
@@ -118,8 +116,8 @@ class FunctionSpace(ufl.FunctionSpace):
         if self.num_sub_spaces() == 1:
             raise ValueError("no SubSpaces to extract")
         if i >= self.num_sub_spaces():
-            raise ValueError("Can only extract SubSpaces with i = 0 ... %d" % \
-                  (self.num_sub_spaces() - 1))
+            raise ValueError("Can only extract SubSpaces with i = 0 ... %d" %
+                             (self.num_sub_spaces() - 1))
         assert hasattr(self.ufl_element(), "sub_elements")
 
         # Extend with the python layer
@@ -131,19 +129,16 @@ class FunctionSpace(ufl.FunctionSpace):
     def contains(self, V):
         "Check whether a function is in the FunctionSpace"
         return self._cpp_object.contains(V._cpp_object)
-        #if isinstance(u, cpp.function.Function):
-        #    return u._in(self)
-        #elif isinstance(u, function.Function):
-        #    return u._cpp_object._in(self)
-        #return False
 
     def __contains__(self, u):
         "Check whether a function is in the FunctionSpace"
-        if isinstance(u, cpp.function.Function):
+        try:
             return u._in(self._cpp_object)
-        elif isinstance(u, function.Function):
-            return u._cpp_object._in(self._cpp_object)
-        return False
+        except AttributeError:
+            try:
+                return u._cpp_object._in(self._cpp_object)
+            except Exception as e:
+                raise RuntimeError("Unable to check if object is in FunctionSpace ({})".format(e))
 
     def __eq__(self, other):
         "Comparison for equality."
diff --git a/python/dolfin/function/jit.py b/python/dolfin/function/jit.py
index 9ed4bdb..33163c9 100644
--- a/python/dolfin/function/jit.py
+++ b/python/dolfin/function/jit.py
@@ -7,7 +7,7 @@
 # either version 3 of the License, or (at your option) any later
 # version.
 
-import dolfin.cpp as cpp
+from dolfin.cpp.log import log, LogLevel
 from dolfin.jit.jit import compile_class, _math_header
 
 
@@ -27,6 +27,7 @@ def jit_generate(class_data, module_name, signature, parameters):
 #endif
 
 #include <dolfin/function/Expression.h>
+#include <dolfin/math/basic.h>
 #include <Eigen/Dense>
 
 {math_header}
@@ -85,6 +86,8 @@ extern "C" DLL_EXPORT dolfin::Expression * create_{classname}()
     _get_props = """          if (name == "{key_name}") return {name};"""
     _set_props = """          if (name == "{key_name}") {{ {name} = _value; return; }}"""
 
+    log(LogLevel.TRACE, "Calling dijitso just-in-time (JIT) compiler for Expression.")
+
     statements = class_data["statements"]
     statement = ""
     if isinstance(statements, str):
@@ -111,9 +114,9 @@ extern "C" DLL_EXPORT dolfin::Expression * create_{classname}()
         elif hasattr(value, "_cpp_object"):
             members += "std::shared_ptr<dolfin::GenericFunction> generic_function_{key};\n".format(key=k)
             set_generic_function += _set_props.format(key_name=k,
-                                                      name="generic_function_"+k)
+                                                      name="generic_function_" + k)
             get_generic_function += _get_props.format(key_name=k,
-                                                      name="generic_function_"+k)
+                                                      name="generic_function_" + k)
 
             value_size = value._cpp_object.value_size()
             if value_size == 1:
diff --git a/python/dolfin/function/specialfunctions.py b/python/dolfin/function/specialfunctions.py
index 3408915..a4ddf1d 100644
--- a/python/dolfin/function/specialfunctions.py
+++ b/python/dolfin/function/specialfunctions.py
@@ -21,14 +21,16 @@ SpecialFunctions.h).
 # You should have received a copy of the GNU Lesser General Public License
 # along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 
-__all__ = ["MeshCoordinates", "FacetArea", "FacetNormal", "CellSize",
-           "CellVolume", "SpatialCoordinate", "CellNormal",
-           "Circumradius", "MinFacetEdgeLength", "MaxFacetEdgeLength"]
-
 import ufl
 import dolfin.cpp as cpp
 from dolfin.function.expression import BaseExpression
 
+__all__ = ["MeshCoordinates", "FacetArea", "FacetNormal",
+           "CellVolume", "SpatialCoordinate", "CellNormal",
+           "CellDiameter", "Circumradius",
+           "MinCellEdgeLength", "MaxCellEdgeLength",
+           "MinFacetEdgeLength", "MaxFacetEdgeLength"]
+
 
 def _mesh2domain(mesh):
     "Deprecation mechanism for symbolic geometry."
@@ -44,6 +46,7 @@ class MeshCoordinates(BaseExpression):
         vertex.
 
         """
+
         # Initialize C++ part
         self._cpp_object = cpp.function.MeshCoordinates(mesh)
 
@@ -78,14 +81,15 @@ class FacetArea(BaseExpression):
         # Initialize UFL part
         # NB! This is defined as a piecewise constant function for
         # each cell, not for each facet!
-        ufl_element = ufl.FiniteElement("Discontinuous Lagrange", mesh.ufl_cell(), 0)
-        super().__init__(domain=mesh.ufl_domain(), element=ufl_element, label="FacetArea")
+        ufl_element = ufl.FiniteElement("Discontinuous Lagrange",
+                                        mesh.ufl_cell(), 0)
+        super().__init__(domain=mesh.ufl_domain(),
+                         element=ufl_element, label="FacetArea")
 
 
 # Simple definition of FacetNormal via UFL
 def FacetNormal(mesh):
-    """
-    Return symbolic facet normal for given mesh.
+    """Return symbolic facet normal for given mesh.
 
     *Arguments*
         mesh
@@ -104,9 +108,12 @@ def FacetNormal(mesh):
     return ufl.FacetNormal(_mesh2domain(mesh))
 
 
-# Simple definition of CellSize via UFL
-def CellSize(mesh):
-    """Return function cell size for given mesh.
+# Simple definition of CellDiameter via UFL
+def CellDiameter(mesh):
+    """Return function cell diameter for given mesh.
+
+    Note that diameter of cell :math:`K` is defined as
+    :math:`\sup_{\mathbf{x,y}\in K} |\mathbf{x-y}|`.
 
     *Arguments*
         mesh
@@ -117,11 +124,11 @@ def CellSize(mesh):
         .. code-block:: python
 
             mesh = UnitSquare(4,4)
-            h = CellSize(mesh)
+            h = CellDiameter(mesh)
 
     """
 
-    return 2.0*ufl.Circumradius(_mesh2domain(mesh))
+    return ufl.CellDiameter(_mesh2domain(mesh))
 
 
 # Simple definition of CellVolume via UFL
@@ -157,7 +164,7 @@ def SpatialCoordinate(mesh):
         .. code-block:: python
 
             mesh = UnitSquare(4,4)
-            vol = SpatialCoordinate(mesh)
+            x = SpatialCoordinate(mesh)
 
     """
 
@@ -177,7 +184,7 @@ def CellNormal(mesh):
         .. code-block:: python
 
             mesh = UnitSquare(4,4)
-            vol = CellNormal(mesh)
+            n = CellNormal(mesh)
 
     """
 
@@ -197,17 +204,59 @@ def Circumradius(mesh):
         .. code-block:: python
 
             mesh = UnitSquare(4,4)
-            vol = Circumradius(mesh)
+            R = Circumradius(mesh)
 
     """
 
     return ufl.Circumradius(_mesh2domain(mesh))
 
 
+# Simple definition of MinCellEdgeLength via UFL
+def MinCellEdgeLength(mesh):
+    """Return symbolic minimum cell edge length of a cell
+    for given mesh.
+
+    *Arguments*
+        mesh
+            a :py:class:`Mesh <dolfin.cpp.Mesh>`.
+
+    *Example of usage*
+
+        .. code-block:: python
+
+            mesh = UnitSquare(4,4)
+            mince = MinCellEdgeLength(mesh)
+
+    """
+
+    return ufl.MinCellEdgeLength(_mesh2domain(mesh))
+
+
+# Simple definition of MaxCellEdgeLength via UFL
+def MaxCellEdgeLength(mesh):
+    """Return symbolic maximum cell edge length of a cell
+    for given mesh.
+
+    *Arguments*
+        mesh
+            a :py:class:`Mesh <dolfin.cpp.Mesh>`.
+
+    *Example of usage*
+
+        .. code-block:: python
+
+            mesh = UnitSquare(4,4)
+            maxce = MaxCellEdgeLength(mesh)
+
+    """
+
+    return ufl.MaxCellEdgeLength(_mesh2domain(mesh))
+
+
 # Simple definition of MinFacetEdgeLength via UFL
 def MinFacetEdgeLength(mesh):
-    """Return symbolic minimum facet edge length of a cell for given
-    mesh.
+    """Return symbolic minimum facet edge length of a cell
+    for given mesh.
 
     *Arguments*
         mesh
@@ -227,8 +276,8 @@ def MinFacetEdgeLength(mesh):
 
 # Simple definition of MaxFacetEdgeLength via UFL
 def MaxFacetEdgeLength(mesh):
-    """
-    Return symbolic maximum facet edge length of a cell for given mesh.
+    """Return symbolic maximum facet edge length of a cell
+    for given mesh.
 
     *Arguments*
         mesh
@@ -239,7 +288,7 @@ def MaxFacetEdgeLength(mesh):
         .. code-block:: python
 
             mesh = UnitSquare(4,4)
-            vol = MaxFacetEdgeLength(mesh)
+            maxfe = MaxFacetEdgeLength(mesh)
 
     """
 
diff --git a/python/dolfin/jit/__init__.py b/python/dolfin/jit/__init__.py
index 54036f2..66e9d05 100644
--- a/python/dolfin/jit/__init__.py
+++ b/python/dolfin/jit/__init__.py
@@ -16,7 +16,7 @@ def get_pybind_include():
         # Get include paths from module
         import pybind11
         return [pybind11.get_include(True), pybind11.get_include()]
-    except:
+    except Exception:
         pass
 
     # Look in /usr/local/include and /usr/include
diff --git a/python/dolfin/jit/jit.py b/python/dolfin/jit/jit.py
index b2b08a6..58aa64c 100644
--- a/python/dolfin/jit/jit.py
+++ b/python/dolfin/jit/jit.py
@@ -5,6 +5,99 @@ import hashlib
 import dijitso
 import dolfin.cpp as cpp
 
+from dolfin.cpp import MPI
+from functools import wraps
+import ffc
+from dolfin.cpp.parameter import parameters
+
+
+# Copied over from site-packages
+def mpi_jit_decorator(local_jit, *args, **kwargs):
+    """A decorator for jit compilation
+
+    Use this function as a decorator to any jit compiler function.  In
+    a parallel run, this function will first call the jit compilation
+    function on the first process. When this is done, and the module
+    is in the cache, it will call the jit compiler on the remaining
+    processes, which will then use the cached module.
+
+    *Example*
+        .. code-block:: python
+
+            def jit_something(something):
+                ....
+
+    """
+    @wraps(local_jit)
+    def mpi_jit(*args, **kwargs):
+
+        # FIXME: should require mpi_comm to be explicit
+        # and not default to comm_world?
+        mpi_comm = kwargs.pop("mpi_comm", MPI.comm_world)
+
+        # Just call JIT compiler when running in serial
+        if MPI.size(mpi_comm) == 1:
+            return local_jit(*args, **kwargs)
+
+        # Default status (0 == ok, 1 == fail)
+        status = 0
+
+        # Compile first on process 0
+        root = MPI.rank(mpi_comm) == 0
+        if root:
+            try:
+                output = local_jit(*args, **kwargs)
+            except Exception as e:
+                status = 1
+                error_msg = str(e)
+
+        # TODO: This would have lower overhead if using the dijitso.jit
+        # features to inject a waiting callback instead of waiting out here.
+        # That approach allows all processes to first look in the cache,
+        # introducing a barrier only on cache miss.
+        # There's also a sketch in dijitso of how to make only one
+        # process per physical cache directory do the compilation.
+
+        # Wait for the compiling process to finish and get status
+        # TODO: Would be better to broadcast the status from root but this works.
+        global_status = MPI.max(mpi_comm, status)
+
+        if global_status == 0:
+            # Success, call jit on all other processes
+            # (this should just read the cache)
+            if not root:
+                output = local_jit(*args, **kwargs)
+        else:
+            # Fail simultaneously on all processes,
+            # to allow catching the error without deadlock
+            if not root:
+                error_msg = "Compilation failed on root node."
+            cpp.dolfin_error("jit.py",
+                             "perform just-in-time compilation of form",
+                             error_msg)
+        return output
+
+    # Return the decorated jit function
+    return mpi_jit
+
+
+# Wrap FFC JIT compilation with decorator
+ at mpi_jit_decorator
+def ffc_jit(ufl_form, form_compiler_parameters=None):
+
+    # Prepare form compiler parameters with overrides from dolfin and kwargs
+    p = ffc.default_jit_parameters()
+    p.update(dict(parameters["form_compiler"]))
+    p.update(form_compiler_parameters or {})
+    return ffc.jit(ufl_form, parameters=p)
+
+
+# Wrap dijitso JIT compilation with decorator
+ at mpi_jit_decorator
+def dijitso_jit(*args, **kwargs):
+    return dijitso.jit(*args, **kwargs)
+
+
 _cpp_math_builtins = [
     # <cmath> functions: from http://www.cplusplus.com/reference/cmath/
     "cos", "sin", "tan", "acos", "asin", "atan", "atan2",
@@ -61,7 +154,7 @@ def compile_class(cpp_data):
     # Make a string representing the properties (and distinguish float/GenericFunction)
     # by adding '*' for GenericFunction
     property_str = ''
-    for k,v in properties.items():
+    for k, v in properties.items():
         property_str += str(k)
         if hasattr(v, '_cpp_object') and isinstance(v._cpp_object, cpp.function.GenericFunction):
             property_str += '*'
@@ -71,10 +164,10 @@ def compile_class(cpp_data):
     module_name = "dolfin_" + name + "_" + module_hash
 
     try:
-        module, signature = dijitso.jit(cpp_data, module_name, params,
+        module, signature = dijitso_jit(cpp_data, module_name, params,
                                         generate=cpp_data['jit_generate'])
         submodule = dijitso.extract_factory_function(module, "create_" + module_name)()
-    except:
+    except Exception:
         raise RuntimeError("Unable to compile C++ code with dijitso")
 
     if name == 'expression':
diff --git a/python/dolfin/jit/pybind11jit.py b/python/dolfin/jit/pybind11jit.py
index 255d81a..a9d08e1 100644
--- a/python/dolfin/jit/pybind11jit.py
+++ b/python/dolfin/jit/pybind11jit.py
@@ -5,14 +5,18 @@ import dijitso
 import pkgconfig
 import re
 
-import dolfin.cpp as cpp
+from dolfin.cpp.log import log, LogLevel
 from . import get_pybind_include
-from dolfin.function.expression import BaseExpression, _select_element
+
+from dolfin.jit.jit import dijitso_jit
 
 
 def jit_generate(cpp_code, module_name, signature, parameters):
 
-    # Split code on reserved word "SIGNATURE" which will be replaced by the module signature
+    log(LogLevel.TRACE, "Calling dijitso just-in-time (JIT) compiler for pybind11 code.")
+
+    # Split code on reserved word "SIGNATURE" which will be replaced
+    # by the module signature
     # This must occur only once in the code
     split_cpp_code = re.split('SIGNATURE', cpp_code)
     if len(split_cpp_code) < 2:
@@ -27,9 +31,12 @@ def jit_generate(cpp_code, module_name, signature, parameters):
 
     return code_h, code_c, depends
 
+
 def compile_cpp_code(cpp_code):
-    """Compile a user C(++) string to a Python object with pybind11.  Note
-       this is still experimental.
+    """Compile a user C(++) string and expose as a Python object with
+    pybind11.
+
+    Note: this is experimental
 
     """
 
@@ -37,7 +44,7 @@ def compile_cpp_code(cpp_code):
         raise RuntimeError("Could not find DOLFIN pkg-config file. Please make sure appropriate paths are set.")
 
     # Get pkg-config data for DOLFIN
-    d = pkgconfig.parse('dolfin')
+    dolfin_pc = pkgconfig.parse('dolfin')
 
     # Set compiler/build options
     # FIXME: need to locate Python libs and pybind11
@@ -47,32 +54,35 @@ def compile_cpp_code(cpp_code):
     params['cache']['lib_prefix'] = ""
     params['cache']['lib_basename'] = ""
     params['cache']['lib_loader'] = "import"
-    params['build']['include_dirs'] = d["include_dirs"] + get_pybind_include() + [sysconfig.get_config_var("INCLUDEDIR") + "/" + pyversion]
-    params['build']['libs'] = d["libraries"] + [ pyversion ]
-    params['build']['lib_dirs'] = d["library_dirs"] + [sysconfig.get_config_var("LIBDIR")]
+
+    # Include path and library info from DOLFIN (dolfin.pc)
+    params['build']['include_dirs'] = dolfin_pc["include_dirs"] + get_pybind_include() + [sysconfig.get_config_var("INCLUDEDIR") + "/" + pyversion]
+    params['build']['libs'] = dolfin_pc["libraries"] + [pyversion]
+    params['build']['lib_dirs'] = dolfin_pc["library_dirs"] + [sysconfig.get_config_var("LIBDIR")]
+
     params['build']['cxxflags'] += ('-fno-lto',)
 
-    # enable all define macros from DOLFIN
+    # Enable all macros from dolfin.pc
     dmacros = ()
-    for dm in d['define_macros']:
+    for dm in dolfin_pc['define_macros']:
         if len(dm[1]) == 0:
-            dmacros += ('-D'+dm[0],)
+            dmacros += ('-D' + dm[0],)
         else:
-            dmacros += ('-D'+dm[0]+'='+dm[1],)
+            dmacros += ('-D' + dm[0] + '=' + dm[1],)
 
     params['build']['cxxflags'] += dmacros
 
     # This seems to be needed by OSX but not in Linux
     # FIXME: probably needed for other libraries too
-    if cpp.common.has_petsc():
-        import os
-        params['build']['libs'] += ['petsc']
-        params['build']['lib_dirs'] += [os.environ["PETSC_DIR"] + "/lib"]
+    # if cpp.common.has_petsc():
+    #     import os
+    #     params['build']['libs'] += ['petsc']
+    #     params['build']['lib_dirs'] += [os.environ["PETSC_DIR"] + "/lib"]
 
     module_hash = hashlib.md5(cpp_code.encode('utf-8')).hexdigest()
     module_name = "dolfin_cpp_module_" + module_hash
 
-    module, signature = dijitso.jit(cpp_code, module_name, params,
+    module, signature = dijitso_jit(cpp_code, module_name, params,
                                     generate=jit_generate)
 
     return module
diff --git a/python/dolfin/la/__init__.py b/python/dolfin/la/__init__.py
index ca2a0f7..2b7b4df 100644
--- a/python/dolfin/la/__init__.py
+++ b/python/dolfin/la/__init__.py
@@ -14,7 +14,7 @@ def as_backend_type(x):
     type.
 
     """
-    if isinstance(x, cpp.la.Vector) or isinstance(x, cpp.la.Matrix):
+    if isinstance(x, cpp.la.Vector) or isinstance(x, cpp.la.Matrix) or isinstance(x, cpp.la.LinearOperator):
         return x.instance()
     else:
         return x
@@ -22,44 +22,48 @@ def as_backend_type(x):
 
 # Extend GenericVector
 def __gt__(self, value):
+    "Returns a boolean array with > status for all elements"
     if np.isscalar(value):
-        return self.array() > value
-    if np.isinstance(value, dolfin.cpp.la.GenericVector):
-        return self.array() > value.array()
-    return NotImplemented
+        return self.get_local() > value
+    else:
+        return self.get_local() > value.get_local()
+
 
 cpp.la.GenericVector.__gt__ = __gt__
 del __gt__
 
 
 def __ge__(self, value):
-    if isscalar(value):
-        return self.array() >= value
-    if isinstance(value, dolfin.cpp.la.GenericVector):
-        return self.array() >= value.array()
-    return NotImplemented
+    "Returns a boolean array with >= status for all elements"
+    if np.isscalar(value):
+        return self.get_local() >= value
+    else:
+        return self.get_local() >= value.get_local()
+
 
 cpp.la.GenericVector.__ge__ = __ge__
 del __ge__
 
 
 def __lt__(self, value):
+    "Returns a boolean array with < status for all elements"
     if np.isscalar(value):
-        return self.array() < value
-    if isinstance(value, dolfin.cpp.la.GenericVector):
-        return self.array() < value.array()
-    return NotImplemented
+        return self.get_local() < value
+    else:
+        return self.get_local() < value.get_local()
+
 
 cpp.la.GenericVector.__lt__ = __lt__
 del __lt__
 
 
 def __le__(self, value):
+    "Returns a boolean array with <= status for all elements"
     if np.isscalar(value):
-        return self.array() <= value
-    if isinstance(value, dolfin.cpp.la.GenericVector):
-        return self.array() <= value.array()
-    return NotImplemented
+        return self.get_local() <= value
+    else:
+        return self.get_local() <= value.get_local()
+
 
 cpp.la.GenericVector.__le__ = __le__
 del __le__
@@ -67,10 +71,10 @@ del __le__
 
 def __eq__(self, value):
     if np.isscalar(value):
-        return self.array() == value
-    if isinstance(value, dolfin.cpp.la.GenericVector):
-        return self.array() == value.array()
-    return NotImplemented
+        return self.get_local() == value
+    else:
+        return self.get_local() == value.get_local()
+
 
 cpp.la.GenericVector.__eq__ = __eq__
 del __eq__
@@ -79,5 +83,7 @@ del __eq__
 def __iter__(self):
     for i in range(self.local_size()):
         yield self[i]
+
+
 cpp.la.GenericVector.__iter__ = __iter__
 del __iter__
diff --git a/python/dolfin/la/solver.py b/python/dolfin/la/solver.py
new file mode 100644
index 0000000..7ed2a6e
--- /dev/null
+++ b/python/dolfin/la/solver.py
@@ -0,0 +1,72 @@
+# -*- coding: utf-8 -*-
+"""This module provides a small Python layer for solving linear
+sytems.
+
+"""
+
+# Copyright (C) 2011-2017 Ander Logg and Garth N. Wells
+#
+# This file is part of DOLFIN.
+#
+# DOLFIN is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# DOLFIN 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+
+import dolfin.cpp as cpp
+
+
+def solve(A, x, b, method="default", preconditioner="default"):
+    """Solve linear system Ax = b.
+
+    A linear system Ax = b may be solved by calling solve(A, x, b),
+    where A is a matrix and x and b are vectors. Optional arguments
+    may be passed to specify the solver method and preconditioner.
+    Some examples are given below:
+
+    .. code-block:: python
+
+        solve(A, x, b)
+        solve(A, x, b, "lu")
+        solve(A, x, b, "gmres", "ilu")
+
+    Possible values for the solver method and preconditioner depend
+    on which linear algebra backend is used and how that has been
+    configured.
+
+    To list all available LU methods, run the following command:
+
+    .. code-block:: python
+
+        list_lu_solver_methods()
+
+    To list all available Krylov methods, run the following command:
+
+    .. code-block:: python
+
+        list_krylov_solver_methods()
+
+    To list all available preconditioners, run the following command:
+
+    .. code-block:: python
+
+        list_krylov_solver_preconditioners()
+
+    To list all available solver methods, including LU methods, Krylov
+    methods and, possibly, other methods, run the following command:
+
+    .. code-block:: python
+
+        list_linear_solver_methods()
+
+    """
+
+    return cpp.la.solve(A, x, b, method, preconditioner)
diff --git a/python/dolfin/mesh/__init__.py b/python/dolfin/mesh/__init__.py
index 7ee5070..f3a5302 100644
--- a/python/dolfin/mesh/__init__.py
+++ b/python/dolfin/mesh/__init__.py
@@ -4,6 +4,7 @@ from . import svgtools
 
 # Functions to extend cpp.mesh.Mesh with
 
+
 def ufl_cell(self):
     return ufl.Cell(self.cell_name(),
                     geometric_dimension=self.geometry().dim())
@@ -19,6 +20,7 @@ def ufl_coordinate_element(self):
     return ufl.VectorElement("Lagrange", cell, degree,
                              dim=cell.geometric_dimension())
 
+
 def ufl_domain(self):
     """Returns the ufl domain corresponding to the mesh."""
     # Cache object to avoid recreating it a lot
@@ -41,6 +43,7 @@ def _repr_html_(self):
 def _repr_svg_(self):
     return svgtools.mesh2svg(self)
 
+
 # Extend cpp.mesh.Mesh class, and clean-up
 cpp.mesh.Mesh.ufl_cell = ufl_cell
 cpp.mesh.Mesh.ufl_coordinate_element = ufl_coordinate_element
diff --git a/python/dolfin/mesh/ale.py b/python/dolfin/mesh/ale.py
index bd895f0..02e26af 100644
--- a/python/dolfin/mesh/ale.py
+++ b/python/dolfin/mesh/ale.py
@@ -19,10 +19,12 @@
 # First added:  2009-02-12
 # Last changed: 2012-09-28
 
+from dolfin.cpp.mesh import Vertex, edges
+from dolfin.cpp.log import info
+from dolfin import cpp
+
 __all__ = ["compute_vertex_map", "compute_edge_map", "init_parent_edge_indices"]
 
-from dolfin.cpp.mesh import Vertex
-from dolfin import cpp
 
 def compute_vertex_map(mesh0, mesh1):
     """
@@ -43,9 +45,7 @@ def compute_vertex_map(mesh0, mesh1):
 
     # Check arguments
     if not isinstance(mesh0, cpp.mesh.Mesh) or not isinstance(mesh1, cpp.mesh.Mesh):
-        cpp.dolfin_error("ale.py",
-                         "compute vertex map",
-                         "Expected 'Mesh' as argument")
+        raise RuntimeError("Compute vertex map. Expected 'Mesh' as argument.")
 
     # Get parent vertex numbers
     vertices0 = mesh0.data().array("parent_vertex_indices", 0)
@@ -53,9 +53,7 @@ def compute_vertex_map(mesh0, mesh1):
 
     # Check mappings
     if vertices0 is None or vertices1 is None:
-        cpp.dolfin_error("ale.py",
-                         "compute vertex map",
-                         "Parent vertex indices are missing")
+        raise RuntimeError("Compute vertex map. Parent vertex indices are missing")
 
     # Compute parent-to-local mapping for mesh1
     parent_to_local_mesh1 = {}
@@ -71,6 +69,7 @@ def compute_vertex_map(mesh0, mesh1):
 
     return vertex_map
 
+
 def compute_edge_map(mesh0, mesh1):
     """
     Compute map from edges of mesh0 to vertices of mesh1.
@@ -90,19 +89,15 @@ def compute_edge_map(mesh0, mesh1):
 
     # Check arguments
     if not isinstance(mesh0, cpp.mesh.Mesh) or not isinstance(mesh1, cpp.mesh.Mesh):
-        cpp.dolfin_error("ale.py",
-                         "compute edge map",
-                         "Expected 'Mesh' as argument")
+        raise RuntimeError("Compute edge map. Expected 'Mesh' as argument.")
 
     # Get parent vertex numbers
     vertices0 = mesh0.data().array("parent_vertex_indices", 0)
     vertices1 = mesh1.data().array("parent_vertex_indices", 0)
 
     # Check mappings
-    if len(vertices0) == 0  or len(vertices1) == 0:
-        cpp.dolfin_error("ale.py",
-                         "compute edge map",
-                         "Parent vertex indices are missing")
+    if len(vertices0) == 0 or len(vertices1) == 0:
+        raise RuntimeError("Compute edge map. Parent vertex indices are missing.")
 
     # Initialize edges
     mesh0.init(1)
@@ -132,14 +127,13 @@ def compute_edge_map(mesh0, mesh1):
 
     return edge_map
 
+
 def init_parent_edge_indices(submesh, mesh):
     "Initialize data 'parent_edge_indices' for submesh."
 
     # Check arguments
     if not isinstance(submesh, cpp.mesh.Mesh) or not isinstance(mesh, cpp.mesh.Mesh):
-        cpp.dolfin_error("ale.py",
-                         "initialize parent edge indices",
-                         "Expected 'Mesh' as argument")
+        raise RuntimeError("Initialize parent edge indices. Expected 'Mesh' as argument")
 
     # Check if edge map has already been computed
     if not submesh.data().exists("parent_edge_indices", 1):
@@ -148,9 +142,7 @@ def init_parent_edge_indices(submesh, mesh):
     # Get parent vertex numbers
     parent_vertex_indices = submesh.data().array("parent_vertex_indices", 0)
     if parent_vertex_indices is None:
-        cpp.dolfin_error("ale.py",
-                         "initialize parent edge indices",
-                         "Parent vertex indice are missing")
+        raise RuntimeError("Initialize parent edge indices. Parent vertex indice are missing.")
 
     # Make sure that we have edges for both meshes
     submesh.init(1)
@@ -177,9 +169,7 @@ def init_parent_edge_indices(submesh, mesh):
         # Check intersection
         common_edges = edges0.intersection(edges1)
         if not len(common_edges) == 1:
-            cpp.dolfin_error("ale.py",
-                             "initialize parent edge indices",
-                             "Parent vertices do not share exactly one common edge")
+            raise RuntimeError("Initialize parent edge indices. Parent vertices do not share exactly one common edge")
         parent_edge_index = list(common_edges)[0]
 
         # Set value
diff --git a/python/dolfin/mesh/meshfunction.py b/python/dolfin/mesh/meshfunction.py
index 183f9a1..203e4c0 100644
--- a/python/dolfin/mesh/meshfunction.py
+++ b/python/dolfin/mesh/meshfunction.py
@@ -1,6 +1,6 @@
-
 import dolfin.cpp as cpp
 
+
 _meshfunction_types = {"bool": cpp.mesh.MeshFunctionBool,
                        "size_t": cpp.mesh.MeshFunctionSizet,
                        "int": cpp.mesh.MeshFunctionInt,
@@ -16,60 +16,3 @@ class MeshFunction(object):
             return fn(mesh, dim, value)
         else:
             return fn(mesh, dim)
-
-
-class VertexFunction(object):
-    def __new__(cls, value_type, mesh, value=None):
-        if value_type not in _meshfunction_types.keys():
-            raise KeyError("MeshFunction type not recognised")
-        fn = _meshfunction_types[value_type]
-        if value is not None:
-            return fn(mesh, 0, value)
-        else:
-            return fn(mesh, 0)
-
-
-class EdgeFunction(object):
-    def __new__(cls, value_type, mesh, value=None):
-        if value_type not in _meshfunction_types.keys():
-            raise KeyError("MeshFunction type not recognised")
-        fn = _meshfunction_types[value_type]
-        if value is not None:
-            return fn(mesh, 1, value)
-        else:
-            return fn(mesh, 1)
-
-
-class FaceFunction(object):
-    def __new__(cls, value_type, mesh, value=None):
-        if value_type not in _meshfunction_types.keys():
-            raise KeyError("MeshFunction type not recognised")
-        fn = _meshfunction_types[value_type]
-        if value is not None:
-            return fn(mesh, 2, value)
-        else:
-            return fn(mesh, 2)
-
-
-class FacetFunction(object):
-    def __new__(cls, value_type, mesh, value=None):
-        if value_type not in _meshfunction_types.keys():
-            raise KeyError("MeshFunction type not recognised")
-        fn = _meshfunction_types[value_type]
-        tdim = mesh.topology().dim() - 1
-        if value is not None:
-            return fn(mesh, tdim, value)
-        else:
-            return fn(mesh, tdim)
-
-
-class CellFunction(object):
-    def __new__(cls, value_type, mesh, value=None):
-        if value_type not in _meshfunction_types.keys():
-            raise KeyError("MeshFunction type not recognised")
-        fn = _meshfunction_types[value_type]
-        tdim = mesh.topology().dim()
-        if value is not None:
-            return fn(mesh, tdim, value)
-        else:
-            return fn(mesh, tdim)
diff --git a/python/dolfin/mesh/subdomain.py b/python/dolfin/mesh/subdomain.py
index e68c80b..4e539e5 100644
--- a/python/dolfin/mesh/subdomain.py
+++ b/python/dolfin/mesh/subdomain.py
@@ -1,8 +1,23 @@
-import hashlib
-import types
-import dijitso
-import ffc
+# -*- coding: utf-8 -*-
+# Copyright (C) 2017 Chris N. Richardson and Garth N. Wells
+#
+# This file is part of DOLFIN.
+#
+# DOLFIN is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# DOLFIN 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+
 import dolfin.cpp as cpp
+from dolfin.cpp.log import log, LogLevel
 from dolfin.jit.jit import compile_class, _math_header
 
 
@@ -68,6 +83,8 @@ extern "C" DLL_EXPORT dolfin::SubDomain * create_{classname}()
     _set_prop = """ if (name == "{name}") {name} = value;\n"""
     _get_prop = """ if (name == "{name}") return {name};\n"""
 
+    log(LogLevel.TRACE, "Calling dijitso just-in-time (JIT) compiler for SubDomain.")
+
     inside_code = class_data['statements'][0]
 
     members = ""
@@ -75,8 +92,8 @@ extern "C" DLL_EXPORT dolfin::SubDomain * create_{classname}()
     set_props = ""
     for k in class_data['properties']:
         members += " double " + k + ";\n"
-        get_props += _get_prop.format(name = k)
-        set_props += _set_prop.format(name = k)
+        get_props += _get_prop.format(name=k)
+        set_props += _set_prop.format(name=k)
 
     classname = signature
     code_c = template_code.format(inside=inside_code,
diff --git a/python/dolfin/mesh/svgtools.py b/python/dolfin/mesh/svgtools.py
index f55ac72..b8b870a 100644
--- a/python/dolfin/mesh/svgtools.py
+++ b/python/dolfin/mesh/svgtools.py
@@ -45,15 +45,15 @@ def mesh2svg(mesh, display_width=800.0):
 
     # Compute mesh size
     strokewidth = 2
-    mesh_origin = [x[:,k].min() for k in range(d)]
-    x_min = [x[:,k].min() for k in range(d)]
-    x_max = [x[:,k].max() for k in range(d)]
+    #    mesh_origin = [x[:,k].min() for k in range(d)]
+    x_min = [x[:, k].min() for k in range(d)]
+    x_max = [x[:, k].max() for k in range(d)]
     if d == 1:
-        mesh_width  = x_max[0]-x_min[0]
+        mesh_width = x_max[0] - x_min[0]
         mesh_height = 0
     elif d == 2:
-        mesh_width  = x_max[0]-x_min[0]
-        mesh_height = x_max[1]-x_min[1]
+        mesh_width = x_max[0] - x_min[0]
+        mesh_height = x_max[1] - x_min[1]
 
     # Compute display scaling
     scale = float(display_width / mesh_width)
@@ -61,38 +61,38 @@ def mesh2svg(mesh, display_width=800.0):
                          strokewidth)
 
     # Add padding to include vertex circles
-    display_padding = 10*strokewidth
-    display_width = 2*display_padding + display_width
-    display_height = 2*display_padding + display_height
+    display_padding = 10 * strokewidth
+    display_width = 2 * display_padding + display_width
+    display_height = 2 * display_padding + display_height
 
     # Build list of screen coordinate vertices
     vertices = []
     if d == 1:
-        vertices = [(display_padding + int(scale*(x[i,0] - x_min[0])),
+        vertices = [(display_padding + int(scale * (x[i, 0] - x_min[0])),
                      display_padding)
                     for i in range(num_vertices)]
     elif d == 2:
         # Mirror y-axis because of svg coordinate system
-        vertices = [(display_padding + int(scale*(x[i,0] - x_min[0])),
-                     display_padding + int(scale*(x_max[1] - x[i,1])))
+        vertices = [(display_padding + int(scale * (x[i, 0] - x_min[0])),
+                     display_padding + int(scale * (x_max[1] - x[i, 1])))
                     for i in range(num_vertices)]
 
     # Build list of edges
     if cellname == "interval":
         # Build list of unique edges in 1D case
-        edges = [(c[i,0], c[i,1]) for i in range(num_cells)]
-    elif cellname == "triangle": # Should in principle work for quadrilateral as well
+        edges = [(c[i, 0], c[i, 1]) for i in range(num_cells)]
+    elif cellname == "triangle":  # Should in principle work for quadrilateral as well
         # Build list of unique edges in 2D case
         edges = set()
         for i in range(num_cells):
             for j in range(nv):
-                e = (c[i,j], c[i,(j+1)%nv])
+                e = (c[i, j], c[i, (j + 1) % nv])
                 edges.add(tuple(sorted(e)))
         edges = sorted(edges)
     else:
         edges = []
     # Build lines for all edges
-    lines = [(vertices[e0], vertices[e1]) for e0,e1 in edges]
+    lines = [(vertices[e0], vertices[e1]) for e0, e1 in edges]
 
     # Render svg code
     radius = strokewidth
diff --git a/python/dolfin/multistage/__init__.py b/python/dolfin/multistage/__init__.py
index a687677..2712a52 100644
--- a/python/dolfin/multistage/__init__.py
+++ b/python/dolfin/multistage/__init__.py
@@ -5,13 +5,13 @@ from dolfin.multistage import multistagescheme
 from dolfin.multistage import multistagesolvers
 from dolfin.multistage import rushlarsenschemes
 
-from .multistagescheme import *
-from .multistagesolvers import *
-from .rushlarsenschemes import *
+from .multistagescheme import *  # noqa
+from .multistagesolvers import *  # noqa
+from .rushlarsenschemes import *  # noqa
 
 # NOTE: The automatic documentation system in DOLFIN requires to _not_
 # define classes or functions within this file. Use separate modules
 # for that purpose.
 
 __all__ = multistagescheme.__all__ + multistagesolvers.__all__ + \
-          rushlarsenschemes.__all__
+    rushlarsenschemes.__all__
diff --git a/python/dolfin/multistage/factorize.py b/python/dolfin/multistage/factorize.py
index 82816ef..efbc505 100644
--- a/python/dolfin/multistage/factorize.py
+++ b/python/dolfin/multistage/factorize.py
@@ -26,16 +26,18 @@ component.
 # First added:  2014-11-28
 # Last changed: 2014-11-28
 
-from ufl import *
+# from ufl import *
+from ufl import as_ufl
 from ufl.corealg.multifunction import MultiFunction
 from ufl.corealg.map_dag import map_expr_dag
-from ufl.classes import Argument, MultiIndex, Indexed, FixedIndex
+from ufl.classes import Argument, FixedIndex
 from ufl.log import error as ufl_error
 
 __all__ = ["extract_tested_expressions"]
 
 # TODO: "factorization" is not the right term
 
+
 class ScalarFactorizer(MultiFunction):
     def __init__(self):
         MultiFunction.__init__(self)
@@ -47,7 +49,7 @@ class ScalarFactorizer(MultiFunction):
             self._arg = expr
         elif self._arg is not expr:
             ufl_error("Expecting only one Argument in this algorithm implementation.")
-        return { component: self._one }
+        return {component: self._one}
 
     def argument(self, e):
         if e.ufl_shape != ():
@@ -113,13 +115,13 @@ class ScalarFactorizer(MultiFunction):
             ufl_error("Expecting only one Argument in this algorithm. Products of Arguments are not allowed.")
         elif a_is_dict:
             c = {}
-            for k,v in a.items():
-                c[k] = v*b
+            for k, v in a.items():
+                c[k] = v * b
             return c
         elif b_is_dict:
             c = {}
-            for k,v in b.items():
-                c[k] = v*a
+            for k, v in b.items():
+                c[k] = v * a
             return c
         else:
             return e
@@ -129,7 +131,7 @@ class ScalarFactorizer(MultiFunction):
             ufl_error("Cannot divide by Arguments.")
         if isinstance(a, dict):
             c = {}
-            for k,v in a.items():
+            for k, v in a.items():
                 c[k] = v / b
             return c
         else:
diff --git a/python/dolfin/multistage/multistagescheme.py b/python/dolfin/multistage/multistagescheme.py
index e34dc51..6ad174d 100644
--- a/python/dolfin/multistage/multistagescheme.py
+++ b/python/dolfin/multistage/multistagescheme.py
@@ -32,9 +32,7 @@ import dolfin.cpp as cpp
 from dolfin.function.constant import Constant
 from dolfin.function.expression import Expression
 from dolfin.function.function import Function
-from dolfin.function.argument import TestFunction
 from dolfin.fem.formmanipulations import derivative, adjoint
-from dolfin.multistage.factorize import extract_tested_expressions
 from ufl import action as ufl_action
 from dolfin.fem.form import Form
 import ufl.algorithms
@@ -51,16 +49,16 @@ def safe_adjoint(x):
 def safe_action(x, y):
     x = expand_derivatives(x)
     if x.integrals() == ():
-        return x # form is empty, return anyway
+        return x  # form is empty, return anyway
     else:
         return ufl_action(x, y)
 
 
 def _check_abc(a, b, c):
-    if not (isinstance(a, np.ndarray) and (len(a) == 1 or \
-            (len(a.shape)==2 and a.shape[0] == a.shape[1]))):
+    if not (isinstance(a, np.ndarray) and (len(a) == 1 or
+            (len(a.shape) == 2 and a.shape[0] == a.shape[1]))):
         raise TypeError("Expected an m x m numpy array as the first argument")
-    if not (isinstance(b, np.ndarray) and len(b.shape) in [1,2]):
+    if not (isinstance(b, np.ndarray) and len(b.shape) in [1, 2]):
         raise TypeError("Expected a 1 or 2 dimensional numpy array as the second argument")
     if not (isinstance(c, np.ndarray) and len(c.shape) == 1):
         raise TypeError("Expected a 1 dimensional numpy array as the third argument")
@@ -75,24 +73,24 @@ def _check_abc(a, b, c):
     # If b is a matrix we expect it to have two rows
     if len(b.shape) == 2:
         if not (b.shape[0] == 2 and b.shape[1] == size):
-            raise ValueError("Expected a 2 row matrix with the same number "\
+            raise ValueError("Expected a 2 row matrix with the same number "
                              "of collumns as the first dimension of the a matrix.")
     elif len(b) != size:
-        raise ValueError("Expected the length of the b vector to have the "\
+        raise ValueError("Expected the length of the b vector to have the "
                          "same size as the first dimension of the a matrix.")
 
     if len(c) != size:
-        raise ValueError("Expected the length of the c vector to have the "\
+        raise ValueError("Expected the length of the c vector to have the "
                          "same size as the first dimension of the a matrix.")
 
     # Check if the method is singly diagonally implicit
     sigma = -1
     for i in range(size):
         # If implicit
-        if a[i,i] != 0:
+        if a[i, i] != 0:
             if sigma == -1:
-                sigma = a[i,i]
-            elif sigma != a[i,i]:
+                sigma = a[i, i]
+            elif sigma != a[i, i]:
                 raise ValueError("Expected only singly diagonally implicit "
                                  "schemes. (Same value on the diagonal of 'a'.)")
 
@@ -193,7 +191,7 @@ def _butcher_scheme_generator(a, b, c, time, solution, rhs_form):
 
     # Get test function
     arguments = rhs_form.arguments()
-    coefficients = rhs_form.coefficients()
+    # coefficients = rhs_form.coefficients()
     v = arguments[0]
 
     # Create time step
@@ -204,7 +202,7 @@ def _butcher_scheme_generator(a, b, c, time, solution, rhs_form):
     ufl_stage_forms = []
 
     # Stage solutions
-    k = [Function(solution.function_space(), name="k_%d"%i) for i in range(size)]
+    k = [Function(solution.function_space(), name="k_%d" % i) for i in range(size)]
 
     jacobian_indices = []
 
@@ -216,12 +214,12 @@ def _butcher_scheme_generator(a, b, c, time, solution, rhs_form):
     for i, ki in enumerate(k):
 
         # Check whether the stage is explicit
-        explicit = a[i,i] == 0
+        explicit = a[i, i] == 0
 
         # Evaluation arguments for the ith stage
-        evalargs = y_ + dt * sum([float(a[i,j]) * k[j] \
-                                  for j in range(i+1)], zero_)
-        time = time_ + dt*c[i]
+        evalargs = y_ + dt * sum([float(a[i, j]) * k[j]
+                                  for j in range(i + 1)], zero_)
+        time = time_ + dt * c[i]
 
         replace_dict = _replace_dict_time_dependent_expression(time_dep_expressions,
                                                                time_, dt, c[i])
@@ -235,7 +233,7 @@ def _butcher_scheme_generator(a, b, c, time, solution, rhs_form):
             jacobian_indices.append(-1)
         else:
             # Create a F=0 form and differentiate it
-            stage_form -= ufl.inner(ki, v)*DX
+            stage_form -= ufl.inner(ki, v) * DX
             stage_forms = [stage_form, derivative(stage_form, ki)]
             jacobian_indices.append(0)
         ufl_stage_forms.append(stage_forms)
@@ -244,25 +242,25 @@ def _butcher_scheme_generator(a, b, c, time, solution, rhs_form):
 
     # Only one last stage
     if len(b.shape) == 1:
-        last_stage = Form(ufl.inner(y_+sum([dt*float(bi)*ki for bi, ki in \
-                                            zip(b, k)], zero_), v)*DX)
+        last_stage = Form(ufl.inner(y_ + sum([dt * float(bi) * ki for bi, ki in
+                                              zip(b, k)], zero_), v) * DX)
     else:
         # FIXME: Add support for adaptivity in RKSolver and
         # MultiStageScheme
-        last_stage = [Form(ufl.inner(y_+sum([dt*float(bi)*ki for bi, ki in \
-                                             zip(b[0,:], k)], zero_), v)*DX),
-                      Form(ufl.inner(y_+sum([dt*float(bi)*ki for bi, ki in \
-                                             zip(b[1,:], k)], zero_), v)*DX)]
+        last_stage = [Form(ufl.inner(y_ + sum([dt * float(bi) * ki for bi, ki in
+                                               zip(b[0, :], k)], zero_), v) * DX),
+                      Form(ufl.inner(y_ + sum([dt * float(bi) * ki for bi, ki in
+                                               zip(b[1, :], k)], zero_), v) * DX)]
 
     # Create the Function holding the solution at end of time step
-    #k.append(solution.copy())
+    # k.append(solution.copy())
 
     # Generate human form of MultiStageScheme
     human_form = []
     for i in range(size):
-        kterm = " + ".join("%sh*k_%s" % ("" if a[i,j] == 1.0 else \
-                                         "%s*"% a[i,j], j) \
-                           for j in range(size) if a[i,j] != 0)
+        kterm = " + ".join("%sh*k_%s" % ("" if a[i, j] == 1.0 else
+                                         "%s*" % a[i, j], j)
+                           for j in range(size) if a[i, j] != 0)
         if c[i] in [0.0, 1.0]:
             cih = " + h" if c[i] == 1.0 else ""
         else:
@@ -271,18 +269,18 @@ def _butcher_scheme_generator(a, b, c, time, solution, rhs_form):
         if len(kterm) == 0:
             human_form.append("k_%(i)s = f(t_n%(cih)s, y_n)" % {"i": i, "cih": cih})
         else:
-            human_form.append("k_%(i)s = f(t_n%(cih)s, y_n + %(kterm)s)" % \
-                          {"i": i, "cih": cih, "kterm": kterm})
+            human_form.append("k_%(i)s = f(t_n%(cih)s, y_n + %(kterm)s)" %
+                              {"i": i, "cih": cih, "kterm": kterm})
 
-    parentheses = "(%s)" if np.sum(b>0) > 1 else "%s"
-    human_form.append("y_{n+1} = y_n + h*" + parentheses % (" + ".join(\
-        "%sk_%s" % ("" if b[i] == 1.0 else "%s*" % b[i], i) \
+    parentheses = "(%s)" if np.sum(b > 0) > 1 else "%s"
+    human_form.append("y_{n+1} = y_n + h*" + parentheses % (" + ".join(
+        "%sk_%s" % ("" if b[i] == 1.0 else "%s*" % b[i], i)
         for i in range(size) if b[i] > 0)))
 
     human_form = "\n".join(human_form)
 
     return ufl_stage_forms, dolfin_stage_forms, jacobian_indices, last_stage, \
-           k, dt, human_form, None
+        k, dt, human_form, None
 
 
 def _butcher_scheme_generator_tlm(a, b, c, time, solution, rhs_form,
@@ -316,7 +314,7 @@ def _butcher_scheme_generator_tlm(a, b, c, time, solution, rhs_form,
 
     # Get test function
     arguments = rhs_form.arguments()
-    coefficients = rhs_form.coefficients()
+    # coefficients = rhs_form.coefficients()
     v = arguments[0]
 
     # Create time step
@@ -327,8 +325,8 @@ def _butcher_scheme_generator_tlm(a, b, c, time, solution, rhs_form,
     ufl_stage_forms = []
 
     # Stage solutions
-    k = [Function(solution.function_space(), name="k_%d"%i) for i in range(size)]
-    kdot = [Function(solution.function_space(), name="kdot_%d"%i) \
+    k = [Function(solution.function_space(), name="k_%d" % i) for i in range(size)]
+    kdot = [Function(solution.function_space(), name="kdot_%d" % i)
             for i in range(size)]
 
     # Create the stage forms
@@ -343,12 +341,12 @@ def _butcher_scheme_generator_tlm(a, b, c, time, solution, rhs_form,
     for i, ki in enumerate(k):
 
         # Check whether the stage is explicit
-        explicit = a[i,i] == 0
+        explicit = a[i, i] == 0
 
         # Evaluation arguments for the ith stage
-        evalargs = y_ + dt * sum([float(a[i,j]) * k[j] \
-                                  for j in range(i+1)], zero_)
-        time = time_ + dt*c[i]
+        evalargs = y_ + dt * sum([float(a[i, j]) * k[j]
+                                  for j in range(i + 1)], zero_)
+        time = time_ + dt * c[i]
 
         replace_dict = _replace_dict_time_dependent_expression(time_dep_expressions,
                                                                time_, dt, c[i])
@@ -366,7 +364,7 @@ def _butcher_scheme_generator_tlm(a, b, c, time, solution, rhs_form,
             jacobian_indices.append(-1)
         else:
             # Create a F=0 form and differentiate it
-            stage_form_implicit = stage_form - ufl.inner(ki, v)*DX
+            stage_form_implicit = stage_form - ufl.inner(ki, v) * DX
             stage_forms = [stage_form_implicit, derivative(stage_form_implicit, ki)]
             jacobian_indices.append(0)
 
@@ -376,14 +374,14 @@ def _butcher_scheme_generator_tlm(a, b, c, time, solution, rhs_form,
 
         # And now the tangent linearisation:
         stage_form_tlm = safe_action(derivative(stage_form, y_), perturbation) + \
-                         sum([dt*float(a[i,j]) * safe_action(derivative(\
-            forward_forms[j], y_), kdot[j]) for j in range(i+1)])
+            sum([dt * float(a[i, j]) * safe_action(derivative(
+                forward_forms[j], y_), kdot[j]) for j in range(i + 1)])
         if explicit:
             stage_forms_tlm = [stage_form_tlm]
             jacobian_indices.append(-1)
         else:
             # Create a F=0 form and differentiate it
-            stage_form_tlm -= ufl.inner(kdot[i], v)*DX
+            stage_form_tlm -= ufl.inner(kdot[i], v) * DX
             stage_forms_tlm = [stage_form_tlm, derivative(stage_form_tlm, kdot[i])]
             jacobian_indices.append(1)
 
@@ -393,44 +391,44 @@ def _butcher_scheme_generator_tlm(a, b, c, time, solution, rhs_form,
 
     # Only one last stage
     if len(b.shape) == 1:
-        last_stage = Form(ufl.inner(perturbation + sum(\
-            [dt*float(bi)*kdoti for bi, kdoti in zip(b, kdot)], zero_), v)*DX)
+        last_stage = Form(ufl.inner(perturbation + sum(
+            [dt * float(bi) * kdoti for bi, kdoti in zip(b, kdot)], zero_), v) * DX)
     else:
         raise Exception("Not sure what to do here")
 
     human_form = []
     for i in range(size):
-        kterm = " + ".join("%sh*k_%s" % ("" if a[i,j] == 1.0 else \
-                                         "%s*"% a[i,j], j) \
-                           for j in range(size) if a[i,j] != 0)
+        kterm = " + ".join("%sh*k_%s" % ("" if a[i, j] == 1.0 else
+                                         "%s*" % a[i, j], j)
+                           for j in range(size) if a[i, j] != 0)
         if c[i] in [0.0, 1.0]:
             cih = " + h" if c[i] == 1.0 else ""
         else:
             cih = " + %s*h" % c[i]
 
-        kdotterm = " + ".join("%(a)sh*action(derivative(f(t_n%(cih)s, y_n + "\
-                              "%(kterm)s), kdot_%(i)s" % \
-                              {"a": ("" if a[i,j] == 1.0 else "%s*"% a[i,j], j),
+        kdotterm = " + ".join("%(a)sh*action(derivative(f(t_n%(cih)s, y_n + "
+                              "%(kterm)s), kdot_%(i)s" %
+                              {"a": ("" if a[i, j] == 1.0 else "%s*" % a[i, j], j),
                                "i": i,
                                "cih": cih,
-                               "kterm": kterm} \
-                              for j in range(size) if a[i,j] != 0)
+                               "kterm": kterm}
+                              for j in range(size) if a[i, j] != 0)
 
         if len(kterm) == 0:
             human_form.append("k_%(i)s = f(t_n%(cih)s, y_n)" % {"i": i, "cih": cih})
-            human_form.append("kdot_%(i)s = action(derivative("\
-                              "f(t_n%(cih)s, y_n), y_n), ydot_n)" % \
+            human_form.append("kdot_%(i)s = action(derivative("
+                              "f(t_n%(cih)s, y_n), y_n), ydot_n)" %
                               {"i": i, "cih": cih})
         else:
-            human_form.append("k_%(i)s = f(t_n%(cih)s, y_n + %(kterm)s)" % \
-                          {"i": i, "cih": cih, "kterm": kterm})
-            human_form.append("kdot_%(i)s = action(derivative(f(t_n%(cih)s, "\
-                              "y_n + %(kterm)s), y_n) + %(kdotterm)s" % \
-                          {"i": i, "cih": cih, "kterm": kterm, "kdotterm": kdotterm})
-
-    parentheses = "(%s)" if np.sum(b>0) > 1 else "%s"
-    human_form.append("ydot_{n+1} = ydot_n + h*" + parentheses % (" + ".join(\
-        "%skdot_%s" % ("" if b[i] == 1.0 else "%s*" % b[i], i) \
+            human_form.append("k_%(i)s = f(t_n%(cih)s, y_n + %(kterm)s)" %
+                              {"i": i, "cih": cih, "kterm": kterm})
+            human_form.append("kdot_%(i)s = action(derivative(f(t_n%(cih)s, "
+                              "y_n + %(kterm)s), y_n) + %(kdotterm)s" %
+                              {"i": i, "cih": cih, "kterm": kterm, "kdotterm": kdotterm})
+
+    parentheses = "(%s)" if np.sum(b > 0) > 1 else "%s"
+    human_form.append("ydot_{n+1} = ydot_n + h*" + parentheses % (" + ".join(
+        "%skdot_%s" % ("" if b[i] == 1.0 else "%s*" % b[i], i)
         for i in range(size) if b[i] > 0)))
 
     human_form = "\n".join(human_form)
@@ -469,7 +467,7 @@ def _butcher_scheme_generator_adm(a, b, c, time, solution, rhs_form, adj):
 
     # Get test function
     arguments = rhs_form.arguments()
-    coefficients = rhs_form.coefficients()
+    # coefficients = rhs_form.coefficients()
     v = arguments[0]
 
     # Create time step
@@ -480,8 +478,8 @@ def _butcher_scheme_generator_adm(a, b, c, time, solution, rhs_form, adj):
     ufl_stage_forms = []
 
     # Stage solutions
-    k = [Function(solution.function_space(), name="k_%d"%i) for i in range(size)]
-    kbar = [Function(solution.function_space(), name="kbar_%d"%i) \
+    k = [Function(solution.function_space(), name="k_%d" % i) for i in range(size)]
+    kbar = [Function(solution.function_space(), name="kbar_%d" % i)
             for i in range(size)]
 
     # Create the stage forms
@@ -497,14 +495,14 @@ def _butcher_scheme_generator_adm(a, b, c, time, solution, rhs_form, adj):
     for i, ki in enumerate(k):
 
         # Check whether the stage is explicit
-        explicit = a[i,i] == 0
+        explicit = a[i, i] == 0
 
         # Evaluation arguments for the ith stage
-        evalargs = y_ + dt * sum([float(a[i,j]) * k[j] \
-                                  for j in range(i+1)], zero_)
-        time = time_ + dt*c[i]
+        evalargs = y_ + dt * sum([float(a[i, j]) * k[j]
+                                  for j in range(i + 1)], zero_)
+        time = time_ + dt * c[i]
 
-        replace_dict = _replace_dict_time_dependent_expression(\
+        replace_dict = _replace_dict_time_dependent_expression(
             time_dep_expressions, time_, dt, c[i])
 
         replace_dict[y_] = evalargs
@@ -518,8 +516,8 @@ def _butcher_scheme_generator_adm(a, b, c, time, solution, rhs_form, adj):
             jacobian_indices.append(-1)
         else:
             # Create a F=0 form and differentiate it
-            stage_form_implicit = stage_form - ufl.inner(ki, v)*DX
-            stage_forms = [stage_form_implicit, derivative(\
+            stage_form_implicit = stage_form - ufl.inner(ki, v) * DX
+            stage_forms = [stage_form_implicit, derivative(
                 stage_form_implicit, ki)]
             jacobian_indices.append(0)
 
@@ -530,18 +528,18 @@ def _butcher_scheme_generator_adm(a, b, c, time, solution, rhs_form, adj):
     for i, kbari in reversed(list(enumerate(kbar))):
 
         # Check whether the stage is explicit
-        explicit = a[i,i] == 0
+        explicit = a[i, i] == 0
 
         # And now the adjoint linearisation:
-        stage_form_adm = ufl.inner(dt * b[i] * adj, v)*DX  + sum(\
-            [dt * float(a[j,i]) * safe_action(safe_adjoint(derivative(\
+        stage_form_adm = ufl.inner(dt * b[i] * adj, v) * DX + sum(
+            [dt * float(a[j, i]) * safe_action(safe_adjoint(derivative(
                 forward_forms[j], y_)), kbar[j]) for j in range(i, size)])
         if explicit:
             stage_forms_adm = [stage_form_adm]
             jacobian_indices.append(-1)
         else:
             # Create a F=0 form and differentiate it
-            stage_form_adm -= ufl.inner(kbar[i], v)*DX
+            stage_form_adm -= ufl.inner(kbar[i], v) * DX
             stage_forms_adm = [stage_form_adm, derivative(stage_form_adm, kbari)]
             jacobian_indices.append(1)
 
@@ -551,16 +549,16 @@ def _butcher_scheme_generator_adm(a, b, c, time, solution, rhs_form, adj):
 
     # Only one last stage
     if len(b.shape) == 1:
-        last_stage = Form(ufl.inner(adj, v)*DX + sum(\
-            [safe_action(safe_adjoint(derivative(forward_forms[i], y_)), kbar[i]) \
+        last_stage = Form(ufl.inner(adj, v) * DX + sum(
+            [safe_action(safe_adjoint(derivative(forward_forms[i], y_)), kbar[i])
              for i in range(size)]))
     else:
         raise Exception("Not sure what to do here")
 
     human_form = "unimplemented"
 
-    return ufl_stage_forms, dolfin_stage_forms, jacobian_indices, last_stage,\
-           stage_solutions, dt, human_form, adj
+    return ufl_stage_forms, dolfin_stage_forms, jacobian_indices, last_stage, \
+        stage_solutions, dt, human_form, adj
 
 
 class MultiStageScheme(cpp.multistage.MultiStageScheme):
@@ -633,6 +631,7 @@ class MultiStageScheme(cpp.multistage.MultiStageScheme):
     def stage_solutions(self):
         "Return the stage solutions"
         return self._stage_solutions
+
     def to_tlm(self, perturbation):
         raise NotImplementedError("'to_tlm:' implement in derived classes")
 
@@ -649,8 +648,8 @@ class ButcherMultiStageScheme(MultiStageScheme):
         bcs = bcs or []
         time = time or Constant(0.0)
         ufl_stage_forms, dolfin_stage_forms, jacobian_indices, last_stage, \
-                         stage_solutions, dt, human_form, contraction = \
-                         generator(a, b, c, time, solution, rhs_form)
+            stage_solutions, dt, human_form, contraction = \
+            generator(a, b, c, time, solution, rhs_form)
 
         # Store data
         self.a = a
@@ -725,7 +724,7 @@ class ExplicitMidPoint(ButcherMultiStageScheme):
     """Explicit 2nd order scheme"""
     def __init__(self, rhs_form, solution, t=None, bcs=None):
 
-        a = np.array([[0, 0],[0.5, 0.0]])
+        a = np.array([[0, 0], [0.5, 0.0]])
         b = np.array([0., 1])
         c = np.array([0, 0.5])
         ButcherMultiStageScheme.__init__(self, rhs_form, solution, t, bcs,
@@ -735,7 +734,7 @@ class ExplicitMidPoint(ButcherMultiStageScheme):
 class CN2(ButcherMultiStageScheme):
     """Semi-implicit 2nd order scheme"""
     def __init__(self, rhs_form, solution, t=None, bcs=None):
-        a = np.array([[0, 0],[0.5, 0.5]])
+        a = np.array([[0, 0], [0.5, 0.5]])
         b = np.array([0.5, 0.5])
         c = np.array([0, 1.0])
 
@@ -750,7 +749,7 @@ class ERK4(ButcherMultiStageScheme):
                       [0.5, 0, 0, 0],
                       [0, 0.5, 0, 0],
                       [0, 0, 1, 0]])
-        b = np.array([1./6, 1./3, 1./3, 1./6])
+        b = np.array([1. / 6, 1. / 3, 1. / 3, 1. / 6])
         c = np.array([0, 0.5, 0.5, 1])
         ButcherMultiStageScheme.__init__(self, rhs_form, solution, t, bcs,
                                          a, b, c, 4)
@@ -765,11 +764,11 @@ class ESDIRK3(ButcherMultiStageScheme):
 
     """
     def __init__(self, rhs_form, solution, t=None, bcs=None):
-        a = np.array([[0,                   0,                   0,                   0 ],
-                      [0.435866521500000,   0.435866521500000,   0,                   0 ],
-                      [0.490563388419108,   0.073570090080892,   0.435866521500000,   0 ],
-                      [0.308809969973036,   1.490563388254108,  -1.235239879727145,   0.435866521500000 ]])
-        b = a[-1,:].copy()
+        a = np.array([[0.000000000000000, 0.000000000000000, 0.000000000000000, 0.00000000000000],
+                      [0.435866521500000, 0.435866521500000, 0.000000000000000, 0.00000000000000],
+                      [0.490563388419108, 0.073570090080892, 0.435866521500000, 0.00000000000000],
+                      [0.308809969973036, 1.490563388254108, -1.235239879727145, 0.435866521500000]])
+        b = a[-1, :].copy()
         c = a.sum(1)
         ButcherMultiStageScheme.__init__(self, rhs_form, solution, t, bcs, a, b, c, 3)
 
@@ -783,13 +782,13 @@ class ESDIRK4(ButcherMultiStageScheme):
 
     """
     def __init__(self, rhs_form, solution, t=None, bcs=None):
-        a = np.array([[0,                  0,                 0,                  0,                   0],
-                      [0.435866521500000,  0.4358665215,      0,                  0,                   0                   ],
-                      [0.140737774731968, -0.108365551378832, 0.435866521500000,  0,                   0                   ],
-                      [0.102399400616089, -0.376878452267324, 0.838612530151233,  0.435866521500000,   0                   ],
-                      [0.157024897860995,  0.117330441357768, 0.616678030391680, -0.326899891110444,   0.435866521500000   ]])
+        a = np.array([[0.000000000000000, 0.0000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000],
+                      [0.435866521500000, 0.4358665215000000, 0.000000000000000, 0.000000000000000, 0.000000000000000],
+                      [0.140737774731968, -0.108365551378832, 0.435866521500000, 0.000000000000000, 0.000000000000000],
+                      [0.102399400616089, -0.376878452267324, 0.838612530151233, 0.435866521500000, 0.000000000000000],
+                      [0.157024897860995, 0.1173304413577680, 0.616678030391680, -0.326899891110444, 0.435866521500000]])
 
-        b = a[-1,:].copy()
+        b = a[-1, :].copy()
         c = a.sum(1)
         ButcherMultiStageScheme.__init__(self, rhs_form, solution, t, bcs, a, b, c, 4)
 
@@ -803,7 +802,7 @@ BackwardEuler = BDF1
 ERK = ERK1
 RK4 = ERK4
 
-__all__ = [name for name, attr in list(globals().items()) \
+__all__ = [name for name, attr in list(globals().items())
            if isinstance(attr, type) and issubclass(attr, MultiStageScheme)]
 
 __all__.append("MultiStageScheme")
diff --git a/python/dolfin/multistage/multistagesolvers.py b/python/dolfin/multistage/multistagesolvers.py
index f0ae073..935a6e0 100644
--- a/python/dolfin/multistage/multistagesolvers.py
+++ b/python/dolfin/multistage/multistagesolvers.py
@@ -26,6 +26,7 @@ import dolfin.cpp as cpp
 
 __all__ = ["PointIntegralSolver", "RKSolver"]
 
+
 class PointIntegralSolver(cpp.multistage.PointIntegralSolver):
     def __init__(self, scheme):
         """
diff --git a/python/dolfin/multistage/rushlarsenschemes.py b/python/dolfin/multistage/rushlarsenschemes.py
index ad26618..9a7bf34 100644
--- a/python/dolfin/multistage/rushlarsenschemes.py
+++ b/python/dolfin/multistage/rushlarsenschemes.py
@@ -22,30 +22,26 @@ PointIntegralSolver
 # You should have received a copy of the GNU Lesser General Public License
 # along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 
-import numpy as np
 import functools
 import ufl
 
-import dolfin.cpp as cpp
 from dolfin.function.constant import Constant
 from dolfin.function.function import Function
-from dolfin.function.argument import TestFunction
 from dolfin.fem.formmanipulations import derivative
 from dolfin.multistage.factorize import extract_tested_expressions
-from ufl import action as ufl_action
 from dolfin.fem.form import Form
 from dolfin.multistage.multistagescheme import (MultiStageScheme,
                                                 _check_form, _time_dependent_expressions,
                                                 _replace_dict_time_dependent_expression, safe_action,
                                                 safe_adjoint)
 from dolfin import DOLFIN_EPS
-from dolfin import assemble
 from dolfin import TrialFunction
 
 import ufl.algorithms
 from ufl.algorithms import (expand_derivatives, expand_indices,
                             extract_coefficients)
 
+
 def _rush_larsen_step(rhs_exprs, diff_rhs_exprs, linear_terms,
                       system_size, y0, stage_solution, dt, time, a, c,
                       v, DX, time_dep_expressions):
@@ -62,9 +58,9 @@ def _rush_larsen_step(rhs_exprs, diff_rhs_exprs, linear_terms,
     # If we have time dependent expressions
     if time_dep_expressions and abs(float(c)) > DOLFIN_EPS:
         time_ = time
-        time = time + dt*float(c)
+        time = time + dt * float(c)
 
-        repl.update(_replace_dict_time_dependent_expression(time_dep_expressions, \
+        repl.update(_replace_dict_time_dependent_expression(time_dep_expressions,
                                                             time_, dt, float(c)))
         repl[time_] = time
 
@@ -78,7 +74,7 @@ def _rush_larsen_step(rhs_exprs, diff_rhs_exprs, linear_terms,
     for ind in range(system_size):
 
         # forward euler step
-        fe_du_i = rhs_exprs[ind]*dt*float(a)
+        fe_du_i = rhs_exprs[ind] * dt * float(a)
 
         # If exact integration
         if linear_terms[ind]:
@@ -88,8 +84,8 @@ def _rush_larsen_step(rhs_exprs, diff_rhs_exprs, linear_terms,
             # diff_rhs_exprs[ind] is never 1.0e-16!  Let's get rid of
             # this when the conditional fixes land properly in UFL.
             eps = Constant(1.0e-16)
-            rl_du_i = rhs_exprs[ind]/(diff_rhs_exprs[ind] + eps)*(\
-                ufl.exp(diff_rhs_exprs[ind]*dt) - 1.0)
+            rl_du_i = rhs_exprs[ind] / (diff_rhs_exprs[ind] + eps) * (
+                ufl.exp(diff_rhs_exprs[ind] * dt) - 1.0)
 
             # If safe guard
             if safe_guard:
@@ -103,9 +99,9 @@ def _rush_larsen_step(rhs_exprs, diff_rhs_exprs, linear_terms,
         if repl:
             du_i = ufl.replace(du_i, repl)
 
-        rl_ufl_form += (y0[ind] + du_i)*v[ind]
+        rl_ufl_form += (y0[ind] + du_i) * v[ind]
 
-    return rl_ufl_form*DX
+    return rl_ufl_form * DX
 
 
 def _find_linear_terms(rhs_exprs, u):
@@ -117,15 +113,15 @@ def _find_linear_terms(rhs_exprs, u):
 
     uu = [Constant(1.0) for _ in rhs_exprs]
     if len(rhs_exprs) > 1:
-        repl = {u:ufl.as_vector(uu)}
+        repl = {u: ufl.as_vector(uu)}
     else:
-        repl = {u:uu[0]}
+        repl = {u: uu[0]}
 
     linear_terms = []
     for i, ui in enumerate(uu):
         comp_i_s = expand_indices(ufl.replace(rhs_exprs[i], repl))
-        linear_terms.append(ui in extract_coefficients(comp_i_s) and \
-                            ui not in extract_coefficients(\
+        linear_terms.append(ui in extract_coefficients(comp_i_s) and
+                            ui not in extract_coefficients(
                                 expand_derivatives(ufl.diff(comp_i_s, ui))))
     return linear_terms
 
@@ -158,8 +154,8 @@ def _rush_larsen_scheme_generator(rhs_form, solution, time, order, generalized):
     dt = Constant(0.1)
 
     # Get test function
-    arguments = rhs_form.arguments()
-    coefficients = rhs_form.coefficients()
+    #    arguments = rhs_form.arguments()
+    #    coefficients = rhs_form.coefficients()
 
     # Get time dependent expressions
     time_dep_expressions = _time_dependent_expressions(rhs_form, time)
@@ -167,7 +163,7 @@ def _rush_larsen_scheme_generator(rhs_form, solution, time, order, generalized):
     # Extract rhs expressions from form
     rhs_integrand = rhs_form.integrals()[0].integrand()
     rhs_exprs, v = extract_tested_expressions(rhs_integrand)
-    vector_rhs = len(v.ufl_shape)>0 and v.ufl_shape[0]>1
+    vector_rhs = len(v.ufl_shape) > 0 and v.ufl_shape[0] > 1
 
     system_size = v.ufl_shape[0] if vector_rhs else 1
 
@@ -186,7 +182,7 @@ def _rush_larsen_scheme_generator(rhs_form, solution, time, order, generalized):
 
     # Takes time!
     if vector_rhs:
-        diff_rhs_exprs = [expand_indices(expand_derivatives(rhs_jac[ind, ind]))\
+        diff_rhs_exprs = [expand_indices(expand_derivatives(rhs_jac[ind, ind]))
                           for ind in range(system_size)]
     else:
         diff_rhs_exprs = [expand_indices(expand_derivatives(rhs_jac[0]))]
@@ -233,7 +229,7 @@ def _rush_larsen_scheme_generator(rhs_form, solution, time, order, generalized):
                                        str(order))
 
     return rhs_form, linear_terms, ufl_stage_forms, dolfin_stage_forms, last_stage, \
-           stage_solutions, dt, dt_stage_offsets, human_form, None
+        stage_solutions, dt, dt_stage_offsets, human_form, None
 
 
 def _rush_larsen_scheme_generator_tlm(rhs_form, solution, time, order,
@@ -267,8 +263,8 @@ def _rush_larsen_scheme_generator_tlm(rhs_form, solution, time, order,
     dt = Constant(0.1)
 
     # Get test function
-    arguments = rhs_form.arguments()
-    coefficients = rhs_form.coefficients()
+    #    arguments = rhs_form.arguments()
+    #    coefficients = rhs_form.coefficients()
 
     # Get time dependent expressions
     time_dep_expressions = _time_dependent_expressions(rhs_form, time)
@@ -276,7 +272,7 @@ def _rush_larsen_scheme_generator_tlm(rhs_form, solution, time, order,
     # Extract rhs expressions from form
     rhs_integrand = rhs_form.integrals()[0].integrand()
     rhs_exprs, v = extract_tested_expressions(rhs_integrand)
-    vector_rhs = len(v.ufl_shape)>0 and v.ufl_shape[0]>1
+    vector_rhs = len(v.ufl_shape) > 0 and v.ufl_shape[0] > 1
 
     system_size = v.ufl_shape[0] if vector_rhs else 1
 
@@ -295,7 +291,7 @@ def _rush_larsen_scheme_generator_tlm(rhs_form, solution, time, order,
 
     # Takes time!
     if vector_rhs:
-        diff_rhs_exprs = [expand_indices(expand_derivatives(rhs_jac[ind, ind]))\
+        diff_rhs_exprs = [expand_indices(expand_derivatives(rhs_jac[ind, ind]))
                           for ind in range(system_size)]
         soln = solution
     else:
@@ -344,8 +340,8 @@ def _rush_larsen_scheme_generator_tlm(rhs_form, solution, time, order,
                                        dt, time, 1.0, 0.5, v, DX,
                                        time_dep_expressions)
 
-        rl_ufl_form    = safe_action(derivative(y_one_form, soln, trial), perturbation) + \
-                         safe_action(derivative(y_one_form, stage_solutions[0], trial), stage_solutions[1])
+        rl_ufl_form = safe_action(derivative(y_one_form, soln, trial), perturbation) + \
+            safe_action(derivative(y_one_form, stage_solutions[0], trial), stage_solutions[1])
 
         ufl_stage_forms.append([y_half_form])
         ufl_stage_forms.append([y_dot_half_form])
@@ -361,7 +357,7 @@ def _rush_larsen_scheme_generator_tlm(rhs_form, solution, time, order,
                                        str(order))
 
     return rhs_form, linear_terms, ufl_stage_forms, dolfin_stage_forms, last_stage, \
-           stage_solutions, dt, dt_stage_offsets, human_form, perturbation
+        stage_solutions, dt, dt_stage_offsets, human_form, perturbation
 
 
 def _rush_larsen_scheme_generator_adm(rhs_form, solution, time, order,
@@ -395,8 +391,8 @@ def _rush_larsen_scheme_generator_adm(rhs_form, solution, time, order,
     dt = Constant(0.1)
 
     # Get test function
-    arguments = rhs_form.arguments()
-    coefficients = rhs_form.coefficients()
+    #    arguments = rhs_form.arguments()
+    #    coefficients = rhs_form.coefficients()
 
     # Get time dependent expressions
     time_dep_expressions = _time_dependent_expressions(rhs_form, time)
@@ -404,7 +400,7 @@ def _rush_larsen_scheme_generator_adm(rhs_form, solution, time, order,
     # Extract rhs expressions from form
     rhs_integrand = rhs_form.integrals()[0].integrand()
     rhs_exprs, v = extract_tested_expressions(rhs_integrand)
-    vector_rhs = len(v.ufl_shape)>0 and v.ufl_shape[0]>1
+    vector_rhs = len(v.ufl_shape) > 0 and v.ufl_shape[0] > 1
 
     system_size = v.ufl_shape[0] if vector_rhs else 1
 
@@ -423,7 +419,7 @@ def _rush_larsen_scheme_generator_adm(rhs_form, solution, time, order,
 
     # Takes time!
     if vector_rhs:
-        diff_rhs_exprs = [expand_indices(expand_derivatives(rhs_jac[ind, ind]))\
+        diff_rhs_exprs = [expand_indices(expand_derivatives(rhs_jac[ind, ind]))
                           for ind in range(system_size)]
         soln = solution
     else:
@@ -476,8 +472,8 @@ def _rush_larsen_scheme_generator_adm(rhs_form, solution, time, order,
         y_bar_half_form = safe_action(safe_adjoint(derivative(y_one_form,
                                                               stage_solutions[0], trial)), perturbation)
 
-        rl_ufl_form    = safe_action(safe_adjoint(derivative(y_one_form, soln, trial)), perturbation) + \
-                         safe_action(safe_adjoint(derivative(y_half_form, soln, trial)), stage_solutions[2])
+        rl_ufl_form = safe_action(safe_adjoint(derivative(y_one_form, soln, trial)), perturbation) + \
+            safe_action(safe_adjoint(derivative(y_half_form, soln, trial)), stage_solutions[2])
 
         ufl_stage_forms.append([y_half_form])
         ufl_stage_forms.append([y_one_form])
@@ -493,7 +489,7 @@ def _rush_larsen_scheme_generator_adm(rhs_form, solution, time, order,
                                        str(order))
 
     return rhs_form, linear_terms, ufl_stage_forms, dolfin_stage_forms, last_stage, \
-           stage_solutions, dt, dt_stage_offsets, human_form, perturbation
+        stage_solutions, dt, dt_stage_offsets, human_form, perturbation
 
 
 class RushLarsenScheme(MultiStageScheme):
@@ -509,12 +505,12 @@ class RushLarsenScheme(MultiStageScheme):
         # FIXME: What with bcs?
         bcs = []
         time = time or Constant(0.0)
-        if order not in [1,2]:
+        if order not in [1, 2]:
             raise ValueError("Expected order to be either 1 or 2")
 
         rhs_form, ufl_stage_forms, linear_terms, dofin_stage_forms, last_stage, \
-                  stage_solutions, dt, dt_stage_offsets, human_form, contraction = \
-                  generator(rhs_form, solution, time, order, generalized)
+            stage_solutions, dt, dt_stage_offsets, human_form, contraction = \
+            generator(rhs_form, solution, time, order, generalized)
 
         self.linear_terms = linear_terms
 
@@ -597,7 +593,7 @@ class GRL2(RushLarsenScheme):
         RushLarsenScheme.__init__(self, rhs_form, solution, t, 2, True)
 
 
-__all__ = [name for name, attr in list(globals().items()) \
+__all__ = [name for name, attr in list(globals().items())
            if isinstance(attr, type) and issubclass(attr, MultiStageScheme)]
 
 __all__.append("MultiStageScheme")
diff --git a/python/dolfin/parameter/__init__.py b/python/dolfin/parameter/__init__.py
index d13f8b3..a0f5340 100644
--- a/python/dolfin/parameter/__init__.py
+++ b/python/dolfin/parameter/__init__.py
@@ -8,6 +8,8 @@
 # version.
 
 import dolfin.cpp as cpp
+from ffc import default_jit_parameters
+from dolfin.cpp.parameter import parameters, Parameters
 
 
 #  Extend cpp.Parameters with a __getitem__ method
@@ -19,8 +21,8 @@ def __getitem__(self, key):
         # FIXME: I think we want to return the parameter set rather than a copy?
         p = self._get_parameter_set(key)
         return p
-        #np = cpp.parameter.Parameters(p)
-        #return np
+        # np = cpp.parameter.Parameters(p)
+        # return np
     else:
         raise RuntimeError("Invalid parameter: {}".format(key))
 
@@ -43,12 +45,7 @@ def update(self, params):
 # Extend the cpp.parameter.Parameters class and clean-up
 cpp.parameter.Parameters.__getitem__ = __getitem__
 cpp.parameter.Parameters.update = update
-del __getitem__,  update
-
-
-# Import global form compiler parameters from FFC
-from ffc import default_jit_parameters
-from dolfin.cpp.parameter import parameters, Parameters
+del __getitem__, update
 
 
 def ffc_default_parameters():
diff --git a/python/dolfin_utils/meshconvert/meshconvert.py b/python/dolfin_utils/meshconvert/meshconvert.py
index 385546e..5a54fb5 100644
--- a/python/dolfin_utils/meshconvert/meshconvert.py
+++ b/python/dolfin_utils/meshconvert/meshconvert.py
@@ -867,7 +867,7 @@ def diffpack2xml(ifilename, ofilename):
     xml_writer.write_footer_vertices(ofile)
     xml_writer.write_header_cells(ofile, num_cells)
 
-    # Output unique vertex markers as individual VertexFunctions
+    # Output unique vertex markers as individual MeshFunctions on vertices
     unique_vertex_markers.difference_update([0])
     for unique_marker in unique_vertex_markers:
         ofile_marker = open(ofilename.replace(".xml", "") + \
diff --git a/python/dolfin_utils/test/fixtures.py b/python/dolfin_utils/test/fixtures.py
index 59f7d93..7f6db83 100644
--- a/python/dolfin_utils/test/fixtures.py
+++ b/python/dolfin_utils/test/fixtures.py
@@ -41,14 +41,15 @@ def fixture(func):
     NOTE: Probably does not work with yield fixtures or
     maybe just ignores post-yield code
 
-    This is the preferred decorator for writing fixtures
-    involving objects which might have collective destructors.
-    If in a need for using ``pytest.fixture`` directly, do::
+    This is the preferred decorator for writing fixtures involving
+    objects which might have collective destructors.  If in a need for
+    using ``pytest.fixture`` directly, do::
 
         yield result_of_fixture
 
         gc.collect()
         MPI.barrier(MPI.comm_world)
+
     """
 
     def wrapper(func, *args, **kwargs):
@@ -74,24 +75,35 @@ def fixture(func):
 
 
 def gc_barrier():
-    """Internal utility to easily switch on and off calls to
-    gc.collect() and MPI.barrier(world) in all fixtures here.
-    Helps make the tests deterministic when debugging.
+    """Internal utility to easily switch on and off calls to gc.collect()
+    and MPI.barrier(world) in all fixtures here.  Helps make the tests
+    deterministic when debugging.
+
     """
     gc.collect()
     if MPI.size(MPI.comm_world) > 1:
         MPI.barrier(MPI.comm_world)
 
 
+ at pytest.fixture
+def worker_id(request):
+    """Returns thread id when running with pytest-xdist in parallel."""
+    if hasattr(request.config, 'slaveinput'):
+        return request.config.slaveinput['slaveid']
+    else:
+        return 'master'
+
+
 @pytest.yield_fixture(scope="function")
 def gc_barrier_fixture():
     """Function decorator to call gc.collect() and
     MPI.barrier(world) before and after a test.  Helps
     make the tests deterministic when debugging.
 
-    NOTE: This decorator is not needed now for writing tests,
-    as there is ``gc.collect()`` call in ``conftest.py`` on
-    teardown of every test.
+    NOTE: This decorator is not needed now for writing tests, as there
+    is ``gc.collect()`` call in ``conftest.py`` on teardown of every
+    test.
+
     """
     gc_barrier()
     yield
@@ -117,7 +129,10 @@ def filedir(request):
 
 @pytest.fixture(scope="module")
 def rootdir(request):
-    "Return the root directory of the repository. Assumes run from within repository filetree."
+    """Return the root directory of the repository. Assumes run from
+    within repository filetree.
+
+    """
     gc_barrier()
     d = os.path.dirname(os.path.abspath(request.module.__file__))
     t = ''
@@ -128,7 +143,10 @@ def rootdir(request):
 
 @pytest.fixture(scope="module")
 def datadir(request):
-    "Return the directory of the shared test data. Assumes run from within repository filetree."
+    """Return the directory of the shared test data. Assumes run from
+    within repository filetree.
+
+    """
     d = os.path.dirname(os.path.abspath(request.module.__file__))
     t = os.path.join(d, "data")
     while not os.path.isdir(t):
@@ -144,7 +162,8 @@ def _create_tempdir(request):
 
     # Construct name test_foo_tempdir from name test_foo.py
     testfilename = os.path.basename(testfile)
-    outputname = testfilename.replace(".py", "_tempdir")
+    outputname = testfilename.replace(".py",
+                                      "_tempdir_{}".format(worker_id(request)))
 
     # Get function name test_something from test_foo.py
     function = request.function.__name__
@@ -164,19 +183,22 @@ def _create_tempdir(request):
 
     # Delete and re-create directory on root node
     if MPI.rank(MPI.comm_world) == 0:
-        # First time visiting this basepath, delete the old and create a new
+        # First time visiting this basepath, delete the old and create
+        # a new
         if basepath not in _create_tempdir._basepaths:
             _create_tempdir._basepaths.add(basepath)
             if os.path.exists(basepath):
                 shutil.rmtree(basepath)
-            # Make sure we have the base path test_foo_tempdir for this test_foo.py file
+            # Make sure we have the base path test_foo_tempdir for
+            # this test_foo.py file
             if not os.path.exists(basepath):
                 os.mkdir(basepath)
 
         # Delete path from old test run
         if os.path.exists(path):
             shutil.rmtree(path)
-        # Make sure we have the path for this test execution: e.g. test_foo_tempdir/test_something__3
+        # Make sure we have the path for this test execution:
+        # e.g. test_foo_tempdir/test_something__3
         if not os.path.exists(path):
             os.mkdir(path)
     MPI.barrier(MPI.comm_world)
@@ -194,12 +216,13 @@ def tempdir(request):
     Deletes and re-creates directory from previous test runs but lets
     the directory stay after the test run for eventual inspection.
 
-    Returns the directory name, derived from the test file and function
-    plus a sequence number to work with parameterized tests.
+    Returns the directory name, derived from the test file and
+    function plus a sequence number to work with parameterized tests.
 
     Does NOT change the current directory.
 
     MPI safe (assuming MPI.comm_world context).
+
     """
     gc_barrier()
     return _create_tempdir(request)
@@ -212,12 +235,14 @@ def cd_tempdir(request):
     Deletes and re-creates directory from previous test runs but lets
     the directory stay after the test run for eventual inspection.
 
-    Returns the directory name, derived from the test file and function
-    plus a sequence number to work with parameterized tests.
+    Returns the directory name, derived from the test file and
+    function plus a sequence number to work with parameterized tests.
 
-    Changes the current directory to the tempdir and resets cwd afterwards.
+    Changes the current directory to the tempdir and resets cwd
+    afterwards.
 
     MPI safe (assuming MPI.comm_world context).
+
     """
     gc_barrier()
     cwd = os.getcwd()
@@ -238,9 +263,9 @@ def pushpop_parameters():
 
 # TODO: Rename set_parameters_fixture to e.g. use_parameter_values
 def set_parameters_fixture(paramname, values, key=lambda x: x):
-    """Return a fixture that sets and resets a global parameter
-    to each of a list of values before and after each test run.
-    Allows paramname="foo.bar.var" meaning parameters["foo"]["bar"]["var"].
+    """Return a fixture that sets and resets a global parameter to each of
+    a list of values before and after each test run.  Allows
+    paramname="foo.bar.var" meaning parameters["foo"]["bar"]["var"].
 
     Usage:
         repr = set_parameters_fixture("form_compiler.representation", ["quadrature", "uflacs"])
@@ -260,6 +285,7 @@ def set_parameters_fixture(paramname, values, key=lambda x: x):
             assert parameters["linear_algebra_backend"] == my_fixture2[0]
 
     Try it and see.
+
     """
     global parameters
     def _pushpop(request):
@@ -277,9 +303,9 @@ def set_parameters_fixture(paramname, values, key=lambda x: x):
                 yield request.param                                            # Let test run
                 parameters[names[0]][names[1]][names[2]] = prev                # Reset value
         else:
-            prev = parameters[paramname]               # Remember original value
-            parameters[paramname] = key(request.param) # Set value
-            yield request.param                        # Let test run
-            parameters[paramname] = prev               # Reset value
+            prev = parameters[paramname]                # Remember original value
+            parameters[paramname] = key(request.param)  # Set value
+            yield request.param                         # Let test run
+            parameters[paramname] = prev                # Reset value
 
     return pytest.yield_fixture(scope="function", params=values)(_pushpop)
diff --git a/python/setup.cfg b/python/setup.cfg
new file mode 100644
index 0000000..e44b810
--- /dev/null
+++ b/python/setup.cfg
@@ -0,0 +1,2 @@
+[flake8]
+ignore = E501
diff --git a/python/setup.py b/python/setup.py
index c574e1a..3da0818 100644
--- a/python/setup.py
+++ b/python/setup.py
@@ -50,7 +50,7 @@ class CMakeBuild(build_ext):
             if "CIRCLECI" in os.environ:
                 build_args += ['--', '-j2']
             else:
-                num_build_threads = max(1, multiprocessing.cpu_count() - 2)
+                num_build_threads = max(1, multiprocessing.cpu_count() - 1)
                 build_args += ['--', '-j' + str(num_build_threads)]
 
         env = os.environ.copy()
@@ -65,7 +65,7 @@ class CMakeBuild(build_ext):
 setup(name='dolfin',
       version='0.0.1',
       author='FEniCS Project',
-      description='Experimental DOLFIN pybind11 interface',
+      description='DOLFIN Python interface (via pybind11)',
       long_description='',
       packages=["dolfin",
                 "dolfin.common",
@@ -83,8 +83,8 @@ setup(name='dolfin',
       ext_modules=[CMakeExtension('dolfin.cpp')],
       cmdclass=dict(build_ext=CMakeBuild),
       install_requires=["numpy",
-                        "ffc",
-                        "ufl",
                         "pkgconfig",
-                        "dijitso"],
+                        "fenics-ffc",
+                        "fenics-ufl",
+                        "fenics-dijitso"],
       zip_safe=False)
diff --git a/dolfin/geometry/intersect.cpp b/python/src/MPICommWrapper.cpp
similarity index 56%
copy from dolfin/geometry/intersect.cpp
copy to python/src/MPICommWrapper.cpp
index bc7364f..70dc1eb 100644
--- a/dolfin/geometry/intersect.cpp
+++ b/python/src/MPICommWrapper.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2013 Anders Logg
+// Copyright (C) 2017 Tormod Landet
 //
 // This file is part of DOLFIN.
 //
@@ -14,20 +14,30 @@
 //
 // You should have received a copy of the GNU Lesser General Public License
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
-//
-// First added:  2013-05-30
-// Last changed: 2013-05-30
 
-#include "MeshPointIntersection.h"
-#include "intersect.h"
+#include "MPICommWrapper.h"
 
-using namespace dolfin;
+using namespace dolfin_wrappers;
 
 //-----------------------------------------------------------------------------
-std::shared_ptr<const MeshPointIntersection>
-dolfin::intersect(const Mesh& mesh, const Point& point)
+MPICommWrapper::MPICommWrapper() : _comm(MPI_COMM_NULL)
+{
+  // Do nothing
+}
+//-----------------------------------------------------------------------------
+MPICommWrapper::MPICommWrapper(MPI_Comm comm) : _comm(comm)
+{
+  // Do nothing
+}
+//-----------------------------------------------------------------------------
+MPICommWrapper& MPICommWrapper::operator=(const MPI_Comm comm)
+{
+  this->_comm = comm;
+  return *this;
+}
+//-----------------------------------------------------------------------------
+MPI_Comm MPICommWrapper::get() const
 {
-  return std::shared_ptr<const MeshPointIntersection>
-    (new MeshPointIntersection(mesh, point));
+  return _comm;
 }
 //-----------------------------------------------------------------------------
diff --git a/dolfin/la/PETScObject.h b/python/src/MPICommWrapper.h
similarity index 50%
copy from dolfin/la/PETScObject.h
copy to python/src/MPICommWrapper.h
index 08df1d7..77eb013 100644
--- a/dolfin/la/PETScObject.h
+++ b/python/src/MPICommWrapper.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 Garth N. Wells
+// Copyright (C) 2017 Tormod Landet
 //
 // This file is part of DOLFIN.
 //
@@ -15,37 +15,40 @@
 // You should have received a copy of the GNU Lesser General Public License
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 
-#ifndef __PETSC_OBJECT_H
-#define __PETSC_OBJECT_H
+#ifndef __MPI_COMM_WRAPPER_H
+#define __MPI_COMM_WRAPPER_H
 
-#ifdef HAS_PETSC
+#include <dolfin/common/MPI.h>
 
-#include <string>
-#include <dolfin/common/SubSystemsManager.h>
-
-namespace dolfin
+namespace dolfin_wrappers
 {
 
-  /// This class calls SubSystemsManager to initialise PETSc.
-  ///
-  /// All PETSc objects must be derived from this class.
+  /// This class wraps the MPI_Comm type for use in the pybind11
+  /// generation of python wrappers. MPI_Comm is either a pointer or
+  /// an int (MPICH vs OpenMPI) and this cannot be wrapped in a type
+  /// safe way with pybind11.
 
-  class PETScObject
+  class MPICommWrapper
   {
   public:
 
-    /// Constructor. Ensures that PETSc has been initialised.
-    PETScObject() { SubSystemsManager::init_petsc(); }
+    MPICommWrapper();
+
+    /// Wrap a MPI_Comm object
+    MPICommWrapper(MPI_Comm comm);
+
+    /// Assignment operator
+    MPICommWrapper& operator=(const MPI_Comm comm);
 
-    /// Destructor
-    virtual ~PETScObject() {}
+    /// Get the underlying MPI communicator
+    MPI_Comm get() const;
+
+  private:
+
+    // The underlying communicator
+    MPI_Comm _comm;
 
-    /// Print error message for PETSc calls that return an error
-    static void petsc_error(int error_code,
-                            std::string filename,
-                            std::string petsc_function);
   };
 }
 
 #endif
-#endif
diff --git a/python/src/adaptivity.cpp b/python/src/adaptivity.cpp
index bd83f74..10989b0 100644
--- a/python/src/adaptivity.cpp
+++ b/python/src/adaptivity.cpp
@@ -31,6 +31,7 @@
 #include <dolfin/fem/Form.h>
 #include <dolfin/fem/LinearVariationalProblem.h>
 #include <dolfin/fem/NonlinearVariationalProblem.h>
+#include <dolfin/function/Function.h>
 #include <dolfin/la/GenericVector.h>
 #include <dolfin/mesh/Mesh.h>
 
@@ -45,9 +46,10 @@ namespace dolfin_wrappers
   {
 #ifdef HAS_HDF5
     // dolfin::TimesSeries
-    py::class_<dolfin::TimeSeries, std::shared_ptr<dolfin::TimeSeries>>(m, "TimeSeries")
+    py::class_<dolfin::TimeSeries, std::shared_ptr<dolfin::TimeSeries>, dolfin::Variable>(m, "TimeSeries")
       .def(py::init<std::string>())
-      .def(py::init<MPI_Comm, std::string>())
+      .def(py::init([](const MPICommWrapper comm, const std::string &arg)
+                    { return std::unique_ptr<dolfin::TimeSeries>(new dolfin::TimeSeries(comm.get(), arg)); }))
       .def("store", (void (dolfin::TimeSeries::*)(const dolfin::GenericVector&, double)) &dolfin::TimeSeries::store)
       .def("store", (void (dolfin::TimeSeries::*)(const dolfin::Mesh&, double)) &dolfin::TimeSeries::store)
       .def("retrieve", (void (dolfin::TimeSeries::*)(dolfin::GenericVector&, double, bool) const) &dolfin::TimeSeries::retrieve,
@@ -111,7 +113,5 @@ namespace dolfin_wrappers
       .def(py::init<std::shared_ptr<dolfin::NonlinearVariationalProblem>,
            std::shared_ptr<dolfin::Form>,
            std::shared_ptr<dolfin::ErrorControl>>());
-
   }
-
 }
diff --git a/python/src/ale.cpp b/python/src/ale.cpp
index 6eb1fd1..e2f3462 100644
--- a/python/src/ale.cpp
+++ b/python/src/ale.cpp
@@ -52,7 +52,5 @@ namespace dolfin_wrappers
                     auto _disp = disp.attr("_cpp_object").cast<const dolfin::GenericFunction*>();
                     dolfin::ALE::move(mesh, *_disp);
                   });
-
   }
-
 }
diff --git a/python/src/casters.h b/python/src/casters.h
index 7508af5..19dae45 100644
--- a/python/src/casters.h
+++ b/python/src/casters.h
@@ -38,7 +38,8 @@ namespace pybind11
     template <typename... Ts>
       struct type_caster<boost::variant<Ts...>> : variant_caster<boost::variant<Ts...>> {};
 
-    // Specifies the function used to visit the variant -- `apply_visitor` instead of `visit`
+    // Specifies the function used to visit the variant --
+    // `apply_visitor` instead of `visit`
     template <>
       struct visit_helper<boost::variant> {
       template <typename... Args>
diff --git a/python/src/common.cpp b/python/src/common.cpp
index c218949..186774b 100644
--- a/python/src/common.cpp
+++ b/python/src/common.cpp
@@ -32,6 +32,7 @@
 #include <dolfin/log/Table.h>
 
 #include "casters.h"
+#include "MPICommWrapper.h"
 
 namespace py = pybind11;
 
@@ -54,11 +55,38 @@ namespace dolfin_wrappers
     m.def("has_hdf5", &dolfin::has_hdf5);
     m.def("has_hdf5_parallel", &dolfin::has_hdf5_parallel);
     m.def("has_mpi", &dolfin::has_mpi);
+    m.def("has_mpi4py", []()
+          {
+            #ifdef HAS_PYBIND11_MPI4PY
+            return true;
+            #else
+            return false;
+            #endif
+          }, "Return `True` if DOLFIN is configured with mpi4py");
     m.def("has_parmetis", &dolfin::has_parmetis);
     m.def("has_scotch", &dolfin::has_scotch);
-    m.def("has_petsc", &dolfin::has_petsc);
-    m.def("has_slepc", &dolfin::has_slepc, "Return `True` if DOLFIN is configured with SLEPc");
-    m.def("git_commit_hash", &dolfin::git_commit_hash, "Get git hash for this build.");
+    m.def("has_petsc", &dolfin::has_petsc,
+          "Return `True` if DOLFIN is configured with PETSc");
+    m.def("has_slepc", &dolfin::has_slepc,
+          "Return `True` if DOLFIN is configured with SLEPc");
+    m.def("has_petsc4py", []()
+          {
+            #ifdef HAS_PYBIND11_PETSC4PY
+            return true;
+            #else
+            return false;
+            #endif
+          }, "Return `True` if DOLFIN is configured with petsc4py");
+    m.def("has_slepc4py", []()
+          {
+            #ifdef HAS_PYBIND11_SLEPC4PY
+            return true;
+            #else
+            return false;
+            #endif
+          }, "Return `True` if DOLFIN is configured with slepc4py");
+    m.def("git_commit_hash", &dolfin::git_commit_hash,
+          "Returns git hash for this build.");
     m.def("sizeof_la_index", &dolfin::sizeof_la_index);
 
     m.attr("DOLFIN_EPS") = DOLFIN_EPS;
@@ -97,71 +125,92 @@ namespace dolfin_wrappers
           });
     m.def("dump_timings_to_xml", &dolfin::dump_timings_to_xml);
 
+    // dolfin::SubSystemsManager
+    py::class_<dolfin::SubSystemsManager, std::unique_ptr<dolfin::SubSystemsManager, py::nodelete>>
+      (m, "SubSystemsManager")
+      .def_static("init_petsc", (void (*)()) &dolfin::SubSystemsManager::init_petsc)
+      .def_static("init_petsc", [](std::vector<std::string> args)
+                  {
+                    std::vector<char*> argv(args.size());
+                    for (std::size_t i = 0; i < args.size(); ++i)
+                      argv[i] = const_cast<char*>(args[i].data());
+                    dolfin::SubSystemsManager::init_petsc(args.size(), argv.data());
+                  })
+      .def_static("finalize", &dolfin::SubSystemsManager::finalize)
+      .def_static("responsible_mpi", &dolfin::SubSystemsManager::responsible_mpi)
+      .def_static("responsible_petsc", &dolfin::SubSystemsManager::responsible_petsc)
+      .def_static("mpi_initialized", &dolfin::SubSystemsManager::mpi_initialized)
+      .def_static("mpi_finalized", &dolfin::SubSystemsManager::mpi_finalized);
+
   }
 
   // Interface for MPI
   void mpi(py::module& m)
   {
-    /*
-    #ifdef HAS_MPI4PY
-    dolfin::SubSystemsManager::init_mpi();
-    import_mpi4py();
+
+    #ifndef HAS_PYBIND11_MPI4PY
+    // Expose the MPICommWrapper directly since we cannot cast it to
+    // mpi4py
+    py::class_<MPICommWrapper>(m, "MPICommWrapper",
+      "DOLFIN is compiled without support for mpi4py. This object can be "
+      "passed into DOLFIN as an MPI communicator, but is not an mpi4py comm.")
+      .def("underlying_comm", [](MPICommWrapper self)
+           { return (std::uintptr_t) self.get(); },
+           "Return the underlying MPI_Comm cast to std::uintptr_t. "
+           "The return value may or may not make sense depending on the MPI implementation.");
     #endif
-    */
 
     // dolfin::MPI
     py::class_<dolfin::MPI>(m, "MPI", "MPI utilities")
-#ifdef OPEN_MPI
       .def_property_readonly_static("comm_world", [](py::object)
-                                    { return reinterpret_cast<std::uintptr_t>(MPI_COMM_WORLD); })
+                                    { return MPICommWrapper(MPI_COMM_WORLD); })
       .def_property_readonly_static("comm_self", [](py::object)
-                                    { return reinterpret_cast<std::uintptr_t>(MPI_COMM_SELF); })
+                                    { return MPICommWrapper(MPI_COMM_SELF); })
       .def_property_readonly_static("comm_null", [](py::object)
-                                    { return reinterpret_cast<std::uintptr_t>(MPI_COMM_NULL); })
-#else
-      .def_property_readonly_static("comm_world", [](py::object) { return MPI_COMM_WORLD; })
-      .def_property_readonly_static("comm_self", [](py::object) { return MPI_COMM_SELF; })
-      .def_property_readonly_static("comm_null", [](py::object) { return MPI_COMM_NULL; })
-#endif
-      .def_static("init", [](){ dolfin::SubSystemsManager::init_mpi(); }, "Initialise MPI")
-      .def_static("barrier", &dolfin::MPI::barrier)
-      .def_static("rank", &dolfin::MPI::rank)
-      .def_static("size", &dolfin::MPI::size)
-      .def_static("local_range", (std::pair<std::int64_t, std::int64_t> (*)(MPI_Comm, std::int64_t))
-                  &dolfin::MPI::local_range)
-      .def_static("max", &dolfin::MPI::max<double>)
-      .def_static("min", &dolfin::MPI::min<double>)
-      .def_static("sum", &dolfin::MPI::sum<double>)
-      .def_static("min", &dolfin::MPI::min<dolfin::Table>)
-      .def_static("max", &dolfin::MPI::max<dolfin::Table>)
-      .def_static("sum", &dolfin::MPI::sum<dolfin::Table>)
-      .def_static("avg", &dolfin::MPI::avg<dolfin::Table>)
-      /*
-#ifdef HAS_MPI4PY
-      .def("to_mpi4py_comm", [](py::object obj){
-          // If object is already a mpi4py communicator, return
-          if (PyObject_TypeCheck(obj.ptr(), &PyMPIComm_Type))
-            return obj;
-
-          MPI_Comm comm_new;
-          #ifdef OPEN_MPI
-          std::uintptr_t c = obj.cast<std::uintptr_t>();
-          MPI_Comm_dup(reinterpret_cast<MPI_Comm>(c), &comm_new);
-          #else
-          auto value = PyLong_AsLong(obj.ptr());
-          MPI_Comm_dup(value, &comm_new);
-          #endif
-
-          // Create wrapper for conversion to mpi4py
-          dolfin_wrappers::mpi_communicator mpi_comm;
-          mpi_comm.comm = comm_new;
-
-          return py::cast(mpi_comm);
-        },
-        "Convert a plain MPI communicator into a mpi4py communicator")
-#endif
-      */
-      ;
-     }
-
+                                    { return MPICommWrapper(MPI_COMM_NULL); })
+      .def_static("init", (void (*)()) &dolfin::SubSystemsManager::init_mpi,
+                  "Initialise MPI")
+      .def_static("init",
+                  [](std::vector<std::string> args, int required_thread_level)->int
+                  {
+                    std::vector<char*> argv(args.size());
+                    for (std::size_t i = 0; i < args.size(); ++i)
+                      argv[i] = const_cast<char*>(args[i].data());
+                    return dolfin::SubSystemsManager::
+                      init_mpi(args.size(), argv.data(), required_thread_level);
+                  },
+                  "Initialise MPI with command-line args and required level "
+                  "of thread support. Return provided thread level.")
+      .def_static("responsible", &dolfin::SubSystemsManager::responsible_mpi,
+                  "Return true if DOLFIN initialised MPI (and is therefore "
+                  "responsible for finalization)")
+      .def_static("initialized", &dolfin::SubSystemsManager::mpi_initialized,
+                  "Check if MPI has been initialised")
+      .def_static("finalized", &dolfin::SubSystemsManager::mpi_finalized,
+                  "Check if MPI has been finalized")
+      .def_static("barrier", [](const MPICommWrapper comm)
+                  { return dolfin::MPI::barrier(comm.get()); })
+      .def_static("rank", [](const MPICommWrapper comm)
+                  { return dolfin::MPI::rank(comm.get()); })
+      .def_static("size", [](const MPICommWrapper comm)
+                  { return dolfin::MPI::size(comm.get()); })
+      .def_static("local_range", [](MPICommWrapper comm, std::int64_t N)
+                  { return dolfin::MPI::local_range(comm.get(), N); })
+      // templated for double
+      .def_static("max", [](const MPICommWrapper comm, double value)
+                  { return dolfin::MPI::max(comm.get(), value); })
+      .def_static("min", [](const MPICommWrapper comm, double value)
+                  { return dolfin::MPI::min(comm.get(), value); })
+      .def_static("sum", [](const MPICommWrapper comm, double value)
+                  { return dolfin::MPI::sum(comm.get(), value); })
+      // templated for dolfin::Table
+      .def_static("max", [](const MPICommWrapper comm, dolfin::Table value)
+                  { return dolfin::MPI::max(comm.get(), value); })
+      .def_static("min", [](const MPICommWrapper comm, dolfin::Table value)
+                  { return dolfin::MPI::min(comm.get(), value); })
+      .def_static("sum", [](const MPICommWrapper comm, dolfin::Table value)
+                  { return dolfin::MPI::sum(comm.get(), value); })
+      .def_static("avg", [](const MPICommWrapper comm, dolfin::Table value)
+                  { return dolfin::MPI::avg(comm.get(), value); });
+  }
 }
diff --git a/python/src/dolfin.cpp b/python/src/dolfin.cpp
index 1690f5c..8dde3d3 100644
--- a/python/src/dolfin.cpp
+++ b/python/src/dolfin.cpp
@@ -15,6 +15,7 @@
 // You should have received a copy of the GNU Lesser General Public License
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 
+#include <iostream>
 #include <pybind11/pybind11.h>
 #include <dolfin/log/log.h>
 
@@ -52,7 +53,8 @@ namespace dolfin_wrappers
 PYBIND11_MODULE(cpp, m)
 {
   // Create module for C++ wrappers
-  m.doc() ="DOLFIN Python interface";
+  m.doc() = "DOLFIN Python interface";
+  m.attr("__version__") = DOLFIN_VERSION;
 
   // Create common submodule [common]
   py::module common = m.def_submodule("common", "Common module");
diff --git a/python/src/fem.cpp b/python/src/fem.cpp
index ff6e3d5..4454fc1 100644
--- a/python/src/fem.cpp
+++ b/python/src/fem.cpp
@@ -25,8 +25,11 @@
 #include <pybind11/stl.h>
 #include <pybind11/cast.h>
 
-#include <ufc.h>
+#ifdef HAS_PYBIND11_PETSC4PY
+#include <petsc4py/petsc4py.h>
+#endif
 
+#include <ufc.h>
 #include <dolfin/fem/fem_utils.h>
 #include <dolfin/fem/assemble.h>
 #include <dolfin/fem/assemble_local.h>
@@ -41,18 +44,19 @@
 #include <dolfin/fem/LocalSolver.h>
 #include <dolfin/fem/NonlinearVariationalProblem.h>
 #include <dolfin/fem/NonlinearVariationalSolver.h>
-#include <dolfin/fem/PointSource.h>
-#include <dolfin/fem/SystemAssembler.h>
 #include <dolfin/fem/PETScDMCollection.h>
+#include <dolfin/fem/PointSource.h>
 #include <dolfin/fem/SparsityPatternBuilder.h>
-#include <dolfin/function/FunctionSpace.h>
+#include <dolfin/fem/SystemAssembler.h>
 #include <dolfin/function/GenericFunction.h>
-#include <dolfin/mesh/Mesh.h>
-#include <dolfin/mesh/SubDomain.h>
-#include <dolfin/la/GenericTensor.h>
+#include <dolfin/function/FunctionSpace.h>
+#include <dolfin/function/Function.h>
 #include <dolfin/la/GenericMatrix.h>
 #include <dolfin/la/GenericVector.h>
+#include <dolfin/la/GenericTensor.h>
 #include <dolfin/la/SparsityPattern.h>
+#include <dolfin/mesh/Mesh.h>
+#include <dolfin/mesh/SubDomain.h>
 
 #include "casters.h"
 
@@ -62,12 +66,6 @@ namespace dolfin_wrappers
 {
   void fem(py::module& m)
   {
-#ifdef HAS_PETSC4PY
-    int ierr = import_petsc4py();
-    if (ierr != 0)
-      throw std::runtime_error("Failed to import petsc4py");
-#endif
-
     // UFC objects
     py::class_<ufc::finite_element, std::shared_ptr<ufc::finite_element>>
       (m, "ufc_finite_element", "UFC finite element object");
@@ -172,8 +170,10 @@ namespace dolfin_wrappers
       .def("signature", &dolfin::FiniteElement::signature);
 
     // dolfin::GenericDofMap
-    py::class_<dolfin::GenericDofMap, std::shared_ptr<dolfin::GenericDofMap>>
+    py::class_<dolfin::GenericDofMap, std::shared_ptr<dolfin::GenericDofMap>, dolfin::Variable>
       (m, "GenericDofMap", "DOLFIN DofMap object")
+      .def("global_dimension", &dolfin::GenericDofMap::global_dimension,
+           "The dimension of the global finite element function space")
       .def("index_map", &dolfin::GenericDofMap::index_map)
       .def("neighbours", &dolfin::GenericDofMap::neighbours)
       .def("off_process_owner", &dolfin::GenericDofMap::off_process_owner)
@@ -187,16 +187,24 @@ namespace dolfin_wrappers
            &dolfin::GenericDofMap::entity_dofs)
       .def("entity_closure_dofs", (std::vector<dolfin::la_index>(dolfin::GenericDofMap::*)(const dolfin::Mesh&, std::size_t) const)
            &dolfin::GenericDofMap::entity_closure_dofs)
-      .def("entity_dofs", (std::vector<dolfin::la_index>(dolfin::GenericDofMap::*)(const dolfin::Mesh&,
+          .def("entity_dofs", (std::vector<dolfin::la_index>(dolfin::GenericDofMap::*)(const dolfin::Mesh&,
                                                                                    std::size_t,
                                                                                    const std::vector<std::size_t>&) const)
            &dolfin::GenericDofMap::entity_dofs)
-      .def("entity_closure_dofs", (std::vector<dolfin::la_index>(dolfin::GenericDofMap::*)(const dolfin::Mesh&,
+          .def("entity_closure_dofs", (std::vector<dolfin::la_index>(dolfin::GenericDofMap::*)(const dolfin::Mesh&,
                                                                                            std::size_t,
                                                                                            const std::vector<std::size_t>&) const)
            &dolfin::GenericDofMap::entity_closure_dofs)
       .def("num_entity_dofs", &dolfin::GenericDofMap::num_entity_dofs)
       .def("tabulate_local_to_global_dofs", &dolfin::GenericDofMap::tabulate_local_to_global_dofs)
+      .def("local_to_global_index", &dolfin::GenericDofMap::local_to_global_index)
+      .def("local_to_global_unowned",
+           [](dolfin::GenericDofMap& self) {
+             return Eigen::Map<const Eigen::Matrix<std::size_t, Eigen::Dynamic, 1>>(
+               self.local_to_global_unowned().data(),
+               self.local_to_global_unowned().size()); },
+           py::return_value_policy::reference_internal,
+           "Return view into unowned part of local-to-global map")
       .def("clear_sub_map_data", &dolfin::GenericDofMap::clear_sub_map_data)
       .def("tabulate_entity_dofs", [](const dolfin::GenericDofMap& instance, std::size_t entity_dim,
                                       std::size_t cell_entity_index)
@@ -233,7 +241,7 @@ namespace dolfin_wrappers
                   py::arg("init")=true, py::arg("finalize")=true);
 
     // dolfin::DirichletBC
-    py::class_<dolfin::DirichletBC, std::shared_ptr<dolfin::DirichletBC>>
+    py::class_<dolfin::DirichletBC, std::shared_ptr<dolfin::DirichletBC>, dolfin::Variable>
       (m, "DirichletBC", "DOLFIN DirichletBC object")
       .def(py::init<const dolfin::DirichletBC&>())
       .def(py::init<std::shared_ptr<const dolfin::FunctionSpace>,
@@ -265,6 +273,10 @@ namespace dolfin_wrappers
            &dolfin::DirichletBC::apply)
       .def("apply", (void (dolfin::DirichletBC::*)(dolfin::GenericMatrix&, dolfin::GenericVector&) const)
            &dolfin::DirichletBC::apply)
+      .def("apply", (void (dolfin::DirichletBC::*)(dolfin::GenericVector&, const dolfin::GenericVector&) const)
+           &dolfin::DirichletBC::apply)
+      .def("apply", (void (dolfin::DirichletBC::*)(dolfin::GenericMatrix&, dolfin::GenericVector&, const dolfin::GenericVector&) const)
+           &dolfin::DirichletBC::apply)
       .def("user_subdomain", &dolfin::DirichletBC::user_sub_domain)
       .def("set_value", &dolfin::DirichletBC::set_value)
       .def("set_value", [](dolfin::DirichletBC& self, py::object value)
diff --git a/python/src/function.cpp b/python/src/function.cpp
index 71ea458..2c176ac 100644
--- a/python/src/function.cpp
+++ b/python/src/function.cpp
@@ -32,6 +32,8 @@
 #include <dolfin/function/FunctionAssigner.h>
 #include <dolfin/function/FunctionAXPY.h>
 #include <dolfin/function/FunctionSpace.h>
+#include <dolfin/function/MultiMeshFunction.h>
+#include <dolfin/function/MultiMeshFunctionSpace.h>
 #include <dolfin/function/LagrangeInterpolator.h>
 #include <dolfin/function/SpecialFunctions.h>
 #include <dolfin/fem/FiniteElement.h>
@@ -90,7 +92,20 @@ namespace dolfin_wrappers
            { std::vector<double> values;
              self.compute_vertex_values(values, mesh);
              return py::array_t<double>(values.size(), values.data());
-           })
+           }, "Compute values at all mesh vertices")
+      .def("compute_vertex_values", [](dolfin::GenericFunction& self)
+           {
+             auto V = self.function_space();
+             if (!V)
+                 throw py::value_error("GenericFunction has no function space. You must supply a mesh.");
+             auto mesh = V->mesh();
+             if (!mesh)
+                 throw py::value_error("GenericFunction has no function space mesh. You must supply a mesh.");
+             std::vector<double> values;
+             self.compute_vertex_values(values, *mesh);
+             // FIXME: this causes a copy, we should rewrite the C++ interface to use Eigen when SWIG is removed
+             return py::array_t<double>(values.size(), values.data());
+           }, "Compute values at all mesh vertices by using the mesh function.function_space().mesh()")
       .def("function_space", &dolfin::GenericFunction::function_space);
 
     // Create dolfin::Expression from a JIT pointer
@@ -424,6 +439,18 @@ namespace dolfin_wrappers
              }
            });
 
+    py::class_<dolfin::MultiMeshFunction>(m, "MultiMeshFunction")
+      .def(py::init<std::shared_ptr<dolfin::MultiMeshFunctionSpace>>())
+      .def("vector", static_cast<std::shared_ptr<dolfin::GenericVector>(dolfin::MultiMeshFunction::*)()>(&dolfin::MultiMeshFunction::vector));
+
+    py::class_<dolfin::MultiMeshFunctionSpace, std::shared_ptr<dolfin::MultiMeshFunctionSpace>>
+      (m, "MultiMeshFunctionSpace")
+      .def(py::init<std::shared_ptr<dolfin::MultiMesh>>())
+      .def("add", &dolfin::MultiMeshFunctionSpace::add)
+      .def("build", static_cast<void(dolfin::MultiMeshFunctionSpace::*)()>(&dolfin::MultiMeshFunctionSpace::build));
+
+
+
     // dolfin::assign interface
     m.def("assign", [](py::object v0, py::object v1)
            {
diff --git a/python/src/generation.cpp b/python/src/generation.cpp
index 2d7ed55..44807d7 100644
--- a/python/src/generation.cpp
+++ b/python/src/generation.cpp
@@ -15,12 +15,15 @@
 // You should have received a copy of the GNU Lesser General Public License
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 
+#include <array>
 #include <iostream>
 #include <memory>
+#include <string>
 #include <pybind11/pybind11.h>
 #include <pybind11/numpy.h>
 
 #include <dolfin/geometry/Point.h>
+#include <dolfin/mesh/CellType.h>
 #include <dolfin/generation/BoxMesh.h>
 #include <dolfin/generation/UnitTriangleMesh.h>
 #include <dolfin/generation/UnitCubeMesh.h>
@@ -28,8 +31,6 @@
 #include <dolfin/generation/SphericalShellMesh.h>
 #include <dolfin/generation/UnitSquareMesh.h>
 #include <dolfin/generation/UnitIntervalMesh.h>
-#include <dolfin/generation/UnitQuadMesh.h>
-#include <dolfin/generation/UnitHexMesh.h>
 #include <dolfin/generation/IntervalMesh.h>
 
 #include "casters.h"
@@ -44,64 +45,104 @@ namespace dolfin_wrappers
     // dolfin::IntervalMesh
     py::class_<dolfin::IntervalMesh, std::shared_ptr<dolfin::IntervalMesh>, dolfin::Mesh>(m, "IntervalMesh")
       .def(py::init<std::size_t, double, double>())
-      .def(py::init<MPI_Comm, std::size_t, double, double>());
+      .def(py::init([](const MPICommWrapper comm, std::size_t n, double a, double b)
+                    { return std::unique_ptr<dolfin::IntervalMesh>(new dolfin::IntervalMesh(comm.get(), n, a, b)); }));
 
     // dolfin::UnitIntervalMesh
     py::class_<dolfin::UnitIntervalMesh, std::shared_ptr<dolfin::UnitIntervalMesh>,
                dolfin::IntervalMesh, dolfin::Mesh>(m, "UnitIntervalMesh")
       .def(py::init<std::size_t>())
-      .def(py::init<MPI_Comm, std::size_t>())
-      .def_static("create", [](std::size_t n){ return dolfin::UnitIntervalMesh::create(n); });
+      .def(py::init([](const MPICommWrapper comm, std::size_t n)
+                    { return std::unique_ptr<dolfin::UnitIntervalMesh>(new dolfin::UnitIntervalMesh(comm.get(), n)); }))
+      .def_static("create", [](std::size_t n)
+                  { return dolfin::UnitIntervalMesh::create(n); });
 
     // dolfin::RectangleMesh
     py::class_<dolfin::RectangleMesh, std::shared_ptr<dolfin::RectangleMesh>, dolfin::Mesh>(m, "RectangleMesh")
+      .def_static("create", [](std::array<dolfin::Point, 2> p, std::array<std::size_t, 2> n,
+                               dolfin::CellType::Type cell_type, std::string diagonal)
+                  { return dolfin::RectangleMesh::create(p, n, cell_type, diagonal); },
+                  py::arg("p"), py::arg("n"), py::arg("cell_type"), py::arg("diagonal")="right")
+      .def_static("create", [](const MPICommWrapper comm, std::array<dolfin::Point, 2> p,
+                               std::array<std::size_t, 2> n, dolfin::CellType::Type cell_type,
+                               std::string diagonal)
+                  { return dolfin::RectangleMesh::create(comm.get(), p, n, cell_type, diagonal); },
+                  py::arg("comm"), py::arg("p"), py::arg("n"), py::arg("cell_type"),
+                  py::arg("diagonal")="right")
+      // Remove
       .def(py::init<dolfin::Point, dolfin::Point, std::size_t, std::size_t, std::string>(),
            py::arg("p0"), py::arg("p1"), py::arg("nx"), py::arg("ny"), py::arg("diagonal")="right")
-      .def(py::init<MPI_Comm, dolfin::Point, dolfin::Point, std::size_t, std::size_t, std::string>(),
-           py::arg("comm"), py::arg("p0"), py::arg("p1"), py::arg("nx"), py::arg("ny"),
-           py::arg("diagonal")="right");
+      .def(py::init([](const MPICommWrapper comm, const dolfin::Point& p0, const dolfin::Point& p1,
+                       std::size_t nx, std::size_t ny, std::string diagonal="right")
+                    { return std::unique_ptr<dolfin::RectangleMesh>(new dolfin::RectangleMesh(comm.get(), p0, p1, nx, ny, diagonal)); }),
+           py::arg("comm"), py::arg("p0"), py::arg("p1"), py::arg("nx"), py::arg("ny"), py::arg("diagonal")="right");
 
     // dolfin::UnitSquareMesh
     py::class_<dolfin::UnitSquareMesh, std::shared_ptr<dolfin::UnitSquareMesh>, dolfin::Mesh>(m, "UnitSquareMesh")
-      .def(py::init<std::size_t, std::size_t>())
-      .def(py::init<MPI_Comm, std::size_t, std::size_t>())
-      .def(py::init<std::size_t, std::size_t, std::string>())
-      .def(py::init<MPI_Comm, std::size_t, std::size_t, std::string>());
+      .def(py::init<std::size_t, std::size_t, std::string>(), py::arg("nx"), py::arg("ny"), py::arg("diagonal")="right")
+      .def(py::init([](const MPICommWrapper comm, std::size_t nx, std::size_t ny, std::string diagonal="right")
+                    { return std::unique_ptr<dolfin::UnitSquareMesh>(new dolfin::UnitSquareMesh(comm.get(), nx, ny, diagonal)); }),
+           py::arg("comm"), py::arg("nx"), py::arg("ny"), py::arg("diagonal")="right")
+      .def_static("create", [](std::array<std::size_t, 2> n, dolfin::CellType::Type cell_type,
+                               std::string diagonal)
+                  { return dolfin::UnitSquareMesh::create(n, cell_type, diagonal); },
+                  py::arg("n"), py::arg("cell_type"), py::arg("diagonal")="right")
+      .def_static("create", [](const MPICommWrapper comm, std::array<std::size_t, 2> n,
+                               dolfin::CellType::Type cell_type, std::string diagonal="right")
+                  { return dolfin::UnitSquareMesh::create(comm.get(), n, cell_type, diagonal); },
+                  py::arg("comm"), py::arg("n"), py::arg("cell_type"), py::arg("diagonal")="right")
+      // Remove below for 2018.1 release
+      .def_static("create", [](std::size_t nx, std::size_t ny, dolfin::CellType::Type cell_type)
+                  { return dolfin::UnitSquareMesh::create({nx, ny}, cell_type); },
+                  py::arg("nx"), py::arg("ny"), py::arg("cell_type"))
+      .def_static("create", [](const MPICommWrapper comm, std::size_t nx, std::size_t ny,
+                               dolfin::CellType::Type cell_type)
+                  { return dolfin::UnitSquareMesh::create(comm.get(), {nx, ny}, cell_type); },
+                  py::arg("comm"), py::arg("nx"), py::arg("ny"), py::arg("cell_type"));
 
     // dolfin::UnitCubeMesh
     py::class_<dolfin::UnitCubeMesh, std::shared_ptr<dolfin::UnitCubeMesh>, dolfin::Mesh>(m, "UnitCubeMesh")
       .def(py::init<std::size_t, std::size_t, std::size_t>())
-      .def(py::init<MPI_Comm, std::size_t, std::size_t, std::size_t>());
+      .def(py::init([](const MPICommWrapper comm, std::size_t nx, std::size_t ny, std::size_t nz)
+                    { return std::unique_ptr<dolfin::UnitCubeMesh>(new dolfin::UnitCubeMesh(comm.get(), nx, ny, nz)); }),
+           py::arg("comm"), py::arg("nx"), py::arg("ny"), py::arg("nz"))
+      .def_static("create", [](std::array<std::size_t, 3> n, dolfin::CellType::Type cell_type)
+                  { return dolfin::UnitCubeMesh::create(n, cell_type); },
+                  py::arg("n"), py::arg("cell_type"))
+      .def_static("create", [](const MPICommWrapper comm, std::array<std::size_t, 3> n,
+                               dolfin::CellType::Type cell_type)
+                  { return dolfin::UnitCubeMesh::create(comm.get(), n, cell_type); },
+                  py::arg("comm"), py::arg("n"), py::arg("cell_type"))
+      // Remove below for 2018.1 release
+      .def_static("create", [](std::size_t nx, std::size_t ny, std::size_t nz,
+                               dolfin::CellType::Type cell_type)
+                  { return dolfin::UnitCubeMesh::create({nx, ny, nz}, cell_type); },
+                  py::arg("nx"), py::arg("ny"), py::arg("nz"), py::arg("cell_type"))
+      .def_static("create", [](const MPICommWrapper comm, std::size_t nx, std::size_t ny, std::size_t nz,
+                               dolfin::CellType::Type cell_type)
+                  { return dolfin::UnitCubeMesh::create(comm.get(), {nx, ny, nz}, cell_type); },
+                  py::arg("comm"), py::arg("nx"), py::arg("ny"), py::arg("nz"), py::arg("cell_type"));
 
     // dolfin::UnitDiscMesh
     py::class_<dolfin::UnitDiscMesh>(m, "UnitDiscMesh")
-      .def_static("create", &dolfin::UnitDiscMesh::create);
+      .def_static("create", [](const MPICommWrapper comm, std::size_t n, std::size_t degree, std::size_t gdim)
+                  { return dolfin::UnitDiscMesh::create(comm.get(), n, degree, gdim); });
 
     // dolfin::SphericalShellMesh
     py::class_<dolfin::SphericalShellMesh>(m, "SphericalShellMesh")
-      .def_static("create", &dolfin::SphericalShellMesh::create);
+      .def_static("create", [](const MPICommWrapper comm, std::size_t degree)
+                  { return dolfin::SphericalShellMesh::create(comm.get(), degree); });
 
     // dolfin::UnitTriangleMesh
     py::class_<dolfin::UnitTriangleMesh>(m, "UnitTriangleMesh")
       .def_static("create", &dolfin::UnitTriangleMesh::create);
 
-    // dolfin::UnitQuadMesh
-    py::class_<dolfin::UnitQuadMesh>(m, "UnitQuadMesh")
-      .def_static("create", [](std::size_t nx, std::size_t ny)
-                  { return dolfin::UnitQuadMesh::create(nx, ny); })
-      .def_static("create", [](MPI_Comm comm, std::size_t nx, std::size_t ny)
-                  { return dolfin::UnitQuadMesh::create(comm, nx, ny); });
-
-    // dolfin::UnitHexMesh
-    py::class_<dolfin::UnitHexMesh>(m, "UnitHexMesh")
-      .def_static("create", [](std::size_t nx, std::size_t ny, std::size_t nz)
-                  { return dolfin::UnitHexMesh::create(nx, ny, nz); })
-      .def_static("create", [](MPI_Comm comm, std::size_t nx, std::size_t ny, std::size_t nz)
-                  { return dolfin::UnitHexMesh::create(comm, nx, ny, nz); });
-
     // dolfin::BoxMesh
     py::class_<dolfin::BoxMesh, std::shared_ptr<dolfin::BoxMesh>, dolfin::Mesh>(m, "BoxMesh")
       .def(py::init<const dolfin::Point&, const dolfin::Point&, std::size_t, std::size_t, std::size_t>())
-      .def(py::init<MPI_Comm, const dolfin::Point&, const dolfin::Point&, std::size_t, std::size_t, std::size_t>());
+      .def(py::init([](const MPICommWrapper comm, const dolfin::Point& p0, const dolfin::Point& p1,
+                       std::size_t nx, std::size_t ny, std::size_t nz)
+                    { return std::unique_ptr<dolfin::BoxMesh>(new dolfin::BoxMesh(comm.get(), p0, p1, nx, ny, nz)); }),
+           py::arg("comm"), py::arg("p0"), py::arg("p1"), py::arg("nx"), py::arg("ny"), py::arg("nz"));
   }
 }
diff --git a/python/src/geometry.cpp b/python/src/geometry.cpp
index 17cc268..f4b3d70 100644
--- a/python/src/geometry.cpp
+++ b/python/src/geometry.cpp
@@ -26,6 +26,8 @@
 #include <dolfin/geometry/intersect.h>
 #include <dolfin/geometry/BoundingBoxTree.h>
 #include <dolfin/geometry/MeshPointIntersection.h>
+#include <dolfin/geometry/CollisionPredicates.h>
+#include <dolfin/geometry/IntersectionConstruction.h>
 #include <dolfin/geometry/Point.h>
 #include <dolfin/mesh/Mesh.h>
 
@@ -55,7 +57,7 @@ namespace dolfin_wrappers
       .def("compute_entity_collisions",
            (std::pair<std::vector<unsigned int>, std::vector<unsigned int>>
             (dolfin::BoundingBoxTree::*)(const dolfin::BoundingBoxTree&) const)
-            &dolfin::BoundingBoxTree::compute_entity_collisions)
+	   &dolfin::BoundingBoxTree::compute_entity_collisions)
       .def("compute_first_collision", &dolfin::BoundingBoxTree::compute_first_collision)
       .def("compute_first_entity_collision", &dolfin::BoundingBoxTree::compute_first_entity_collision)
       .def("compute_closest_entity", &dolfin::BoundingBoxTree::compute_closest_entity);
@@ -116,10 +118,12 @@ namespace dolfin_wrappers
            })
       .def(py::self + py::self)
       .def(py::self - py::self)
+      .def(py::self == py::self)
       .def(py::self * float())
       .def(py::self / float())
-      .def("array", [](dolfin::Point& self)
-           { return Eigen::Map<Eigen::Vector3d>(self.coordinates()); })
+      .def("array",
+           [](dolfin::Point& self) { return Eigen::Vector3d(self.coordinates()); },
+           "Return copy of coordinate array")
       .def("norm", &dolfin::Point::norm)
       .def("x", &dolfin::Point::x)
       .def("y", &dolfin::Point::y)
@@ -132,6 +136,27 @@ namespace dolfin_wrappers
       (m, "MeshPointIntersection")
       .def("intersected_cells", &dolfin::MeshPointIntersection::intersected_cells);
 
+    // These classes are wrapped only to be able to write tests in python.
+    // They are not imported into the dolfin namespace in python, but must be accessed through
+    // dolfin.cpp.geometry
+    py::class_<dolfin::CollisionPredicates>(m, "CollisionPredicates")
+      .def_static("collides_segment_point_2d",
+		  &dolfin::CollisionPredicates::collides_segment_point_2d)
+      .def_static("collides_triangle_point_2d",
+		  &dolfin::CollisionPredicates::collides_triangle_point_2d)
+      .def_static("collides_triangle_triangle_2d",
+		  &dolfin::CollisionPredicates::collides_triangle_triangle_2d)
+      .def_static("collides_segment_segment_2d",
+		  &dolfin::CollisionPredicates::collides_segment_segment_2d);
+
+    py::class_<dolfin::IntersectionConstruction>(m, "IntersectionConstruction")
+      .def_static("intersection_triangle_triangle_2d",
+		  &dolfin::IntersectionConstruction::intersection_triangle_triangle_2d)
+      .def_static("intersection_segment_segment_2d",
+		  &dolfin::IntersectionConstruction::intersection_segment_segment_2d)
+      .def_static("intersection_triangle_segment_2d",
+		  &dolfin::IntersectionConstruction::intersection_triangle_segment_2d);
+
     // dolfin/geometry free functions
     m.def("intersect", &dolfin::intersect);
 
diff --git a/python/src/io.cpp b/python/src/io.cpp
index 0d35030..96272f1 100644
--- a/python/src/io.cpp
+++ b/python/src/io.cpp
@@ -48,7 +48,9 @@ namespace dolfin_wrappers
     py::class_<dolfin::File, std::shared_ptr<dolfin::File>>(m, "File")
       .def(py::init<std::string>())
       .def(py::init<std::string, std::string>())
-      .def(py::init<MPI_Comm, std::string>())
+      .def(py::init([](const MPICommWrapper comm, std::string filename)
+        { return std::unique_ptr<dolfin::File>(new dolfin::File(comm.get(), filename)); }),
+        py::arg("comm"), py::arg("filename"))
       //
       .def("write", (void (dolfin::File::*)(const dolfin::Parameters&)) &dolfin::File::write)
       //
@@ -225,8 +227,11 @@ namespace dolfin_wrappers
       .def("type_str", &dolfin::HDF5Attribute::type_str);
 
     // dolfin::HDF5File
-    py::class_<dolfin::HDF5File, std::shared_ptr<dolfin::HDF5File>> (m, "HDF5File")
-      .def(py::init<MPI_Comm, std::string, std::string>())
+    py::class_<dolfin::HDF5File, std::shared_ptr<dolfin::HDF5File>,
+               dolfin::Variable> (m, "HDF5File")
+      .def(py::init([](const MPICommWrapper comm, const std::string filename, const std::string file_mode)
+        { return std::unique_ptr<dolfin::HDF5File>(new dolfin::HDF5File(comm.get(), filename, file_mode)); }),
+        py::arg("comm"), py::arg("filename"), py::arg("file_mode"))
       .def("__enter__", [](dolfin::HDF5File& self){ return &self; })
       .def("__exit__", [](dolfin::HDF5File& self, py::args args, py::kwargs kwargs){ self.close(); })
       .def("close", &dolfin::HDF5File::close)
@@ -301,16 +306,20 @@ namespace dolfin_wrappers
            }, py::arg("u"), py::arg("name"), py::arg("t"))
       .def("set_mpi_atomicity", &dolfin::HDF5File::set_mpi_atomicity)
       .def("get_mpi_atomicity", &dolfin::HDF5File::get_mpi_atomicity)
-      // attributes
+      // others
+      .def("has_dataset", &dolfin::HDF5File::has_dataset)
       .def("attributes", &dolfin::HDF5File::attributes);
 
 #endif
 
     // dolfin::XDMFFile
-    py::class_<dolfin::XDMFFile, std::shared_ptr<dolfin::XDMFFile>> xdmf_file(m, "XDMFFile");
+    py::class_<dolfin::XDMFFile, std::shared_ptr<dolfin::XDMFFile>,
+               dolfin::Variable> xdmf_file(m, "XDMFFile");
 
     xdmf_file
-      .def(py::init<MPI_Comm, std::string>())
+      .def(py::init([](const MPICommWrapper comm, std::string filename)
+        { return std::unique_ptr<dolfin::XDMFFile>(new dolfin::XDMFFile(comm.get(), filename)); }),
+        py::arg("comm"), py::arg("filename"))
       .def(py::init<std::string>())
       .def("__enter__", [](dolfin::XDMFFile& self){ return &self; })
       .def("__exit__", [](dolfin::XDMFFile& self, py::args args, py::kwargs kwargs){ self.close(); });
@@ -436,7 +445,7 @@ namespace dolfin_wrappers
            {
              if (color.ndim() != 1 or color.shape(0) != 3)
                throw pybind11::type_error("Color must be a 1D array or length 3");
-             self.set_diffuse_color({*color.data(0), *color.data(1), *color.data(2)});
+             self.set_diffuse_color({{*color.data(0), *color.data(1), *color.data(2)}});
            });
 
     // dolfin::X3DOM
diff --git a/python/src/la.cpp b/python/src/la.cpp
index b93801c..0706777 100644
--- a/python/src/la.cpp
+++ b/python/src/la.cpp
@@ -22,6 +22,10 @@
 #include <pybind11/stl.h>
 #include <pybind11/operators.h>
 
+#ifdef HAS_PYBIND11_PETSC4PY
+#include <petsc4py/petsc4py.h>
+#endif
+
 #include "casters.h"
 
 #include <dolfin/common/Array.h>
@@ -44,9 +48,10 @@
 #include <dolfin/la/EigenFactory.h>
 #include <dolfin/la/EigenMatrix.h>
 #include <dolfin/la/EigenVector.h>
+#include <dolfin/la/PETScFactory.h>
 #include <dolfin/la/PETScKrylovSolver.h>
 #include <dolfin/la/PETScLUSolver.h>
-#include <dolfin/la/PETScFactory.h>
+#include <dolfin/la/PETScLinearOperator.h>
 #include <dolfin/la/PETScMatrix.h>
 #include <dolfin/la/PETScOptions.h>
 #include <dolfin/la/PETScPreconditioner.h>
@@ -72,29 +77,68 @@ namespace
   template<typename T>
   void check_indices(const py::array_t<T>& x, std::int64_t local_size)
   {
-    for (std::size_t i = 0; i < x.size(); ++i)
+    for (std::int64_t i = 0; i < (std::int64_t) x.size(); ++i)
     {
       std::int64_t _x = *(x.data() + i);
       if (_x < 0 or !(_x < local_size))
         throw py::index_error("Vector index out of range");
     }
   }
+
+  // Linear operator trampoline class
+  template<typename LinearOperatorBase>
+  class PyLinearOperator : public LinearOperatorBase
+  {
+    using LinearOperatorBase::LinearOperatorBase;
+
+    // pybdind11 has some issues when passing by reference (due to
+    // the return value policy), so the below is non-standard.  See
+    // https://github.com/pybind/pybind11/issues/250.
+
+    std::size_t size(std::size_t dim) const
+    { PYBIND11_OVERLOAD_PURE(std::size_t, LinearOperatorBase, size, ); }
+
+    void mult(const dolfin::GenericVector& x, dolfin::GenericVector& y) const
+    { PYBIND11_OVERLOAD_INT(void, LinearOperatorBase, "mult", &x, &y); }
+  };
+
+  // Linear operator trampoline class (with pure virtual 'mult'
+  // function)
+  template<typename LinearOperatorBase>
+  class PyLinearOperatorPure : public LinearOperatorBase
+  {
+    using LinearOperatorBase::LinearOperatorBase;
+
+    std::size_t size(std::size_t dim) const
+    { PYBIND11_OVERLOAD_PURE(std::size_t, LinearOperatorBase, size, ); }
+
+    void mult(const dolfin::GenericVector& x, dolfin::GenericVector& y) const
+    {
+      PYBIND11_OVERLOAD_INT(void, LinearOperatorBase, "mult", &x, &y);
+      py::pybind11_fail("Tried to call pure virtual function \'mult\'");
+    }
+  };
+
 }
 
 namespace dolfin_wrappers
 {
+  using RowMatrixXd = Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
+
   void la(py::module& m)
   {
-#ifdef HAS_PETSC4PY
-    int ierr = import_petsc4py();
-    if (ierr != 0)
-      throw std::runtime_error("Failed to import petsc4py");
-#endif
-
     // dolfin::IndexMap
     py::class_<dolfin::IndexMap, std::shared_ptr<dolfin::IndexMap>> index_map(m, "IndexMap");
-    index_map.def("size", &dolfin::IndexMap::size);
-    index_map.def("local_range", &dolfin::IndexMap::local_range);
+    index_map.def("size", &dolfin::IndexMap::size)
+      .def("block_size", &dolfin::IndexMap::block_size)
+      .def("local_range", &dolfin::IndexMap::local_range)
+      .def("local_to_global_unowned",
+           [](dolfin::IndexMap& self) {
+             return Eigen::Map<const Eigen::Matrix<std::size_t, Eigen::Dynamic, 1>>(
+               self.local_to_global_unowned().data(),
+               self.local_to_global_unowned().size()); },
+           py::return_value_policy::reference_internal,
+           "Return view into unowned part of local-to-global map");
 
     // dolfin::IndexMap enums
     py::enum_<dolfin::IndexMap::MapSize>(index_map, "MapSize")
@@ -157,7 +201,8 @@ namespace dolfin_wrappers
            });
 
     // dolfin::TensorLayout
-    py::class_<dolfin::TensorLayout, std::shared_ptr<dolfin::TensorLayout>> tensor_layout(m, "TensorLayout");
+    py::class_<dolfin::TensorLayout, std::shared_ptr<dolfin::TensorLayout>,
+               dolfin::Variable> tensor_layout(m, "TensorLayout");
 
     // dolfin::TensorLayout enums
     py::enum_<dolfin::TensorLayout::Sparsity>(tensor_layout, "Sparsity")
@@ -168,36 +213,49 @@ namespace dolfin_wrappers
       .value("UNGHOSTED", dolfin::TensorLayout::Ghosts::UNGHOSTED);
 
     tensor_layout
-      .def(py::init<MPI_Comm, std::size_t, dolfin::TensorLayout::Sparsity>())
-      .def(py::init<MPI_Comm, std::vector<std::shared_ptr<const dolfin::IndexMap>>,
-           std::size_t, dolfin::TensorLayout::Sparsity, dolfin::TensorLayout::Ghosts>())
+      .def(py::init([](const MPICommWrapper comm, std::size_t primary_dim,
+                       dolfin::TensorLayout::Sparsity sparsity_pattern)
+        { return std::unique_ptr<dolfin::TensorLayout>(new dolfin::TensorLayout(comm.get(), primary_dim, sparsity_pattern)); }))
+      .def(py::init([](const MPICommWrapper comm,
+                       std::vector<std::shared_ptr<const dolfin::IndexMap>> index_maps,
+                       std::size_t primary_dim, dolfin::TensorLayout::Sparsity sparsity_pattern,
+                       dolfin::TensorLayout::Ghosts ghosted)
+        { return std::unique_ptr<dolfin::TensorLayout>(new dolfin::TensorLayout(comm.get(), index_maps, primary_dim,
+                                                                                sparsity_pattern, ghosted)); }))
       .def("init", &dolfin::TensorLayout::init)
       .def("sparsity_pattern", (std::shared_ptr<dolfin::SparsityPattern> (dolfin::TensorLayout::*)()) &dolfin::TensorLayout::sparsity_pattern);
 
     // dolfin::LinearAlgebraObject
     py::class_<dolfin::LinearAlgebraObject, std::shared_ptr<dolfin::LinearAlgebraObject>,
                dolfin::Variable>(m, "LinearAlgebraObject")
-    .def("mpi_comm", &dolfin::GenericLinearOperator::mpi_comm);
+      .def("mpi_comm", [](dolfin::LinearAlgebraObject& self)
+        { return MPICommWrapper(self.mpi_comm()); });
 
     // dolfin::GenericLinearOperator
     py::class_<dolfin::GenericLinearOperator, std::shared_ptr<dolfin::GenericLinearOperator>,
-               dolfin::LinearAlgebraObject>
-      (m, "GenericLinearOperator", "DOLFIN GenericLinearOperator object")
-      .def("mult", &dolfin::GenericLinearOperator::mult);
+               PyLinearOperatorPure<dolfin::GenericLinearOperator>, dolfin::LinearAlgebraObject>
+      (m, "GenericLinearOperator", "GenericLinearOperator object");
 
     // dolfin::GenericTensor
     py::class_<dolfin::GenericTensor, std::shared_ptr<dolfin::GenericTensor>,
                dolfin::LinearAlgebraObject>
       (m, "GenericTensor", "DOLFIN GenericTensor object")
       .def("init", &dolfin::GenericTensor::init)
+      .def("empty", &dolfin::GenericTensor::empty)
+      .def("factory", &dolfin::GenericTensor::factory)
+      .def("local_range", &dolfin::GenericTensor::local_range)
+      .def("rank", &dolfin::GenericTensor::rank)
+      .def("size", &dolfin::GenericTensor::size)
+      .def("str", &dolfin::GenericTensor::str)
       .def("zero", &dolfin::GenericTensor::zero);
 
     // dolfin::GenericMatrix
     py::class_<dolfin::GenericMatrix, std::shared_ptr<dolfin::GenericMatrix>,
                dolfin::GenericTensor, dolfin::GenericLinearOperator>
-      (m, "GenericMatrix", "DOLFIN GenericMatrix object")
+      (m, "GenericMatrix", py::dynamic_attr(), "DOLFIN GenericMatrix object")
       .def("init_vector", &dolfin::GenericMatrix::init_vector)
       .def("axpy", &dolfin::GenericMatrix::axpy)
+      .def("mult", &dolfin::GenericMatrix::mult)
       .def("transpmult", &dolfin::GenericMatrix::transpmult)
       // __ifoo__
       .def("__imul__", &dolfin::GenericMatrix::operator*=, "Multiply by a scalar")
@@ -235,7 +293,7 @@ namespace dolfin_wrappers
            {
              if (x.ndim() != 1)
                throw py::index_error("NumPy must be a 1D array for multiplication by a GenericMatrix");
-             if (x.size() != self.size(1))
+             if ((std::size_t) x.size() != self.size(1))
                throw py::index_error("Length of array must match number of matrix columns");
 
              auto _x = self.factory().create_vector(self.mpi_comm());
@@ -261,9 +319,34 @@ namespace dolfin_wrappers
       .def("norm", &dolfin::GenericMatrix::norm)
       .def("nnz", &dolfin::GenericMatrix::nnz)
       .def("size", &dolfin::GenericMatrix::size)
+      .def("apply", &dolfin::GenericMatrix::apply)
       .def("get_diagonal", &dolfin::GenericMatrix::get_diagonal)
       .def("set_diagonal", &dolfin::GenericMatrix::set_diagonal)
-      .def("ident_zeros", &dolfin::GenericMatrix::ident_zeros)
+      .def("ident_zeros", &dolfin::GenericMatrix::ident_zeros, py::arg("tol") = DOLFIN_EPS)
+      .def("ident", [](dolfin::GenericMatrix& self, std::vector<dolfin::la_index> rows)
+           { self.ident(rows.size(), rows.data()); }, py::arg("rows"))
+      .def("get", [](dolfin::GenericMatrix& self, Eigen::Ref<RowMatrixXd> block,
+                     const std::vector<dolfin::la_index> rows,
+                     const std::vector<dolfin::la_index> cols)
+           {
+             if ((std::size_t) block.rows() != rows.size())
+               throw py::value_error("Block must have the same number of rows as len(rows)");
+             if ((std::size_t) block.cols() != cols.size())
+               throw py::value_error("Block must have the same number of columns as len(cols)");
+             self.get((double *) block.data(), rows.size(), rows.data(),
+                      cols.size(), cols.data());
+           }, py::arg("block"), py::arg("rows"), py::arg("cols"))
+      .def("set", [](dolfin::GenericMatrix& self, const Eigen::Ref<const RowMatrixXd> block,
+                     const std::vector<dolfin::la_index> rows,
+                     const std::vector<dolfin::la_index> cols)
+           {
+             if ((std::size_t) block.rows() != rows.size())
+               throw py::value_error("Block must have the same number of rows as len(rows)");
+             if ((std::size_t) block.cols() != cols.size())
+               throw py::value_error("Block must have the same number of columns as len(cols)");
+             self.set((const double *) block.data(), rows.size(), rows.data(),
+                      cols.size(), cols.data());
+           }, py::arg("block"), py::arg("rows"), py::arg("cols"))
       .def("getrow", [](const dolfin::GenericMatrix& instance, std::size_t row)
            {
              std::vector<double> values;
@@ -272,7 +355,7 @@ namespace dolfin_wrappers
              auto _columns = py::array_t<std::size_t>(columns.size(), columns.data());
              auto _values = py::array_t<double>(values.size(), values.data());
              return std::make_pair(_columns, _values);
-           })
+           }, py::arg("row"))
       .def("array", [](const dolfin::GenericMatrix& instance)
            {
              // FIXME: This function is highly dubious. It assumes a
@@ -299,7 +382,7 @@ namespace dolfin_wrappers
     // dolfin::GenericVector
     py::class_<dolfin::GenericVector, std::shared_ptr<dolfin::GenericVector>,
                dolfin::GenericTensor>
-      (m, "GenericVector", "DOLFIN GenericVector object")
+      (m, "GenericVector", py::dynamic_attr(), "DOLFIN GenericVector object")
       .def("init", (void (dolfin::GenericVector::*)(std::size_t)) &dolfin::GenericVector::init)
       .def("init", (void (dolfin::GenericVector::*)(const dolfin::TensorLayout&)) &dolfin::GenericVector::init)
       .def("init", (void (dolfin::GenericVector::*)(std::pair<std::size_t, std::size_t>)) &dolfin::GenericVector::init)
@@ -366,7 +449,7 @@ namespace dolfin_wrappers
            {
              if (indices.ndim() != 1)
                throw py::index_error("Indices must be a 1D array");
-             if (indices.size() != self.local_size())
+             if ((std::size_t) indices.size() != self.local_size())
                throw py::index_error("Indices size mismatch");
              check_indices(indices, self.local_size());
 
@@ -376,7 +459,7 @@ namespace dolfin_wrappers
 
              // Extract filtered values
              std::vector<double> filtered;
-             for (std::size_t i = 0; i < indices.size(); ++i)
+             for (std::size_t i = 0; i < (std::size_t) indices.size(); ++i)
              {
                bool e = *(indices.data() + i);
                if (e)
@@ -474,13 +557,19 @@ namespace dolfin_wrappers
       .def("__len__", [](dolfin::GenericVector& self) { return self.local_size(); })
       .def("size",  (std::size_t (dolfin::GenericVector::*)() const) &dolfin::GenericVector::size)
       //
-      .def("get_local", [](const dolfin::GenericVector& instance, const std::vector<long>& rows)
+      .def("get_local", [](const dolfin::GenericVector& instance,
+                           const std::vector<dolfin::la_index>& rows)
            {
-             std::vector<dolfin::la_index> _rows(rows.begin(), rows.end());
              py::array_t<double> data(rows.size());
-             instance.get_local(data.mutable_data(), _rows.size(), _rows.data());
+             instance.get_local(data.mutable_data(), rows.size(), rows.data());
              return data;
            })
+      .def("get_local", [](const dolfin::GenericVector& instance)
+           {
+             std::vector<double> values;
+             instance.get_local(values);
+             return py::array_t<double>(values.size(), values.data());
+           })
       .def("set_local", [](dolfin::GenericVector& instance, std::vector<double> values)
            {
              std::vector<dolfin::la_index> indices(values.size());
@@ -527,23 +616,16 @@ namespace dolfin_wrappers
       .def("local_range", (std::pair<std::int64_t, std::int64_t> (dolfin::GenericVector::*)() const) &dolfin::GenericVector::local_range)
       .def("owns_index", &dolfin::GenericVector::owns_index)
       .def("apply", &dolfin::GenericVector::apply)
-      .def("array", [](const dolfin::GenericVector& instance)
-           {
-             std::vector<double> values;
-             instance.get_local(values);
-             return py::array_t<double>(values.size(), values.data());
-           })
       .def_property_readonly("__array_priority__", [](const dolfin::GenericVector& self){ return 0; });
 
-
-
     // dolfin::Matrix
     py::class_<dolfin::Matrix, std::shared_ptr<dolfin::Matrix>, dolfin::GenericMatrix>
       (m, "Matrix", "DOLFIN Matrix object")
       .def(py::init<>())
       .def(py::init<const dolfin::Matrix&>())  // Remove? (use copy instead)
       .def(py::init<const dolfin::GenericMatrix&>())  // Remove? (use copy instead)
-      .def(py::init<MPI_Comm>()) // This comes last of constructors so pybind11 attempts it lasts (avoid OpenMPI comm casting problems)
+      .def(py::init([](const MPICommWrapper comm)
+        { return std::unique_ptr<dolfin::Matrix>(new dolfin::Matrix(comm.get())); }))
       // Enabling the below messes up the operators because pybind11
       // then fails to try the GenericMatrix __mul__ operators
       /*
@@ -568,8 +650,10 @@ namespace dolfin_wrappers
       .def(py::init<>())
       .def(py::init<const dolfin::Vector&>())
       .def(py::init<const dolfin::GenericVector&>())
-      .def(py::init<MPI_Comm>())
-      .def(py::init<MPI_Comm, std::size_t>())
+      .def(py::init([](const MPICommWrapper comm)
+        { return std::unique_ptr<dolfin::Vector>(new dolfin::Vector(comm.get())); }))
+      .def(py::init([](const MPICommWrapper comm, std::size_t N)
+        { return std::unique_ptr<dolfin::Vector>(new dolfin::Vector(comm.get(), N)); }))
       .def("min", &dolfin::Vector::min)
       .def("max", &dolfin::Vector::max)
       .def("abs", &dolfin::Vector::abs)
@@ -619,40 +703,21 @@ namespace dolfin_wrappers
     py::class_<dolfin::Scalar, std::shared_ptr<dolfin::Scalar>, dolfin::GenericTensor>
       (m, "Scalar")
       .def(py::init<>())
-      .def(py::init<MPI_Comm>())
+      .def(py::init([](const MPICommWrapper comm)
+        { return std::unique_ptr<dolfin::Scalar>(new dolfin::Scalar(comm.get())); }))
       .def("add_local_value", &dolfin::Scalar::add_local_value)
       .def("apply", &dolfin::Scalar::apply)
-      .def("mpi_comm", &dolfin::Scalar::mpi_comm)
+      .def("mpi_comm", [](dolfin::Scalar& self)
+        { return MPICommWrapper(self.mpi_comm()); })
       .def("get_scalar_value", &dolfin::Scalar::get_scalar_value);
 
-    class PyLinearOperator : public dolfin::LinearOperator
-    {
-      // dolfin::LinearOperator trampoline class
-
-      using dolfin::LinearOperator::LinearOperator;
-
-      // pybdind11 has some issues when passing by reference (due to
-      // the return value policy), so the below is non-standard.  See
-      // https://github.com/pybind/pybind11/issues/250.
-
-      std::size_t size(std::size_t dim) const
-      {
-        PYBIND11_OVERLOAD_PURE(std::size_t, dolfin::LinearOperator, size, );
-      }
-
-      void mult(const dolfin::GenericVector& x, dolfin::GenericVector& y) const
-      {
-        PYBIND11_OVERLOAD_INT(void, dolfin::LinearOperator, "mult", &x, &y);
-        py::pybind11_fail("Tried to call pure virtual function dolfin::LinearOpertor::mult");
-      }
-    };
-
     // dolfin::LinearOperator
     py::class_<dolfin::LinearOperator, std::shared_ptr<dolfin::LinearOperator>,
-               PyLinearOperator, dolfin::GenericLinearOperator>
+               PyLinearOperatorPure<dolfin::LinearOperator>, dolfin::GenericLinearOperator>
       (m, "LinearOperator")
-      //.def(py::init<>())
-      .def(py::init<const dolfin::GenericVector&, const dolfin::GenericVector&>());
+      .def(py::init<const dolfin::GenericVector&, const dolfin::GenericVector&>())
+      .def("instance", (std::shared_ptr<dolfin::LinearAlgebraObject>(dolfin::LinearOperator::*)())
+           &dolfin::LinearOperator::shared_instance);
 
     // dolfin::GenericLinearAlgebraFactory
     py::class_<dolfin::GenericLinearAlgebraFactory, std::shared_ptr<dolfin::GenericLinearAlgebraFactory>>
@@ -663,26 +728,32 @@ namespace dolfin_wrappers
       (m, "DefaultFactory", "DOLFIN DefaultFactory object")
       .def(py::init<>())
       .def_static("factory", &dolfin::DefaultFactory::factory)
-      .def("create_matrix", &dolfin::DefaultFactory::create_matrix)
-      .def("create_vector", &dolfin::DefaultFactory::create_vector);
+      .def("create_matrix", [](const dolfin::DefaultFactory &self, const MPICommWrapper comm)
+        { return self.create_matrix(comm.get()); })
+      .def("create_vector", [](const dolfin::DefaultFactory &self, const MPICommWrapper comm)
+        { return self.create_vector(comm.get()); });
 
     // dolfin::EigenFactory
     py::class_<dolfin::EigenFactory, std::shared_ptr<dolfin::EigenFactory>,
       dolfin::GenericLinearAlgebraFactory>
       (m, "EigenFactory", "DOLFIN EigenFactory object")
       .def("instance", &dolfin::EigenFactory::instance)
-      .def("create_matrix", &dolfin::EigenFactory::create_matrix)
-      .def("create_vector", &dolfin::EigenFactory::create_vector);
+      .def("create_matrix", [](const dolfin::EigenFactory &self, const MPICommWrapper comm)
+        { return self.create_matrix(comm.get()); })
+      .def("create_vector", [](const dolfin::EigenFactory &self, const MPICommWrapper comm)
+        { return self.create_vector(comm.get()); });
 
     // dolfin::EigenVector
     py::class_<dolfin::EigenVector, std::shared_ptr<dolfin::EigenVector>,
                dolfin::GenericVector>
       (m, "EigenVector", "DOLFIN EigenVector object")
       .def(py::init<>())
-      .def(py::init<MPI_Comm>())
-      .def(py::init<MPI_Comm, std::size_t>())
-      //.def("array", (std::shared_ptr<Eigen::VectorXd> (dolfin::EigenVector::*)()) &dolfin::EigenVector::vec);
-      .def("array", [](dolfin::EigenVector& self) -> Eigen::Ref<Eigen::VectorXd> { return *self.vec(); } );
+      .def(py::init([](const MPICommWrapper comm)
+        { return std::unique_ptr<dolfin::EigenVector>(new dolfin::EigenVector(comm.get())); }))
+      .def(py::init([](const MPICommWrapper comm, std::size_t N)
+        { return std::unique_ptr<dolfin::EigenVector>(new dolfin::EigenVector(comm.get(), N)); }))
+      .def("array_view", [](dolfin::EigenVector& self) -> Eigen::Ref<Eigen::VectorXd> { return *self.vec(); },
+           "Return a writable numpy array view of the data in the EigenVector");
 
     // dolfin::EigenMatrix
     py::class_<dolfin::EigenMatrix, std::shared_ptr<dolfin::EigenMatrix>,
@@ -732,43 +803,67 @@ namespace dolfin_wrappers
       .def_static("clear", (void (*)(std::string)) &dolfin::PETScOptions::clear)
       .def_static("clear", (void (*)()) &dolfin::PETScOptions::clear);
 
+    // dolfin::PETScObject
     py::class_<dolfin::PETScObject, std::shared_ptr<dolfin::PETScObject>>(m, "PETScObject");
 
     // dolfin::PETScFactory
     py::class_<dolfin::PETScFactory, std::shared_ptr<dolfin::PETScFactory>,
-      dolfin::GenericLinearAlgebraFactory>
+               dolfin::GenericLinearAlgebraFactory>
       (m, "PETScFactory", "DOLFIN PETScFactory object")
       .def("instance", &dolfin::PETScFactory::instance)
-      .def("create_matrix", &dolfin::PETScFactory::create_matrix)
-      .def("create_vector", &dolfin::PETScFactory::create_vector);
+      .def("create_matrix", [](const dolfin::PETScFactory &self, const MPICommWrapper comm)
+        { return self.create_matrix(comm.get()); })
+      .def("create_vector", [](const dolfin::PETScFactory &self, const MPICommWrapper comm)
+        { return self.create_vector(comm.get()); });
 
     // dolfin::PETScVector
     py::class_<dolfin::PETScVector, std::shared_ptr<dolfin::PETScVector>,
                dolfin::GenericVector, dolfin::PETScObject>
       (m, "PETScVector", "DOLFIN PETScVector object")
       .def(py::init<>())
-      .def(py::init<MPI_Comm>())
-      .def(py::init<MPI_Comm, std::size_t>())
+      .def(py::init([](const MPICommWrapper comm)
+                    { return std::unique_ptr<dolfin::PETScVector>(new dolfin::PETScVector(comm.get())); }))
+      .def(py::init([](const MPICommWrapper comm, std::size_t N)
+                    { return std::unique_ptr<dolfin::PETScVector>(new dolfin::PETScVector(comm.get(), N)); }))
+      .def(py::init<Vec>())
       .def("get_options_prefix", &dolfin::PETScVector::get_options_prefix)
       .def("set_options_prefix", &dolfin::PETScVector::set_options_prefix)
-      .def("update_ghost_values", &dolfin::PETScVector::update_ghost_values);
+      .def("update_ghost_values", &dolfin::PETScVector::update_ghost_values)
+      .def("vec", &dolfin::PETScVector::vec, "Return underlying PETSc Vec object");
 
     // dolfin::PETScBaseMatrix
     py::class_<dolfin::PETScBaseMatrix, std::shared_ptr<dolfin::PETScBaseMatrix>,
-               dolfin::PETScObject, dolfin::Variable>(m, "PETScBaseMatrix");
+               dolfin::PETScObject, dolfin::Variable>(m, "PETScBaseMatrix")
+      .def("size", (std::size_t (dolfin::PETScBaseMatrix::*)(std::size_t) const) &dolfin::PETScBaseMatrix::size)
+      .def("mat", &dolfin::PETScBaseMatrix::mat, "Return underlying PETSc Mat object");
+
+    // dolfin::PETScLinearOperator
+    py::class_<dolfin::PETScLinearOperator, std::shared_ptr<dolfin::PETScLinearOperator>,
+               PyLinearOperator<dolfin::PETScLinearOperator>, dolfin::PETScBaseMatrix,
+               dolfin::GenericLinearOperator>
+      (m, "PETScLinearOperator", "PETScLinearOperator object")
+      .def(py::init([](const MPICommWrapper comm)
+        { return std::unique_ptr<dolfin::PETScLinearOperator>(new dolfin::PETScLinearOperator(comm.get())); }))
+      .def("size", &dolfin::PETScLinearOperator::size)
+      .def("mult", &dolfin::PETScLinearOperator::mult)
+      .def("mpi_comm", [](dolfin::PETScLinearOperator& self)
+        { return MPICommWrapper(self.mpi_comm()); });
 
     // dolfin::PETScMatrix
     py::class_<dolfin::PETScMatrix, std::shared_ptr<dolfin::PETScMatrix>,
                dolfin::GenericMatrix, dolfin::PETScBaseMatrix>
       (m, "PETScMatrix", "DOLFIN PETScMatrix object")
       .def(py::init<>())
-      .def(py::init<MPI_Comm>())
+      .def(py::init([](const MPICommWrapper comm)
+        { return std::unique_ptr<dolfin::PETScMatrix>(new dolfin::PETScMatrix(comm.get())); }))
+      .def(py::init<Mat>())
       .def("get_options_prefix", &dolfin::PETScMatrix::get_options_prefix)
       .def("set_options_prefix", &dolfin::PETScMatrix::set_options_prefix)
       .def("set_nullspace", &dolfin::PETScMatrix::set_nullspace)
       .def("set_near_nullspace", &dolfin::PETScMatrix::set_near_nullspace);
 
-    py::class_<dolfin::PETScPreconditioner, std::shared_ptr<dolfin::PETScPreconditioner>>
+    py::class_<dolfin::PETScPreconditioner, std::shared_ptr<dolfin::PETScPreconditioner>,
+               dolfin::Variable>
       (m, "PETScPreconditioner", "DOLFIN PETScPreconditioner object")
       .def(py::init<std::string>(), py::arg("type")="default")
       .def("preconditioners", &dolfin::PETScPreconditioner::preconditioners);
@@ -779,18 +874,23 @@ namespace dolfin_wrappers
 
     // dolfin::TpetraFactory
     py::class_<dolfin::TpetraFactory, std::shared_ptr<dolfin::TpetraFactory>,
-      dolfin::GenericLinearAlgebraFactory>
+               dolfin::GenericLinearAlgebraFactory>
       (m, "TpetraFactory", "DOLFIN TpetraFactory object")
       .def("instance", &dolfin::TpetraFactory::instance)
-      .def("create_matrix", &dolfin::TpetraFactory::create_matrix)
-      .def("create_vector", &dolfin::TpetraFactory::create_vector);
+      .def("create_matrix", [](const dolfin::TpetraFactory &self, const MPICommWrapper comm)
+        { return self.create_matrix(comm.get()); })
+      .def("create_vector", [](const dolfin::TpetraFactory &self, const MPICommWrapper comm)
+        { return self.create_vector(comm.get()); });
 
     // dolfin::TpetraVector
     py::class_<dolfin::TpetraVector, std::shared_ptr<dolfin::TpetraVector>,
                dolfin::GenericVector>
       (m, "TpetraVector", "DOLFIN TpetraVector object")
-      .def(py::init<MPI_Comm>(), py::arg("comm")=MPI_COMM_WORLD)
-      .def(py::init<MPI_Comm, std::size_t>());
+      .def(py::init([](const MPICommWrapper comm=MPICommWrapper(MPI_COMM_WORLD))
+        { return std::unique_ptr<dolfin::TpetraVector>(new dolfin::TpetraVector(comm.get())); }),
+        py::arg("comm")=MPICommWrapper(MPI_COMM_WORLD))
+      .def(py::init([](const MPICommWrapper comm, std::size_t N)
+        { return std::unique_ptr<dolfin::TpetraVector>(new dolfin::TpetraVector(comm.get(), N)); }));
 
     // dolfin::TpetraMatrix
     py::class_<dolfin::TpetraMatrix, std::shared_ptr<dolfin::TpetraMatrix>,
@@ -810,7 +910,7 @@ namespace dolfin_wrappers
 
     // dolfin::BelosKrylovSolver
     py::class_<dolfin::BelosKrylovSolver, std::shared_ptr<dolfin::BelosKrylovSolver>,
-              dolfin::GenericLinearSolver>
+               dolfin::GenericLinearSolver>
       (m, "BelosKrylovSolver", "Belos KrylovSolver")
       .def(py::init<std::string, std::shared_ptr<dolfin::TrilinosPreconditioner>>())
       .def("set_operator", &dolfin::BelosKrylovSolver::set_operator)
@@ -826,14 +926,16 @@ namespace dolfin_wrappers
 
     // dolfin::LUSolver
     py::class_<dolfin::LUSolver, std::shared_ptr<dolfin::LUSolver>,
-      dolfin::GenericLinearSolver>
-    (m, "LUSolver", "DOLFIN LUSolver object")
+               dolfin::GenericLinearSolver>
+      (m, "LUSolver", "DOLFIN LUSolver object")
       .def(py::init<>())
       .def(py::init<std::shared_ptr<const dolfin::GenericLinearOperator>, std::string>(),
            py::arg("A"), py::arg("method")="default")
-      .def(py::init<MPI_Comm, std::shared_ptr<const dolfin::GenericLinearOperator>,
-         std::string>(),
-           py::arg("comm"), py::arg("A"), py::arg("method") = "default")
+      .def(py::init([](const MPICommWrapper comm,
+                       std::shared_ptr<const dolfin::GenericLinearOperator> A,
+                       std::string method="default")
+          { return std::unique_ptr<dolfin::LUSolver>(new dolfin::LUSolver(comm.get(), A, method)); }),
+          py::arg("comm"), py::arg("A"), py::arg("method") = "default")
       .def("set_operator", &dolfin::LUSolver::set_operator)
       .def("solve", (std::size_t (dolfin::LUSolver::*)(dolfin::GenericVector&,
                                                        const dolfin::GenericVector&))
@@ -846,19 +948,30 @@ namespace dolfin_wrappers
     #ifdef HAS_PETSC
     // dolfin::PETScLUSolver
     py::class_<dolfin::PETScLUSolver, std::shared_ptr<dolfin::PETScLUSolver>,
-      dolfin::GenericLinearSolver>
+               dolfin::GenericLinearSolver>
       (m, "PETScLUSolver", "DOLFIN PETScLUSolver object")
-      .def(py::init<MPI_Comm, std::string>(), py::arg("comm"), py::arg("method")="default")
       .def(py::init<std::string>(), py::arg("method")="default")
-      .def(py::init<MPI_Comm, std::shared_ptr<const dolfin::PETScMatrix>, std::string>(),
-           py::arg("comm"), py::arg("A"), py::arg("method")="default")
+      .def(py::init([](const MPICommWrapper comm,
+                       std::string method="default")
+          { return std::unique_ptr<dolfin::PETScLUSolver>(new dolfin::PETScLUSolver(comm.get(), method)); }),
+          py::arg("comm"), py::arg("method") = "default")
+      .def(py::init([](const MPICommWrapper comm,
+                       std::shared_ptr<const dolfin::PETScMatrix> A,
+                       std::string method="default")
+          { return std::unique_ptr<dolfin::PETScLUSolver>(new dolfin::PETScLUSolver(comm.get(), A, method)); }),
+          py::arg("comm"), py::arg("A"), py::arg("method") = "default")
       .def(py::init<std::shared_ptr<const dolfin::PETScMatrix>, std::string>(),
            py::arg("A"), py::arg("method")="default")
       .def("get_options_prefix", &dolfin::PETScLUSolver::get_options_prefix)
       .def("set_options_prefix", &dolfin::PETScLUSolver::set_options_prefix)
       .def("solve", (std::size_t (dolfin::PETScLUSolver::*)(dolfin::GenericVector&, const dolfin::GenericVector&))
-           &dolfin::PETScLUSolver::solve);
-    #endif
+           &dolfin::PETScLUSolver::solve)
+      .def("solve", (std::size_t (dolfin::PETScLUSolver::*)(const dolfin::GenericLinearOperator&,
+                                                            dolfin::GenericVector&,
+                                                            const dolfin::GenericVector&))
+           &dolfin::PETScLUSolver::solve)
+      .def("ksp", &dolfin::PETScLUSolver::ksp);
+#endif
 
     // dolfin::KrylovSolver
     py::class_<dolfin::KrylovSolver, std::shared_ptr<dolfin::KrylovSolver>,
@@ -869,13 +982,20 @@ namespace dolfin_wrappers
       .def(py::init<std::shared_ptr<const dolfin::GenericLinearOperator>,
            std::string, std::string>(), py::arg("A"),
            py::arg("method")="default", py::arg("preconditioner")="default")
-      .def(py::init<MPI_Comm, std::shared_ptr<const dolfin::GenericLinearOperator>,
-           std::string, std::string>(), py::arg("comm"), py::arg("A"),
-           py::arg("method")="default", py::arg("preconditioner")="default")
+      .def(py::init([](const MPICommWrapper comm,
+                       std::shared_ptr<const dolfin::GenericLinearOperator> A,
+                       std::string method="default",
+                       std::string preconditioner="default")
+          { return std::unique_ptr<dolfin::KrylovSolver>(new dolfin::KrylovSolver(comm.get(), A,
+              method, preconditioner)); }),
+          py::arg("comm"), py::arg("A"), py::arg("method") = "default", py::arg("preconditioner")="default")
       .def("set_operator", &dolfin::KrylovSolver::set_operator)
       .def("set_operators", &dolfin::KrylovSolver::set_operators)
       .def("solve", (std::size_t (dolfin::KrylovSolver::*)(dolfin::GenericVector&,
                                                            const dolfin::GenericVector&))
+           &dolfin::KrylovSolver::solve)
+      .def("solve", (std::size_t (dolfin::KrylovSolver::*)(const dolfin::GenericLinearOperator&,
+                      dolfin::GenericVector&, const dolfin::GenericVector&))
            &dolfin::KrylovSolver::solve);
 
     #ifdef HAS_PETSC
@@ -901,6 +1021,9 @@ namespace dolfin_wrappers
            &dolfin::PETScKrylovSolver::set_operators)
       .def("solve", (std::size_t (dolfin::PETScKrylovSolver::*)(dolfin::GenericVector&, const dolfin::GenericVector&))
            &dolfin::PETScKrylovSolver::solve)
+      .def("solve", (std::size_t (dolfin::PETScKrylovSolver::*)(const dolfin::GenericLinearOperator&,
+                                                                dolfin::GenericVector&, const dolfin::GenericVector&))
+           &dolfin::PETScKrylovSolver::solve)
       .def("set_from_options", &dolfin::PETScKrylovSolver::set_from_options)
       .def("set_reuse_preconditioner", &dolfin::PETScKrylovSolver::set_reuse_preconditioner)
       .def("set_dm", &dolfin::PETScKrylovSolver::set_dm)
@@ -917,15 +1040,18 @@ namespace dolfin_wrappers
 
     #ifdef HAS_SLEPC
     // dolfin::SLEPcEigenSolver
-    py::class_<dolfin::SLEPcEigenSolver, std::shared_ptr<dolfin::SLEPcEigenSolver>, dolfin::Variable>(m, "SLEPcEigenSolver")
+    py::class_<dolfin::SLEPcEigenSolver, std::shared_ptr<dolfin::SLEPcEigenSolver>,
+               dolfin::Variable>(m, "SLEPcEigenSolver")
       .def(py::init<std::shared_ptr<const dolfin::PETScMatrix>>())
       .def(py::init<std::shared_ptr<const dolfin::PETScMatrix>, std::shared_ptr<const dolfin::PETScMatrix>>())
       // FIXME: The below must come after the other
       // constructors. Check the MPI_Comm caster raises appropriate
       // exceptions for pybind11 to move onto next interface.
-      .def(py::init<MPI_Comm>())
+      .def(py::init([](const MPICommWrapper comm)
+          { return std::unique_ptr<dolfin::SLEPcEigenSolver>(new dolfin::SLEPcEigenSolver(comm.get())); }))
       .def("set_options_prefix", &dolfin::SLEPcEigenSolver::set_options_prefix)
       .def("set_from_options", &dolfin::SLEPcEigenSolver::set_from_options)
+      .def("set_operators", &dolfin::SLEPcEigenSolver::set_operators)
       .def("get_options_prefix", &dolfin::SLEPcEigenSolver::get_options_prefix)
       .def("get_number_converged", &dolfin::SLEPcEigenSolver::get_number_converged)
       .def("set_deflation_space", &dolfin::SLEPcEigenSolver::set_deflation_space)
@@ -960,7 +1086,8 @@ namespace dolfin_wrappers
       .def("__getitem__", &dolfin::VectorSpaceBasis::operator[]);
 
     // test_nullspace.h
-    m.def("in_nullspace", &dolfin::in_nullspace, py::arg("A"), py::arg("x"), py::arg("type")="right");
+    m.def("in_nullspace", &dolfin::in_nullspace, py::arg("A"), py::arg("x"),
+          py::arg("type")="right");
 
     // la free functions
     m.def("has_linear_algebra_backend", &dolfin::has_linear_algebra_backend);
diff --git a/python/src/log.cpp b/python/src/log.cpp
index a792d52..15e5192 100644
--- a/python/src/log.cpp
+++ b/python/src/log.cpp
@@ -33,8 +33,19 @@ namespace dolfin_wrappers
 {
   void log(py::module& m)
   {
+
+    // dolfin::LogLevel enums
+    py::enum_<dolfin::LogLevel>(m, "LogLevel", py::arithmetic())
+      .value("DEBUG", dolfin::LogLevel::DBG)
+      .value("TRACE", dolfin::LogLevel::TRACE)
+      .value("PROGRESS", dolfin::LogLevel::PROGRESS)
+      .value("INFO", dolfin::LogLevel::INFO)
+      .value("WARNING", dolfin::LogLevel::WARNING)
+      .value("ERROR", dolfin::LogLevel::ERROR)
+      .value("CRITICAL", dolfin::LogLevel::CRITICAL);
+
     // dolfin::Table
-    py::class_<dolfin::Table, std::shared_ptr<dolfin::Table>>(m, "Table")
+    py::class_<dolfin::Table, std::shared_ptr<dolfin::Table>, dolfin::Variable>(m, "Table")
       .def(py::init<std::string>())
       .def("str", &dolfin::Table::str);
 
@@ -49,15 +60,7 @@ namespace dolfin_wrappers
           py::arg("scheme"), py::arg("verbose")=false);
     m.def("set_log_level", &dolfin::set_log_level);
     m.def("get_log_level", &dolfin::get_log_level);
+    m.def("log", [](dolfin::LogLevel level, std::string s){ dolfin::log(level, s); });
 
-    // dolfin::LogLevel enums
-    py::enum_<dolfin::LogLevel>(m, "LogLevel")
-      .value("DEBUG", dolfin::LogLevel::DBG)
-      .value("TRACE", dolfin::LogLevel::TRACE)
-      .value("PROGRESS", dolfin::LogLevel::PROGRESS)
-      .value("INFO", dolfin::LogLevel::INFO)
-      .value("WARNING", dolfin::LogLevel::WARNING)
-      .value("ERROR", dolfin::LogLevel::ERROR)
-      .value("CRITICAL", dolfin::LogLevel::CRITICAL);
   }
 }
diff --git a/python/src/mesh.cpp b/python/src/mesh.cpp
index 34988ed..2acf261 100644
--- a/python/src/mesh.cpp
+++ b/python/src/mesh.cpp
@@ -48,6 +48,8 @@
 #include <dolfin/mesh/DomainBoundary.h>
 #include <dolfin/mesh/PeriodicBoundaryComputation.h>
 #include <dolfin/mesh/MeshTransformation.h>
+#include <dolfin/mesh/MultiMesh.h>
+#include <dolfin/function/Expression.h>
 
 #include "casters.h"
 
@@ -90,32 +92,39 @@ namespace dolfin_wrappers
       .def("degree", &dolfin::MeshGeometry::degree, "Degree");
 
     // dolfin::MeshTopology class
-    py::class_<dolfin::MeshTopology, std::shared_ptr<dolfin::MeshTopology>>
+    py::class_<dolfin::MeshTopology, std::shared_ptr<dolfin::MeshTopology>, dolfin::Variable>
       (m, "MeshTopology", "DOLFIN MeshTopology object")
       .def("dim", &dolfin::MeshTopology::dim, "Topological dimension")
+      .def("init", (void (dolfin::MeshTopology::*)(std::size_t)) &dolfin::MeshTopology::init)
+      .def("init", (void (dolfin::MeshTopology::*)(std::size_t, std::size_t, std::size_t))
+           &dolfin::MeshTopology::init)
       .def("__call__", (const dolfin::MeshConnectivity& (dolfin::MeshTopology::*)(std::size_t, std::size_t) const)
            &dolfin::MeshTopology::operator())
       .def("size", &dolfin::MeshTopology::size)
       .def("hash", &dolfin::MeshTopology::hash)
+      .def("init_global_indices", &dolfin::MeshTopology::init_global_indices)
       .def("have_global_indices", &dolfin::MeshTopology::have_global_indices)
       .def("ghost_offset", &dolfin::MeshTopology::ghost_offset)
       .def("cell_owner", (const std::vector<unsigned int>& (dolfin::MeshTopology::*)() const) &dolfin::MeshTopology::cell_owner)
+      .def("set_global_index", &dolfin::MeshTopology::set_global_index)
       .def("global_indices", [](const dolfin::MeshTopology& self, int dim)
            { auto& indices = self.global_indices(dim); return py::array_t<std::int64_t>(indices.size(), indices.data()); })
       .def("have_shared_entities", &dolfin::MeshTopology::have_shared_entities)
       .def("shared_entities",
            (std::map<std::int32_t, std::set<unsigned int> >&(dolfin::MeshTopology::*)(unsigned int))
-           &dolfin::MeshTopology::shared_entities);
+           &dolfin::MeshTopology::shared_entities)
+      .def("str", &dolfin::MeshTopology::str);
 
     // dolfin::Mesh
-    py::class_<dolfin::Mesh, std::shared_ptr<dolfin::Mesh>>(m, "Mesh",
-                                                            py::dynamic_attr(),
-                                                            "DOLFIN Mesh object")
+    py::class_<dolfin::Mesh, std::shared_ptr<dolfin::Mesh>, dolfin::Variable>
+      (m, "Mesh", py::dynamic_attr(), "DOLFIN Mesh object")
       .def(py::init<>())
       .def(py::init<std::string>())
       .def(py::init<const dolfin::Mesh&>())
-      .def(py::init<MPI_Comm>())
-      .def(py::init<MPI_Comm, std::string>())  // Put MPI constructors last to avoid casting problems
+      .def(py::init([](const MPICommWrapper comm)
+                    { return std::unique_ptr<dolfin::Mesh>(new dolfin::Mesh(comm.get())); }))
+      .def(py::init([](const MPICommWrapper comm, const std::string filename)
+                    { return std::unique_ptr<dolfin::Mesh>(new dolfin::Mesh(comm.get(), filename)); }))
       .def("bounding_box_tree", &dolfin::Mesh::bounding_box_tree)
       .def("cells", [](const dolfin::Mesh& self)
            {
@@ -141,6 +150,7 @@ namespace dolfin_wrappers
            &dolfin::Mesh::data, "Data associated with a mesh")
       .def("geometry", (dolfin::MeshGeometry& (dolfin::Mesh::*)()) &dolfin::Mesh::geometry,
            py::return_value_policy::reference, "Mesh geometry")
+      .def("hash", &dolfin::Mesh::hash)
       .def("hmax", &dolfin::Mesh::hmax)
       .def("hmin", &dolfin::Mesh::hmin)
       .def("id", &dolfin::Mesh::id)
@@ -154,27 +164,30 @@ namespace dolfin_wrappers
              auto _o = o.attr("_cpp_object").cast<dolfin::Expression*>();
              self.init_cell_orientations(*_o);
            })
-      .def("mpi_comm", &dolfin::Mesh::mpi_comm)
-      .def("num_entities", &dolfin::Mesh::num_entities, "Number of mesh entities")
+      .def("mpi_comm", [](dolfin::Mesh& self)
+           { return MPICommWrapper(self.mpi_comm()); })
+      .def("num_entities", &dolfin::Mesh::num_entities,
+           "Number of mesh entities")
       .def("num_vertices", &dolfin::Mesh::num_vertices, "Number of vertices")
       .def("num_edges", &dolfin::Mesh::num_edges, "Number of edges")
       .def("num_faces", &dolfin::Mesh::num_faces, "Number of faces")
       .def("num_facets", &dolfin::Mesh::num_facets, "Number of facets")
       .def("num_cells", &dolfin::Mesh::num_cells, "Number of cells")
       .def("ordered", &dolfin::Mesh::ordered)
-      .def("size", &dolfin::Mesh::size)
       .def("rmax", &dolfin::Mesh::rmax)
       .def("rmin", &dolfin::Mesh::rmin)
       .def("rotate", (void (dolfin::Mesh::*)(double, std::size_t, const dolfin::Point&))
            &dolfin::Mesh::rotate)
       .def("rotate", (void (dolfin::Mesh::*)(double, std::size_t)) &dolfin::Mesh::rotate,
                       py::arg("angle"), py::arg("axis")=2)
-      .def("size_global", &dolfin::Mesh::size_global)
+      .def("num_entities_global", &dolfin::Mesh::num_entities_global)
       .def("smooth", &dolfin::Mesh::smooth, py::arg("num_iterations")=1)
       .def("smooth_boundary", &dolfin::Mesh::smooth_boundary)
-      .def("snap_boundary", &dolfin::Mesh::snap_boundary, py::arg("subdomain"), py::arg("harmonic_smoothing")=true)
-      .def("topology", (const dolfin::MeshTopology& (dolfin::Mesh::*)() const)
-           &dolfin::Mesh::topology, "Mesh topology")
+      .def("snap_boundary", &dolfin::Mesh::snap_boundary, py::arg("subdomain"),
+           py::arg("harmonic_smoothing")=true)
+      .def("topology", (dolfin::MeshTopology& (dolfin::Mesh::*)())
+           &dolfin::Mesh::topology, "Mesh topology",
+           py::return_value_policy::reference_internal)
       .def("translate", &dolfin::Mesh::translate)
       .def("type", (const dolfin::CellType& (dolfin::Mesh::*)() const) &dolfin::Mesh::type,
            py::return_value_policy::reference)
@@ -183,7 +196,8 @@ namespace dolfin_wrappers
            { return dolfin::CellType::type2string(self.type().cell_type()); });
 
     // dolfin::MeshData
-    py::class_<dolfin::MeshData, std::shared_ptr<dolfin::MeshData>>(m, "MeshData", "Mesh data object")
+    py::class_<dolfin::MeshData, std::shared_ptr<dolfin::MeshData>, dolfin::Variable>
+      (m, "MeshData", "Mesh data object")
       .def("array", [](dolfin::MeshData& self, std::string key, std::size_t i)
            {
              const std::vector<std::size_t>& a = self.array(key, i);
@@ -208,9 +222,9 @@ namespace dolfin_wrappers
     // dolfin::MeshConnectivity class
     py::class_<dolfin::MeshConnectivity, std::shared_ptr<dolfin::MeshConnectivity>>
       (m, "MeshConnectivity", "DOLFIN MeshConnectivity object")
-      .def("__call__", [](const dolfin::MeshConnectivity& self, std::size_t i){
-          return Eigen::Map<const Eigen::Matrix<unsigned int, Eigen::Dynamic, 1>>
-            (self(i), self.size(i));})
+      .def("__call__", [](const dolfin::MeshConnectivity& self, std::size_t i)
+           {
+             return Eigen::Map<const Eigen::Matrix<unsigned int, Eigen::Dynamic, 1>>(self(i), self.size(i));})
       .def("size", (std::size_t (dolfin::MeshConnectivity::*)() const)
            &dolfin::MeshConnectivity::size)
       .def("size", (std::size_t (dolfin::MeshConnectivity::*)(std::size_t) const)
@@ -230,10 +244,10 @@ namespace dolfin_wrappers
       .def("num_global_entities", &dolfin::MeshEntity::num_global_entities,
            "Global number of incident entities of given dimension")
       .def("entities", [](dolfin::MeshEntity& self, std::size_t dim)
-        {
-          return Eigen::Map<const Eigen::Matrix<unsigned int, Eigen::Dynamic, 1>>
-            (self.entities(dim), self.num_entities(dim));
-        })
+           {
+             return Eigen::Map<const Eigen::Matrix<unsigned int, Eigen::Dynamic, 1>>
+               (self.entities(dim), self.num_entities(dim));
+           })
       .def("midpoint", &dolfin::MeshEntity::midpoint, "Midpoint of Entity")
       .def("sharing_processes", &dolfin::MeshEntity::sharing_processes)
       .def("is_shared", &dolfin::MeshEntity::is_shared)
@@ -265,7 +279,8 @@ namespace dolfin_wrappers
     py::class_<dolfin::Facet, std::shared_ptr<dolfin::Facet>, dolfin::MeshEntity>
       (m, "Facet", "DOLFIN Facet object")
       .def(py::init<const dolfin::Mesh&, std::size_t>())
-      .def("exterior", &dolfin::Facet::exterior);
+      .def("exterior", &dolfin::Facet::exterior)
+      .def("normal", (dolfin::Point (dolfin::Facet::*)() const)  &dolfin::Facet::normal);
 
     // dolfin::Cell
     py::class_<dolfin::Cell, std::shared_ptr<dolfin::Cell>, dolfin::MeshEntity>
@@ -281,7 +296,6 @@ namespace dolfin_wrappers
       .def("normal", (dolfin::Point (dolfin::Cell::*)(std::size_t) const) &dolfin::Cell::normal)
       .def("circumradius", &dolfin::Cell::circumradius)
       .def("radius_ratio", &dolfin::Cell::radius_ratio)
-      .def("triangulate_intersection", &dolfin::Cell::triangulate_intersection)
       .def("volume", &dolfin::Cell::volume)
       .def("get_vertex_coordinates", [](const dolfin::Cell& self){
           std::vector<double> x;
@@ -316,7 +330,6 @@ namespace dolfin_wrappers
              return *self;
            });
 
-
     m.def("entities", [](dolfin::Mesh& mesh, std::size_t dim)
           { return dolfin::MeshEntityIterator(mesh, dim); });
     m.def("entities", [](dolfin::MeshEntity& meshentity, std::size_t dim)
@@ -377,6 +390,7 @@ namespace dolfin_wrappers
       .def("id", &dolfin::MeshFunction<SCALAR>::id) \
       .def("ufl_id", &dolfin::MeshFunction<SCALAR>::id) \
       .def("mesh", &dolfin::MeshFunction<SCALAR>::mesh) \
+      .def("set_values", &dolfin::MeshFunction<SCALAR>::set_values) \
       .def("set_all", &dolfin::MeshFunction<SCALAR>::set_all) \
       .def("where_equal", &dolfin::MeshFunction<SCALAR>::where_equal) \
       .def("array", [](dolfin::MeshFunction<SCALAR>& self) \
@@ -388,32 +402,6 @@ namespace dolfin_wrappers
     MESHFUNCTION_MACRO(std::size_t, Sizet);
 #undef MESHFUNCTION_MACRO
 
-#define MESH_ENTITY_FUNCTION_MACRO(TYPE, SCALAR, SCALAR_NAME) \
-    py::class_<dolfin::TYPE<SCALAR>, std::shared_ptr<dolfin::TYPE<SCALAR>>, \
-      dolfin::MeshFunction<SCALAR>>(m, #TYPE""#SCALAR_NAME)
-
-    MESH_ENTITY_FUNCTION_MACRO(VertexFunction, bool, Bool);
-    MESH_ENTITY_FUNCTION_MACRO(VertexFunction, int, Int);
-    MESH_ENTITY_FUNCTION_MACRO(VertexFunction, double, Double);
-    MESH_ENTITY_FUNCTION_MACRO(VertexFunction, std::size_t, Sizet);
-    MESH_ENTITY_FUNCTION_MACRO(EdgeFunction, bool, Bool);
-    MESH_ENTITY_FUNCTION_MACRO(EdgeFunction, int, Int);
-    MESH_ENTITY_FUNCTION_MACRO(EdgeFunction, double, Double);
-    MESH_ENTITY_FUNCTION_MACRO(EdgeFunction, std::size_t, Sizet);
-    MESH_ENTITY_FUNCTION_MACRO(FaceFunction, bool, Bool);
-    MESH_ENTITY_FUNCTION_MACRO(FaceFunction, int, Int);
-    MESH_ENTITY_FUNCTION_MACRO(FaceFunction, double, Double);
-    MESH_ENTITY_FUNCTION_MACRO(FaceFunction, std::size_t, Sizet);
-    MESH_ENTITY_FUNCTION_MACRO(FacetFunction, bool, Bool);
-    MESH_ENTITY_FUNCTION_MACRO(FacetFunction, int, Int);
-    MESH_ENTITY_FUNCTION_MACRO(FacetFunction, double, Double);
-    MESH_ENTITY_FUNCTION_MACRO(FacetFunction, std::size_t, Sizet);
-    MESH_ENTITY_FUNCTION_MACRO(CellFunction, bool, Bool);
-    MESH_ENTITY_FUNCTION_MACRO(CellFunction, int, Int);
-    MESH_ENTITY_FUNCTION_MACRO(CellFunction, double, Double);
-    MESH_ENTITY_FUNCTION_MACRO(CellFunction, std::size_t, Sizet);
-#undef MESH_ENTITY_FUNCTION_MACRO
-
     // dolfin::MeshValueCollection
 #define MESHVALUECOLLECTION_MACRO(SCALAR, SCALAR_NAME) \
     py::class_<dolfin::MeshValueCollection<SCALAR>, \
@@ -456,6 +444,10 @@ namespace dolfin_wrappers
            &dolfin::MeshEditor::add_vertex)
       .def("add_vertex", (void (dolfin::MeshEditor::*)(std::size_t, const std::vector<double>&))
            &dolfin::MeshEditor::add_vertex)
+      .def("add_vertex_global", (void (dolfin::MeshEditor::*)(std::size_t, std::size_t, const dolfin::Point&))
+           &dolfin::MeshEditor::add_vertex_global)
+      .def("add_vertex_global", (void (dolfin::MeshEditor::*)(std::size_t, std::size_t, const std::vector<double>&))
+           &dolfin::MeshEditor::add_vertex_global)
       .def("add_cell", (void (dolfin::MeshEditor::*)(std::size_t, const std::vector<std::size_t>&))
            &dolfin::MeshEditor::add_cell)
       .def("close", &dolfin::MeshEditor::close, py::arg("order") = true);
@@ -525,7 +517,7 @@ namespace dolfin_wrappers
 
     // dolfin::MeshColoring
     py::class_<dolfin::MeshColoring>(m, "MeshColoring")
-      .def_static("cell_colors", (dolfin::CellFunction<std::size_t> (*)(std::shared_ptr<const dolfin::Mesh>, std::vector<std::size_t>))
+      .def_static("cell_colors", (dolfin::MeshFunction<std::size_t> (*)(std::shared_ptr<const dolfin::Mesh>, std::vector<std::size_t>))
                   &dolfin::MeshColoring::cell_colors)
       .def_static("color_cells", &dolfin::MeshColoring::color_cells);
 
@@ -536,5 +528,21 @@ namespace dolfin_wrappers
       .def_static("rotate", (void (*)(dolfin::Mesh&, double, std::size_t)) &dolfin::MeshTransformation::rotate)
       .def_static("rotate", (void (*)(dolfin::Mesh&, double, std::size_t, const dolfin::Point&))
                   &dolfin::MeshTransformation::rotate);
+
+    py::class_<dolfin::MultiMesh, std::shared_ptr<dolfin::MultiMesh>,
+	       dolfin::Variable>(m, "MultiMesh")
+      .def(py::init<>())
+      .def("add", &dolfin::MultiMesh::add)
+      .def("build", &dolfin::MultiMesh::build, py::arg("quadrature_order") = 2)
+      .def("num_parts", &dolfin::MultiMesh::num_parts)
+      .def("compute_volume", &dolfin::MultiMesh::compute_volume)
+      .def("part", &dolfin::MultiMesh::part)
+      .def("cut_cells", &dolfin::MultiMesh::cut_cells)
+      .def("uncut_cells", &dolfin::MultiMesh::uncut_cells)
+      .def("covered_cells", &dolfin::MultiMesh::covered_cells)
+      .def("quadrature_rules_cut_cells",
+	   static_cast<const dolfin::MultiMesh::quadrature_rule(dolfin::MultiMesh::*)(std::size_t, unsigned int) const>(&dolfin::MultiMesh::quadrature_rules_cut_cells));
   }
+
+
 }
diff --git a/python/src/mpi_casters.h b/python/src/mpi_casters.h
index e9f8571..d3d00ec 100644
--- a/python/src/mpi_casters.h
+++ b/python/src/mpi_casters.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Chris Richardson and Garth N. Wells
+// Copyright (C) 2017 Chris Richardson, Garth N. Wells and Tormod Landet
 //
 // This file is part of DOLFIN.
 //
@@ -19,138 +19,62 @@
 #define _DOLFIN_PYBIND11_MPI
 
 #include <pybind11/pybind11.h>
+#include "MPICommWrapper.h"
 
+// Macro for casting between dolfin and mpi4py MPI communicators
 #ifdef HAS_MPI
-#include <mpi.h>
-// #ifdef HAS_MPI4PY
-// #include <mpi4py/mpi4py.h>
-// #endif
-#endif
-
-
-#ifdef HAS_MPI
-
-// Tools for managing MPI communicators
+#ifdef HAS_PYBIND11_MPI4PY
+#include <mpi4py/mpi4py.h>
+
+// Import mpi4py on demand
+#define VERIFY_MPI4PY(func)     \
+  if (!func)                    \
+  {                             \
+    if (import_mpi4py() != 0)   \
+    {                           \
+      std::cout << "ERROR: could not import mpi4py!" << std::endl; \
+      throw std::runtime_error("Error when importing mpi4py");     \
+    }                           \
+  }
 
 namespace pybind11
 {
   namespace detail
   {
-
-//     // Caster used to convert MPI_Comm to a mpi4py communicator
-//     template <> class type_caster<dolfin_wrappers::mpi_communicator>
-//     {
-//     public:
-//       PYBIND11_TYPE_CASTER(dolfin_wrappers::mpi_communicator, _("mpi_communicator"));
-
-//       // Helper from pybind to C++
-//       bool load(handle src, bool)
-//       {
-//         //std::cout << "***Here I am" << std::endl;
-//         return true;
-//       }
-
-//       // From C++ to Python
-//       static handle cast(const dolfin_wrappers::mpi_communicator &src, return_value_policy, handle)
-//       {
-//         //std::cout << "cpp to Py for comm struct" << std::endl;
-//         #ifdef HAS_MPI4PY
-//         return PyMPIComm_New(src.comm);
-//         #else
-//         std::cerr << "Cannot convert MPI communicator to a mpi4py communicator. DOLFIN must be enabled \
-// with mpi4py for this functionality" << std::endl;
-//         #endif
-//         return nullptr;
-//       }
-
-//       operator dolfin_wrappers::mpi_communicator()
-//       {
-//         //std::cout << "****mpi comm op" << std::endl;
-//         return value;
-//       }
-
-//     };
-
-
-    // Custom type caster for OpenMPI MPI_Comm, in which MPI_Comm is
-    // defined as a typedef of ompi_communicator_t*
-    #ifdef OPEN_MPI
-    template <> class type_caster<ompi_communicator_t>
-    {
-    public:
-      PYBIND11_TYPE_CASTER(MPI_Comm, _("ompi_communicator_t"));
-
-      // Pass communicator from Python to C++
-      bool load(handle src, bool)
+    template <> class type_caster<dolfin_wrappers::MPICommWrapper>
       {
-        PyObject* obj = src.ptr();
-        void* v = PyLong_AsVoidPtr(obj);
-        value = reinterpret_cast<MPI_Comm>(v);
-        if (PyErr_Occurred())
-          return false;
-
-        return true;
-      }
-
-      // Cast from C++ to Python (cast to pointer)
-      static handle cast(MPI_Comm src, pybind11::return_value_policy policy, handle parent)
-      {
-        // Return a pybind11::handle (rather than a pybind11::object)
-        return pybind11::cast(reinterpret_cast<std::uintptr_t>(src)).release();
-      }
-
-      operator MPI_Comm()
-      { return value; }
+      public:
+        // Define this->value of type MPICommWrapper
+        PYBIND11_TYPE_CASTER(dolfin_wrappers::MPICommWrapper, _("MPICommWrapper"));
+
+        // Python to C++
+        bool load(handle src, bool)
+        {
+          // Simplified version of isinstance(src, mpi4py.MPI.Comm) - avoids segfault
+          // when pybind11 tries to convert some other random type to MPICommWrapper
+          if (not hasattr(src, "Allgather"))
+            return false;
+          VERIFY_MPI4PY(PyMPIComm_Get);
+          value = dolfin_wrappers::MPICommWrapper(*PyMPIComm_Get(src.ptr()));
+          return true;
+        }
+
+        // C++ to Python
+        static handle cast(dolfin_wrappers::MPICommWrapper src,
+            pybind11::return_value_policy policy, handle parent)
+        {
+          VERIFY_MPI4PY(PyMPIComm_New);
+          return pybind11::handle(PyMPIComm_New(src.get()));
+        }
+
+        operator dolfin_wrappers::MPICommWrapper()
+        {
+          return this->value;
+        }
     };
-//     #else
-
-//     // Custom type caster for MPI_Comm, where MPI_Comm is defined
-//     // as a typedef of int, when mpi4py is available
-//     #ifdef HAS_MPI4PY
-//     template <> class type_caster<MPI_Comm>
-//     {
-//     public:
-//       PYBIND11_TYPE_CASTER(MPI_Comm, _("MPI_Comm"));
-
-//       // From Python (possibly a mpi4py comm) to C++
-//       bool load(handle src, bool)
-//       {
-
-//         PyObject* obj = src.ptr();
-
-//         if (PyObject_TypeCheck(obj, &PyMPIComm_Type))
-//         {
-//           MPI_Comm *comm_p = PyMPIComm_Get(obj);
-//           value = *comm_p;
-//           if (PyErr_Occurred())
-//             return false;
-//         }
-//         else if (PyObject_TypeCheck(obj, &PyLong_Type))
-//         {
-//           //std::cout << "In caster" << std::endl;
-//           value = PyLong_AsLong(obj);
-//           if (PyErr_Occurred())
-//             return false;
-//         }
-//         else
-//           std::cerr << "MPI communicator (MPI_Comm) type is unknown." << std::endl;
-
-//         return true;
-//       }
-
-//       // Cast from C/C++ communicator to Python. Cannot return mpi4py
-//       // caster because we cannot distinguish between MPI_Comm and int
-//       static handle cast(const MPI_Comm &src, return_value_policy, handle)
-//       { return PyLong_FromLong(src); }
-
-//       operator MPI_Comm()
-//       { return value; }
-//     };
-//     #endif
-    #endif
-
   }
 }
 
-#endif
+#endif // HAS_PYBIND11_MPI4PY
+#endif // HAS_MPI
 #endif
diff --git a/python/src/multistage.cpp b/python/src/multistage.cpp
index 3e1e616..baf7b3b 100644
--- a/python/src/multistage.cpp
+++ b/python/src/multistage.cpp
@@ -35,7 +35,7 @@ namespace dolfin_wrappers
   void multistage(py::module& m)
   {
     // dolfin::MultiStageScheme
-    py::class_<dolfin::MultiStageScheme, std::shared_ptr<dolfin::MultiStageScheme>>
+    py::class_<dolfin::MultiStageScheme, std::shared_ptr<dolfin::MultiStageScheme>, dolfin::Variable>
       (m, "MultiStageScheme")
       .def(py::init<std::vector<std::vector<std::shared_ptr<const dolfin::Form>>>,
            std::shared_ptr<const dolfin::Form>,
@@ -58,7 +58,7 @@ namespace dolfin_wrappers
       .def("step_interval", &dolfin::RKSolver::step_interval);
 
     // dolfin::PointIntegralSolver
-    py::class_<dolfin::PointIntegralSolver, std::shared_ptr<dolfin::PointIntegralSolver>>
+    py::class_<dolfin::PointIntegralSolver, std::shared_ptr<dolfin::PointIntegralSolver>, dolfin::Variable>
       (m, "PointIntegralSolver")
       .def(py::init<std::shared_ptr<dolfin::MultiStageScheme>>())
       .def("reset_newton_solver", &dolfin::PointIntegralSolver::reset_newton_solver)
diff --git a/python/src/nls.cpp b/python/src/nls.cpp
index ed7afe4..7b533d4 100644
--- a/python/src/nls.cpp
+++ b/python/src/nls.cpp
@@ -95,7 +95,8 @@ namespace dolfin_wrappers
     py::class_<dolfin::NewtonSolver, std::shared_ptr<dolfin::NewtonSolver>, PyNewtonSolver,
                dolfin::Variable>(m, "NewtonSolver")
       .def(py::init<>())
-      .def(py::init<MPI_Comm>())
+      .def(py::init([](const MPICommWrapper comm)
+          { return std::unique_ptr<dolfin::NewtonSolver>(new dolfin::NewtonSolver(comm.get())); }))
       .def("solve", &dolfin::NewtonSolver::solve)
       .def("converged", &PyPublicNewtonSolver::converged)
       .def("solver_setup", &PyPublicNewtonSolver::solver_setup)
@@ -106,15 +107,21 @@ namespace dolfin_wrappers
     py::class_<dolfin::PETScSNESSolver, std::shared_ptr<dolfin::PETScSNESSolver>,
                dolfin::PETScObject>(m, "PETScSNESSolver")
       .def(py::init<std::string>(), py::arg("nls_type")="default")
-      .def(py::init<MPI_Comm, std::string>(), py::arg("comm"), py::arg("nls_type")="default")
+      .def(py::init([](const MPICommWrapper comm, std::string nls_type="default")
+          { return std::unique_ptr<dolfin::PETScSNESSolver>(
+              new dolfin::PETScSNESSolver(comm.get(), nls_type)); }),
+          py::arg("comm"), py::arg("nls_type") = "default")
       .def_readwrite("parameters", &dolfin::PETScSNESSolver::parameters)
+      .def("snes", &dolfin::PETScSNESSolver::snes)
       .def("solve", (std::pair<std::size_t, bool> (dolfin::PETScSNESSolver::*)(dolfin::NonlinearProblem&,
                                                                                dolfin::GenericVector&))
            &dolfin::PETScSNESSolver::solve);
 
     // dolfin::TAOLinearBoundSolver
-    py::class_<dolfin::TAOLinearBoundSolver>(m, "TAOLinearBoundSolver")
-      .def(py::init<MPI_Comm>())
+    py::class_<dolfin::TAOLinearBoundSolver, std::shared_ptr<dolfin::TAOLinearBoundSolver>, dolfin::Variable>
+      (m, "TAOLinearBoundSolver")
+      .def(py::init([](const MPICommWrapper comm)
+          { return std::unique_ptr<dolfin::TAOLinearBoundSolver>(new dolfin::TAOLinearBoundSolver(comm.get())); }))
       .def(py::init<std::string, std::string, std::string>(), py::arg("method")="default",
            py::arg("ksp_type")="default", py::arg("pc_type")="default")
       .def("solve", (std::size_t (dolfin::TAOLinearBoundSolver::*)
@@ -126,9 +133,10 @@ namespace dolfin_wrappers
     // dolfin::PETScTAOSolver
     py::class_<dolfin::PETScTAOSolver, std::shared_ptr<dolfin::PETScTAOSolver>, dolfin::PETScObject>(m, "PETScTAOSolver")
       .def(py::init<>())
-      .def(py::init([](MPI_Comm comm, std::string tao_type,
-                       std::string ksp_type, std::string pc_type)
-                    { return dolfin::PETScTAOSolver(comm, tao_type, ksp_type, pc_type); }),
+      .def(py::init([](const MPICommWrapper comm, std::string tao_type="default",
+                       std::string ksp_type="default", std::string pc_type="default")
+          { return std::unique_ptr<dolfin::PETScTAOSolver>(
+              new dolfin::PETScTAOSolver(comm.get(), tao_type, ksp_type, pc_type)); }),
            py::arg("comm"), py::arg("tao_type")="default",
            py::arg("ksp_type")="default", py::arg("pc_type")="default")
       .def_readwrite("parameters", &dolfin::PETScTAOSolver::parameters)
diff --git a/python/src/parameter.cpp b/python/src/parameter.cpp
index 9cefa29..7e7cb9a 100644
--- a/python/src/parameter.cpp
+++ b/python/src/parameter.cpp
@@ -94,6 +94,13 @@ namespace dolfin_wrappers
            py::keep_alive<0, 1>())
       .def("items", [](const dolfin::Parameters& p) { return py::make_iterator(p.begin(), p.end()); },
            py::keep_alive<0, 1>())
+      .def("keys", [](const dolfin::Parameters& p)
+           {
+             std::vector<std::string> keys;
+             for (auto &q : p)
+               keys.push_back(q.first);
+             return keys;
+           })
       // These set_range function should be remove - they're just duplication
       .def("set_range", [](dolfin::Parameters& self, std::string name, double min, double max)
            { self[name].set_range(min, max);} )
@@ -188,6 +195,10 @@ namespace dolfin_wrappers
              auto param = self.find_parameter_set(key);
              *param = other;
            })
+      .def("__getitem__", [](dolfin::Parameters& self, std::string key)
+           {
+             return self[key];
+           })
       .def("parse", [](dolfin::Parameters& self, py::list argv)
            {
              if(argv.size() == 0)
@@ -207,7 +218,15 @@ namespace dolfin_wrappers
 
     // dolfin::Parameter
     py::class_<dolfin::Parameter, std::shared_ptr<dolfin::Parameter>>(m, "Parameter")
-      .def("value", &dolfin::Parameter::value)
+      .def("value", [](const dolfin::Parameter& self)
+           {
+             py::object value;
+             if (self.is_set())
+               value = py::cast(self.value());
+             else
+               value = py::none();
+             return value;
+           })
       .def("set_range", (void (dolfin::Parameter::*)(double, double)) &dolfin::Parameter::set_range)
       .def("set_range", (void (dolfin::Parameter::*)(int, int)) &dolfin::Parameter::set_range)
       .def("set_range", (void (dolfin::Parameter::*)(std::set<std::string>)) &dolfin::Parameter::set_range)
diff --git a/python/src/petsc_casters.h b/python/src/petsc_casters.h
index 3b1eabe..838d032 100644
--- a/python/src/petsc_casters.h
+++ b/python/src/petsc_casters.h
@@ -22,95 +22,88 @@
 #include <pybind11/stl.h>
 
 #ifdef HAS_PETSC
-#include <petscksp.h>
 #include <petscdm.h>
+#include <petscksp.h>
+#include <petscmat.h>
+#include <petscsnes.h>
+#include <petscvec.h>
 
-#ifdef HAS_PETSC4PY
+// pybind11 casters for PETSc/petsc4py objects
+#ifdef HAS_PYBIND11_PETSC4PY
 #include <petsc4py/petsc4py.h>
-#endif
 
+// Import petsc4py on demand
+#define VERIFY_PETSC4PY(func)   \
+  if (!func)                    \
+  {                             \
+    if (import_petsc4py() != 0) \
+    {                           \
+      std::cout << "ERROR: could not import petsc4py!" << std::endl; \
+      throw std::runtime_error("Error when importing petsc4py");     \
+    }                           \
+  }
+
+// Macro for casting between dolfin and petsc4py objects
+#define PETSC_CASTER_MACRO(TYPE, NAME)          \
+  template <> class type_caster<_p_##TYPE>      \
+    {                                           \
+    public:                                     \
+      PYBIND11_TYPE_CASTER(TYPE, _(#NAME));     \
+      bool load(handle src, bool)               \
+      {                                         \
+        VERIFY_PETSC4PY(PyPetsc##TYPE##_Get);   \
+        if (PyObject_TypeCheck(src.ptr(), &PyPetsc##TYPE##_Type) == 0)  \
+          return false;                                                 \
+        value = PyPetsc##TYPE##_Get(src.ptr());                         \
+        return true;                                                    \
+      }                                                                 \
+                                                                        \
+      static handle cast(TYPE src, pybind11::return_value_policy policy, handle parent) \
+      {                                                                 \
+        VERIFY_PETSC4PY(PyPetsc##TYPE##_New);                           \
+        return pybind11::handle(PyPetsc##TYPE##_New(src));              \
+      }                                                                 \
+                                                                        \
+      operator TYPE()                                                   \
+      { return value; }                                                 \
+    }
+#else
+#define PETSC_CASTER_MACRO(TYPE, NAME)          \
+  template <> class type_caster<_p_##TYPE>      \
+    {                                           \
+    public:                                     \
+      PYBIND11_TYPE_CASTER(TYPE, _(#NAME));     \
+      bool load(handle src, bool)               \
+      {                                         \
+        throw std::runtime_error("DOLFIN has not been configured with petsc4py. Accessing underlying PETSc object requires petsc4py"); \
+        return false;                                                   \
+      }                                                                 \
+                                                                        \
+      static handle cast(TYPE src, pybind11::return_value_policy policy, handle parent) \
+      {                                                                 \
+        throw std::runtime_error("DOLFIN has not been configured with petsc4py. Accessing underlying PETSc object requires petsc4py"); \
+        return handle();                                                \
+      }                                                                 \
+                                                                        \
+      operator TYPE()                                                   \
+      { return value; }                                                 \
+    }
+#endif
 
-// pybind11 casters for PETSc/petsc4py objects
 
 namespace pybind11
 {
   namespace detail
   {
-    template <> class type_caster<_p_KSP>
-    {
-    public:
-      PYBIND11_TYPE_CASTER(KSP, _("ksp"));
-
-      // Pass communicator from Python to C++
-      bool load(handle src, bool)
-      {
-        // FIXME: check reference counting
-        //std::cout << "Py to c++" << std::endl;
-        #ifdef HAS_PETSC4PY
-        value = PyPetscKSP_Get(src.ptr());
-        return true;
-        #else
-        throw std::runtime_error("DOLFIN has not been configured with petsc4py. Accessing underlying PETSc object requires petsc4py");
-        return false;
-        #endif
-      }
-
-      // Cast from C++ to Python (cast to pointer)
-      static handle cast(KSP src, pybind11::return_value_policy policy, handle parent)
-      {
-        // FIXME: check reference counting
-        #ifdef HAS_PETSC4PY
-        //std::cout << "C++ to Python" << std::endl;
-        return pybind11::handle(PyPetscKSP_New(src));
-        #else
-        throw std::runtime_error("DOLFIN has not been configured with petsc4py. Accessing underlying PETSc object requires petsc4py");
-        return handle();
-        #endif
-      }
-
-      operator KSP()
-      { return value; }
-    };
-
-    template <> class type_caster<_p_DM>
-    {
-    public:
-      PYBIND11_TYPE_CASTER(DM, _("DM"));
-
-      // Pass communicator from Python to C++
-      bool load(handle src, bool)
-      {
-        // FIXME: check reference counting
-        #ifdef HAS_PETSC4PY
-        //std::cout << "Py to C++ (DM)" << std::endl;
-        value = PyPetscDM_Get(src.ptr());
-        //std::cout << "Returning" << std::endl;
-        return true;
-        #else
-        throw std::runtime_error("DOLFIN has not been configured with petsc4py. Accessing underlying PETSc object requires petsc4py");
-        return false;
-        #endif
-
-      }
-
-      // Cast from C++ to Python (cast to pointer)
-      static handle cast(DM src, pybind11::return_value_policy policy, handle parent)
-      {
-        // FIXME: check reference counting
-        #ifdef HAS_PETSC4PY
-        //std::cout << "C++ to Python (DM)" << std::endl;
-        return pybind11::handle(PyPetscDM_New(src));
-        #else
-        throw std::runtime_error("DOLFIN has not been configured with petsc4py. Accessing underlying PETSc object requires petsc4py");
-        return pybind11::handle();
-        #endif
-      }
-
-      operator DM()
-      { return value; }
-    };
+    PETSC_CASTER_MACRO(DM, dm);
+    PETSC_CASTER_MACRO(KSP, ksp);
+    PETSC_CASTER_MACRO(Mat, mat);
+    PETSC_CASTER_MACRO(SNES, snes);
+    PETSC_CASTER_MACRO(Vec, vec);
   }
 }
 
+#undef PETSC_CASTER_MACRO
+
 #endif
 #endif
diff --git a/scripts/dolfin-order/mesh0.xml.gz b/scripts/dolfin-order/mesh0.xml.gz
deleted file mode 100644
index 3b62961..0000000
Binary files a/scripts/dolfin-order/mesh0.xml.gz and /dev/null differ
diff --git a/scripts/dolfin-order/mesh1.xml.gz b/scripts/dolfin-order/mesh1.xml.gz
deleted file mode 100644
index 79ef4a5..0000000
Binary files a/scripts/dolfin-order/mesh1.xml.gz and /dev/null differ
diff --git a/scripts/dolfin-plot/mesh.xml.gz b/scripts/dolfin-plot/mesh.xml.gz
deleted file mode 100644
index df60442..0000000
Binary files a/scripts/dolfin-plot/mesh.xml.gz and /dev/null differ
diff --git a/shippable.yml b/shippable.yml
deleted file mode 100644
index 0df9b73..0000000
--- a/shippable.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-language: none
-build:
-  pre_ci_boot:
-    image_name: quay.io/fenicsproject/dev-env
-    image_tag: latest
-    pull: true
-  ci:
-    - apt-get -qq -y --no-install-recommends install cmake
-    - pip3 install --upgrade pip
-    - pip3 install git+https://bitbucket.org/fenics-project/fiat.git@master
-    - pip3 install git+https://bitbucket.org/fenics-project/ufl.git@master
-    - pip3 install git+https://bitbucket.org/fenics-project/dijitso.git@master
-    - pip3 install git+https://bitbucket.org/fenics-project/instant.git@master
-    - pip3 install git+https://bitbucket.org/fenics-project/ffc.git@master
-    - mkdir -p build
-    - cd build
-    - cmake .. -DCMAKE_BUILD_TYPE=Debug -DDOLFIN_ENABLE_TESTING=ON
-    - make
-    - make install
-    - source /usr/local/share/dolfin/dolfin.conf
-    - make run_unittests
-    - make run run_regressiontests
diff --git a/site-packages/dolfin/common/plotting.py b/site-packages/dolfin/common/plotting.py
index d9b01b8..6ee37cc 100644
--- a/site-packages/dolfin/common/plotting.py
+++ b/site-packages/dolfin/common/plotting.py
@@ -24,7 +24,6 @@
 
 from __future__ import print_function
 import os
-from distutils.version import StrictVersion
 
 import dolfin
 import dolfin.cpp as cpp
@@ -125,7 +124,7 @@ def mplot_function(ax, f, **kwargs):
 
     if fvec.size() == mesh.num_cells():
         # DG0 cellwise function
-        C = fvec.array()  # NB! Assuming here dof ordering matching cell numbering
+        C = fvec.get_local()  # NB! Assuming here dof ordering matching cell numbering
         if gdim == 2 and tdim == 2:
             return ax.tripcolor(mesh2triang(mesh), C, **kwargs)
         elif gdim == 3 and tdim == 2:  # surface in 3d
@@ -223,14 +222,6 @@ def mplot_function(ax, f, **kwargs):
         if mode == "glyphs":
             args = X + U + [C]
             if gdim == 3:
-                # 3d quiver plot works only since matplotlib 1.4
-                import matplotlib
-                if StrictVersion(matplotlib.__version__) < '1.4':
-                    cpp.warning('Matplotlib version %s does not support 3d '
-                                'quiver plot. Continuing without plotting...'
-                                % matplotlib.__version__)
-                    return
-
                 length = kwargs.pop("length", 0.1)
                 return ax.quiver(*args, length=length, **kwargs)
             else:
diff --git a/site-packages/dolfin/compilemodules/compilemodule.py b/site-packages/dolfin/compilemodules/compilemodule.py
index cad627a..e4906e8 100644
--- a/site-packages/dolfin/compilemodules/compilemodule.py
+++ b/site-packages/dolfin/compilemodules/compilemodule.py
@@ -47,7 +47,7 @@ __all__ = ["compile_extension_module",
 # Bump the interface version if anything changes that invalidates
 # cached modules (not required for change in generated code, swig
 # version or dolfin version)
-_interface_version = 6
+_interface_version = 8
 
 # Add max_signature_length to parameter system (don't need this in C++)
 cpp.parameters.add("max_signature_length", 0)
diff --git a/site-packages/dolfin/fem/assembling.py b/site-packages/dolfin/fem/assembling.py
index d7a37f8..ca9009e 100644
--- a/site-packages/dolfin/fem/assembling.py
+++ b/site-packages/dolfin/fem/assembling.py
@@ -241,12 +241,13 @@ def assemble_multimesh(form,
     # Extract multimesh function spaces for arguments
     V_multi = [v._V_multi for v in arguments]
 
-    # Exstract number of parts, the multimesh and create the multimesh form
+    # Extract number of parts, the multimesh and create the multimesh form
+    num_parts = None
     if rank > 0:
         num_parts = V_multi[0].num_parts()
         multimesh_form = cpp.MultiMeshForm(*V_multi)
         multimesh = V_multi[0].multimesh()
-    else:
+    elif len(coefficients) > 0:
         for coeff in coefficients:
             # Only create these variables once
             if isinstance(coeff, MultiMeshFunction):
@@ -254,7 +255,12 @@ def assemble_multimesh(form,
                 num_parts = coeff.function_space().num_parts()
                 multimesh_form = cpp.MultiMeshForm(multimesh)
                 break
-    # Developer note: This won't work for assemble_multimesh(Constant(1)*dX)
+
+    if not num_parts:
+        # Handle the case Constant(1)*dx(domain=multimesh)
+        multimesh = form.ufl_domains()[0].ufl_cargo()
+        num_parts = multimesh.num_parts()
+        multimesh_form = cpp.MultiMeshForm(multimesh)
 
     # Build multimesh DOLFIN form
     for part in range(num_parts):
@@ -283,6 +289,10 @@ def assemble_multimesh(form,
         dolfin_form.set_mesh(multimesh.part(part))
         multimesh_form.add(dolfin_form)
 
+    for i, coeff in enumerate(coefficients):
+        if isinstance(coeff, MultiMeshFunction):
+            multimesh_form.set_multimesh_coefficient(i, coeff)
+
     # Build multimesh form
     multimesh_form.build()
 
diff --git a/site-packages/dolfin/fem/form.py b/site-packages/dolfin/fem/form.py
index b375091..00a6181 100644
--- a/site-packages/dolfin/fem/form.py
+++ b/site-packages/dolfin/fem/form.py
@@ -78,6 +78,8 @@ class Form(cpp.Form):
         self.subdomains, = list(sd.values())  # Assuming single domain
         domain, = list(sd.keys())  # Assuming single domain
         mesh = domain.ufl_cargo()
+        if isinstance(mesh, cpp.MultiMesh):
+            mesh = mesh.part(0)
 
         # Having a mesh in the form is now a strict requirement
         if mesh is None:
diff --git a/site-packages/dolfin/fem/interpolation.py b/site-packages/dolfin/fem/interpolation.py
index a03a8ee..ce5976c 100644
--- a/site-packages/dolfin/fem/interpolation.py
+++ b/site-packages/dolfin/fem/interpolation.py
@@ -4,7 +4,7 @@
 :py:class:`Expression <dolfin.functions.expression.Expression>` onto a
 finite element space."""
 
-# Copyright (C) 2009-2011 Anders Logg
+# Copyright (C) 2009-2017 Anders Logg
 #
 # This file is part of DOLFIN.
 #
@@ -21,29 +21,35 @@ finite element space."""
 # You should have received a copy of the GNU Lesser General Public License
 # along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 #
+# Modified by Jørgen S. Dokken, 2017
 # First added:  2009-08-29
-# Last changed: 2011-11-15
+# Last changed: 2017-03-17
 
 # Local imports
 import dolfin.cpp as cpp
 
-from dolfin.functions.functionspace import FunctionSpace
+from dolfin.functions.functionspace import FunctionSpace, MultiMeshFunctionSpace
 from dolfin.functions.function import Function
+from dolfin.functions.multimeshfunction import MultiMeshFunction
 
 __all__ = ["interpolate"]
 
 
 def interpolate(v, V):
     """Return interpolation of a given function into a given finite
-    element space.
+    element space. Also supports MultiMesh.
 
     *Arguments*
         v
             a :py:class:`Function <dolfin.functions.function.Function>` or
             an :py:class:`Expression <dolfin.functions.expression.Expression>`
+            or an :py:class`MultiMeshFunction <dolfin.functions.multimeshfunction.MultiMeshFunction>`
         V
             a :py:class:`FunctionSpace (standard, mixed, etc.)
-            <dolfin.functions.functionspace.FunctionSpace>`
+            <dolfin.functions.functionspace.FunctionSpace>` or
+            a :py:class:`MultiMeshFunctionSpace
+            <dolfin.cpp.function.MultiMeshFunctionSpace>`.
+
 
     *Example of usage*
 
@@ -56,10 +62,14 @@ def interpolate(v, V):
     """
 
     # Check arguments
-    if not isinstance(V, FunctionSpace):
+    if not isinstance(V, (FunctionSpace, cpp.MultiMeshFunctionSpace)):
         cpp.dolfin_error("interpolation.py",
                          "compute interpolation",
                          "Illegal function space for interpolation, not a FunctionSpace (%s)" % str(v))
+    if isinstance(V, cpp.MultiMeshFunctionSpace):
+        Pv = MultiMeshFunction(V)
+        Pv.interpolate(v)
+        return Pv
 
     # Compute interpolation
     Pv = Function(V)
diff --git a/site-packages/dolfin/fem/norms.py b/site-packages/dolfin/fem/norms.py
index 7a9bbc7..d5f02b5 100644
--- a/site-packages/dolfin/fem/norms.py
+++ b/site-packages/dolfin/fem/norms.py
@@ -4,7 +4,7 @@
 <dolfin.functions.function.Function>`, including the standard
 :math:`L^2`-norm and other norms."""
 
-# Copyright (C) 2008-2014 Anders Logg
+# Copyright (C) 2008-2017 Anders Logg
 #
 # This file is part of DOLFIN.
 #
@@ -20,20 +20,25 @@
 #
 # You should have received a copy of the GNU Lesser General Public License
 # along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+#
+# Modified by: Jørgen S. Dokken, 2017
+# First added: 2007
+# Last changed: 2017-03-17
 
 from six import string_types
 import ufl
-from ufl import inner, grad, div, curl, dx, FiniteElement, VectorElement, Coefficient
+from ufl import inner, grad, div, curl, dx, FiniteElement, VectorElement, Coefficient, TensorElement
 from math import sqrt
 
 import dolfin.cpp as cpp
 
 from dolfin.cpp import GenericVector, GenericFunction, Function, Mesh, error, Vector
-from dolfin.fem.assembling import assemble
+from dolfin.fem.assembling import assemble, assemble_multimesh
 from dolfin.fem.interpolation import interpolate
 from dolfin.functions.function import Function
+from dolfin.functions.multimeshfunction import MultiMeshFunction
 from dolfin.functions.functionspace import FunctionSpace, \
-    VectorFunctionSpace, TensorFunctionSpace
+    VectorFunctionSpace, TensorFunctionSpace, MultiMeshFunctionSpace
 
 __all__ = ["norm", "errornorm"]
 
@@ -45,11 +50,13 @@ def norm(v, norm_type="L2", mesh=None):
     *Arguments*
         v
             a :py:class:`Vector <dolfin.cpp.Vector>` or
-            a :py:class:`Function <dolfin.functions.function.Function>`.
+            a :py:class:`Function <dolfin.functions.function.Function>` or
+            a :py:class:`MultiMeshFunction <dolfin.functions.multimeshfunction.MultiMeshFunction>`
         norm_type
             see below for alternatives.
         mesh
-            optional :py:class:`Mesh <dolfin.cpp.Mesh>` on
+            optional :py:class:`Mesh <dolfin.cpp.Mesh>` or
+            a :py:class:`MultiMesh <dolfin.cpp.MultiMesh>` on
             which to compute the norm.
 
     If the norm type is not specified, the standard :math:`L^2` -norm
@@ -94,48 +101,53 @@ def norm(v, norm_type="L2", mesh=None):
 
     """
 
-    if not isinstance(v, (GenericVector, GenericFunction)):
+    if not isinstance(v, (GenericVector, GenericFunction, MultiMeshFunction)):
         cpp.dolfin_error("norms.py",
                          "compute norm",
-                         "expected a GenericVector or GenericFunction")
-
+                         "expected a GenericVector ,GenericFunction or a MultiMeshFunction")
     # Check arguments
     if not isinstance(norm_type, string_types):
         cpp.dolfin_error("norms.py",
                          "compute norm",
                          "Norm type must be a string, not " +
                          str(type(norm_type)))
-    if mesh is not None and not isinstance(mesh, cpp.Mesh):
+    if mesh is not None and not isinstance(mesh, (cpp.Mesh, cpp.MultiMesh)):
         cpp.dolfin_error("norms.py",
                          "compute norm",
-                         "Expecting a Mesh, not " + str(type(mesh)))
+                         "Expecting a Mesh or a MultiMesh, not " + str(type(mesh)))
 
     # Get mesh from function
     if isinstance(v, Function) and mesh is None:
         mesh = v.function_space().mesh()
+    elif isinstance(v, MultiMeshFunction) and mesh is None:
+        mesh = v.function_space().multimesh()
 
     # Define integration measure and domain
-    dx = ufl.dx(mesh)
-
+    multimesh = False
+    if isinstance(v, MultiMeshFunction):
+        multimesh = True
+        dc = ufl.dx(mesh) + ufl.dC(mesh)
+    else:
+        dc = ufl.dx(mesh)
     # Select norm type
     if isinstance(v, GenericVector):
         return v.norm(norm_type.lower())
-
-    elif (isinstance(v, Coefficient) and isinstance(v, GenericFunction)):
+    elif (isinstance(v, Coefficient) and isinstance(v, (GenericFunction,
+                                                        MultiMeshFunction))):
         if norm_type.lower() == "l2":
-            M = v**2*dx
+            M = v**2*dc
         elif norm_type.lower() == "h1":
-            M = (v**2 + grad(v)**2)*dx
+            M = (v**2 + grad(v)**2)*dc
         elif norm_type.lower() == "h10":
-            M = grad(v)**2*dx
+            M = grad(v)**2*dc
         elif norm_type.lower() == "hdiv":
-            M = (v**2 + div(v)**2)*dx
+            M = (v**2 + div(v)**2)*dc
         elif norm_type.lower() == "hdiv0":
-            M = div(v)**2*dx
+            M = div(v)**2*dc
         elif norm_type.lower() == "hcurl":
-            M = (v**2 + curl(v)**2)*dx
+            M = (v**2 + curl(v)**2)*dc
         elif norm_type.lower() == "hcurl0":
-            M = curl(v)**2*dx
+            M = curl(v)**2*dc
         else:
             cpp.dolfin_error("norms.py",
                              "compute norm",
@@ -144,10 +156,13 @@ def norm(v, norm_type="L2", mesh=None):
     else:
         cpp.dolfin_error("norms.py",
                          "compute norm",
-                         "Unknown object type. Must be a vector or a function")
+                         "Unknown object type. Must be a vector, function or a multimeshfunction")
 
     # Assemble value
-    r = assemble(M, form_compiler_parameters={"representation": "quadrature"})
+    if multimesh:
+        r = assemble_multimesh(M, form_compiler_parameters={"representation": "quadrature"})
+    else:
+        r = assemble(M)
 
     # Check value
     if r < 0.0:
@@ -211,20 +226,26 @@ def errornorm(u, uh, norm_type="l2", degree_rise=3, mesh=None):
     """
 
     # Check argument
-    if not isinstance(u, cpp.GenericFunction):
+    if not isinstance(u, (cpp.GenericFunction, cpp.MultiMeshFunction)):
         cpp.dolfin_error("norms.py",
                          "compute error norm",
-                         "Expecting a Function or Expression for u")
-    if not isinstance(uh, cpp.Function):
+                         "Expecting a Function, MultiMeshFunction or Expression for u")
+    if not (isinstance(uh, cpp.Function) or (uh, cpp.MultiMeshFunction)):
         cpp.dolfin_error("norms.py",
                          "compute error norm",
                          "Expecting a Function for uh")
+    # Test if errornorm is for multimesh
+    multimesh=False
 
     # Get mesh
     if isinstance(u, Function) and mesh is None:
         mesh = u.function_space().mesh()
     if isinstance(uh, Function) and mesh is None:
         mesh = uh.function_space().mesh()
+    if isinstance(uh, MultiMeshFunction) and mesh is None:
+        mesh = uh.function_space().multimesh()
+        multimesh=True
+
     if mesh is None:
         cpp.dolfin_error("norms.py",
                          "compute error norm",
@@ -253,21 +274,37 @@ def errornorm(u, uh, norm_type="l2", degree_rise=3, mesh=None):
         cpp.warning("Degree of exact solution may be inadequate for accurate result in errornorm.")
 
     # Create function space
-    if rank == 0:
-        V = FunctionSpace(mesh, "Discontinuous Lagrange", degree)
-    elif rank == 1:
-        V = VectorFunctionSpace(mesh, "Discontinuous Lagrange", degree,
-                                dim=shape[0])
-    elif rank > 1:
-        V = TensorFunctionSpace(mesh, "Discontinuous Lagrange", degree,
-                                shape=shape)
+    if multimesh:
+        if rank == 0:
+            element = FiniteElement("Discontinuous Lagrange", mesh.ufl_cell(),
+                                    degree)
+        elif rank == 1:
+            element = VectorElement("Discontinuous Lagrange", mesh.ufl_cell(),
+                                    degree)
+        elif rank == 2:
+            element = TensorElement("Discontinuous Lagrange", mesh.ufl_cell(),
+                                    degree)
+        V = MultiMeshFunctionSpace(mesh, element)
+    else:
+        if rank == 0:
+            V = FunctionSpace(mesh, "Discontinuous Lagrange", degree)
+        elif rank == 1:
+            V = VectorFunctionSpace(mesh, "Discontinuous Lagrange", degree,
+                                    dim=shape[0])
+        elif rank > 1:
+            V = TensorFunctionSpace(mesh, "Discontinuous Lagrange", degree,
+                                    shape=shape)
 
     # Interpolate functions into finite element space
     pi_u = interpolate(u, V)
     pi_uh = interpolate(uh, V)
 
     # Compute the difference
-    e = Function(V)
+    if multimesh:
+        e = MultiMeshFunction(V)
+    else:
+        e = Function(V)
+
     e.assign(pi_u)
     e.vector().axpy(-1.0, pi_uh.vector())
 
diff --git a/site-packages/dolfin/functions/multimeshfunction.py b/site-packages/dolfin/functions/multimeshfunction.py
index 6ff8917..d706807 100644
--- a/site-packages/dolfin/functions/multimeshfunction.py
+++ b/site-packages/dolfin/functions/multimeshfunction.py
@@ -24,8 +24,10 @@ __all__ = ["MultiMeshFunction"]
 # Import UFL and SWIG-generated extension module (DOLFIN C++)
 import ufl
 import dolfin.cpp as cpp
+import numpy
 
 from dolfin.functions.functionspace import MultiMeshFunctionSpace
+from dolfin.functions.function import Function
 
 class MultiMeshFunction(ufl.Coefficient, cpp.MultiMeshFunction):
     """This class represents a multimeshfunction
@@ -123,4 +125,67 @@ class MultiMeshFunction(ufl.Coefficient, cpp.MultiMeshFunction):
         return self._V
 
     def assign(self, rhs):
-        self.vector()[:]= rhs.vector()[:]
+        """
+        Parameters: 
+            rhs: A dolfin.MultiMeshFunction
+        """
+        # Assign a MultiMeshFunction into a MultiMeshFunction
+        if isinstance(rhs, MultiMeshFunction):
+            self.vector()[:]= rhs.vector()[:]
+        else:
+            raise TypeError("expected a MultiMeshFunction as argument.")
+
+    def part(self, i, deepcopy=False):
+        f = Function(super(MultiMeshFunction, self).part(i, deepcopy))
+        f.rename(super(MultiMeshFunction, self).name(), super(MultiMeshFunction, self).label())
+        return f
+
+    def parts(self, deepcopy=False):
+        """
+        Generator for MultiMeshFunction
+        """
+        for part in range(self._V.num_parts()):
+            yield self.part(part, deepcopy)
+
+    def interpolate(self, v):
+        """
+        Interpolate function.
+
+        *Arguments*
+            v
+              a :py:class:`MultiMeshFunction <dolfin.functions.function.MultimeshFunction>` or
+              an :py:class:`Expression <dolfin.functions.expression.Expression'>
+        *Example of usage*
+            .. code-block:: python
+
+                V = MultiMeshFunctionSpace(multimesh, "Lagrange", 1)
+                v = MultiMeshFunction(V)
+                w = Expression("sin(pi*x[0])")
+                v.interpolate(w)
+        """
+        # Developer note: This version involves a lot of copying
+        # and should be changed at some point.
+        # Developer note: Interpolate does not set inactive dofs to zero,
+        # and should be fixed
+        # Check argument
+        if isinstance(v, cpp.GenericFunction):
+            for i, vp in enumerate(self.parts(deepcopy=True)):
+                vp.interpolate(v)
+                self.assign_part(i, vp)
+
+        elif isinstance(v, MultiMeshFunction):
+            # Same multimesh required for interpolation
+            # Developer note: Is this test necessary?
+            if  self._V.multimesh().id() != v._V.multimesh().id():
+                raise RuntimeError("MultiMeshFunctions must live on same MultiMesh")
+            for i, vp in enumerate(self.parts(deepcopy=True)):
+                vmm = v.part(i, deepcopy=True)
+                vp.interpolate(vmm)
+                self.assign_part(i, vp)
+        else:
+            raise TypeError("Expected an Expression or a MultiMeshFunction.")
+
+        # Set inactive dofs to zero
+        for part in range(self._V.num_parts()):
+            dofs = self._V.dofmap().inactive_dofs(self._V.multimesh(),part)
+            self.vector()[dofs]=0
diff --git a/site-packages/dolfin/functions/specialfunctions.py b/site-packages/dolfin/functions/specialfunctions.py
index c335348..fc2bb23 100644
--- a/site-packages/dolfin/functions/specialfunctions.py
+++ b/site-packages/dolfin/functions/specialfunctions.py
@@ -24,7 +24,9 @@
 # Modified by Martin Sandve Alnæs 2013-2014
 
 __all__ = ["MeshCoordinates", "FacetArea", "FacetNormal", "CellSize", "CellVolume",
-           'SpatialCoordinate', 'CellNormal', 'Circumradius', 'MinFacetEdgeLength', 'MaxFacetEdgeLength']
+           'SpatialCoordinate', 'CellNormal', 'CellDiameter', 'Circumradius',
+           'MinCellEdgeLength', 'MaxCellEdgeLength',
+           'MinFacetEdgeLength', 'MaxFacetEdgeLength']
 
 # Import UFL and SWIG-generated extension module (DOLFIN C++)
 import ufl
@@ -116,9 +118,12 @@ def FacetNormal(mesh):
     return ufl.FacetNormal(_mesh2domain(mesh))
 
 # Simple definition of CellSize via UFL
-def CellSize(mesh):
+def CellDiameter(mesh):
     """
-    Return function cell size for given mesh.
+    Return function cell diameter for given mesh.
+
+    Note that diameter of cell :math:`K` is defined as
+    :math:`\sup_{\mathbf{x,y}\in K} |\mathbf{x-y}|`.
 
     *Arguments*
         mesh
@@ -129,10 +134,36 @@ def CellSize(mesh):
         .. code-block:: python
 
             mesh = UnitSquare(4,4)
-            h = CellSize(mesh)
+            h = CellDiameter(mesh)
+
+    """
+    return ufl.CellDiameter(_mesh2domain(mesh))
 
+# Simple definition of CellSize via UFL
+def CellSize(mesh):
     """
+    Return function twice the cell circumradius for given mesh.
+
+    This does not generalize to quadrilateral/hexahedral cells
+    and the function name is misleading. The function is hence
+    deprecated. Use ``CellDiameter`` (or ``2*Circumradius`` if
+    you really want that).
+
+    *Arguments*
+        mesh
+            a :py:class:`Mesh <dolfin.cpp.Mesh>`.
+
+    *Example of usage*
+
+        .. code-block:: python
 
+            mesh = UnitSquare(4,4)
+            D = CellSize(mesh)
+
+    """
+    cpp.deprecation("\"CellSize\"",
+                    "2017.2.0",
+                    "Use \"CellDiameter\" or \"2*Circumradius\".")
     return 2.0*ufl.Circumradius(_mesh2domain(mesh))
 
 # Simple definition of CellVolume via UFL
@@ -169,7 +200,7 @@ def SpatialCoordinate(mesh):
         .. code-block:: python
 
             mesh = UnitSquare(4,4)
-            vol = SpatialCoordinate(mesh)
+            x = SpatialCoordinate(mesh)
 
     """
 
@@ -189,7 +220,7 @@ def CellNormal(mesh):
         .. code-block:: python
 
             mesh = UnitSquare(4,4)
-            vol = CellNormal(mesh)
+            n = CellNormal(mesh)
 
     """
 
@@ -209,12 +240,52 @@ def Circumradius(mesh):
         .. code-block:: python
 
             mesh = UnitSquare(4,4)
-            vol = Circumradius(mesh)
+            R = Circumradius(mesh)
 
     """
 
     return ufl.Circumradius(_mesh2domain(mesh))
 
+# Simple definition of MinCellEdgeLength via UFL
+def MinCellEdgeLength(mesh):
+    """
+    Return symbolic minimum cell edge length of a cell for given mesh.
+
+    *Arguments*
+        mesh
+            a :py:class:`Mesh <dolfin.cpp.Mesh>`.
+
+    *Example of usage*
+
+        .. code-block:: python
+
+            mesh = UnitSquare(4,4)
+            mince = MinCellEdgeLength(mesh)
+
+    """
+
+    return ufl.MinCellEdgeLength(_mesh2domain(mesh))
+
+# Simple definition of MaxCellEdgeLength via UFL
+def MaxCellEdgeLength(mesh):
+    """
+    Return symbolic maximum cell edge length of a cell for given mesh.
+
+    *Arguments*
+        mesh
+            a :py:class:`Mesh <dolfin.cpp.Mesh>`.
+
+    *Example of usage*
+
+        .. code-block:: python
+
+            mesh = UnitSquare(4,4)
+            maxce = MaxCellEdgeLength(mesh)
+
+    """
+
+    return ufl.MaxCellEdgeLength(_mesh2domain(mesh))
+
 # Simple definition of MinFacetEdgeLength via UFL
 def MinFacetEdgeLength(mesh):
     """
@@ -229,7 +300,7 @@ def MinFacetEdgeLength(mesh):
         .. code-block:: python
 
             mesh = UnitSquare(4,4)
-            vol = MinFacetEdgeLength(mesh)
+            minfe = MinFacetEdgeLength(mesh)
 
     """
 
@@ -249,7 +320,7 @@ def MaxFacetEdgeLength(mesh):
         .. code-block:: python
 
             mesh = UnitSquare(4,4)
-            vol = MaxFacetEdgeLength(mesh)
+            maxfe = MaxFacetEdgeLength(mesh)
 
     """
 
diff --git a/site-packages/dolfin_utils/meshconvert/abaqus.py b/site-packages/dolfin_utils/meshconvert/abaqus.py
index ef42ef1..2d1d689 100644
--- a/site-packages/dolfin_utils/meshconvert/abaqus.py
+++ b/site-packages/dolfin_utils/meshconvert/abaqus.py
@@ -195,7 +195,7 @@ def convert(ifilename, handler):
 
         mesh = Mesh()
         mesh_editor = MeshEditor()
-        mesh_editor.open(mesh, 3, 3)
+        mesh_editor.open(mesh, "tetrahedron", 3, 3)
 
     node_ids_order = {}
     # Check for gaps in vertex numbering
diff --git a/site-packages/dolfin_utils/meshconvert/meshconvert.py b/site-packages/dolfin_utils/meshconvert/meshconvert.py
index 385546e..5a1623e 100644
--- a/site-packages/dolfin_utils/meshconvert/meshconvert.py
+++ b/site-packages/dolfin_utils/meshconvert/meshconvert.py
@@ -342,7 +342,12 @@ def gmsh2xml(ifilename, handler):
             _error("DOLFIN must be installed to handle Gmsh boundary regions")
         mesh = Mesh()
         mesh_editor = MeshEditor ()
-        mesh_editor.open( mesh, highest_dim, highest_dim )
+        if (highest_dim == 2):
+            mesh_editor.open(mesh, "triangle", highest_dim, highest_dim)
+        elif (highest_dim == 3):
+            mesh_editor.open(mesh, "tetrahedron", highest_dim, highest_dim)
+        else:
+            raise RuntimeError
         process_facets = True
     else:
         # TODO: Output a warning or an error here
diff --git a/site-packages/dolfin_utils/test/fixtures.py b/site-packages/dolfin_utils/test/fixtures.py
index 78e89ff..3103d7f 100644
--- a/site-packages/dolfin_utils/test/fixtures.py
+++ b/site-packages/dolfin_utils/test/fixtures.py
@@ -81,6 +81,16 @@ def gc_barrier():
     if MPI.size(mpi_comm_world()) > 1:
         MPI.barrier(mpi_comm_world())
 
+
+ at pytest.fixture()
+def worker_id(request):
+    """Returns thread id when running with pytest-xdist in parallel."""
+    if hasattr(request.config, 'slaveinput'):
+        return request.config.slaveinput['slaveid']
+    else:
+        return 'master'
+
+
 @pytest.yield_fixture(scope="function")
 def gc_barrier_fixture():
     """Function decorator to call gc.collect() and
@@ -112,6 +122,7 @@ def filedir(request):
     d = os.path.dirname(os.path.abspath(request.module.__file__))
     return d
 
+
 @pytest.fixture(scope="module")
 def rootdir(request):
     "Return the root directory of the repository. Assumes run from within repository filetree."
@@ -122,15 +133,20 @@ def rootdir(request):
         d, t = os.path.split(d)
     return d
 
+
 @pytest.fixture(scope="module")
 def datadir(request):
-    "Return the directory of the shared test data. Assumes run from within repository filetree."
+    """Return the directory of the shared test data. Assumes run from
+    within repository filetree.
+
+    """
     d = os.path.dirname(os.path.abspath(request.module.__file__))
     t = ''
     while t != "test":
         d, t = os.path.split(d)
     return os.path.join(d, "test", "data")
 
+
 def _create_tempdir(request):
     # Get directory name of test_foo.py file
     testfile = request.module.__file__
@@ -138,7 +154,7 @@ def _create_tempdir(request):
 
     # Construct name test_foo_tempdir from name test_foo.py
     testfilename = os.path.basename(testfile)
-    outputname = testfilename.replace(".py", "_tempdir")
+    outputname = testfilename.replace(".py", "_tempdir_{}".format(worker_id(request)))
 
     # Get function name test_something from test_foo.py
     function = request.function.__name__
@@ -176,10 +192,12 @@ def _create_tempdir(request):
     MPI.barrier(mpi_comm_world())
 
     return path
+
 from collections import defaultdict
 _create_tempdir._sequencenumber = defaultdict(int)
 _create_tempdir._basepaths = set()
 
+
 @pytest.fixture(scope="function")
 def tempdir(request):
     """Return a unique directory name for this test function instance.
@@ -193,10 +211,13 @@ def tempdir(request):
     Does NOT change the current directory.
 
     MPI safe (assuming mpi_comm_world() context).
+
     """
+
     gc_barrier()
     return _create_tempdir(request)
 
+
 @pytest.yield_fixture(scope="function")
 def cd_tempdir(request):
     """Return a unique directory name for this test function instance.
@@ -218,6 +239,7 @@ def cd_tempdir(request):
     yield path
     os.chdir(cwd)
 
+
 @pytest.yield_fixture
 def pushpop_parameters():
     global parameters
diff --git a/test/README b/test/README
index 561b870..9d167db 100644
--- a/test/README
+++ b/test/README
@@ -31,14 +31,3 @@ the LinearOperator.py Python unit tests, do
 
   cd build/test/unit/la/python
   python LinearOperator.py
-
-Similarly, to run one of the C++ unit tests, do
-
-  cd build/test/unit/la/cpp
-  make
-  ./test_LinearOperator
-
-Modifications of tests should be made in the source directory, not in
-the build directory. After a modification, simply run cmake (or the
-cmake.local script) to copy the tests to the build folder. Then run
-the tests from the build folder.
diff --git a/test/regression/test.py b/test/regression/test.py
index 1506301..e26132a 100644
--- a/test/regression/test.py
+++ b/test/regression/test.py
@@ -129,6 +129,8 @@ def main():
        os.path.join(demodir, 'undocumented', 'mplot',                       'cpp'),
        os.path.join(demodir, 'undocumented', 'plot',                        'cpp'),
        os.path.join(demodir, 'undocumented', 'coordinates',                 'cpp'),
+       os.path.join(demodir, 'undocumented', 'multimesh-quadrature',        'cpp'),
+       os.path.join(demodir, 'undocumented', 'multimesh-3d',                'cpp'),       
        os.path.join(demodir, 'documented',   'stokes-mini',                 'cpp'),
        os.path.join(demodir, 'documented',   'tensor-weighted-poisson',     'cpp'),
        os.path.join(demodir, 'documented',   'subdomains-poisson',          'cpp'),
diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt
deleted file mode 100644
index 027c19d..0000000
--- a/test/unit/CMakeLists.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-cmake_minimum_required(VERSION 3.5)
-
-project(googletest-download NONE)
-
-# Using ExternalProject to Build GTest and use the Library
-include(ExternalProject)
-
-# Set the build type if it isn't already
-if(NOT CMAKE_BUILD_TYPE)
-  set(CMAKE_BUILD_TYPE Release)
-endif()
-
-# Set default ExternalProject root directory
-set_directory_properties(PROPERTIES EP_PREFIX ${CMAKE_BINARY_DIR}/GoogleTest)
-
-# Add gtest
-ExternalProject_Add(
-    googletest
-    URL https://github.com/google/googletest/archive/release-1.7.0.tar.gz
-    TIMEOUT 60
-    CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-               -Dgtest_force_shared_crt=ON
-    # Disable install step
-    INSTALL_COMMAND ""
-    # Wrap download, configure and build steps in a script to log output
-    LOG_DOWNLOAD ON
-    LOG_CONFIGURE ON
-    LOG_BUILD ON)
-
-# Specify include dir
-ExternalProject_Get_Property(googletest source_dir)
-include_directories(${source_dir}/include)
diff --git a/test/unit/README b/test/unit/README
index 13687d0..6e065d3 100644
--- a/test/unit/README
+++ b/test/unit/README
@@ -21,6 +21,3 @@ Debugging random test deadlocks under MPI:
   while true; do git clean -fdx . && mpirun -n 3 xterm -e gdb -ex r -ex q -args python -m pytest -sv; done
 
 See 'man pytest' for how to use pdb, profiling, coverage, etc.
-
-TODO: Move {function,mesh,io,la,parameter}/cpp to cpp/* and rewrite to google test framework.
-
diff --git a/test/unit/cpp/CMakeLists.txt b/test/unit/cpp/CMakeLists.txt
index 3e50f92..421b2d7 100644
--- a/test/unit/cpp/CMakeLists.txt
+++ b/test/unit/cpp/CMakeLists.txt
@@ -1,90 +1,32 @@
-project(dolfin-tests)
-
-# Require CMake 2.8
 cmake_minimum_required(VERSION 3.5)
+project(dolfin-tests)
 
-# Set special link option, see `cmake --help-policy CMP0003`
-if(COMMAND cmake_policy)
-  cmake_policy(SET CMP0003 NEW)
-endif()
-
-# Find DOLFIN config file (not used here, but checks that tests will be able
-# to find it
 find_package(DOLFIN REQUIRED)
-
-# Add GoogleTest Directory
-include_directories(${CMAKE_BINARY_DIR}/GoogleTest/src/googletest/include)
-link_directories(${CMAKE_BINARY_DIR}/GoogleTest/src/googletest-build)
-
-# If config file is found, add all demo sub-directories, else print helper
-# message
-if (DOLFIN_FOUND)
-
-  # Build list of all cpp directories
-  file(GLOB_RECURSE initial_list "*.cpp")
-
-  set(added_files "") # Change to targetting cpp files instead
-
-  # Add each C++ demo directory only once
-  foreach (cpp_test ${initial_list})
-
-    # Get directory
-    get_filename_component(cpp_lib_dir ${cpp_test} DIRECTORY)
-
-    # Get one upper directory
-    get_filename_component(cpp_dir ${cpp_lib_dir} DIRECTORY)
-
-    # Get last dir name
-    get_filename_component(last_component ${cpp_dir} NAME)
-
-    # Only process if last dirname is cpp
-    if ((${last_component} STREQUAL "cpp"))
-      # If you find the cpp lib dir
-      # That means you have allocated the cpp files
-      # Don't need to recheck the directories
-      list(APPEND added_files ${cpp_test})
-
-    endif()
-  endforeach()
-
-  # Set CMake behavior
-  cmake_policy(SET CMP0004 NEW)
-
-  if (EXISTS ${DOLFIN_USE_FILE})
-    include(${DOLFIN_USE_FILE})
-
-    # Default build type (can be overridden by user)
-    if (NOT CMAKE_BUILD_TYPE)
-      set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
-        "Choose the type of build, options are: Debug MinSizeRel Release RelWithDebInfo." FORCE)
-    endif()
-  else()
-    # Compiler definitions
-    add_definitions(${DOLFIN_CXX_DEFINITIONS})
-
-    # Compiler flags
-    set(CMAKE_CXX_FLAGS "${DOLFIN_CXX_FLAGS} ${CMAKE_CXX_FLAGS}")
-
-    # Include directories
-    include_directories(${DOLFIN_INCLUDE_DIRS})
-    include_directories(SYSTEM ${DOLFIN_3RD_PARTY_INCLUDE_DIRS})
-  endif()
-
-  # Google Test uses threads
-  if (NOT APPLE)
-    set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
-    find_package(Threads REQUIRED)
-    if (CMAKE_USE_PTHREADS_INIT)
-      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
-    endif()
-  endif()
-
-  add_executable(unittests_cpp ${added_files})
-  add_dependencies(unittests_cpp googletest)
-  target_link_libraries(unittests_cpp ${DOLFIN_LIBRARIES} gtest gtest_main ${CMAKE_THREAD_LIBS_INIT})
-
-else()
-
-  message(STATUS "Could not locate DOLFINConfig.cmake file. Did you do 'make install' for the DOLFIN library and set the appropriate paths (source <build_dir>/dolfin.conf)?")
-
-endif()
+include(${DOLFIN_USE_FILE})
+
+# Prepare "Catch" library for other executables
+set(CATCH_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/catch)
+
+add_library(Catch INTERFACE)
+target_include_directories(Catch INTERFACE ${CATCH_INCLUDE_DIR})
+
+# Make test executable
+set(TEST_SOURCES
+  ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/common/SubSystemsManager.cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/function/Expression.cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/geometry/ConvexTriangulation.cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/io/XMLMeshData.cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/io/XMLMeshValueCollection.cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/la/LinearOperator.cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/la/Vector.cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/mesh/Mesh.cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/mesh/MeshColoring.cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/mesh/MeshFunction.cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/mesh/MeshValueCollection.cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/mesh/MultiMesh.cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/parameter/Parameters.cpp
+  )
+
+add_executable(unittests_cpp ${TEST_SOURCES})
+target_link_libraries(unittests_cpp PRIVATE Catch dolfin)
diff --git a/test/unit/cpp/catch/catch.hpp b/test/unit/cpp/catch/catch.hpp
new file mode 100644
index 0000000..f7681f4
--- /dev/null
+++ b/test/unit/cpp/catch/catch.hpp
@@ -0,0 +1,11545 @@
+/*
+ *  Catch v1.9.6
+ *  Generated: 2017-06-27 12:19:54.557875
+ *  ----------------------------------------------------------
+ *  This file has been merged from multiple headers. Please don't edit it directly
+ *  Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
+ *
+ *  Distributed under the Boost Software License, Version 1.0. (See accompanying
+ *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+
+#define TWOBLUECUBES_CATCH_HPP_INCLUDED
+
+#ifdef __clang__
+#    pragma clang system_header
+#elif defined __GNUC__
+#    pragma GCC system_header
+#endif
+
+// #included from: internal/catch_suppress_warnings.h
+
+#ifdef __clang__
+#   ifdef __ICC // icpc defines the __clang__ macro
+#       pragma warning(push)
+#       pragma warning(disable: 161 1682)
+#   else // __ICC
+#       pragma clang diagnostic ignored "-Wglobal-constructors"
+#       pragma clang diagnostic ignored "-Wvariadic-macros"
+#       pragma clang diagnostic ignored "-Wc99-extensions"
+#       pragma clang diagnostic ignored "-Wunused-variable"
+#       pragma clang diagnostic push
+#       pragma clang diagnostic ignored "-Wpadded"
+#       pragma clang diagnostic ignored "-Wc++98-compat"
+#       pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
+#       pragma clang diagnostic ignored "-Wswitch-enum"
+#       pragma clang diagnostic ignored "-Wcovered-switch-default"
+#    endif
+#elif defined __GNUC__
+#    pragma GCC diagnostic ignored "-Wvariadic-macros"
+#    pragma GCC diagnostic ignored "-Wunused-variable"
+#    pragma GCC diagnostic ignored "-Wparentheses"
+
+#    pragma GCC diagnostic push
+#    pragma GCC diagnostic ignored "-Wpadded"
+#endif
+#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
+#  define CATCH_IMPL
+#endif
+
+#ifdef CATCH_IMPL
+#  ifndef CLARA_CONFIG_MAIN
+#    define CLARA_CONFIG_MAIN_NOT_DEFINED
+#    define CLARA_CONFIG_MAIN
+#  endif
+#endif
+
+// #included from: internal/catch_notimplemented_exception.h
+#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED
+
+// #included from: catch_common.h
+#define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
+
+// #included from: catch_compiler_capabilities.h
+#define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
+
+// Detect a number of compiler features - mostly C++11/14 conformance - by compiler
+// The following features are defined:
+//
+// CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported?
+// CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
+// CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
+// CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported?
+// CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported
+// CATCH_CONFIG_CPP11_LONG_LONG : is long long supported?
+// CATCH_CONFIG_CPP11_OVERRIDE : is override supported?
+// CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
+// CATCH_CONFIG_CPP11_SHUFFLE : is std::shuffle supported?
+// CATCH_CONFIG_CPP11_TYPE_TRAITS : are type_traits and enable_if supported?
+
+// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
+
+// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
+// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
+// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
+// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
+// ****************
+// Note to maintainers: if new toggles are added please document them
+// in configuration.md, too
+// ****************
+
+// In general each macro has a _NO_<feature name> form
+// (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
+// Many features, at point of detection, define an _INTERNAL_ macro, so they
+// can be combined, en-mass, with the _NO_ forms later.
+
+// All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11
+
+#ifdef __cplusplus
+
+#  if __cplusplus >= 201103L
+#    define CATCH_CPP11_OR_GREATER
+#  endif
+
+#  if __cplusplus >= 201402L
+#    define CATCH_CPP14_OR_GREATER
+#  endif
+
+#endif
+
+#ifdef __clang__
+
+#  if __has_feature(cxx_nullptr)
+#    define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
+#  endif
+
+#  if __has_feature(cxx_noexcept)
+#    define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
+#  endif
+
+#   if defined(CATCH_CPP11_OR_GREATER)
+#       define CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
+            _Pragma( "clang diagnostic push" ) \
+            _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" )
+#       define CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
+            _Pragma( "clang diagnostic pop" )
+
+#       define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
+            _Pragma( "clang diagnostic push" ) \
+            _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
+#       define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
+            _Pragma( "clang diagnostic pop" )
+#   endif
+
+#endif // __clang__
+
+////////////////////////////////////////////////////////////////////////////////
+// We know some environments not to support full POSIX signals
+#if defined(__CYGWIN__) || defined(__QNX__)
+
+#   if !defined(CATCH_CONFIG_POSIX_SIGNALS)
+#       define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
+#   endif
+
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// Cygwin
+#ifdef __CYGWIN__
+
+// Required for some versions of Cygwin to declare gettimeofday
+// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
+#   define _BSD_SOURCE
+
+#endif // __CYGWIN__
+
+////////////////////////////////////////////////////////////////////////////////
+// Borland
+#ifdef __BORLANDC__
+
+#endif // __BORLANDC__
+
+////////////////////////////////////////////////////////////////////////////////
+// EDG
+#ifdef __EDG_VERSION__
+
+#endif // __EDG_VERSION__
+
+////////////////////////////////////////////////////////////////////////////////
+// Digital Mars
+#ifdef __DMC__
+
+#endif // __DMC__
+
+////////////////////////////////////////////////////////////////////////////////
+// GCC
+#ifdef __GNUC__
+
+#   if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
+#       define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
+#   endif
+
+// - otherwise more recent versions define __cplusplus >= 201103L
+// and will get picked up below
+
+#endif // __GNUC__
+
+////////////////////////////////////////////////////////////////////////////////
+// Visual C++
+#ifdef _MSC_VER
+
+#define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
+
+#if (_MSC_VER >= 1600)
+#   define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
+#   define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
+#endif
+
+#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
+#define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
+#define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+#define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE
+#define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS
+#endif
+
+#endif // _MSC_VER
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Use variadic macros if the compiler supports them
+#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
+    ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
+    ( defined __GNUC__ && __GNUC__ >= 3 ) || \
+    ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
+
+#define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
+
+#endif
+
+// Use __COUNTER__ if the compiler supports it
+#if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \
+    ( defined __GNUC__  && ( __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3 )) ) || \
+    ( defined __clang__ && __clang_major__ >= 3 )
+
+#define CATCH_INTERNAL_CONFIG_COUNTER
+
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// C++ language feature support
+
+// catch all support for C++11
+#if defined(CATCH_CPP11_OR_GREATER)
+
+#  if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR)
+#    define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
+#  endif
+
+#  ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
+#    define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
+#  endif
+
+#  ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+#    define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+#  endif
+
+#  ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
+#    define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
+#  endif
+
+#  ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE
+#    define CATCH_INTERNAL_CONFIG_CPP11_TUPLE
+#  endif
+
+#  ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
+#    define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
+#  endif
+
+#  if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG)
+#    define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG
+#  endif
+
+#  if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE)
+#    define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE
+#  endif
+#  if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
+#    define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
+#  endif
+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE)
+#   define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE
+#  endif
+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS)
+#  define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS
+# endif
+
+#endif // __cplusplus >= 201103L
+
+// Now set the actual defines based on the above + anything the user has configured
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11)
+#   define CATCH_CONFIG_CPP11_NULLPTR
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11)
+#   define CATCH_CONFIG_CPP11_NOEXCEPT
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11)
+#   define CATCH_CONFIG_CPP11_GENERATED_METHODS
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11)
+#   define CATCH_CONFIG_CPP11_IS_ENUM
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11)
+#   define CATCH_CONFIG_CPP11_TUPLE
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS)
+#   define CATCH_CONFIG_VARIADIC_MACROS
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11)
+#   define CATCH_CONFIG_CPP11_LONG_LONG
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11)
+#   define CATCH_CONFIG_CPP11_OVERRIDE
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11)
+#   define CATCH_CONFIG_CPP11_UNIQUE_PTR
+#endif
+// Use of __COUNTER__ is suppressed if __JETBRAINS_IDE__ is #defined (meaning we're being parsed by a JetBrains IDE for
+// analytics) because, at time of writing, __COUNTER__ is not properly handled by it.
+// This does not affect compilation
+#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) && !defined(__JETBRAINS_IDE__)
+#   define CATCH_CONFIG_COUNTER
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_NO_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_NO_CPP11)
+#   define CATCH_CONFIG_CPP11_SHUFFLE
+#endif
+# if defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_NO_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_NO_CPP11)
+#  define CATCH_CONFIG_CPP11_TYPE_TRAITS
+# endif
+#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH)
+#   define CATCH_CONFIG_WINDOWS_SEH
+#endif
+// This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
+#if !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
+#   define CATCH_CONFIG_POSIX_SIGNALS
+#endif
+
+#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
+#   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
+#   define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
+#endif
+#if !defined(CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS)
+#   define CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS
+#   define CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
+#endif
+
+// noexcept support:
+#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)
+#  define CATCH_NOEXCEPT noexcept
+#  define CATCH_NOEXCEPT_IS(x) noexcept(x)
+#else
+#  define CATCH_NOEXCEPT throw()
+#  define CATCH_NOEXCEPT_IS(x)
+#endif
+
+// nullptr support
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+#   define CATCH_NULL nullptr
+#else
+#   define CATCH_NULL NULL
+#endif
+
+// override support
+#ifdef CATCH_CONFIG_CPP11_OVERRIDE
+#   define CATCH_OVERRIDE override
+#else
+#   define CATCH_OVERRIDE
+#endif
+
+// unique_ptr support
+#ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR
+#   define CATCH_AUTO_PTR( T ) std::unique_ptr<T>
+#else
+#   define CATCH_AUTO_PTR( T ) std::auto_ptr<T>
+#endif
+
+#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
+#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
+#ifdef CATCH_CONFIG_COUNTER
+#  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
+#else
+#  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
+#endif
+
+#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
+#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
+
+#include <sstream>
+#include <algorithm>
+
+namespace Catch {
+
+    struct IConfig;
+
+    struct CaseSensitive { enum Choice {
+        Yes,
+        No
+    }; };
+
+    class NonCopyable {
+#ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+        NonCopyable( NonCopyable const& )              = delete;
+        NonCopyable( NonCopyable && )                  = delete;
+        NonCopyable& operator = ( NonCopyable const& ) = delete;
+        NonCopyable& operator = ( NonCopyable && )     = delete;
+#else
+        NonCopyable( NonCopyable const& info );
+        NonCopyable& operator = ( NonCopyable const& );
+#endif
+
+    protected:
+        NonCopyable() {}
+        virtual ~NonCopyable();
+    };
+
+    class SafeBool {
+    public:
+        typedef void (SafeBool::*type)() const;
+
+        static type makeSafe( bool value ) {
+            return value ? &SafeBool::trueValue : 0;
+        }
+    private:
+        void trueValue() const {}
+    };
+
+    template<typename ContainerT>
+    inline void deleteAll( ContainerT& container ) {
+        typename ContainerT::const_iterator it = container.begin();
+        typename ContainerT::const_iterator itEnd = container.end();
+        for(; it != itEnd; ++it )
+            delete *it;
+    }
+    template<typename AssociativeContainerT>
+    inline void deleteAllValues( AssociativeContainerT& container ) {
+        typename AssociativeContainerT::const_iterator it = container.begin();
+        typename AssociativeContainerT::const_iterator itEnd = container.end();
+        for(; it != itEnd; ++it )
+            delete it->second;
+    }
+
+    bool startsWith( std::string const& s, std::string const& prefix );
+    bool startsWith( std::string const& s, char prefix );
+    bool endsWith( std::string const& s, std::string const& suffix );
+    bool endsWith( std::string const& s, char suffix );
+    bool contains( std::string const& s, std::string const& infix );
+    void toLowerInPlace( std::string& s );
+    std::string toLower( std::string const& s );
+    std::string trim( std::string const& str );
+    bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
+
+    struct pluralise {
+        pluralise( std::size_t count, std::string const& label );
+
+        friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
+
+        std::size_t m_count;
+        std::string m_label;
+    };
+
+    struct SourceLineInfo {
+
+        SourceLineInfo();
+        SourceLineInfo( char const* _file, std::size_t _line );
+#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+        SourceLineInfo(SourceLineInfo const& other)          = default;
+        SourceLineInfo( SourceLineInfo && )                  = default;
+        SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
+        SourceLineInfo& operator = ( SourceLineInfo && )     = default;
+#  endif
+        bool empty() const;
+        bool operator == ( SourceLineInfo const& other ) const;
+        bool operator < ( SourceLineInfo const& other ) const;
+
+        char const* file;
+        std::size_t line;
+    };
+
+    std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
+
+    // This is just here to avoid compiler warnings with macro constants and boolean literals
+    inline bool isTrue( bool value ){ return value; }
+    inline bool alwaysTrue() { return true; }
+    inline bool alwaysFalse() { return false; }
+
+    void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
+
+    void seedRng( IConfig const& config );
+    unsigned int rngSeed();
+
+    // Use this in variadic streaming macros to allow
+    //    >> +StreamEndStop
+    // as well as
+    //    >> stuff +StreamEndStop
+    struct StreamEndStop {
+        std::string operator+() {
+            return std::string();
+        }
+    };
+    template<typename T>
+    T const& operator + ( T const& value, StreamEndStop ) {
+        return value;
+    }
+}
+
+#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
+#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
+
+namespace Catch {
+
+    class NotImplementedException : public std::exception
+    {
+    public:
+        NotImplementedException( SourceLineInfo const& lineInfo );
+        NotImplementedException( NotImplementedException const& ) {}
+
+        virtual ~NotImplementedException() CATCH_NOEXCEPT {}
+
+        virtual const char* what() const CATCH_NOEXCEPT;
+
+    private:
+        std::string m_what;
+        SourceLineInfo m_lineInfo;
+    };
+
+} // end namespace Catch
+
+///////////////////////////////////////////////////////////////////////////////
+#define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO )
+
+// #included from: internal/catch_context.h
+#define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
+
+// #included from: catch_interfaces_generators.h
+#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+    struct IGeneratorInfo {
+        virtual ~IGeneratorInfo();
+        virtual bool moveNext() = 0;
+        virtual std::size_t getCurrentIndex() const = 0;
+    };
+
+    struct IGeneratorsForTest {
+        virtual ~IGeneratorsForTest();
+
+        virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0;
+        virtual bool moveNext() = 0;
+    };
+
+    IGeneratorsForTest* createGeneratorsForTest();
+
+} // end namespace Catch
+
+// #included from: catch_ptr.hpp
+#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+namespace Catch {
+
+    // An intrusive reference counting smart pointer.
+    // T must implement addRef() and release() methods
+    // typically implementing the IShared interface
+    template<typename T>
+    class Ptr {
+    public:
+        Ptr() : m_p( CATCH_NULL ){}
+        Ptr( T* p ) : m_p( p ){
+            if( m_p )
+                m_p->addRef();
+        }
+        Ptr( Ptr const& other ) : m_p( other.m_p ){
+            if( m_p )
+                m_p->addRef();
+        }
+        ~Ptr(){
+            if( m_p )
+                m_p->release();
+        }
+        void reset() {
+            if( m_p )
+                m_p->release();
+            m_p = CATCH_NULL;
+        }
+        Ptr& operator = ( T* p ){
+            Ptr temp( p );
+            swap( temp );
+            return *this;
+        }
+        Ptr& operator = ( Ptr const& other ){
+            Ptr temp( other );
+            swap( temp );
+            return *this;
+        }
+        void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }
+        T* get() const{ return m_p; }
+        T& operator*() const { return *m_p; }
+        T* operator->() const { return m_p; }
+        bool operator !() const { return m_p == CATCH_NULL; }
+        operator SafeBool::type() const { return SafeBool::makeSafe( m_p != CATCH_NULL ); }
+
+    private:
+        T* m_p;
+    };
+
+    struct IShared : NonCopyable {
+        virtual ~IShared();
+        virtual void addRef() const = 0;
+        virtual void release() const = 0;
+    };
+
+    template<typename T = IShared>
+    struct SharedImpl : T {
+
+        SharedImpl() : m_rc( 0 ){}
+
+        virtual void addRef() const {
+            ++m_rc;
+        }
+        virtual void release() const {
+            if( --m_rc == 0 )
+                delete this;
+        }
+
+        mutable unsigned int m_rc;
+    };
+
+} // end namespace Catch
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+namespace Catch {
+
+    class TestCase;
+    class Stream;
+    struct IResultCapture;
+    struct IRunner;
+    struct IGeneratorsForTest;
+    struct IConfig;
+
+    struct IContext
+    {
+        virtual ~IContext();
+
+        virtual IResultCapture* getResultCapture() = 0;
+        virtual IRunner* getRunner() = 0;
+        virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0;
+        virtual bool advanceGeneratorsForCurrentTest() = 0;
+        virtual Ptr<IConfig const> getConfig() const = 0;
+    };
+
+    struct IMutableContext : IContext
+    {
+        virtual ~IMutableContext();
+        virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
+        virtual void setRunner( IRunner* runner ) = 0;
+        virtual void setConfig( Ptr<IConfig const> const& config ) = 0;
+    };
+
+    IContext& getCurrentContext();
+    IMutableContext& getCurrentMutableContext();
+    void cleanUpContext();
+    Stream createStream( std::string const& streamName );
+
+}
+
+// #included from: internal/catch_test_registry.hpp
+#define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
+
+// #included from: catch_interfaces_testcase.h
+#define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
+
+#include <vector>
+
+namespace Catch {
+
+    class TestSpec;
+
+    struct ITestCase : IShared {
+        virtual void invoke () const = 0;
+    protected:
+        virtual ~ITestCase();
+    };
+
+    class TestCase;
+    struct IConfig;
+
+    struct ITestCaseRegistry {
+        virtual ~ITestCaseRegistry();
+        virtual std::vector<TestCase> const& getAllTests() const = 0;
+        virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
+    };
+
+    bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
+    std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
+    std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
+
+}
+
+namespace Catch {
+
+template<typename C>
+class MethodTestCase : public SharedImpl<ITestCase> {
+
+public:
+    MethodTestCase( void (C::*method)() ) : m_method( method ) {}
+
+    virtual void invoke() const {
+        C obj;
+        (obj.*m_method)();
+    }
+
+private:
+    virtual ~MethodTestCase() {}
+
+    void (C::*m_method)();
+};
+
+typedef void(*TestFunction)();
+
+struct NameAndDesc {
+    NameAndDesc( const char* _name = "", const char* _description= "" )
+    : name( _name ), description( _description )
+    {}
+
+    const char* name;
+    const char* description;
+};
+
+void registerTestCase
+    (   ITestCase* testCase,
+        char const* className,
+        NameAndDesc const& nameAndDesc,
+        SourceLineInfo const& lineInfo );
+
+struct AutoReg {
+
+    AutoReg
+        (   TestFunction function,
+            SourceLineInfo const& lineInfo,
+            NameAndDesc const& nameAndDesc );
+
+    template<typename C>
+    AutoReg
+        (   void (C::*method)(),
+            char const* className,
+            NameAndDesc const& nameAndDesc,
+            SourceLineInfo const& lineInfo ) {
+
+        registerTestCase
+            (   new MethodTestCase<C>( method ),
+                className,
+                nameAndDesc,
+                lineInfo );
+    }
+
+    ~AutoReg();
+
+private:
+    AutoReg( AutoReg const& );
+    void operator= ( AutoReg const& );
+};
+
+void registerTestCaseFunction
+    (   TestFunction function,
+        SourceLineInfo const& lineInfo,
+        NameAndDesc const& nameAndDesc );
+
+} // end namespace Catch
+
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+    ///////////////////////////////////////////////////////////////////////////////
+    #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
+        static void TestName(); \
+        CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
+        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); } \
+        CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
+        static void TestName()
+    #define INTERNAL_CATCH_TESTCASE( ... ) \
+        INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
+
+    ///////////////////////////////////////////////////////////////////////////////
+    #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
+        CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
+        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); } \
+        CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
+
+    ///////////////////////////////////////////////////////////////////////////////
+    #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
+        CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
+        namespace{ \
+            struct TestName : ClassName{ \
+                void test(); \
+            }; \
+            Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \
+        } \
+        CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
+        void TestName::test()
+    #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
+        INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
+
+    ///////////////////////////////////////////////////////////////////////////////
+    #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
+        CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
+        Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); \
+        CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
+
+#else
+    ///////////////////////////////////////////////////////////////////////////////
+    #define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \
+        static void TestName(); \
+        CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
+        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\
+        CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
+        static void TestName()
+    #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
+        INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc )
+
+    ///////////////////////////////////////////////////////////////////////////////
+    #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
+        CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
+        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); } \
+        CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
+
+    ///////////////////////////////////////////////////////////////////////////////
+    #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\
+        CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
+        namespace{ \
+            struct TestCaseName : ClassName{ \
+                void test(); \
+            }; \
+            Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \
+        } \
+        CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \
+        void TestCaseName::test()
+    #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
+        INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc )
+
+    ///////////////////////////////////////////////////////////////////////////////
+    #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \
+        CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \
+        Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); \
+        CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
+
+#endif
+
+// #included from: internal/catch_capture.hpp
+#define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
+
+// #included from: catch_result_builder.h
+#define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
+
+// #included from: catch_result_type.h
+#define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED
+
+namespace Catch {
+
+    // ResultWas::OfType enum
+    struct ResultWas { enum OfType {
+        Unknown = -1,
+        Ok = 0,
+        Info = 1,
+        Warning = 2,
+
+        FailureBit = 0x10,
+
+        ExpressionFailed = FailureBit | 1,
+        ExplicitFailure = FailureBit | 2,
+
+        Exception = 0x100 | FailureBit,
+
+        ThrewException = Exception | 1,
+        DidntThrowException = Exception | 2,
+
+        FatalErrorCondition = 0x200 | FailureBit
+
+    }; };
+
+    inline bool isOk( ResultWas::OfType resultType ) {
+        return ( resultType & ResultWas::FailureBit ) == 0;
+    }
+    inline bool isJustInfo( int flags ) {
+        return flags == ResultWas::Info;
+    }
+
+    // ResultDisposition::Flags enum
+    struct ResultDisposition { enum Flags {
+        Normal = 0x01,
+
+        ContinueOnFailure = 0x02,   // Failures fail test, but execution continues
+        FalseTest = 0x04,           // Prefix expression with !
+        SuppressFail = 0x08         // Failures are reported but do not fail the test
+    }; };
+
+    inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
+        return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
+    }
+
+    inline bool shouldContinueOnFailure( int flags )    { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
+    inline bool isFalseTest( int flags )                { return ( flags & ResultDisposition::FalseTest ) != 0; }
+    inline bool shouldSuppressFailure( int flags )      { return ( flags & ResultDisposition::SuppressFail ) != 0; }
+
+} // end namespace Catch
+
+// #included from: catch_assertionresult.h
+#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+    struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
+
+    struct DecomposedExpression
+    {
+        virtual ~DecomposedExpression() {}
+        virtual bool isBinaryExpression() const {
+            return false;
+        }
+        virtual void reconstructExpression( std::string& dest ) const = 0;
+
+        // Only simple binary comparisons can be decomposed.
+        // If more complex check is required then wrap sub-expressions in parentheses.
+        template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( T const& );
+        template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( T const& );
+        template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( T const& );
+        template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( T const& );
+        template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator % ( T const& );
+        template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( T const& );
+        template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( T const& );
+
+    private:
+        DecomposedExpression& operator = (DecomposedExpression const&);
+    };
+
+    struct AssertionInfo
+    {
+        AssertionInfo() {}
+        AssertionInfo(  char const * _macroName,
+                        SourceLineInfo const& _lineInfo,
+                        char const * _capturedExpression,
+                        ResultDisposition::Flags _resultDisposition,
+                        char const * _secondArg = "");
+
+        char const * macroName;
+        SourceLineInfo lineInfo;
+        char const * capturedExpression;
+        ResultDisposition::Flags resultDisposition;
+        char const * secondArg;
+    };
+
+    struct AssertionResultData
+    {
+        AssertionResultData() : decomposedExpression( CATCH_NULL )
+                              , resultType( ResultWas::Unknown )
+                              , negated( false )
+                              , parenthesized( false ) {}
+
+        void negate( bool parenthesize ) {
+            negated = !negated;
+            parenthesized = parenthesize;
+            if( resultType == ResultWas::Ok )
+                resultType = ResultWas::ExpressionFailed;
+            else if( resultType == ResultWas::ExpressionFailed )
+                resultType = ResultWas::Ok;
+        }
+
+        std::string const& reconstructExpression() const {
+            if( decomposedExpression != CATCH_NULL ) {
+                decomposedExpression->reconstructExpression( reconstructedExpression );
+                if( parenthesized ) {
+                    reconstructedExpression.insert( 0, 1, '(' );
+                    reconstructedExpression.append( 1, ')' );
+                }
+                if( negated ) {
+                    reconstructedExpression.insert( 0, 1, '!' );
+                }
+                decomposedExpression = CATCH_NULL;
+            }
+            return reconstructedExpression;
+        }
+
+        mutable DecomposedExpression const* decomposedExpression;
+        mutable std::string reconstructedExpression;
+        std::string message;
+        ResultWas::OfType resultType;
+        bool negated;
+        bool parenthesized;
+    };
+
+    class AssertionResult {
+    public:
+        AssertionResult();
+        AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
+        ~AssertionResult();
+#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+         AssertionResult( AssertionResult const& )              = default;
+         AssertionResult( AssertionResult && )                  = default;
+         AssertionResult& operator = ( AssertionResult const& ) = default;
+         AssertionResult& operator = ( AssertionResult && )     = default;
+#  endif
+
+        bool isOk() const;
+        bool succeeded() const;
+        ResultWas::OfType getResultType() const;
+        bool hasExpression() const;
+        bool hasMessage() const;
+        std::string getExpression() const;
+        std::string getExpressionInMacro() const;
+        bool hasExpandedExpression() const;
+        std::string getExpandedExpression() const;
+        std::string getMessage() const;
+        SourceLineInfo getSourceInfo() const;
+        std::string getTestMacroName() const;
+        void discardDecomposedExpression() const;
+        void expandDecomposedExpression() const;
+
+    protected:
+        AssertionInfo m_info;
+        AssertionResultData m_resultData;
+    };
+
+} // end namespace Catch
+
+// #included from: catch_matchers.hpp
+#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
+
+namespace Catch {
+namespace Matchers {
+    namespace Impl {
+
+        template<typename ArgT> struct MatchAllOf;
+        template<typename ArgT> struct MatchAnyOf;
+        template<typename ArgT> struct MatchNotOf;
+
+        class MatcherUntypedBase {
+        public:
+            std::string toString() const {
+                if( m_cachedToString.empty() )
+                    m_cachedToString = describe();
+                return m_cachedToString;
+            }
+
+        protected:
+            virtual ~MatcherUntypedBase();
+            virtual std::string describe() const = 0;
+            mutable std::string m_cachedToString;
+        private:
+            MatcherUntypedBase& operator = ( MatcherUntypedBase const& );
+        };
+
+        template<typename ObjectT>
+        struct MatcherMethod {
+            virtual bool match( ObjectT const& arg ) const = 0;
+        };
+        template<typename PtrT>
+        struct MatcherMethod<PtrT*> {
+            virtual bool match( PtrT* arg ) const = 0;
+        };
+
+        template<typename ObjectT, typename ComparatorT = ObjectT>
+        struct MatcherBase : MatcherUntypedBase, MatcherMethod<ObjectT> {
+
+            MatchAllOf<ComparatorT> operator && ( MatcherBase const& other ) const;
+            MatchAnyOf<ComparatorT> operator || ( MatcherBase const& other ) const;
+            MatchNotOf<ComparatorT> operator ! () const;
+        };
+
+        template<typename ArgT>
+        struct MatchAllOf : MatcherBase<ArgT> {
+            virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE {
+                for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
+                    if (!m_matchers[i]->match(arg))
+                        return false;
+                }
+                return true;
+            }
+            virtual std::string describe() const CATCH_OVERRIDE {
+                std::string description;
+                description.reserve( 4 + m_matchers.size()*32 );
+                description += "( ";
+                for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
+                    if( i != 0 )
+                        description += " and ";
+                    description += m_matchers[i]->toString();
+                }
+                description += " )";
+                return description;
+            }
+
+            MatchAllOf<ArgT>& operator && ( MatcherBase<ArgT> const& other ) {
+                m_matchers.push_back( &other );
+                return *this;
+            }
+
+            std::vector<MatcherBase<ArgT> const*> m_matchers;
+        };
+        template<typename ArgT>
+        struct MatchAnyOf : MatcherBase<ArgT> {
+
+            virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE {
+                for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
+                    if (m_matchers[i]->match(arg))
+                        return true;
+                }
+                return false;
+            }
+            virtual std::string describe() const CATCH_OVERRIDE {
+                std::string description;
+                description.reserve( 4 + m_matchers.size()*32 );
+                description += "( ";
+                for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
+                    if( i != 0 )
+                        description += " or ";
+                    description += m_matchers[i]->toString();
+                }
+                description += " )";
+                return description;
+            }
+
+            MatchAnyOf<ArgT>& operator || ( MatcherBase<ArgT> const& other ) {
+                m_matchers.push_back( &other );
+                return *this;
+            }
+
+            std::vector<MatcherBase<ArgT> const*> m_matchers;
+        };
+
+        template<typename ArgT>
+        struct MatchNotOf : MatcherBase<ArgT> {
+
+            MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}
+
+            virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE {
+                return !m_underlyingMatcher.match( arg );
+            }
+
+            virtual std::string describe() const CATCH_OVERRIDE {
+                return "not " + m_underlyingMatcher.toString();
+            }
+            MatcherBase<ArgT> const& m_underlyingMatcher;
+        };
+
+        template<typename ObjectT, typename ComparatorT>
+        MatchAllOf<ComparatorT> MatcherBase<ObjectT, ComparatorT>::operator && ( MatcherBase const& other ) const {
+            return MatchAllOf<ComparatorT>() && *this && other;
+        }
+        template<typename ObjectT, typename ComparatorT>
+        MatchAnyOf<ComparatorT> MatcherBase<ObjectT, ComparatorT>::operator || ( MatcherBase const& other ) const {
+            return MatchAnyOf<ComparatorT>() || *this || other;
+        }
+        template<typename ObjectT, typename ComparatorT>
+        MatchNotOf<ComparatorT> MatcherBase<ObjectT, ComparatorT>::operator ! () const {
+            return MatchNotOf<ComparatorT>( *this );
+        }
+
+    } // namespace Impl
+
+    // The following functions create the actual matcher objects.
+    // This allows the types to be inferred
+    // - deprecated: prefer ||, && and !
+    template<typename T>
+    inline Impl::MatchNotOf<T> Not( Impl::MatcherBase<T> const& underlyingMatcher ) {
+        return Impl::MatchNotOf<T>( underlyingMatcher );
+    }
+    template<typename T>
+    inline Impl::MatchAllOf<T> AllOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2 ) {
+        return Impl::MatchAllOf<T>() && m1 && m2;
+    }
+    template<typename T>
+    inline Impl::MatchAllOf<T> AllOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2, Impl::MatcherBase<T> const& m3 ) {
+        return Impl::MatchAllOf<T>() && m1 && m2 && m3;
+    }
+    template<typename T>
+    inline Impl::MatchAnyOf<T> AnyOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2 ) {
+        return Impl::MatchAnyOf<T>() || m1 || m2;
+    }
+    template<typename T>
+    inline Impl::MatchAnyOf<T> AnyOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2, Impl::MatcherBase<T> const& m3 ) {
+        return Impl::MatchAnyOf<T>() || m1 || m2 || m3;
+    }
+
+} // namespace Matchers
+
+using namespace Matchers;
+using Matchers::Impl::MatcherBase;
+
+} // namespace Catch
+
+namespace Catch {
+
+    struct TestFailureException{};
+
+    template<typename T> class ExpressionLhs;
+
+    struct CopyableStream {
+        CopyableStream() {}
+        CopyableStream( CopyableStream const& other ) {
+            oss << other.oss.str();
+        }
+        CopyableStream& operator=( CopyableStream const& other ) {
+            oss.str(std::string());
+            oss << other.oss.str();
+            return *this;
+        }
+        std::ostringstream oss;
+    };
+
+    class ResultBuilder : public DecomposedExpression {
+    public:
+        ResultBuilder(  char const* macroName,
+                        SourceLineInfo const& lineInfo,
+                        char const* capturedExpression,
+                        ResultDisposition::Flags resultDisposition,
+                        char const* secondArg = "" );
+        ~ResultBuilder();
+
+        template<typename T>
+        ExpressionLhs<T const&> operator <= ( T const& operand );
+        ExpressionLhs<bool> operator <= ( bool value );
+
+        template<typename T>
+        ResultBuilder& operator << ( T const& value ) {
+            m_stream().oss << value;
+            return *this;
+        }
+
+        ResultBuilder& setResultType( ResultWas::OfType result );
+        ResultBuilder& setResultType( bool result );
+
+        void endExpression( DecomposedExpression const& expr );
+
+        virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE;
+
+        AssertionResult build() const;
+        AssertionResult build( DecomposedExpression const& expr ) const;
+
+        void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );
+        void captureResult( ResultWas::OfType resultType );
+        void captureExpression();
+        void captureExpectedException( std::string const& expectedMessage );
+        void captureExpectedException( Matchers::Impl::MatcherBase<std::string> const& matcher );
+        void handleResult( AssertionResult const& result );
+        void react();
+        bool shouldDebugBreak() const;
+        bool allowThrows() const;
+
+        template<typename ArgT, typename MatcherT>
+        void captureMatch( ArgT const& arg, MatcherT const& matcher, char const* matcherString );
+
+        void setExceptionGuard();
+        void unsetExceptionGuard();
+
+    private:
+        AssertionInfo m_assertionInfo;
+        AssertionResultData m_data;
+
+        static CopyableStream &m_stream()
+        {
+            static CopyableStream s;
+            return s;
+        }
+
+        bool m_shouldDebugBreak;
+        bool m_shouldThrow;
+        bool m_guardException;
+    };
+
+} // namespace Catch
+
+// Include after due to circular dependency:
+// #included from: catch_expression_lhs.hpp
+#define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED
+
+// #included from: catch_evaluate.hpp
+#define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
+#pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)
+#endif
+
+#include <cstddef>
+
+namespace Catch {
+namespace Internal {
+
+    enum Operator {
+        IsEqualTo,
+        IsNotEqualTo,
+        IsLessThan,
+        IsGreaterThan,
+        IsLessThanOrEqualTo,
+        IsGreaterThanOrEqualTo
+    };
+
+    template<Operator Op> struct OperatorTraits             { static const char* getName(){ return "*error*"; } };
+    template<> struct OperatorTraits<IsEqualTo>             { static const char* getName(){ return "=="; } };
+    template<> struct OperatorTraits<IsNotEqualTo>          { static const char* getName(){ return "!="; } };
+    template<> struct OperatorTraits<IsLessThan>            { static const char* getName(){ return "<"; } };
+    template<> struct OperatorTraits<IsGreaterThan>         { static const char* getName(){ return ">"; } };
+    template<> struct OperatorTraits<IsLessThanOrEqualTo>   { static const char* getName(){ return "<="; } };
+    template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
+
+    template<typename T>
+    inline T& opCast(T const& t) { return const_cast<T&>(t); }
+
+// nullptr_t support based on pull request #154 from Konstantin Baumann
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+    inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
+#endif // CATCH_CONFIG_CPP11_NULLPTR
+
+    // So the compare overloads can be operator agnostic we convey the operator as a template
+    // enum, which is used to specialise an Evaluator for doing the comparison.
+    template<typename T1, typename T2, Operator Op>
+    class Evaluator{};
+
+    template<typename T1, typename T2>
+    struct Evaluator<T1, T2, IsEqualTo> {
+        static bool evaluate( T1 const& lhs, T2 const& rhs) {
+            return bool( opCast( lhs ) ==  opCast( rhs ) );
+        }
+    };
+    template<typename T1, typename T2>
+    struct Evaluator<T1, T2, IsNotEqualTo> {
+        static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+            return bool( opCast( lhs ) != opCast( rhs ) );
+        }
+    };
+    template<typename T1, typename T2>
+    struct Evaluator<T1, T2, IsLessThan> {
+        static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+            return bool( opCast( lhs ) < opCast( rhs ) );
+        }
+    };
+    template<typename T1, typename T2>
+    struct Evaluator<T1, T2, IsGreaterThan> {
+        static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+            return bool( opCast( lhs ) > opCast( rhs ) );
+        }
+    };
+    template<typename T1, typename T2>
+    struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
+        static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+            return bool( opCast( lhs ) >= opCast( rhs ) );
+        }
+    };
+    template<typename T1, typename T2>
+    struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
+        static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+            return bool( opCast( lhs ) <= opCast( rhs ) );
+        }
+    };
+
+    template<Operator Op, typename T1, typename T2>
+    bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {
+        return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
+    }
+
+    // This level of indirection allows us to specialise for integer types
+    // to avoid signed/ unsigned warnings
+
+    // "base" overload
+    template<Operator Op, typename T1, typename T2>
+    bool compare( T1 const& lhs, T2 const& rhs ) {
+        return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
+    }
+
+    // unsigned X to int
+    template<Operator Op> bool compare( unsigned int lhs, int rhs ) {
+        return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
+    }
+    template<Operator Op> bool compare( unsigned long lhs, int rhs ) {
+        return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
+    }
+    template<Operator Op> bool compare( unsigned char lhs, int rhs ) {
+        return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
+    }
+
+    // unsigned X to long
+    template<Operator Op> bool compare( unsigned int lhs, long rhs ) {
+        return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
+    }
+    template<Operator Op> bool compare( unsigned long lhs, long rhs ) {
+        return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
+    }
+    template<Operator Op> bool compare( unsigned char lhs, long rhs ) {
+        return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
+    }
+
+    // int to unsigned X
+    template<Operator Op> bool compare( int lhs, unsigned int rhs ) {
+        return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
+    }
+    template<Operator Op> bool compare( int lhs, unsigned long rhs ) {
+        return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
+    }
+    template<Operator Op> bool compare( int lhs, unsigned char rhs ) {
+        return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
+    }
+
+    // long to unsigned X
+    template<Operator Op> bool compare( long lhs, unsigned int rhs ) {
+        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+    }
+    template<Operator Op> bool compare( long lhs, unsigned long rhs ) {
+        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+    }
+    template<Operator Op> bool compare( long lhs, unsigned char rhs ) {
+        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+    }
+
+    // pointer to long (when comparing against NULL)
+    template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {
+        return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
+    }
+    template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {
+        return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
+    }
+
+    // pointer to int (when comparing against NULL)
+    template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {
+        return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
+    }
+    template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {
+        return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
+    }
+
+#ifdef CATCH_CONFIG_CPP11_LONG_LONG
+    // long long to unsigned X
+    template<Operator Op> bool compare( long long lhs, unsigned int rhs ) {
+        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+    }
+    template<Operator Op> bool compare( long long lhs, unsigned long rhs ) {
+        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+    }
+    template<Operator Op> bool compare( long long lhs, unsigned long long rhs ) {
+        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+    }
+    template<Operator Op> bool compare( long long lhs, unsigned char rhs ) {
+        return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+    }
+
+    // unsigned long long to X
+    template<Operator Op> bool compare( unsigned long long lhs, int rhs ) {
+        return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
+    }
+    template<Operator Op> bool compare( unsigned long long lhs, long rhs ) {
+        return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
+    }
+    template<Operator Op> bool compare( unsigned long long lhs, long long rhs ) {
+        return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
+    }
+    template<Operator Op> bool compare( unsigned long long lhs, char rhs ) {
+        return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
+    }
+
+    // pointer to long long (when comparing against NULL)
+    template<Operator Op, typename T> bool compare( long long lhs, T* rhs ) {
+        return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
+    }
+    template<Operator Op, typename T> bool compare( T* lhs, long long rhs ) {
+        return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
+    }
+#endif // CATCH_CONFIG_CPP11_LONG_LONG
+
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+    // pointer to nullptr_t (when comparing against nullptr)
+    template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
+        return Evaluator<T*, T*, Op>::evaluate( nullptr, rhs );
+    }
+    template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {
+        return Evaluator<T*, T*, Op>::evaluate( lhs, nullptr );
+    }
+#endif // CATCH_CONFIG_CPP11_NULLPTR
+
+} // end of namespace Internal
+} // end of namespace Catch
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+// #included from: catch_tostring.h
+#define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED
+
+#include <sstream>
+#include <iomanip>
+#include <limits>
+#include <vector>
+#include <cstddef>
+
+#ifdef __OBJC__
+// #included from: catch_objc_arc.hpp
+#define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED
+
+#import <Foundation/Foundation.h>
+
+#ifdef __has_feature
+#define CATCH_ARC_ENABLED __has_feature(objc_arc)
+#else
+#define CATCH_ARC_ENABLED 0
+#endif
+
+void arcSafeRelease( NSObject* obj );
+id performOptionalSelector( id obj, SEL sel );
+
+#if !CATCH_ARC_ENABLED
+inline void arcSafeRelease( NSObject* obj ) {
+    [obj release];
+}
+inline id performOptionalSelector( id obj, SEL sel ) {
+    if( [obj respondsToSelector: sel] )
+        return [obj performSelector: sel];
+    return nil;
+}
+#define CATCH_UNSAFE_UNRETAINED
+#define CATCH_ARC_STRONG
+#else
+inline void arcSafeRelease( NSObject* ){}
+inline id performOptionalSelector( id obj, SEL sel ) {
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
+#endif
+    if( [obj respondsToSelector: sel] )
+        return [obj performSelector: sel];
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+    return nil;
+}
+#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
+#define CATCH_ARC_STRONG __strong
+#endif
+
+#endif
+
+#ifdef CATCH_CONFIG_CPP11_TUPLE
+#include <tuple>
+#endif
+
+#ifdef CATCH_CONFIG_CPP11_IS_ENUM
+#include <type_traits>
+#endif
+
+namespace Catch {
+
+// Why we're here.
+template<typename T>
+std::string toString( T const& value );
+
+// Built in overloads
+
+std::string toString( std::string const& value );
+std::string toString( std::wstring const& value );
+std::string toString( const char* const value );
+std::string toString( char* const value );
+std::string toString( const wchar_t* const value );
+std::string toString( wchar_t* const value );
+std::string toString( int value );
+std::string toString( unsigned long value );
+std::string toString( unsigned int value );
+std::string toString( const double value );
+std::string toString( const float value );
+std::string toString( bool value );
+std::string toString( char value );
+std::string toString( signed char value );
+std::string toString( unsigned char value );
+
+#ifdef CATCH_CONFIG_CPP11_LONG_LONG
+std::string toString( long long value );
+std::string toString( unsigned long long value );
+#endif
+
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+std::string toString( std::nullptr_t );
+#endif
+
+#ifdef __OBJC__
+    std::string toString( NSString const * const& nsstring );
+    std::string toString( NSString * CATCH_ARC_STRONG & nsstring );
+    std::string toString( NSObject* const& nsObject );
+#endif
+
+namespace Detail {
+
+    extern const std::string unprintableString;
+
+ #if !defined(CATCH_CONFIG_CPP11_STREAM_INSERTABLE_CHECK)
+    struct BorgType {
+        template<typename T> BorgType( T const& );
+    };
+
+    struct TrueType { char sizer[1]; };
+    struct FalseType { char sizer[2]; };
+
+    TrueType& testStreamable( std::ostream& );
+    FalseType testStreamable( FalseType );
+
+    FalseType operator<<( std::ostream const&, BorgType const& );
+
+    template<typename T>
+    struct IsStreamInsertable {
+        static std::ostream &s;
+        static T  const&t;
+        enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };
+    };
+#else
+    template<typename T>
+    class IsStreamInsertable {
+        template<typename SS, typename TT>
+        static auto test(int)
+        -> decltype( std::declval<SS&>() << std::declval<TT>(), std::true_type() );
+
+        template<typename, typename>
+        static auto test(...) -> std::false_type;
+
+    public:
+        static const bool value = decltype(test<std::ostream,const T&>(0))::value;
+    };
+#endif
+
+#if defined(CATCH_CONFIG_CPP11_IS_ENUM)
+    template<typename T,
+             bool IsEnum = std::is_enum<T>::value
+             >
+    struct EnumStringMaker
+    {
+        static std::string convert( T const& ) { return unprintableString; }
+    };
+
+    template<typename T>
+    struct EnumStringMaker<T,true>
+    {
+        static std::string convert( T const& v )
+        {
+            return ::Catch::toString(
+                static_cast<typename std::underlying_type<T>::type>(v)
+                );
+        }
+    };
+#endif
+    template<bool C>
+    struct StringMakerBase {
+#if defined(CATCH_CONFIG_CPP11_IS_ENUM)
+        template<typename T>
+        static std::string convert( T const& v )
+        {
+            return EnumStringMaker<T>::convert( v );
+        }
+#else
+        template<typename T>
+        static std::string convert( T const& ) { return unprintableString; }
+#endif
+    };
+
+    template<>
+    struct StringMakerBase<true> {
+        template<typename T>
+        static std::string convert( T const& _value ) {
+            std::ostringstream oss;
+            oss << _value;
+            return oss.str();
+        }
+    };
+
+    std::string rawMemoryToString( const void *object, std::size_t size );
+
+    template<typename T>
+    inline std::string rawMemoryToString( const T& object ) {
+      return rawMemoryToString( &object, sizeof(object) );
+    }
+
+} // end namespace Detail
+
+template<typename T>
+struct StringMaker :
+    Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {};
+
+template<typename T>
+struct StringMaker<T*> {
+    template<typename U>
+    static std::string convert( U* p ) {
+        if( !p )
+            return "NULL";
+        else
+            return Detail::rawMemoryToString( p );
+    }
+};
+
+template<typename R, typename C>
+struct StringMaker<R C::*> {
+    static std::string convert( R C::* p ) {
+        if( !p )
+            return "NULL";
+        else
+            return Detail::rawMemoryToString( p );
+    }
+};
+
+namespace Detail {
+    template<typename InputIterator>
+    std::string rangeToString( InputIterator first, InputIterator last );
+}
+
+//template<typename T, typename Allocator>
+//struct StringMaker<std::vector<T, Allocator> > {
+//    static std::string convert( std::vector<T,Allocator> const& v ) {
+//        return Detail::rangeToString( v.begin(), v.end() );
+//    }
+//};
+
+template<typename T, typename Allocator>
+std::string toString( std::vector<T,Allocator> const& v ) {
+    return Detail::rangeToString( v.begin(), v.end() );
+}
+
+#ifdef CATCH_CONFIG_CPP11_TUPLE
+
+// toString for tuples
+namespace TupleDetail {
+  template<
+      typename Tuple,
+      std::size_t N = 0,
+      bool = (N < std::tuple_size<Tuple>::value)
+      >
+  struct ElementPrinter {
+      static void print( const Tuple& tuple, std::ostream& os )
+      {
+          os << ( N ? ", " : " " )
+             << Catch::toString(std::get<N>(tuple));
+          ElementPrinter<Tuple,N+1>::print(tuple,os);
+      }
+  };
+
+  template<
+      typename Tuple,
+      std::size_t N
+      >
+  struct ElementPrinter<Tuple,N,false> {
+      static void print( const Tuple&, std::ostream& ) {}
+  };
+
+}
+
+template<typename ...Types>
+struct StringMaker<std::tuple<Types...>> {
+
+    static std::string convert( const std::tuple<Types...>& tuple )
+    {
+        std::ostringstream os;
+        os << '{';
+        TupleDetail::ElementPrinter<std::tuple<Types...>>::print( tuple, os );
+        os << " }";
+        return os.str();
+    }
+};
+#endif // CATCH_CONFIG_CPP11_TUPLE
+
+namespace Detail {
+    template<typename T>
+    std::string makeString( T const& value ) {
+        return StringMaker<T>::convert( value );
+    }
+} // end namespace Detail
+
+/// \brief converts any type to a string
+///
+/// The default template forwards on to ostringstream - except when an
+/// ostringstream overload does not exist - in which case it attempts to detect
+/// that and writes {?}.
+/// Overload (not specialise) this template for custom typs that you don't want
+/// to provide an ostream overload for.
+template<typename T>
+std::string toString( T const& value ) {
+    return StringMaker<T>::convert( value );
+}
+
+    namespace Detail {
+    template<typename InputIterator>
+    std::string rangeToString( InputIterator first, InputIterator last ) {
+        std::ostringstream oss;
+        oss << "{ ";
+        if( first != last ) {
+            oss << Catch::toString( *first );
+            for( ++first ; first != last ; ++first )
+                oss << ", " << Catch::toString( *first );
+        }
+        oss << " }";
+        return oss.str();
+    }
+}
+
+} // end namespace Catch
+
+namespace Catch {
+
+template<typename LhsT, Internal::Operator Op, typename RhsT>
+class BinaryExpression;
+
+template<typename ArgT, typename MatcherT>
+class MatchExpression;
+
+// Wraps the LHS of an expression and overloads comparison operators
+// for also capturing those and RHS (if any)
+template<typename T>
+class ExpressionLhs : public DecomposedExpression {
+public:
+    ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ), m_truthy(false) {}
+
+    ExpressionLhs& operator = ( const ExpressionLhs& );
+
+    template<typename RhsT>
+    BinaryExpression<T, Internal::IsEqualTo, RhsT const&>
+    operator == ( RhsT const& rhs ) {
+        return captureExpression<Internal::IsEqualTo>( rhs );
+    }
+
+    template<typename RhsT>
+    BinaryExpression<T, Internal::IsNotEqualTo, RhsT const&>
+    operator != ( RhsT const& rhs ) {
+        return captureExpression<Internal::IsNotEqualTo>( rhs );
+    }
+
+    template<typename RhsT>
+    BinaryExpression<T, Internal::IsLessThan, RhsT const&>
+    operator < ( RhsT const& rhs ) {
+        return captureExpression<Internal::IsLessThan>( rhs );
+    }
+
+    template<typename RhsT>
+    BinaryExpression<T, Internal::IsGreaterThan, RhsT const&>
+    operator > ( RhsT const& rhs ) {
+        return captureExpression<Internal::IsGreaterThan>( rhs );
+    }
+
+    template<typename RhsT>
+    BinaryExpression<T, Internal::IsLessThanOrEqualTo, RhsT const&>
+    operator <= ( RhsT const& rhs ) {
+        return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
+    }
+
+    template<typename RhsT>
+    BinaryExpression<T, Internal::IsGreaterThanOrEqualTo, RhsT const&>
+    operator >= ( RhsT const& rhs ) {
+        return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
+    }
+
+    BinaryExpression<T, Internal::IsEqualTo, bool> operator == ( bool rhs ) {
+        return captureExpression<Internal::IsEqualTo>( rhs );
+    }
+
+    BinaryExpression<T, Internal::IsNotEqualTo, bool> operator != ( bool rhs ) {
+        return captureExpression<Internal::IsNotEqualTo>( rhs );
+    }
+
+    void endExpression() {
+        m_truthy = m_lhs ? true : false;
+        m_rb
+            .setResultType( m_truthy )
+            .endExpression( *this );
+    }
+
+    virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE {
+        dest = Catch::toString( m_lhs );
+    }
+
+private:
+    template<Internal::Operator Op, typename RhsT>
+    BinaryExpression<T, Op, RhsT&> captureExpression( RhsT& rhs ) const {
+        return BinaryExpression<T, Op, RhsT&>( m_rb, m_lhs, rhs );
+    }
+
+    template<Internal::Operator Op>
+    BinaryExpression<T, Op, bool> captureExpression( bool rhs ) const {
+        return BinaryExpression<T, Op, bool>( m_rb, m_lhs, rhs );
+    }
+
+private:
+    ResultBuilder& m_rb;
+    T m_lhs;
+    bool m_truthy;
+};
+
+template<typename LhsT, Internal::Operator Op, typename RhsT>
+class BinaryExpression : public DecomposedExpression {
+public:
+    BinaryExpression( ResultBuilder& rb, LhsT lhs, RhsT rhs )
+        : m_rb( rb ), m_lhs( lhs ), m_rhs( rhs ) {}
+
+    BinaryExpression& operator = ( BinaryExpression& );
+
+    void endExpression() const {
+        m_rb
+            .setResultType( Internal::compare<Op>( m_lhs, m_rhs ) )
+            .endExpression( *this );
+    }
+
+    virtual bool isBinaryExpression() const CATCH_OVERRIDE {
+        return true;
+    }
+
+    virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE {
+        std::string lhs = Catch::toString( m_lhs );
+        std::string rhs = Catch::toString( m_rhs );
+        char delim = lhs.size() + rhs.size() < 40 &&
+                     lhs.find('\n') == std::string::npos &&
+                     rhs.find('\n') == std::string::npos ? ' ' : '\n';
+        dest.reserve( 7 + lhs.size() + rhs.size() );
+                   // 2 for spaces around operator
+                   // 2 for operator
+                   // 2 for parentheses (conditionally added later)
+                   // 1 for negation (conditionally added later)
+        dest = lhs;
+        dest += delim;
+        dest += Internal::OperatorTraits<Op>::getName();
+        dest += delim;
+        dest += rhs;
+    }
+
+private:
+    ResultBuilder& m_rb;
+    LhsT m_lhs;
+    RhsT m_rhs;
+};
+
+template<typename ArgT, typename MatcherT>
+class MatchExpression : public DecomposedExpression {
+public:
+    MatchExpression( ArgT arg, MatcherT matcher, char const* matcherString )
+        : m_arg( arg ), m_matcher( matcher ), m_matcherString( matcherString ) {}
+
+    virtual bool isBinaryExpression() const CATCH_OVERRIDE {
+        return true;
+    }
+
+    virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE {
+        std::string matcherAsString = m_matcher.toString();
+        dest = Catch::toString( m_arg );
+        dest += ' ';
+        if( matcherAsString == Detail::unprintableString )
+            dest += m_matcherString;
+        else
+            dest += matcherAsString;
+    }
+
+private:
+    ArgT m_arg;
+    MatcherT m_matcher;
+    char const* m_matcherString;
+};
+
+} // end namespace Catch
+
+
+namespace Catch {
+
+    template<typename T>
+    inline ExpressionLhs<T const&> ResultBuilder::operator <= ( T const& operand ) {
+        return ExpressionLhs<T const&>( *this, operand );
+    }
+
+    inline ExpressionLhs<bool> ResultBuilder::operator <= ( bool value ) {
+        return ExpressionLhs<bool>( *this, value );
+    }
+
+    template<typename ArgT, typename MatcherT>
+    inline void ResultBuilder::captureMatch( ArgT const& arg, MatcherT const& matcher,
+                                             char const* matcherString ) {
+        MatchExpression<ArgT const&, MatcherT const&> expr( arg, matcher, matcherString );
+        setResultType( matcher.match( arg ) );
+        endExpression( expr );
+    }
+
+} // namespace Catch
+
+// #included from: catch_message.h
+#define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+    struct MessageInfo {
+        MessageInfo(    std::string const& _macroName,
+                        SourceLineInfo const& _lineInfo,
+                        ResultWas::OfType _type );
+
+        std::string macroName;
+        SourceLineInfo lineInfo;
+        ResultWas::OfType type;
+        std::string message;
+        unsigned int sequence;
+
+        bool operator == ( MessageInfo const& other ) const {
+            return sequence == other.sequence;
+        }
+        bool operator < ( MessageInfo const& other ) const {
+            return sequence < other.sequence;
+        }
+    private:
+        static unsigned int globalCount;
+    };
+
+    struct MessageBuilder {
+        MessageBuilder( std::string const& macroName,
+                        SourceLineInfo const& lineInfo,
+                        ResultWas::OfType type )
+        : m_info( macroName, lineInfo, type )
+        {}
+
+        template<typename T>
+        MessageBuilder& operator << ( T const& value ) {
+            m_stream << value;
+            return *this;
+        }
+
+        MessageInfo m_info;
+        std::ostringstream m_stream;
+    };
+
+    class ScopedMessage {
+    public:
+        ScopedMessage( MessageBuilder const& builder );
+        ScopedMessage( ScopedMessage const& other );
+        ~ScopedMessage();
+
+        MessageInfo m_info;
+    };
+
+} // end namespace Catch
+
+// #included from: catch_interfaces_capture.h
+#define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+    class TestCase;
+    class AssertionResult;
+    struct AssertionInfo;
+    struct SectionInfo;
+    struct SectionEndInfo;
+    struct MessageInfo;
+    class ScopedMessageBuilder;
+    struct Counts;
+
+    struct IResultCapture {
+
+        virtual ~IResultCapture();
+
+        virtual void assertionEnded( AssertionResult const& result ) = 0;
+        virtual bool sectionStarted(    SectionInfo const& sectionInfo,
+                                        Counts& assertions ) = 0;
+        virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
+        virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
+        virtual void pushScopedMessage( MessageInfo const& message ) = 0;
+        virtual void popScopedMessage( MessageInfo const& message ) = 0;
+
+        virtual std::string getCurrentTestName() const = 0;
+        virtual const AssertionResult* getLastResult() const = 0;
+
+        virtual void exceptionEarlyReported() = 0;
+
+        virtual void handleFatalErrorCondition( std::string const& message ) = 0;
+    };
+
+    IResultCapture& getResultCapture();
+}
+
+// #included from: catch_debugger.h
+#define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
+
+// #included from: catch_platform.h
+#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
+
+#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
+#  define CATCH_PLATFORM_MAC
+#elif  defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
+#  define CATCH_PLATFORM_IPHONE
+#elif defined(linux) || defined(__linux) || defined(__linux__)
+#  define CATCH_PLATFORM_LINUX
+#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
+#  define CATCH_PLATFORM_WINDOWS
+#  if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)
+#    define CATCH_DEFINES_NOMINMAX
+#  endif
+#  if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)
+#    define CATCH_DEFINES_WIN32_LEAN_AND_MEAN
+#  endif
+#endif
+
+#include <string>
+
+namespace Catch{
+
+    bool isDebuggerActive();
+    void writeToDebugConsole( std::string const& text );
+}
+
+#ifdef CATCH_PLATFORM_MAC
+
+    // The following code snippet based on:
+    // http://cocoawithlove.com/2008/03/break-into-debugger.html
+    #if defined(__ppc64__) || defined(__ppc__)
+        #define CATCH_TRAP() \
+                __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
+                : : : "memory","r0","r3","r4" )
+    #else
+        #define CATCH_TRAP() __asm__("int $3\n" : : )
+    #endif
+
+#elif defined(CATCH_PLATFORM_LINUX)
+    // If we can use inline assembler, do it because this allows us to break
+    // directly at the location of the failing check instead of breaking inside
+    // raise() called from it, i.e. one stack frame below.
+    #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
+        #define CATCH_TRAP() asm volatile ("int $3")
+    #else // Fall back to the generic way.
+        #include <signal.h>
+
+        #define CATCH_TRAP() raise(SIGTRAP)
+    #endif
+#elif defined(_MSC_VER)
+    #define CATCH_TRAP() __debugbreak()
+#elif defined(__MINGW32__)
+    extern "C" __declspec(dllimport) void __stdcall DebugBreak();
+    #define CATCH_TRAP() DebugBreak()
+#endif
+
+#ifdef CATCH_TRAP
+    #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); }
+#else
+    #define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
+#endif
+
+// #included from: catch_interfaces_runner.h
+#define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED
+
+namespace Catch {
+    class TestCase;
+
+    struct IRunner {
+        virtual ~IRunner();
+        virtual bool aborting() const = 0;
+    };
+}
+
+#if defined(CATCH_CONFIG_FAST_COMPILE)
+///////////////////////////////////////////////////////////////////////////////
+// We can speedup compilation significantly by breaking into debugger lower in
+// the callstack, because then we don't have to expand CATCH_BREAK_INTO_DEBUGGER
+// macro in each assertion
+#define INTERNAL_CATCH_REACT( resultBuilder ) \
+    resultBuilder.react();
+
+///////////////////////////////////////////////////////////////////////////////
+// Another way to speed-up compilation is to omit local try-catch for REQUIRE*
+// macros.
+// This can potentially cause false negative, if the test code catches
+// the exception before it propagates back up to the runner.
+#define INTERNAL_CATCH_TEST_NO_TRY( macroName, resultDisposition, expr ) \
+    do { \
+        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
+        __catchResult.setExceptionGuard(); \
+        CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
+        ( __catchResult <= expr ).endExpression(); \
+        CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
+        __catchResult.unsetExceptionGuard(); \
+        INTERNAL_CATCH_REACT( __catchResult ) \
+    } while( Catch::isTrue( false && static_cast<bool>( !!(expr) ) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
+// The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
+
+#define INTERNAL_CHECK_THAT_NO_TRY( macroName, matcher, resultDisposition, arg ) \
+    do { \
+        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \
+        __catchResult.setExceptionGuard(); \
+        __catchResult.captureMatch( arg, matcher, #matcher ); \
+        __catchResult.unsetExceptionGuard(); \
+        INTERNAL_CATCH_REACT( __catchResult ) \
+    } while( Catch::alwaysFalse() )
+
+#else
+///////////////////////////////////////////////////////////////////////////////
+// In the event of a failure works out if the debugger needs to be invoked
+// and/or an exception thrown and takes appropriate action.
+// This needs to be done as a macro so the debugger will stop in the user
+// source code rather than in Catch library code
+#define INTERNAL_CATCH_REACT( resultBuilder ) \
+    if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
+    resultBuilder.react();
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ) \
+    do { \
+        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
+        try { \
+            CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
+            ( __catchResult <= expr ).endExpression(); \
+            CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
+        } \
+        catch( ... ) { \
+            __catchResult.useActiveException( resultDisposition ); \
+        } \
+        INTERNAL_CATCH_REACT( __catchResult ) \
+    } while( Catch::isTrue( false && static_cast<bool>( !!(expr) ) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
+    // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_IF( macroName, resultDisposition, expr ) \
+    INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \
+    if( Catch::getResultCapture().getLastResult()->succeeded() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_ELSE( macroName, resultDisposition, expr ) \
+    INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \
+    if( !Catch::getResultCapture().getLastResult()->succeeded() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, expr ) \
+    do { \
+        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
+        try { \
+            static_cast<void>(expr); \
+            __catchResult.captureResult( Catch::ResultWas::Ok ); \
+        } \
+        catch( ... ) { \
+            __catchResult.useActiveException( resultDisposition ); \
+        } \
+        INTERNAL_CATCH_REACT( __catchResult ) \
+    } while( Catch::alwaysFalse() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_THROWS( macroName, resultDisposition, matcher, expr ) \
+    do { \
+        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition, #matcher ); \
+        if( __catchResult.allowThrows() ) \
+            try { \
+                static_cast<void>(expr); \
+                __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
+            } \
+            catch( ... ) { \
+                __catchResult.captureExpectedException( matcher ); \
+            } \
+        else \
+            __catchResult.captureResult( Catch::ResultWas::Ok ); \
+        INTERNAL_CATCH_REACT( __catchResult ) \
+    } while( Catch::alwaysFalse() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
+    do { \
+        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr ", " #exceptionType, resultDisposition ); \
+        if( __catchResult.allowThrows() ) \
+            try { \
+                static_cast<void>(expr); \
+                __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
+            } \
+            catch( exceptionType ) { \
+                __catchResult.captureResult( Catch::ResultWas::Ok ); \
+            } \
+            catch( ... ) { \
+                __catchResult.useActiveException( resultDisposition ); \
+            } \
+        else \
+            __catchResult.captureResult( Catch::ResultWas::Ok ); \
+        INTERNAL_CATCH_REACT( __catchResult ) \
+    } while( Catch::alwaysFalse() )
+
+///////////////////////////////////////////////////////////////////////////////
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+    #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
+        do { \
+            Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
+            __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \
+            __catchResult.captureResult( messageType ); \
+            INTERNAL_CATCH_REACT( __catchResult ) \
+        } while( Catch::alwaysFalse() )
+#else
+    #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, log ) \
+        do { \
+            Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
+            __catchResult << log + ::Catch::StreamEndStop(); \
+            __catchResult.captureResult( messageType ); \
+            INTERNAL_CATCH_REACT( __catchResult ) \
+        } while( Catch::alwaysFalse() )
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_INFO( macroName, log ) \
+    Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
+    do { \
+        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \
+        try { \
+            __catchResult.captureMatch( arg, matcher, #matcher ); \
+        } catch( ... ) { \
+            __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
+        } \
+        INTERNAL_CATCH_REACT( __catchResult ) \
+    } while( Catch::alwaysFalse() )
+
+// #included from: internal/catch_section.h
+#define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
+
+// #included from: catch_section_info.h
+#define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED
+
+// #included from: catch_totals.hpp
+#define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED
+
+#include <cstddef>
+
+namespace Catch {
+
+    struct Counts {
+        Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {}
+
+        Counts operator - ( Counts const& other ) const {
+            Counts diff;
+            diff.passed = passed - other.passed;
+            diff.failed = failed - other.failed;
+            diff.failedButOk = failedButOk - other.failedButOk;
+            return diff;
+        }
+        Counts& operator += ( Counts const& other ) {
+            passed += other.passed;
+            failed += other.failed;
+            failedButOk += other.failedButOk;
+            return *this;
+        }
+
+        std::size_t total() const {
+            return passed + failed + failedButOk;
+        }
+        bool allPassed() const {
+            return failed == 0 && failedButOk == 0;
+        }
+        bool allOk() const {
+            return failed == 0;
+        }
+
+        std::size_t passed;
+        std::size_t failed;
+        std::size_t failedButOk;
+    };
+
+    struct Totals {
+
+        Totals operator - ( Totals const& other ) const {
+            Totals diff;
+            diff.assertions = assertions - other.assertions;
+            diff.testCases = testCases - other.testCases;
+            return diff;
+        }
+
+        Totals delta( Totals const& prevTotals ) const {
+            Totals diff = *this - prevTotals;
+            if( diff.assertions.failed > 0 )
+                ++diff.testCases.failed;
+            else if( diff.assertions.failedButOk > 0 )
+                ++diff.testCases.failedButOk;
+            else
+                ++diff.testCases.passed;
+            return diff;
+        }
+
+        Totals& operator += ( Totals const& other ) {
+            assertions += other.assertions;
+            testCases += other.testCases;
+            return *this;
+        }
+
+        Counts assertions;
+        Counts testCases;
+    };
+}
+
+#include <string>
+
+namespace Catch {
+
+    struct SectionInfo {
+        SectionInfo
+            (   SourceLineInfo const& _lineInfo,
+                std::string const& _name,
+                std::string const& _description = std::string() );
+
+        std::string name;
+        std::string description;
+        SourceLineInfo lineInfo;
+    };
+
+    struct SectionEndInfo {
+        SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds )
+        : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
+        {}
+
+        SectionInfo sectionInfo;
+        Counts prevAssertions;
+        double durationInSeconds;
+    };
+
+} // end namespace Catch
+
+// #included from: catch_timer.h
+#define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED
+
+#ifdef _MSC_VER
+
+namespace Catch {
+    typedef unsigned long long UInt64;
+}
+#else
+#include <stdint.h>
+namespace Catch {
+    typedef uint64_t UInt64;
+}
+#endif
+
+namespace Catch {
+    class Timer {
+    public:
+        Timer() : m_ticks( 0 ) {}
+        void start();
+        unsigned int getElapsedMicroseconds() const;
+        unsigned int getElapsedMilliseconds() const;
+        double getElapsedSeconds() const;
+
+    private:
+        UInt64 m_ticks;
+    };
+
+} // namespace Catch
+
+#include <string>
+
+namespace Catch {
+
+    class Section : NonCopyable {
+    public:
+        Section( SectionInfo const& info );
+        ~Section();
+
+        // This indicates whether the section should be executed or not
+        operator bool() const;
+
+    private:
+        SectionInfo m_info;
+
+        std::string m_name;
+        Counts m_assertions;
+        bool m_sectionIncluded;
+        Timer m_timer;
+    };
+
+} // end namespace Catch
+
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+    #define INTERNAL_CATCH_SECTION( ... ) \
+        if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
+#else
+    #define INTERNAL_CATCH_SECTION( name, desc ) \
+        if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) )
+#endif
+
+// #included from: internal/catch_generators.hpp
+#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
+
+#include <vector>
+#include <string>
+#include <stdlib.h>
+
+namespace Catch {
+
+template<typename T>
+struct IGenerator {
+    virtual ~IGenerator() {}
+    virtual T getValue( std::size_t index ) const = 0;
+    virtual std::size_t size () const = 0;
+};
+
+template<typename T>
+class BetweenGenerator : public IGenerator<T> {
+public:
+    BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){}
+
+    virtual T getValue( std::size_t index ) const {
+        return m_from+static_cast<int>( index );
+    }
+
+    virtual std::size_t size() const {
+        return static_cast<std::size_t>( 1+m_to-m_from );
+    }
+
+private:
+
+    T m_from;
+    T m_to;
+};
+
+template<typename T>
+class ValuesGenerator : public IGenerator<T> {
+public:
+    ValuesGenerator(){}
+
+    void add( T value ) {
+        m_values.push_back( value );
+    }
+
+    virtual T getValue( std::size_t index ) const {
+        return m_values[index];
+    }
+
+    virtual std::size_t size() const {
+        return m_values.size();
+    }
+
+private:
+    std::vector<T> m_values;
+};
+
+template<typename T>
+class CompositeGenerator {
+public:
+    CompositeGenerator() : m_totalSize( 0 ) {}
+
+    // *** Move semantics, similar to auto_ptr ***
+    CompositeGenerator( CompositeGenerator& other )
+    :   m_fileInfo( other.m_fileInfo ),
+        m_totalSize( 0 )
+    {
+        move( other );
+    }
+
+    CompositeGenerator& setFileInfo( const char* fileInfo ) {
+        m_fileInfo = fileInfo;
+        return *this;
+    }
+
+    ~CompositeGenerator() {
+        deleteAll( m_composed );
+    }
+
+    operator T () const {
+        size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize );
+
+        typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
+        typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
+        for( size_t index = 0; it != itEnd; ++it )
+        {
+            const IGenerator<T>* generator = *it;
+            if( overallIndex >= index && overallIndex < index + generator->size() )
+            {
+                return generator->getValue( overallIndex-index );
+            }
+            index += generator->size();
+        }
+        CATCH_INTERNAL_ERROR( "Indexed past end of generated range" );
+        return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so
+    }
+
+    void add( const IGenerator<T>* generator ) {
+        m_totalSize += generator->size();
+        m_composed.push_back( generator );
+    }
+
+    CompositeGenerator& then( CompositeGenerator& other ) {
+        move( other );
+        return *this;
+    }
+
+    CompositeGenerator& then( T value ) {
+        ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
+        valuesGen->add( value );
+        add( valuesGen );
+        return *this;
+    }
+
+private:
+
+    void move( CompositeGenerator& other ) {
+        m_composed.insert( m_composed.end(), other.m_composed.begin(), other.m_composed.end() );
+        m_totalSize += other.m_totalSize;
+        other.m_composed.clear();
+    }
+
+    std::vector<const IGenerator<T>*> m_composed;
+    std::string m_fileInfo;
+    size_t m_totalSize;
+};
+
+namespace Generators
+{
+    template<typename T>
+    CompositeGenerator<T> between( T from, T to ) {
+        CompositeGenerator<T> generators;
+        generators.add( new BetweenGenerator<T>( from, to ) );
+        return generators;
+    }
+
+    template<typename T>
+    CompositeGenerator<T> values( T val1, T val2 ) {
+        CompositeGenerator<T> generators;
+        ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
+        valuesGen->add( val1 );
+        valuesGen->add( val2 );
+        generators.add( valuesGen );
+        return generators;
+    }
+
+    template<typename T>
+    CompositeGenerator<T> values( T val1, T val2, T val3 ){
+        CompositeGenerator<T> generators;
+        ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
+        valuesGen->add( val1 );
+        valuesGen->add( val2 );
+        valuesGen->add( val3 );
+        generators.add( valuesGen );
+        return generators;
+    }
+
+    template<typename T>
+    CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) {
+        CompositeGenerator<T> generators;
+        ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
+        valuesGen->add( val1 );
+        valuesGen->add( val2 );
+        valuesGen->add( val3 );
+        valuesGen->add( val4 );
+        generators.add( valuesGen );
+        return generators;
+    }
+
+} // end namespace Generators
+
+using namespace Generators;
+
+} // end namespace Catch
+
+#define INTERNAL_CATCH_LINESTR2( line ) #line
+#define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line )
+
+#define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" )
+
+// #included from: internal/catch_interfaces_exception.h
+#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
+
+#include <string>
+#include <vector>
+
+// #included from: catch_interfaces_registry_hub.h
+#define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+    class TestCase;
+    struct ITestCaseRegistry;
+    struct IExceptionTranslatorRegistry;
+    struct IExceptionTranslator;
+    struct IReporterRegistry;
+    struct IReporterFactory;
+    struct ITagAliasRegistry;
+
+    struct IRegistryHub {
+        virtual ~IRegistryHub();
+
+        virtual IReporterRegistry const& getReporterRegistry() const = 0;
+        virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
+        virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
+
+        virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
+    };
+
+    struct IMutableRegistryHub {
+        virtual ~IMutableRegistryHub();
+        virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) = 0;
+        virtual void registerListener( Ptr<IReporterFactory> const& factory ) = 0;
+        virtual void registerTest( TestCase const& testInfo ) = 0;
+        virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
+        virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;
+    };
+
+    IRegistryHub& getRegistryHub();
+    IMutableRegistryHub& getMutableRegistryHub();
+    void cleanUp();
+    std::string translateActiveException();
+
+}
+
+namespace Catch {
+
+    typedef std::string(*exceptionTranslateFunction)();
+
+    struct IExceptionTranslator;
+    typedef std::vector<const IExceptionTranslator*> ExceptionTranslators;
+
+    struct IExceptionTranslator {
+        virtual ~IExceptionTranslator();
+        virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
+    };
+
+    struct IExceptionTranslatorRegistry {
+        virtual ~IExceptionTranslatorRegistry();
+
+        virtual std::string translateActiveException() const = 0;
+    };
+
+    class ExceptionTranslatorRegistrar {
+        template<typename T>
+        class ExceptionTranslator : public IExceptionTranslator {
+        public:
+
+            ExceptionTranslator( std::string(*translateFunction)( T& ) )
+            : m_translateFunction( translateFunction )
+            {}
+
+            virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE {
+                try {
+                    if( it == itEnd )
+                        throw;
+                    else
+                        return (*it)->translate( it+1, itEnd );
+                }
+                catch( T& ex ) {
+                    return m_translateFunction( ex );
+                }
+            }
+
+        protected:
+            std::string(*m_translateFunction)( T& );
+        };
+
+    public:
+        template<typename T>
+        ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
+            getMutableRegistryHub().registerTranslator
+                ( new ExceptionTranslator<T>( translateFunction ) );
+        }
+    };
+}
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
+    static std::string translatorName( signature ); \
+    namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\
+    static std::string translatorName( signature )
+
+#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
+
+// #included from: internal/catch_approx.hpp
+#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
+
+#include <cmath>
+#include <limits>
+
+#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS)
+#include <type_traits>
+#endif
+
+namespace Catch {
+namespace Detail {
+
+    class Approx {
+    public:
+        explicit Approx ( double value )
+        :   m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
+            m_margin( 0.0 ),
+            m_scale( 1.0 ),
+            m_value( value )
+        {}
+
+        Approx( Approx const& other )
+        :   m_epsilon( other.m_epsilon ),
+            m_margin( other.m_margin ),
+            m_scale( other.m_scale ),
+            m_value( other.m_value )
+        {}
+
+        static Approx custom() {
+            return Approx( 0 );
+        }
+
+#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS)
+
+        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+        Approx operator()( T value ) {
+            Approx approx( static_cast<double>(value) );
+            approx.epsilon( m_epsilon );
+            approx.margin( m_margin );
+            approx.scale( m_scale );
+            return approx;
+        }
+
+        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+        explicit Approx( T value ): Approx(static_cast<double>(value))
+        {}
+
+        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+        friend bool operator == ( const T& lhs, Approx const& rhs ) {
+            // Thanks to Richard Harris for his help refining this formula
+            auto lhs_v = double(lhs);
+            bool relativeOK = std::fabs(lhs_v - rhs.m_value) < rhs.m_epsilon * (rhs.m_scale + (std::max)(std::fabs(lhs_v), std::fabs(rhs.m_value)));
+            if (relativeOK) {
+                return true;
+            }
+            return std::fabs(lhs_v - rhs.m_value) < rhs.m_margin;
+        }
+
+        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+        friend bool operator == ( Approx const& lhs, const T& rhs ) {
+            return operator==( rhs, lhs );
+        }
+
+        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+        friend bool operator != ( T lhs, Approx const& rhs ) {
+            return !operator==( lhs, rhs );
+        }
+
+        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+        friend bool operator != ( Approx const& lhs, T rhs ) {
+            return !operator==( rhs, lhs );
+        }
+
+        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+        friend bool operator <= ( T lhs, Approx const& rhs ) {
+            return double(lhs) < rhs.m_value || lhs == rhs;
+        }
+
+        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+        friend bool operator <= ( Approx const& lhs, T rhs ) {
+            return lhs.m_value < double(rhs) || lhs == rhs;
+        }
+
+        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+        friend bool operator >= ( T lhs, Approx const& rhs ) {
+            return double(lhs) > rhs.m_value || lhs == rhs;
+        }
+
+        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+        friend bool operator >= ( Approx const& lhs, T rhs ) {
+            return lhs.m_value > double(rhs) || lhs == rhs;
+        }
+
+        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+        Approx& epsilon( T newEpsilon ) {
+            m_epsilon = double(newEpsilon);
+            return *this;
+        }
+
+        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+        Approx& margin( T newMargin ) {
+            m_margin = double(newMargin);
+            return *this;
+        }
+
+        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
+        Approx& scale( T newScale ) {
+            m_scale = double(newScale);
+            return *this;
+        }
+
+#else
+
+        Approx operator()( double value ) {
+            Approx approx( value );
+            approx.epsilon( m_epsilon );
+            approx.margin( m_margin );
+            approx.scale( m_scale );
+            return approx;
+        }
+
+        friend bool operator == ( double lhs, Approx const& rhs ) {
+            // Thanks to Richard Harris for his help refining this formula
+            bool relativeOK = std::fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( std::fabs(lhs), std::fabs(rhs.m_value) ) );
+            if (relativeOK) {
+                return true;
+            }
+            return std::fabs(lhs - rhs.m_value) < rhs.m_margin;
+        }
+
+        friend bool operator == ( Approx const& lhs, double rhs ) {
+            return operator==( rhs, lhs );
+        }
+
+        friend bool operator != ( double lhs, Approx const& rhs ) {
+            return !operator==( lhs, rhs );
+        }
+
+        friend bool operator != ( Approx const& lhs, double rhs ) {
+            return !operator==( rhs, lhs );
+        }
+
+        friend bool operator <= ( double lhs, Approx const& rhs ) {
+            return lhs < rhs.m_value || lhs == rhs;
+        }
+
+        friend bool operator <= ( Approx const& lhs, double rhs ) {
+            return lhs.m_value < rhs || lhs == rhs;
+        }
+
+        friend bool operator >= ( double lhs, Approx const& rhs ) {
+            return lhs > rhs.m_value || lhs == rhs;
+        }
+
+        friend bool operator >= ( Approx const& lhs, double rhs ) {
+            return lhs.m_value > rhs || lhs == rhs;
+        }
+
+        Approx& epsilon( double newEpsilon ) {
+            m_epsilon = newEpsilon;
+            return *this;
+        }
+
+        Approx& margin( double newMargin ) {
+            m_margin = newMargin;
+            return *this;
+        }
+
+        Approx& scale( double newScale ) {
+            m_scale = newScale;
+            return *this;
+        }
+#endif
+
+        std::string toString() const {
+            std::ostringstream oss;
+            oss << "Approx( " << Catch::toString( m_value ) << " )";
+            return oss.str();
+        }
+
+    private:
+        double m_epsilon;
+        double m_margin;
+        double m_scale;
+        double m_value;
+    };
+}
+
+template<>
+inline std::string toString<Detail::Approx>( Detail::Approx const& value ) {
+    return value.toString();
+}
+
+} // end namespace Catch
+
+// #included from: internal/catch_matchers_string.h
+#define TWOBLUECUBES_CATCH_MATCHERS_STRING_H_INCLUDED
+
+namespace Catch {
+namespace Matchers {
+
+    namespace StdString {
+
+        struct CasedString
+        {
+            CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity );
+            std::string adjustString( std::string const& str ) const;
+            std::string caseSensitivitySuffix() const;
+
+            CaseSensitive::Choice m_caseSensitivity;
+            std::string m_str;
+        };
+
+        struct StringMatcherBase : MatcherBase<std::string> {
+            StringMatcherBase( std::string const& operation, CasedString const& comparator );
+            virtual std::string describe() const CATCH_OVERRIDE;
+
+            CasedString m_comparator;
+            std::string m_operation;
+        };
+
+        struct EqualsMatcher : StringMatcherBase {
+            EqualsMatcher( CasedString const& comparator );
+            virtual bool match( std::string const& source ) const CATCH_OVERRIDE;
+        };
+        struct ContainsMatcher : StringMatcherBase {
+            ContainsMatcher( CasedString const& comparator );
+            virtual bool match( std::string const& source ) const CATCH_OVERRIDE;
+        };
+        struct StartsWithMatcher : StringMatcherBase {
+            StartsWithMatcher( CasedString const& comparator );
+            virtual bool match( std::string const& source ) const CATCH_OVERRIDE;
+        };
+        struct EndsWithMatcher : StringMatcherBase {
+            EndsWithMatcher( CasedString const& comparator );
+            virtual bool match( std::string const& source ) const CATCH_OVERRIDE;
+        };
+
+    } // namespace StdString
+
+    // The following functions create the actual matcher objects.
+    // This allows the types to be inferred
+
+    StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
+    StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
+    StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
+    StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
+
+} // namespace Matchers
+} // namespace Catch
+
+// #included from: internal/catch_matchers_vector.h
+#define TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED
+
+namespace Catch {
+namespace Matchers {
+
+    namespace Vector {
+
+        template<typename T>
+        struct ContainsElementMatcher : MatcherBase<std::vector<T>, T> {
+
+            ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}
+
+            bool match(std::vector<T> const &v) const CATCH_OVERRIDE {
+                return std::find(v.begin(), v.end(), m_comparator) != v.end();
+            }
+
+            virtual std::string describe() const CATCH_OVERRIDE {
+                return "Contains: " + Catch::toString( m_comparator );
+            }
+
+            T const& m_comparator;
+        };
+
+        template<typename T>
+        struct ContainsMatcher : MatcherBase<std::vector<T>, std::vector<T> > {
+
+            ContainsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
+
+            bool match(std::vector<T> const &v) const CATCH_OVERRIDE {
+                // !TBD: see note in EqualsMatcher
+                if (m_comparator.size() > v.size())
+                    return false;
+                for (size_t i = 0; i < m_comparator.size(); ++i)
+                    if (std::find(v.begin(), v.end(), m_comparator[i]) == v.end())
+                        return false;
+                return true;
+            }
+            virtual std::string describe() const CATCH_OVERRIDE {
+                return "Contains: " + Catch::toString( m_comparator );
+            }
+
+            std::vector<T> const& m_comparator;
+        };
+
+        template<typename T>
+        struct EqualsMatcher : MatcherBase<std::vector<T>, std::vector<T> > {
+
+            EqualsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
+
+            bool match(std::vector<T> const &v) const CATCH_OVERRIDE {
+                // !TBD: This currently works if all elements can be compared using !=
+                // - a more general approach would be via a compare template that defaults
+                // to using !=. but could be specialised for, e.g. std::vector<T> etc
+                // - then just call that directly
+                if (m_comparator.size() != v.size())
+                    return false;
+                for (size_t i = 0; i < v.size(); ++i)
+                    if (m_comparator[i] != v[i])
+                        return false;
+                return true;
+            }
+            virtual std::string describe() const CATCH_OVERRIDE {
+                return "Equals: " + Catch::toString( m_comparator );
+            }
+            std::vector<T> const& m_comparator;
+        };
+
+    } // namespace Vector
+
+    // The following functions create the actual matcher objects.
+    // This allows the types to be inferred
+
+    template<typename T>
+    Vector::ContainsMatcher<T> Contains( std::vector<T> const& comparator ) {
+        return Vector::ContainsMatcher<T>( comparator );
+    }
+
+    template<typename T>
+    Vector::ContainsElementMatcher<T> VectorContains( T const& comparator ) {
+        return Vector::ContainsElementMatcher<T>( comparator );
+    }
+
+    template<typename T>
+    Vector::EqualsMatcher<T> Equals( std::vector<T> const& comparator ) {
+        return Vector::EqualsMatcher<T>( comparator );
+    }
+
+} // namespace Matchers
+} // namespace Catch
+
+// #included from: internal/catch_interfaces_tag_alias_registry.h
+#define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED
+
+// #included from: catch_tag_alias.h
+#define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+    struct TagAlias {
+        TagAlias( std::string const& _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}
+
+        std::string tag;
+        SourceLineInfo lineInfo;
+    };
+
+    struct RegistrarForTagAliases {
+        RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
+    };
+
+} // end namespace Catch
+
+#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); }
+// #included from: catch_option.hpp
+#define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED
+
+namespace Catch {
+
+    // An optional type
+    template<typename T>
+    class Option {
+    public:
+        Option() : nullableValue( CATCH_NULL ) {}
+        Option( T const& _value )
+        : nullableValue( new( storage ) T( _value ) )
+        {}
+        Option( Option const& _other )
+        : nullableValue( _other ? new( storage ) T( *_other ) : CATCH_NULL )
+        {}
+
+        ~Option() {
+            reset();
+        }
+
+        Option& operator= ( Option const& _other ) {
+            if( &_other != this ) {
+                reset();
+                if( _other )
+                    nullableValue = new( storage ) T( *_other );
+            }
+            return *this;
+        }
+        Option& operator = ( T const& _value ) {
+            reset();
+            nullableValue = new( storage ) T( _value );
+            return *this;
+        }
+
+        void reset() {
+            if( nullableValue )
+                nullableValue->~T();
+            nullableValue = CATCH_NULL;
+        }
+
+        T& operator*() { return *nullableValue; }
+        T const& operator*() const { return *nullableValue; }
+        T* operator->() { return nullableValue; }
+        const T* operator->() const { return nullableValue; }
+
+        T valueOr( T const& defaultValue ) const {
+            return nullableValue ? *nullableValue : defaultValue;
+        }
+
+        bool some() const { return nullableValue != CATCH_NULL; }
+        bool none() const { return nullableValue == CATCH_NULL; }
+
+        bool operator !() const { return nullableValue == CATCH_NULL; }
+        operator SafeBool::type() const {
+            return SafeBool::makeSafe( some() );
+        }
+
+    private:
+        T *nullableValue;
+        union {
+            char storage[sizeof(T)];
+
+            // These are here to force alignment for the storage
+            long double dummy1;
+            void (*dummy2)();
+            long double dummy3;
+#ifdef CATCH_CONFIG_CPP11_LONG_LONG
+            long long dummy4;
+#endif
+        };
+    };
+
+} // end namespace Catch
+
+namespace Catch {
+
+    struct ITagAliasRegistry {
+        virtual ~ITagAliasRegistry();
+        virtual Option<TagAlias> find( std::string const& alias ) const = 0;
+        virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
+
+        static ITagAliasRegistry const& get();
+    };
+
+} // end namespace Catch
+
+// These files are included here so the single_include script doesn't put them
+// in the conditionally compiled sections
+// #included from: internal/catch_test_case_info.h
+#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED
+
+#include <string>
+#include <set>
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+namespace Catch {
+
+    struct ITestCase;
+
+    struct TestCaseInfo {
+        enum SpecialProperties{
+            None = 0,
+            IsHidden = 1 << 1,
+            ShouldFail = 1 << 2,
+            MayFail = 1 << 3,
+            Throws = 1 << 4,
+            NonPortable = 1 << 5
+        };
+
+        TestCaseInfo(   std::string const& _name,
+                        std::string const& _className,
+                        std::string const& _description,
+                        std::set<std::string> const& _tags,
+                        SourceLineInfo const& _lineInfo );
+
+        TestCaseInfo( TestCaseInfo const& other );
+
+        friend void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags );
+
+        bool isHidden() const;
+        bool throws() const;
+        bool okToFail() const;
+        bool expectedToFail() const;
+
+        std::string name;
+        std::string className;
+        std::string description;
+        std::set<std::string> tags;
+        std::set<std::string> lcaseTags;
+        std::string tagsAsString;
+        SourceLineInfo lineInfo;
+        SpecialProperties properties;
+    };
+
+    class TestCase : public TestCaseInfo {
+    public:
+
+        TestCase( ITestCase* testCase, TestCaseInfo const& info );
+        TestCase( TestCase const& other );
+
+        TestCase withName( std::string const& _newName ) const;
+
+        void invoke() const;
+
+        TestCaseInfo const& getTestCaseInfo() const;
+
+        void swap( TestCase& other );
+        bool operator == ( TestCase const& other ) const;
+        bool operator < ( TestCase const& other ) const;
+        TestCase& operator = ( TestCase const& other );
+
+    private:
+        Ptr<ITestCase> test;
+    };
+
+    TestCase makeTestCase(  ITestCase* testCase,
+                            std::string const& className,
+                            std::string const& name,
+                            std::string const& description,
+                            SourceLineInfo const& lineInfo );
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+
+#ifdef __OBJC__
+// #included from: internal/catch_objc.hpp
+#define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
+
+#import <objc/runtime.h>
+
+#include <string>
+
+// NB. Any general catch headers included here must be included
+// in catch.hpp first to make sure they are included by the single
+// header for non obj-usage
+
+///////////////////////////////////////////////////////////////////////////////
+// This protocol is really only here for (self) documenting purposes, since
+// all its methods are optional.
+ at protocol OcFixture
+
+ at optional
+
+-(void) setUp;
+-(void) tearDown;
+
+ at end
+
+namespace Catch {
+
+    class OcMethod : public SharedImpl<ITestCase> {
+
+    public:
+        OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
+
+        virtual void invoke() const {
+            id obj = [[m_cls alloc] init];
+
+            performOptionalSelector( obj, @selector(setUp)  );
+            performOptionalSelector( obj, m_sel );
+            performOptionalSelector( obj, @selector(tearDown)  );
+
+            arcSafeRelease( obj );
+        }
+    private:
+        virtual ~OcMethod() {}
+
+        Class m_cls;
+        SEL m_sel;
+    };
+
+    namespace Detail{
+
+        inline std::string getAnnotation(   Class cls,
+                                            std::string const& annotationName,
+                                            std::string const& testCaseName ) {
+            NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
+            SEL sel = NSSelectorFromString( selStr );
+            arcSafeRelease( selStr );
+            id value = performOptionalSelector( cls, sel );
+            if( value )
+                return [(NSString*)value UTF8String];
+            return "";
+        }
+    }
+
+    inline size_t registerTestMethods() {
+        size_t noTestMethods = 0;
+        int noClasses = objc_getClassList( CATCH_NULL, 0 );
+
+        Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
+        objc_getClassList( classes, noClasses );
+
+        for( int c = 0; c < noClasses; c++ ) {
+            Class cls = classes[c];
+            {
+                u_int count;
+                Method* methods = class_copyMethodList( cls, &count );
+                for( u_int m = 0; m < count ; m++ ) {
+                    SEL selector = method_getName(methods[m]);
+                    std::string methodName = sel_getName(selector);
+                    if( startsWith( methodName, "Catch_TestCase_" ) ) {
+                        std::string testCaseName = methodName.substr( 15 );
+                        std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
+                        std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
+                        const char* className = class_getName( cls );
+
+                        getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) );
+                        noTestMethods++;
+                    }
+                }
+                free(methods);
+            }
+        }
+        return noTestMethods;
+    }
+
+    namespace Matchers {
+        namespace Impl {
+        namespace NSStringMatchers {
+
+            struct StringHolder : MatcherBase<NSString*>{
+                StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
+                StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
+                StringHolder() {
+                    arcSafeRelease( m_substr );
+                }
+
+                virtual bool match( NSString* arg ) const CATCH_OVERRIDE {
+                    return false;
+                }
+
+                NSString* m_substr;
+            };
+
+            struct Equals : StringHolder {
+                Equals( NSString* substr ) : StringHolder( substr ){}
+
+                virtual bool match( NSString* str ) const CATCH_OVERRIDE {
+                    return  (str != nil || m_substr == nil ) &&
+                            [str isEqualToString:m_substr];
+                }
+
+                virtual std::string describe() const CATCH_OVERRIDE {
+                    return "equals string: " + Catch::toString( m_substr );
+                }
+            };
+
+            struct Contains : StringHolder {
+                Contains( NSString* substr ) : StringHolder( substr ){}
+
+                virtual bool match( NSString* str ) const {
+                    return  (str != nil || m_substr == nil ) &&
+                            [str rangeOfString:m_substr].location != NSNotFound;
+                }
+
+                virtual std::string describe() const CATCH_OVERRIDE {
+                    return "contains string: " + Catch::toString( m_substr );
+                }
+            };
+
+            struct StartsWith : StringHolder {
+                StartsWith( NSString* substr ) : StringHolder( substr ){}
+
+                virtual bool match( NSString* str ) const {
+                    return  (str != nil || m_substr == nil ) &&
+                            [str rangeOfString:m_substr].location == 0;
+                }
+
+                virtual std::string describe() const CATCH_OVERRIDE {
+                    return "starts with: " + Catch::toString( m_substr );
+                }
+            };
+            struct EndsWith : StringHolder {
+                EndsWith( NSString* substr ) : StringHolder( substr ){}
+
+                virtual bool match( NSString* str ) const {
+                    return  (str != nil || m_substr == nil ) &&
+                            [str rangeOfString:m_substr].location == [str length] - [m_substr length];
+                }
+
+                virtual std::string describe() const CATCH_OVERRIDE {
+                    return "ends with: " + Catch::toString( m_substr );
+                }
+            };
+
+        } // namespace NSStringMatchers
+        } // namespace Impl
+
+        inline Impl::NSStringMatchers::Equals
+            Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
+
+        inline Impl::NSStringMatchers::Contains
+            Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
+
+        inline Impl::NSStringMatchers::StartsWith
+            StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
+
+        inline Impl::NSStringMatchers::EndsWith
+            EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
+
+    } // namespace Matchers
+
+    using namespace Matchers;
+
+} // namespace Catch
+
+///////////////////////////////////////////////////////////////////////////////
+#define OC_TEST_CASE( name, desc )\
++(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
+{\
+return @ name; \
+}\
++(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
+{ \
+return @ desc; \
+} \
+-(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
+
+#endif
+
+#ifdef CATCH_IMPL
+
+// !TBD: Move the leak detector code into a separate header
+#ifdef CATCH_CONFIG_WINDOWS_CRTDBG
+#include <crtdbg.h>
+class LeakDetector {
+public:
+    LeakDetector() {
+        int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
+        flag |= _CRTDBG_LEAK_CHECK_DF;
+        flag |= _CRTDBG_ALLOC_MEM_DF;
+        _CrtSetDbgFlag(flag);
+        _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
+        _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
+        // Change this to leaking allocation's number to break there
+        _CrtSetBreakAlloc(-1);
+    }
+};
+#else
+class LeakDetector {};
+#endif
+
+LeakDetector leakDetector;
+
+// #included from: internal/catch_impl.hpp
+#define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED
+
+// Collect all the implementation files together here
+// These are the equivalent of what would usually be cpp files
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wweak-vtables"
+#endif
+
+// #included from: ../catch_session.hpp
+#define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
+
+// #included from: internal/catch_commandline.hpp
+#define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
+
+// #included from: catch_config.hpp
+#define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
+
+// #included from: catch_test_spec_parser.hpp
+#define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+// #included from: catch_test_spec.hpp
+#define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+// #included from: catch_wildcard_pattern.hpp
+#define TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED
+
+#include <stdexcept>
+
+namespace Catch
+{
+    class WildcardPattern {
+        enum WildcardPosition {
+            NoWildcard = 0,
+            WildcardAtStart = 1,
+            WildcardAtEnd = 2,
+            WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
+        };
+
+    public:
+
+        WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity )
+        :   m_caseSensitivity( caseSensitivity ),
+            m_wildcard( NoWildcard ),
+            m_pattern( adjustCase( pattern ) )
+        {
+            if( startsWith( m_pattern, '*' ) ) {
+                m_pattern = m_pattern.substr( 1 );
+                m_wildcard = WildcardAtStart;
+            }
+            if( endsWith( m_pattern, '*' ) ) {
+                m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
+                m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
+            }
+        }
+        virtual ~WildcardPattern();
+        virtual bool matches( std::string const& str ) const {
+            switch( m_wildcard ) {
+                case NoWildcard:
+                    return m_pattern == adjustCase( str );
+                case WildcardAtStart:
+                    return endsWith( adjustCase( str ), m_pattern );
+                case WildcardAtEnd:
+                    return startsWith( adjustCase( str ), m_pattern );
+                case WildcardAtBothEnds:
+                    return contains( adjustCase( str ), m_pattern );
+            }
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunreachable-code"
+#endif
+            throw std::logic_error( "Unknown enum" );
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+        }
+    private:
+        std::string adjustCase( std::string const& str ) const {
+            return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str;
+        }
+        CaseSensitive::Choice m_caseSensitivity;
+        WildcardPosition m_wildcard;
+        std::string m_pattern;
+    };
+}
+
+#include <string>
+#include <vector>
+
+namespace Catch {
+
+    class TestSpec {
+        struct Pattern : SharedImpl<> {
+            virtual ~Pattern();
+            virtual bool matches( TestCaseInfo const& testCase ) const = 0;
+        };
+        class NamePattern : public Pattern {
+        public:
+            NamePattern( std::string const& name )
+            : m_wildcardPattern( toLower( name ), CaseSensitive::No )
+            {}
+            virtual ~NamePattern();
+            virtual bool matches( TestCaseInfo const& testCase ) const {
+                return m_wildcardPattern.matches( toLower( testCase.name ) );
+            }
+        private:
+            WildcardPattern m_wildcardPattern;
+        };
+
+        class TagPattern : public Pattern {
+        public:
+            TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
+            virtual ~TagPattern();
+            virtual bool matches( TestCaseInfo const& testCase ) const {
+                return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end();
+            }
+        private:
+            std::string m_tag;
+        };
+
+        class ExcludedPattern : public Pattern {
+        public:
+            ExcludedPattern( Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
+            virtual ~ExcludedPattern();
+            virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
+        private:
+            Ptr<Pattern> m_underlyingPattern;
+        };
+
+        struct Filter {
+            std::vector<Ptr<Pattern> > m_patterns;
+
+            bool matches( TestCaseInfo const& testCase ) const {
+                // All patterns in a filter must match for the filter to be a match
+                for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it ) {
+                    if( !(*it)->matches( testCase ) )
+                        return false;
+                }
+                return true;
+            }
+        };
+
+    public:
+        bool hasFilters() const {
+            return !m_filters.empty();
+        }
+        bool matches( TestCaseInfo const& testCase ) const {
+            // A TestSpec matches if any filter matches
+            for( std::vector<Filter>::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it )
+                if( it->matches( testCase ) )
+                    return true;
+            return false;
+        }
+
+    private:
+        std::vector<Filter> m_filters;
+
+        friend class TestSpecParser;
+    };
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+namespace Catch {
+
+    class TestSpecParser {
+        enum Mode{ None, Name, QuotedName, Tag, EscapedName };
+        Mode m_mode;
+        bool m_exclusion;
+        std::size_t m_start, m_pos;
+        std::string m_arg;
+        std::vector<std::size_t> m_escapeChars;
+        TestSpec::Filter m_currentFilter;
+        TestSpec m_testSpec;
+        ITagAliasRegistry const* m_tagAliases;
+
+    public:
+        TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
+
+        TestSpecParser& parse( std::string const& arg ) {
+            m_mode = None;
+            m_exclusion = false;
+            m_start = std::string::npos;
+            m_arg = m_tagAliases->expandAliases( arg );
+            m_escapeChars.clear();
+            for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
+                visitChar( m_arg[m_pos] );
+            if( m_mode == Name )
+                addPattern<TestSpec::NamePattern>();
+            return *this;
+        }
+        TestSpec testSpec() {
+            addFilter();
+            return m_testSpec;
+        }
+    private:
+        void visitChar( char c ) {
+            if( m_mode == None ) {
+                switch( c ) {
+                case ' ': return;
+                case '~': m_exclusion = true; return;
+                case '[': return startNewMode( Tag, ++m_pos );
+                case '"': return startNewMode( QuotedName, ++m_pos );
+                case '\\': return escape();
+                default: startNewMode( Name, m_pos ); break;
+                }
+            }
+            if( m_mode == Name ) {
+                if( c == ',' ) {
+                    addPattern<TestSpec::NamePattern>();
+                    addFilter();
+                }
+                else if( c == '[' ) {
+                    if( subString() == "exclude:" )
+                        m_exclusion = true;
+                    else
+                        addPattern<TestSpec::NamePattern>();
+                    startNewMode( Tag, ++m_pos );
+                }
+                else if( c == '\\' )
+                    escape();
+            }
+            else if( m_mode == EscapedName )
+                m_mode = Name;
+            else if( m_mode == QuotedName && c == '"' )
+                addPattern<TestSpec::NamePattern>();
+            else if( m_mode == Tag && c == ']' )
+                addPattern<TestSpec::TagPattern>();
+        }
+        void startNewMode( Mode mode, std::size_t start ) {
+            m_mode = mode;
+            m_start = start;
+        }
+        void escape() {
+            if( m_mode == None )
+                m_start = m_pos;
+            m_mode = EscapedName;
+            m_escapeChars.push_back( m_pos );
+        }
+        std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
+        template<typename T>
+        void addPattern() {
+            std::string token = subString();
+            for( size_t i = 0; i < m_escapeChars.size(); ++i )
+                token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 );
+            m_escapeChars.clear();
+            if( startsWith( token, "exclude:" ) ) {
+                m_exclusion = true;
+                token = token.substr( 8 );
+            }
+            if( !token.empty() ) {
+                Ptr<TestSpec::Pattern> pattern = new T( token );
+                if( m_exclusion )
+                    pattern = new TestSpec::ExcludedPattern( pattern );
+                m_currentFilter.m_patterns.push_back( pattern );
+            }
+            m_exclusion = false;
+            m_mode = None;
+        }
+        void addFilter() {
+            if( !m_currentFilter.m_patterns.empty() ) {
+                m_testSpec.m_filters.push_back( m_currentFilter );
+                m_currentFilter = TestSpec::Filter();
+            }
+        }
+    };
+    inline TestSpec parseTestSpec( std::string const& arg ) {
+        return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
+    }
+
+} // namespace Catch
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+// #included from: catch_interfaces_config.h
+#define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED
+
+#include <iosfwd>
+#include <string>
+#include <vector>
+
+namespace Catch {
+
+    struct Verbosity { enum Level {
+        NoOutput = 0,
+        Quiet,
+        Normal
+    }; };
+
+    struct WarnAbout { enum What {
+        Nothing = 0x00,
+        NoAssertions = 0x01
+    }; };
+
+    struct ShowDurations { enum OrNot {
+        DefaultForReporter,
+        Always,
+        Never
+    }; };
+    struct RunTests { enum InWhatOrder {
+        InDeclarationOrder,
+        InLexicographicalOrder,
+        InRandomOrder
+    }; };
+    struct UseColour { enum YesOrNo {
+        Auto,
+        Yes,
+        No
+    }; };
+
+    class TestSpec;
+
+    struct IConfig : IShared {
+
+        virtual ~IConfig();
+
+        virtual bool allowThrows() const = 0;
+        virtual std::ostream& stream() const = 0;
+        virtual std::string name() const = 0;
+        virtual bool includeSuccessfulResults() const = 0;
+        virtual bool shouldDebugBreak() const = 0;
+        virtual bool warnAboutMissingAssertions() const = 0;
+        virtual int abortAfter() const = 0;
+        virtual bool showInvisibles() const = 0;
+        virtual ShowDurations::OrNot showDurations() const = 0;
+        virtual TestSpec const& testSpec() const = 0;
+        virtual RunTests::InWhatOrder runOrder() const = 0;
+        virtual unsigned int rngSeed() const = 0;
+        virtual UseColour::YesOrNo useColour() const = 0;
+        virtual std::vector<std::string> const& getSectionsToRun() const = 0;
+
+    };
+}
+
+// #included from: catch_stream.h
+#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
+
+// #included from: catch_streambuf.h
+#define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED
+
+#include <streambuf>
+
+namespace Catch {
+
+    class StreamBufBase : public std::streambuf {
+    public:
+        virtual ~StreamBufBase() CATCH_NOEXCEPT;
+    };
+}
+
+#include <streambuf>
+#include <ostream>
+#include <fstream>
+#include <memory>
+
+namespace Catch {
+
+    std::ostream& cout();
+    std::ostream& cerr();
+
+    struct IStream {
+        virtual ~IStream() CATCH_NOEXCEPT;
+        virtual std::ostream& stream() const = 0;
+    };
+
+    class FileStream : public IStream {
+        mutable std::ofstream m_ofs;
+    public:
+        FileStream( std::string const& filename );
+        virtual ~FileStream() CATCH_NOEXCEPT;
+    public: // IStream
+        virtual std::ostream& stream() const CATCH_OVERRIDE;
+    };
+
+    class CoutStream : public IStream {
+        mutable std::ostream m_os;
+    public:
+        CoutStream();
+        virtual ~CoutStream() CATCH_NOEXCEPT;
+
+    public: // IStream
+        virtual std::ostream& stream() const CATCH_OVERRIDE;
+    };
+
+    class DebugOutStream : public IStream {
+        CATCH_AUTO_PTR( StreamBufBase ) m_streamBuf;
+        mutable std::ostream m_os;
+    public:
+        DebugOutStream();
+        virtual ~DebugOutStream() CATCH_NOEXCEPT;
+
+    public: // IStream
+        virtual std::ostream& stream() const CATCH_OVERRIDE;
+    };
+}
+
+#include <memory>
+#include <vector>
+#include <string>
+#include <stdexcept>
+
+#ifndef CATCH_CONFIG_CONSOLE_WIDTH
+#define CATCH_CONFIG_CONSOLE_WIDTH 80
+#endif
+
+namespace Catch {
+
+    struct ConfigData {
+
+        ConfigData()
+        :   listTests( false ),
+            listTags( false ),
+            listReporters( false ),
+            listTestNamesOnly( false ),
+            listExtraInfo( false ),
+            showSuccessfulTests( false ),
+            shouldDebugBreak( false ),
+            noThrow( false ),
+            showHelp( false ),
+            showInvisibles( false ),
+            filenamesAsTags( false ),
+            abortAfter( -1 ),
+            rngSeed( 0 ),
+            verbosity( Verbosity::Normal ),
+            warnings( WarnAbout::Nothing ),
+            showDurations( ShowDurations::DefaultForReporter ),
+            runOrder( RunTests::InDeclarationOrder ),
+            useColour( UseColour::Auto )
+        {}
+
+        bool listTests;
+        bool listTags;
+        bool listReporters;
+        bool listTestNamesOnly;
+        bool listExtraInfo;
+
+        bool showSuccessfulTests;
+        bool shouldDebugBreak;
+        bool noThrow;
+        bool showHelp;
+        bool showInvisibles;
+        bool filenamesAsTags;
+
+        int abortAfter;
+        unsigned int rngSeed;
+
+        Verbosity::Level verbosity;
+        WarnAbout::What warnings;
+        ShowDurations::OrNot showDurations;
+        RunTests::InWhatOrder runOrder;
+        UseColour::YesOrNo useColour;
+
+        std::string outputFilename;
+        std::string name;
+        std::string processName;
+
+        std::vector<std::string> reporterNames;
+        std::vector<std::string> testsOrTags;
+        std::vector<std::string> sectionsToRun;
+    };
+
+    class Config : public SharedImpl<IConfig> {
+    private:
+        Config( Config const& other );
+        Config& operator = ( Config const& other );
+        virtual void dummy();
+    public:
+
+        Config()
+        {}
+
+        Config( ConfigData const& data )
+        :   m_data( data ),
+            m_stream( openStream() )
+        {
+            if( !data.testsOrTags.empty() ) {
+                TestSpecParser parser( ITagAliasRegistry::get() );
+                for( std::size_t i = 0; i < data.testsOrTags.size(); ++i )
+                    parser.parse( data.testsOrTags[i] );
+                m_testSpec = parser.testSpec();
+            }
+        }
+
+        virtual ~Config() {}
+
+        std::string const& getFilename() const {
+            return m_data.outputFilename ;
+        }
+
+        bool listTests() const { return m_data.listTests; }
+        bool listTestNamesOnly() const { return m_data.listTestNamesOnly; }
+        bool listTags() const { return m_data.listTags; }
+        bool listReporters() const { return m_data.listReporters; }
+        bool listExtraInfo() const { return m_data.listExtraInfo; }
+
+        std::string getProcessName() const { return m_data.processName; }
+
+        std::vector<std::string> const& getReporterNames() const { return m_data.reporterNames; }
+        std::vector<std::string> const& getSectionsToRun() const CATCH_OVERRIDE { return m_data.sectionsToRun; }
+
+        virtual TestSpec const& testSpec() const CATCH_OVERRIDE { return m_testSpec; }
+
+        bool showHelp() const { return m_data.showHelp; }
+
+        // IConfig interface
+        virtual bool allowThrows() const CATCH_OVERRIDE                 { return !m_data.noThrow; }
+        virtual std::ostream& stream() const CATCH_OVERRIDE             { return m_stream->stream(); }
+        virtual std::string name() const CATCH_OVERRIDE                 { return m_data.name.empty() ? m_data.processName : m_data.name; }
+        virtual bool includeSuccessfulResults() const CATCH_OVERRIDE    { return m_data.showSuccessfulTests; }
+        virtual bool warnAboutMissingAssertions() const CATCH_OVERRIDE  { return m_data.warnings & WarnAbout::NoAssertions; }
+        virtual ShowDurations::OrNot showDurations() const CATCH_OVERRIDE { return m_data.showDurations; }
+        virtual RunTests::InWhatOrder runOrder() const CATCH_OVERRIDE   { return m_data.runOrder; }
+        virtual unsigned int rngSeed() const CATCH_OVERRIDE             { return m_data.rngSeed; }
+        virtual UseColour::YesOrNo useColour() const CATCH_OVERRIDE     { return m_data.useColour; }
+        virtual bool shouldDebugBreak() const CATCH_OVERRIDE { return m_data.shouldDebugBreak; }
+        virtual int abortAfter() const CATCH_OVERRIDE { return m_data.abortAfter; }
+        virtual bool showInvisibles() const CATCH_OVERRIDE { return m_data.showInvisibles; }
+
+    private:
+
+        IStream const* openStream() {
+            if( m_data.outputFilename.empty() )
+                return new CoutStream();
+            else if( m_data.outputFilename[0] == '%' ) {
+                if( m_data.outputFilename == "%debug" )
+                    return new DebugOutStream();
+                else
+                    throw std::domain_error( "Unrecognised stream: " + m_data.outputFilename );
+            }
+            else
+                return new FileStream( m_data.outputFilename );
+        }
+        ConfigData m_data;
+
+        CATCH_AUTO_PTR( IStream const ) m_stream;
+        TestSpec m_testSpec;
+    };
+
+} // end namespace Catch
+
+// #included from: catch_clara.h
+#define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED
+
+// Use Catch's value for console width (store Clara's off to the side, if present)
+#ifdef CLARA_CONFIG_CONSOLE_WIDTH
+#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH
+#undef CLARA_CONFIG_CONSOLE_WIDTH
+#endif
+#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
+
+// Declare Clara inside the Catch namespace
+#define STITCH_CLARA_OPEN_NAMESPACE namespace Catch {
+// #included from: ../external/clara.h
+
+// Version 0.0.2.4
+
+// Only use header guard if we are not using an outer namespace
+#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)
+
+#ifndef STITCH_CLARA_OPEN_NAMESPACE
+#define TWOBLUECUBES_CLARA_H_INCLUDED
+#define STITCH_CLARA_OPEN_NAMESPACE
+#define STITCH_CLARA_CLOSE_NAMESPACE
+#else
+#define STITCH_CLARA_CLOSE_NAMESPACE }
+#endif
+
+#define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE
+
+// ----------- #included from tbc_text_format.h -----------
+
+// Only use header guard if we are not using an outer namespace
+#if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE)
+#ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+#define TBC_TEXT_FORMAT_H_INCLUDED
+#endif
+
+#include <string>
+#include <vector>
+#include <sstream>
+#include <algorithm>
+#include <cctype>
+
+// Use optional outer namespace
+#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
+#endif
+
+namespace Tbc {
+
+#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
+    const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
+#else
+    const unsigned int consoleWidth = 80;
+#endif
+
+    struct TextAttributes {
+        TextAttributes()
+        :   initialIndent( std::string::npos ),
+            indent( 0 ),
+            width( consoleWidth-1 ),
+            tabChar( '\t' )
+        {}
+
+        TextAttributes& setInitialIndent( std::size_t _value )  { initialIndent = _value; return *this; }
+        TextAttributes& setIndent( std::size_t _value )         { indent = _value; return *this; }
+        TextAttributes& setWidth( std::size_t _value )          { width = _value; return *this; }
+        TextAttributes& setTabChar( char _value )               { tabChar = _value; return *this; }
+
+        std::size_t initialIndent;  // indent of first line, or npos
+        std::size_t indent;         // indent of subsequent lines, or all if initialIndent is npos
+        std::size_t width;          // maximum width of text, including indent. Longer text will wrap
+        char tabChar;               // If this char is seen the indent is changed to current pos
+    };
+
+    class Text {
+    public:
+        Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
+        : attr( _attr )
+        {
+            std::string wrappableChars = " [({.,/|\\-";
+            std::size_t indent = _attr.initialIndent != std::string::npos
+                ? _attr.initialIndent
+                : _attr.indent;
+            std::string remainder = _str;
+
+            while( !remainder.empty() ) {
+                if( lines.size() >= 1000 ) {
+                    lines.push_back( "... message truncated due to excessive size" );
+                    return;
+                }
+                std::size_t tabPos = std::string::npos;
+                std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
+                std::size_t pos = remainder.find_first_of( '\n' );
+                if( pos <= width ) {
+                    width = pos;
+                }
+                pos = remainder.find_last_of( _attr.tabChar, width );
+                if( pos != std::string::npos ) {
+                    tabPos = pos;
+                    if( remainder[width] == '\n' )
+                        width--;
+                    remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
+                }
+
+                if( width == remainder.size() ) {
+                    spliceLine( indent, remainder, width );
+                }
+                else if( remainder[width] == '\n' ) {
+                    spliceLine( indent, remainder, width );
+                    if( width <= 1 || remainder.size() != 1 )
+                        remainder = remainder.substr( 1 );
+                    indent = _attr.indent;
+                }
+                else {
+                    pos = remainder.find_last_of( wrappableChars, width );
+                    if( pos != std::string::npos && pos > 0 ) {
+                        spliceLine( indent, remainder, pos );
+                        if( remainder[0] == ' ' )
+                            remainder = remainder.substr( 1 );
+                    }
+                    else {
+                        spliceLine( indent, remainder, width-1 );
+                        lines.back() += "-";
+                    }
+                    if( lines.size() == 1 )
+                        indent = _attr.indent;
+                    if( tabPos != std::string::npos )
+                        indent += tabPos;
+                }
+            }
+        }
+
+        void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
+            lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
+            _remainder = _remainder.substr( _pos );
+        }
+
+        typedef std::vector<std::string>::const_iterator const_iterator;
+
+        const_iterator begin() const { return lines.begin(); }
+        const_iterator end() const { return lines.end(); }
+        std::string const& last() const { return lines.back(); }
+        std::size_t size() const { return lines.size(); }
+        std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
+        std::string toString() const {
+            std::ostringstream oss;
+            oss << *this;
+            return oss.str();
+        }
+
+        inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
+            for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
+                it != itEnd; ++it ) {
+                if( it != _text.begin() )
+                    _stream << "\n";
+                _stream << *it;
+            }
+            return _stream;
+        }
+
+    private:
+        std::string str;
+        TextAttributes attr;
+        std::vector<std::string> lines;
+    };
+
+} // end namespace Tbc
+
+#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+} // end outer namespace
+#endif
+
+#endif // TBC_TEXT_FORMAT_H_INCLUDED
+
+// ----------- end of #include from tbc_text_format.h -----------
+// ........... back in clara.h
+
+#undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE
+
+// ----------- #included from clara_compilers.h -----------
+
+#ifndef TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
+#define TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
+
+// Detect a number of compiler features - mostly C++11/14 conformance - by compiler
+// The following features are defined:
+//
+// CLARA_CONFIG_CPP11_NULLPTR : is nullptr supported?
+// CLARA_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
+// CLARA_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
+// CLARA_CONFIG_CPP11_OVERRIDE : is override supported?
+// CLARA_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
+
+// CLARA_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
+
+// CLARA_CONFIG_VARIADIC_MACROS : are variadic macros supported?
+
+// In general each macro has a _NO_<feature name> form
+// (e.g. CLARA_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
+// Many features, at point of detection, define an _INTERNAL_ macro, so they
+// can be combined, en-mass, with the _NO_ forms later.
+
+// All the C++11 features can be disabled with CLARA_CONFIG_NO_CPP11
+
+#ifdef __clang__
+
+#if __has_feature(cxx_nullptr)
+#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
+#endif
+
+#if __has_feature(cxx_noexcept)
+#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
+#endif
+
+#endif // __clang__
+
+////////////////////////////////////////////////////////////////////////////////
+// GCC
+#ifdef __GNUC__
+
+#if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
+#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
+#endif
+
+// - otherwise more recent versions define __cplusplus >= 201103L
+// and will get picked up below
+
+#endif // __GNUC__
+
+////////////////////////////////////////////////////////////////////////////////
+// Visual C++
+#ifdef _MSC_VER
+
+#if (_MSC_VER >= 1600)
+#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
+#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
+#endif
+
+#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
+#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
+#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+#endif
+
+#endif // _MSC_VER
+
+////////////////////////////////////////////////////////////////////////////////
+// C++ language feature support
+
+// catch all support for C++11
+#if defined(__cplusplus) && __cplusplus >= 201103L
+
+#define CLARA_CPP11_OR_GREATER
+
+#if !defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR)
+#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
+#endif
+
+#ifndef CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
+#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
+#endif
+
+#ifndef CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+#endif
+
+#if !defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE)
+#define CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE
+#endif
+#if !defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
+#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
+#endif
+
+#endif // __cplusplus >= 201103L
+
+// Now set the actual defines based on the above + anything the user has configured
+#if defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NO_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_NO_CPP11)
+#define CLARA_CONFIG_CPP11_NULLPTR
+#endif
+#if defined(CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_NO_CPP11)
+#define CLARA_CONFIG_CPP11_NOEXCEPT
+#endif
+#if defined(CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_NO_CPP11)
+#define CLARA_CONFIG_CPP11_GENERATED_METHODS
+#endif
+#if defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_OVERRIDE) && !defined(CLARA_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_CPP11)
+#define CLARA_CONFIG_CPP11_OVERRIDE
+#endif
+#if defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_UNIQUE_PTR) && !defined(CLARA_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_CPP11)
+#define CLARA_CONFIG_CPP11_UNIQUE_PTR
+#endif
+
+// noexcept support:
+#if defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_NOEXCEPT)
+#define CLARA_NOEXCEPT noexcept
+#  define CLARA_NOEXCEPT_IS(x) noexcept(x)
+#else
+#define CLARA_NOEXCEPT throw()
+#  define CLARA_NOEXCEPT_IS(x)
+#endif
+
+// nullptr support
+#ifdef CLARA_CONFIG_CPP11_NULLPTR
+#define CLARA_NULL nullptr
+#else
+#define CLARA_NULL NULL
+#endif
+
+// override support
+#ifdef CLARA_CONFIG_CPP11_OVERRIDE
+#define CLARA_OVERRIDE override
+#else
+#define CLARA_OVERRIDE
+#endif
+
+// unique_ptr support
+#ifdef CLARA_CONFIG_CPP11_UNIQUE_PTR
+#   define CLARA_AUTO_PTR( T ) std::unique_ptr<T>
+#else
+#   define CLARA_AUTO_PTR( T ) std::auto_ptr<T>
+#endif
+
+#endif // TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
+
+// ----------- end of #include from clara_compilers.h -----------
+// ........... back in clara.h
+
+#include <map>
+#include <stdexcept>
+#include <memory>
+
+#if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
+#define CLARA_PLATFORM_WINDOWS
+#endif
+
+// Use optional outer namespace
+#ifdef STITCH_CLARA_OPEN_NAMESPACE
+STITCH_CLARA_OPEN_NAMESPACE
+#endif
+
+namespace Clara {
+
+    struct UnpositionalTag {};
+
+    extern UnpositionalTag _;
+
+#ifdef CLARA_CONFIG_MAIN
+    UnpositionalTag _;
+#endif
+
+    namespace Detail {
+
+#ifdef CLARA_CONSOLE_WIDTH
+    const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;
+#else
+    const unsigned int consoleWidth = 80;
+#endif
+
+        using namespace Tbc;
+
+        inline bool startsWith( std::string const& str, std::string const& prefix ) {
+            return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix;
+        }
+
+        template<typename T> struct RemoveConstRef{ typedef T type; };
+        template<typename T> struct RemoveConstRef<T&>{ typedef T type; };
+        template<typename T> struct RemoveConstRef<T const&>{ typedef T type; };
+        template<typename T> struct RemoveConstRef<T const>{ typedef T type; };
+
+        template<typename T>    struct IsBool       { static const bool value = false; };
+        template<>              struct IsBool<bool> { static const bool value = true; };
+
+        template<typename T>
+        void convertInto( std::string const& _source, T& _dest ) {
+            std::stringstream ss;
+            ss << _source;
+            ss >> _dest;
+            if( ss.fail() )
+                throw std::runtime_error( "Unable to convert " + _source + " to destination type" );
+        }
+        inline void convertInto( std::string const& _source, std::string& _dest ) {
+            _dest = _source;
+        }
+        char toLowerCh(char c) {
+            return static_cast<char>( std::tolower( c ) );
+        }
+        inline void convertInto( std::string const& _source, bool& _dest ) {
+            std::string sourceLC = _source;
+            std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), toLowerCh );
+            if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" )
+                _dest = true;
+            else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" )
+                _dest = false;
+            else
+                throw std::runtime_error( "Expected a boolean value but did not recognise:\n  '" + _source + "'" );
+        }
+
+        template<typename ConfigT>
+        struct IArgFunction {
+            virtual ~IArgFunction() {}
+#ifdef CLARA_CONFIG_CPP11_GENERATED_METHODS
+            IArgFunction()                      = default;
+            IArgFunction( IArgFunction const& ) = default;
+#endif
+            virtual void set( ConfigT& config, std::string const& value ) const = 0;
+            virtual bool takesArg() const = 0;
+            virtual IArgFunction* clone() const = 0;
+        };
+
+        template<typename ConfigT>
+        class BoundArgFunction {
+        public:
+            BoundArgFunction() : functionObj( CLARA_NULL ) {}
+            BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
+            BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : CLARA_NULL ) {}
+            BoundArgFunction& operator = ( BoundArgFunction const& other ) {
+                IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : CLARA_NULL;
+                delete functionObj;
+                functionObj = newFunctionObj;
+                return *this;
+            }
+            ~BoundArgFunction() { delete functionObj; }
+
+            void set( ConfigT& config, std::string const& value ) const {
+                functionObj->set( config, value );
+            }
+            bool takesArg() const { return functionObj->takesArg(); }
+
+            bool isSet() const {
+                return functionObj != CLARA_NULL;
+            }
+        private:
+            IArgFunction<ConfigT>* functionObj;
+        };
+
+        template<typename C>
+        struct NullBinder : IArgFunction<C>{
+            virtual void set( C&, std::string const& ) const {}
+            virtual bool takesArg() const { return true; }
+            virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); }
+        };
+
+        template<typename C, typename M>
+        struct BoundDataMember : IArgFunction<C>{
+            BoundDataMember( M C::* _member ) : member( _member ) {}
+            virtual void set( C& p, std::string const& stringValue ) const {
+                convertInto( stringValue, p.*member );
+            }
+            virtual bool takesArg() const { return !IsBool<M>::value; }
+            virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); }
+            M C::* member;
+        };
+        template<typename C, typename M>
+        struct BoundUnaryMethod : IArgFunction<C>{
+            BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {}
+            virtual void set( C& p, std::string const& stringValue ) const {
+                typename RemoveConstRef<M>::type value;
+                convertInto( stringValue, value );
+                (p.*member)( value );
+            }
+            virtual bool takesArg() const { return !IsBool<M>::value; }
+            virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); }
+            void (C::*member)( M );
+        };
+        template<typename C>
+        struct BoundNullaryMethod : IArgFunction<C>{
+            BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {}
+            virtual void set( C& p, std::string const& stringValue ) const {
+                bool value;
+                convertInto( stringValue, value );
+                if( value )
+                    (p.*member)();
+            }
+            virtual bool takesArg() const { return false; }
+            virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); }
+            void (C::*member)();
+        };
+
+        template<typename C>
+        struct BoundUnaryFunction : IArgFunction<C>{
+            BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {}
+            virtual void set( C& obj, std::string const& stringValue ) const {
+                bool value;
+                convertInto( stringValue, value );
+                if( value )
+                    function( obj );
+            }
+            virtual bool takesArg() const { return false; }
+            virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); }
+            void (*function)( C& );
+        };
+
+        template<typename C, typename T>
+        struct BoundBinaryFunction : IArgFunction<C>{
+            BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {}
+            virtual void set( C& obj, std::string const& stringValue ) const {
+                typename RemoveConstRef<T>::type value;
+                convertInto( stringValue, value );
+                function( obj, value );
+            }
+            virtual bool takesArg() const { return !IsBool<T>::value; }
+            virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); }
+            void (*function)( C&, T );
+        };
+
+    } // namespace Detail
+
+    inline std::vector<std::string> argsToVector( int argc, char const* const* const argv ) {
+        std::vector<std::string> args( static_cast<std::size_t>( argc ) );
+        for( std::size_t i = 0; i < static_cast<std::size_t>( argc ); ++i )
+            args[i] = argv[i];
+
+        return args;
+    }
+
+    class Parser {
+        enum Mode { None, MaybeShortOpt, SlashOpt, ShortOpt, LongOpt, Positional };
+        Mode mode;
+        std::size_t from;
+        bool inQuotes;
+    public:
+
+        struct Token {
+            enum Type { Positional, ShortOpt, LongOpt };
+            Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {}
+            Type type;
+            std::string data;
+        };
+
+        Parser() : mode( None ), from( 0 ), inQuotes( false ){}
+
+        void parseIntoTokens( std::vector<std::string> const& args, std::vector<Token>& tokens ) {
+            const std::string doubleDash = "--";
+            for( std::size_t i = 1; i < args.size() && args[i] != doubleDash; ++i )
+                parseIntoTokens( args[i], tokens);
+        }
+
+        void parseIntoTokens( std::string const& arg, std::vector<Token>& tokens ) {
+            for( std::size_t i = 0; i < arg.size(); ++i ) {
+                char c = arg[i];
+                if( c == '"' )
+                    inQuotes = !inQuotes;
+                mode = handleMode( i, c, arg, tokens );
+            }
+            mode = handleMode( arg.size(), '\0', arg, tokens );
+        }
+        Mode handleMode( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
+            switch( mode ) {
+                case None: return handleNone( i, c );
+                case MaybeShortOpt: return handleMaybeShortOpt( i, c );
+                case ShortOpt:
+                case LongOpt:
+                case SlashOpt: return handleOpt( i, c, arg, tokens );
+                case Positional: return handlePositional( i, c, arg, tokens );
+                default: throw std::logic_error( "Unknown mode" );
+            }
+        }
+
+        Mode handleNone( std::size_t i, char c ) {
+            if( inQuotes ) {
+                from = i;
+                return Positional;
+            }
+            switch( c ) {
+                case '-': return MaybeShortOpt;
+#ifdef CLARA_PLATFORM_WINDOWS
+                case '/': from = i+1; return SlashOpt;
+#endif
+                default: from = i; return Positional;
+            }
+        }
+        Mode handleMaybeShortOpt( std::size_t i, char c ) {
+            switch( c ) {
+                case '-': from = i+1; return LongOpt;
+                default: from = i; return ShortOpt;
+            }
+        }
+
+        Mode handleOpt( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
+            if( std::string( ":=\0", 3 ).find( c ) == std::string::npos )
+                return mode;
+
+            std::string optName = arg.substr( from, i-from );
+            if( mode == ShortOpt )
+                for( std::size_t j = 0; j < optName.size(); ++j )
+                    tokens.push_back( Token( Token::ShortOpt, optName.substr( j, 1 ) ) );
+            else if( mode == SlashOpt && optName.size() == 1 )
+                tokens.push_back( Token( Token::ShortOpt, optName ) );
+            else
+                tokens.push_back( Token( Token::LongOpt, optName ) );
+            return None;
+        }
+        Mode handlePositional( std::size_t i, char c, std::string const& arg, std::vector<Token>& tokens ) {
+            if( inQuotes || std::string( "\0", 1 ).find( c ) == std::string::npos )
+                return mode;
+
+            std::string data = arg.substr( from, i-from );
+            tokens.push_back( Token( Token::Positional, data ) );
+            return None;
+        }
+    };
+
+    template<typename ConfigT>
+    struct CommonArgProperties {
+        CommonArgProperties() {}
+        CommonArgProperties( Detail::BoundArgFunction<ConfigT> const& _boundField ) : boundField( _boundField ) {}
+
+        Detail::BoundArgFunction<ConfigT> boundField;
+        std::string description;
+        std::string detail;
+        std::string placeholder; // Only value if boundField takes an arg
+
+        bool takesArg() const {
+            return !placeholder.empty();
+        }
+        void validate() const {
+            if( !boundField.isSet() )
+                throw std::logic_error( "option not bound" );
+        }
+    };
+    struct OptionArgProperties {
+        std::vector<std::string> shortNames;
+        std::string longName;
+
+        bool hasShortName( std::string const& shortName ) const {
+            return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end();
+        }
+        bool hasLongName( std::string const& _longName ) const {
+            return _longName == longName;
+        }
+    };
+    struct PositionalArgProperties {
+        PositionalArgProperties() : position( -1 ) {}
+        int position; // -1 means non-positional (floating)
+
+        bool isFixedPositional() const {
+            return position != -1;
+        }
+    };
+
+    template<typename ConfigT>
+    class CommandLine {
+
+        struct Arg : CommonArgProperties<ConfigT>, OptionArgProperties, PositionalArgProperties {
+            Arg() {}
+            Arg( Detail::BoundArgFunction<ConfigT> const& _boundField ) : CommonArgProperties<ConfigT>( _boundField ) {}
+
+            using CommonArgProperties<ConfigT>::placeholder; // !TBD
+
+            std::string dbgName() const {
+                if( !longName.empty() )
+                    return "--" + longName;
+                if( !shortNames.empty() )
+                    return "-" + shortNames[0];
+                return "positional args";
+            }
+            std::string commands() const {
+                std::ostringstream oss;
+                bool first = true;
+                std::vector<std::string>::const_iterator it = shortNames.begin(), itEnd = shortNames.end();
+                for(; it != itEnd; ++it ) {
+                    if( first )
+                        first = false;
+                    else
+                        oss << ", ";
+                    oss << "-" << *it;
+                }
+                if( !longName.empty() ) {
+                    if( !first )
+                        oss << ", ";
+                    oss << "--" << longName;
+                }
+                if( !placeholder.empty() )
+                    oss << " <" << placeholder << ">";
+                return oss.str();
+            }
+        };
+
+        typedef CLARA_AUTO_PTR( Arg ) ArgAutoPtr;
+
+        friend void addOptName( Arg& arg, std::string const& optName )
+        {
+            if( optName.empty() )
+                return;
+            if( Detail::startsWith( optName, "--" ) ) {
+                if( !arg.longName.empty() )
+                    throw std::logic_error( "Only one long opt may be specified. '"
+                        + arg.longName
+                        + "' already specified, now attempting to add '"
+                        + optName + "'" );
+                arg.longName = optName.substr( 2 );
+            }
+            else if( Detail::startsWith( optName, "-" ) )
+                arg.shortNames.push_back( optName.substr( 1 ) );
+            else
+                throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" );
+        }
+        friend void setPositionalArg( Arg& arg, int position )
+        {
+            arg.position = position;
+        }
+
+        class ArgBuilder {
+        public:
+            ArgBuilder( Arg* arg ) : m_arg( arg ) {}
+
+            // Bind a non-boolean data member (requires placeholder string)
+            template<typename C, typename M>
+            void bind( M C::* field, std::string const& placeholder ) {
+                m_arg->boundField = new Detail::BoundDataMember<C,M>( field );
+                m_arg->placeholder = placeholder;
+            }
+            // Bind a boolean data member (no placeholder required)
+            template<typename C>
+            void bind( bool C::* field ) {
+                m_arg->boundField = new Detail::BoundDataMember<C,bool>( field );
+            }
+
+            // Bind a method taking a single, non-boolean argument (requires a placeholder string)
+            template<typename C, typename M>
+            void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) {
+                m_arg->boundField = new Detail::BoundUnaryMethod<C,M>( unaryMethod );
+                m_arg->placeholder = placeholder;
+            }
+
+            // Bind a method taking a single, boolean argument (no placeholder string required)
+            template<typename C>
+            void bind( void (C::* unaryMethod)( bool ) ) {
+                m_arg->boundField = new Detail::BoundUnaryMethod<C,bool>( unaryMethod );
+            }
+
+            // Bind a method that takes no arguments (will be called if opt is present)
+            template<typename C>
+            void bind( void (C::* nullaryMethod)() ) {
+                m_arg->boundField = new Detail::BoundNullaryMethod<C>( nullaryMethod );
+            }
+
+            // Bind a free function taking a single argument - the object to operate on (no placeholder string required)
+            template<typename C>
+            void bind( void (* unaryFunction)( C& ) ) {
+                m_arg->boundField = new Detail::BoundUnaryFunction<C>( unaryFunction );
+            }
+
+            // Bind a free function taking a single argument - the object to operate on (requires a placeholder string)
+            template<typename C, typename T>
+            void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) {
+                m_arg->boundField = new Detail::BoundBinaryFunction<C, T>( binaryFunction );
+                m_arg->placeholder = placeholder;
+            }
+
+            ArgBuilder& describe( std::string const& description ) {
+                m_arg->description = description;
+                return *this;
+            }
+            ArgBuilder& detail( std::string const& detail ) {
+                m_arg->detail = detail;
+                return *this;
+            }
+
+        protected:
+            Arg* m_arg;
+        };
+
+        class OptBuilder : public ArgBuilder {
+        public:
+            OptBuilder( Arg* arg ) : ArgBuilder( arg ) {}
+            OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {}
+
+            OptBuilder& operator[]( std::string const& optName ) {
+                addOptName( *ArgBuilder::m_arg, optName );
+                return *this;
+            }
+        };
+
+    public:
+
+        CommandLine()
+        :   m_boundProcessName( new Detail::NullBinder<ConfigT>() ),
+            m_highestSpecifiedArgPosition( 0 ),
+            m_throwOnUnrecognisedTokens( false )
+        {}
+        CommandLine( CommandLine const& other )
+        :   m_boundProcessName( other.m_boundProcessName ),
+            m_options ( other.m_options ),
+            m_positionalArgs( other.m_positionalArgs ),
+            m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ),
+            m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens )
+        {
+            if( other.m_floatingArg.get() )
+                m_floatingArg.reset( new Arg( *other.m_floatingArg ) );
+        }
+
+        CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) {
+            m_throwOnUnrecognisedTokens = shouldThrow;
+            return *this;
+        }
+
+        OptBuilder operator[]( std::string const& optName ) {
+            m_options.push_back( Arg() );
+            addOptName( m_options.back(), optName );
+            OptBuilder builder( &m_options.back() );
+            return builder;
+        }
+
+        ArgBuilder operator[]( int position ) {
+            m_positionalArgs.insert( std::make_pair( position, Arg() ) );
+            if( position > m_highestSpecifiedArgPosition )
+                m_highestSpecifiedArgPosition = position;
+            setPositionalArg( m_positionalArgs[position], position );
+            ArgBuilder builder( &m_positionalArgs[position] );
+            return builder;
+        }
+
+        // Invoke this with the _ instance
+        ArgBuilder operator[]( UnpositionalTag ) {
+            if( m_floatingArg.get() )
+                throw std::logic_error( "Only one unpositional argument can be added" );
+            m_floatingArg.reset( new Arg() );
+            ArgBuilder builder( m_floatingArg.get() );
+            return builder;
+        }
+
+        template<typename C, typename M>
+        void bindProcessName( M C::* field ) {
+            m_boundProcessName = new Detail::BoundDataMember<C,M>( field );
+        }
+        template<typename C, typename M>
+        void bindProcessName( void (C::*_unaryMethod)( M ) ) {
+            m_boundProcessName = new Detail::BoundUnaryMethod<C,M>( _unaryMethod );
+        }
+
+        void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const {
+            typename std::vector<Arg>::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it;
+            std::size_t maxWidth = 0;
+            for( it = itBegin; it != itEnd; ++it )
+                maxWidth = (std::max)( maxWidth, it->commands().size() );
+
+            for( it = itBegin; it != itEnd; ++it ) {
+                Detail::Text usage( it->commands(), Detail::TextAttributes()
+                                                        .setWidth( maxWidth+indent )
+                                                        .setIndent( indent ) );
+                Detail::Text desc( it->description, Detail::TextAttributes()
+                                                        .setWidth( width - maxWidth - 3 ) );
+
+                for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) {
+                    std::string usageCol = i < usage.size() ? usage[i] : "";
+                    os << usageCol;
+
+                    if( i < desc.size() && !desc[i].empty() )
+                        os  << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' )
+                            << desc[i];
+                    os << "\n";
+                }
+            }
+        }
+        std::string optUsage() const {
+            std::ostringstream oss;
+            optUsage( oss );
+            return oss.str();
+        }
+
+        void argSynopsis( std::ostream& os ) const {
+            for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) {
+                if( i > 1 )
+                    os << " ";
+                typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );
+                if( it != m_positionalArgs.end() )
+                    os << "<" << it->second.placeholder << ">";
+                else if( m_floatingArg.get() )
+                    os << "<" << m_floatingArg->placeholder << ">";
+                else
+                    throw std::logic_error( "non consecutive positional arguments with no floating args" );
+            }
+            // !TBD No indication of mandatory args
+            if( m_floatingArg.get() ) {
+                if( m_highestSpecifiedArgPosition > 1 )
+                    os << " ";
+                os << "[<" << m_floatingArg->placeholder << "> ...]";
+            }
+        }
+        std::string argSynopsis() const {
+            std::ostringstream oss;
+            argSynopsis( oss );
+            return oss.str();
+        }
+
+        void usage( std::ostream& os, std::string const& procName ) const {
+            validate();
+            os << "usage:\n  " << procName << " ";
+            argSynopsis( os );
+            if( !m_options.empty() ) {
+                os << " [options]\n\nwhere options are: \n";
+                optUsage( os, 2 );
+            }
+            os << "\n";
+        }
+        std::string usage( std::string const& procName ) const {
+            std::ostringstream oss;
+            usage( oss, procName );
+            return oss.str();
+        }
+
+        ConfigT parse( std::vector<std::string> const& args ) const {
+            ConfigT config;
+            parseInto( args, config );
+            return config;
+        }
+
+        std::vector<Parser::Token> parseInto( std::vector<std::string> const& args, ConfigT& config ) const {
+            std::string processName = args.empty() ? std::string() : args[0];
+            std::size_t lastSlash = processName.find_last_of( "/\\" );
+            if( lastSlash != std::string::npos )
+                processName = processName.substr( lastSlash+1 );
+            m_boundProcessName.set( config, processName );
+            std::vector<Parser::Token> tokens;
+            Parser parser;
+            parser.parseIntoTokens( args, tokens );
+            return populate( tokens, config );
+        }
+
+        std::vector<Parser::Token> populate( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
+            validate();
+            std::vector<Parser::Token> unusedTokens = populateOptions( tokens, config );
+            unusedTokens = populateFixedArgs( unusedTokens, config );
+            unusedTokens = populateFloatingArgs( unusedTokens, config );
+            return unusedTokens;
+        }
+
+        std::vector<Parser::Token> populateOptions( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
+            std::vector<Parser::Token> unusedTokens;
+            std::vector<std::string> errors;
+            for( std::size_t i = 0; i < tokens.size(); ++i ) {
+                Parser::Token const& token = tokens[i];
+                typename std::vector<Arg>::const_iterator it = m_options.begin(), itEnd = m_options.end();
+                for(; it != itEnd; ++it ) {
+                    Arg const& arg = *it;
+
+                    try {
+                        if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) ||
+                            ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) {
+                            if( arg.takesArg() ) {
+                                if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional )
+                                    errors.push_back( "Expected argument to option: " + token.data );
+                                else
+                                    arg.boundField.set( config, tokens[++i].data );
+                            }
+                            else {
+                                arg.boundField.set( config, "true" );
+                            }
+                            break;
+                        }
+                    }
+                    catch( std::exception& ex ) {
+                        errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" );
+                    }
+                }
+                if( it == itEnd ) {
+                    if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens )
+                        unusedTokens.push_back( token );
+                    else if( errors.empty() && m_throwOnUnrecognisedTokens )
+                        errors.push_back( "unrecognised option: " + token.data );
+                }
+            }
+            if( !errors.empty() ) {
+                std::ostringstream oss;
+                for( std::vector<std::string>::const_iterator it = errors.begin(), itEnd = errors.end();
+                        it != itEnd;
+                        ++it ) {
+                    if( it != errors.begin() )
+                        oss << "\n";
+                    oss << *it;
+                }
+                throw std::runtime_error( oss.str() );
+            }
+            return unusedTokens;
+        }
+        std::vector<Parser::Token> populateFixedArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
+            std::vector<Parser::Token> unusedTokens;
+            int position = 1;
+            for( std::size_t i = 0; i < tokens.size(); ++i ) {
+                Parser::Token const& token = tokens[i];
+                typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( position );
+                if( it != m_positionalArgs.end() )
+                    it->second.boundField.set( config, token.data );
+                else
+                    unusedTokens.push_back( token );
+                if( token.type == Parser::Token::Positional )
+                    position++;
+            }
+            return unusedTokens;
+        }
+        std::vector<Parser::Token> populateFloatingArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
+            if( !m_floatingArg.get() )
+                return tokens;
+            std::vector<Parser::Token> unusedTokens;
+            for( std::size_t i = 0; i < tokens.size(); ++i ) {
+                Parser::Token const& token = tokens[i];
+                if( token.type == Parser::Token::Positional )
+                    m_floatingArg->boundField.set( config, token.data );
+                else
+                    unusedTokens.push_back( token );
+            }
+            return unusedTokens;
+        }
+
+        void validate() const
+        {
+            if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() )
+                throw std::logic_error( "No options or arguments specified" );
+
+            for( typename std::vector<Arg>::const_iterator  it = m_options.begin(),
+                                                            itEnd = m_options.end();
+                    it != itEnd; ++it )
+                it->validate();
+        }
+
+    private:
+        Detail::BoundArgFunction<ConfigT> m_boundProcessName;
+        std::vector<Arg> m_options;
+        std::map<int, Arg> m_positionalArgs;
+        ArgAutoPtr m_floatingArg;
+        int m_highestSpecifiedArgPosition;
+        bool m_throwOnUnrecognisedTokens;
+    };
+
+} // end namespace Clara
+
+STITCH_CLARA_CLOSE_NAMESPACE
+#undef STITCH_CLARA_OPEN_NAMESPACE
+#undef STITCH_CLARA_CLOSE_NAMESPACE
+
+#endif // TWOBLUECUBES_CLARA_H_INCLUDED
+#undef STITCH_CLARA_OPEN_NAMESPACE
+
+// Restore Clara's value for console width, if present
+#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
+#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
+#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
+#endif
+
+#include <fstream>
+#include <ctime>
+
+namespace Catch {
+
+    inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; }
+    inline void abortAfterX( ConfigData& config, int x ) {
+        if( x < 1 )
+            throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" );
+        config.abortAfter = x;
+    }
+    inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }
+    inline void addSectionToRun( ConfigData& config, std::string const& sectionName ) { config.sectionsToRun.push_back( sectionName ); }
+    inline void addReporterName( ConfigData& config, std::string const& _reporterName ) { config.reporterNames.push_back( _reporterName ); }
+
+    inline void addWarning( ConfigData& config, std::string const& _warning ) {
+        if( _warning == "NoAssertions" )
+            config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions );
+        else
+            throw std::runtime_error( "Unrecognised warning: '" + _warning + '\'' );
+    }
+    inline void setOrder( ConfigData& config, std::string const& order ) {
+        if( startsWith( "declared", order ) )
+            config.runOrder = RunTests::InDeclarationOrder;
+        else if( startsWith( "lexical", order ) )
+            config.runOrder = RunTests::InLexicographicalOrder;
+        else if( startsWith( "random", order ) )
+            config.runOrder = RunTests::InRandomOrder;
+        else
+            throw std::runtime_error( "Unrecognised ordering: '" + order + '\'' );
+    }
+    inline void setRngSeed( ConfigData& config, std::string const& seed ) {
+        if( seed == "time" ) {
+            config.rngSeed = static_cast<unsigned int>( std::time(0) );
+        }
+        else {
+            std::stringstream ss;
+            ss << seed;
+            ss >> config.rngSeed;
+            if( ss.fail() )
+                throw std::runtime_error( "Argument to --rng-seed should be the word 'time' or a number" );
+        }
+    }
+    inline void setVerbosity( ConfigData& config, int level ) {
+        // !TBD: accept strings?
+        config.verbosity = static_cast<Verbosity::Level>( level );
+    }
+    inline void setShowDurations( ConfigData& config, bool _showDurations ) {
+        config.showDurations = _showDurations
+            ? ShowDurations::Always
+            : ShowDurations::Never;
+    }
+    inline void setUseColour( ConfigData& config, std::string const& value ) {
+        std::string mode = toLower( value );
+
+        if( mode == "yes" )
+            config.useColour = UseColour::Yes;
+        else if( mode == "no" )
+            config.useColour = UseColour::No;
+        else if( mode == "auto" )
+            config.useColour = UseColour::Auto;
+        else
+            throw std::runtime_error( "colour mode must be one of: auto, yes or no" );
+    }
+    inline void forceColour( ConfigData& config ) {
+        config.useColour = UseColour::Yes;
+    }
+    inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) {
+        std::ifstream f( _filename.c_str() );
+        if( !f.is_open() )
+            throw std::domain_error( "Unable to load input file: " + _filename );
+
+        std::string line;
+        while( std::getline( f, line ) ) {
+            line = trim(line);
+            if( !line.empty() && !startsWith( line, '#' ) ) {
+                if( !startsWith( line, '"' ) )
+                    line = '"' + line + '"';
+                addTestOrTags( config, line + ',' );
+            }
+        }
+    }
+
+    inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
+
+        using namespace Clara;
+        CommandLine<ConfigData> cli;
+
+        cli.bindProcessName( &ConfigData::processName );
+
+        cli["-?"]["-h"]["--help"]
+            .describe( "display usage information" )
+            .bind( &ConfigData::showHelp );
+
+        cli["-l"]["--list-tests"]
+            .describe( "list all/matching test cases" )
+            .bind( &ConfigData::listTests );
+
+        cli["-t"]["--list-tags"]
+            .describe( "list all/matching tags" )
+            .bind( &ConfigData::listTags );
+
+        cli["-s"]["--success"]
+            .describe( "include successful tests in output" )
+            .bind( &ConfigData::showSuccessfulTests );
+
+        cli["-b"]["--break"]
+            .describe( "break into debugger on failure" )
+            .bind( &ConfigData::shouldDebugBreak );
+
+        cli["-e"]["--nothrow"]
+            .describe( "skip exception tests" )
+            .bind( &ConfigData::noThrow );
+
+        cli["-i"]["--invisibles"]
+            .describe( "show invisibles (tabs, newlines)" )
+            .bind( &ConfigData::showInvisibles );
+
+        cli["-o"]["--out"]
+            .describe( "output filename" )
+            .bind( &ConfigData::outputFilename, "filename" );
+
+        cli["-r"]["--reporter"]
+//            .placeholder( "name[:filename]" )
+            .describe( "reporter to use (defaults to console)" )
+            .bind( &addReporterName, "name" );
+
+        cli["-n"]["--name"]
+            .describe( "suite name" )
+            .bind( &ConfigData::name, "name" );
+
+        cli["-a"]["--abort"]
+            .describe( "abort at first failure" )
+            .bind( &abortAfterFirst );
+
+        cli["-x"]["--abortx"]
+            .describe( "abort after x failures" )
+            .bind( &abortAfterX, "no. failures" );
+
+        cli["-w"]["--warn"]
+            .describe( "enable warnings" )
+            .bind( &addWarning, "warning name" );
+
+// - needs updating if reinstated
+//        cli.into( &setVerbosity )
+//            .describe( "level of verbosity (0=no output)" )
+//            .shortOpt( "v")
+//            .longOpt( "verbosity" )
+//            .placeholder( "level" );
+
+        cli[_]
+            .describe( "which test or tests to use" )
+            .bind( &addTestOrTags, "test name, pattern or tags" );
+
+        cli["-d"]["--durations"]
+            .describe( "show test durations" )
+            .bind( &setShowDurations, "yes|no" );
+
+        cli["-f"]["--input-file"]
+            .describe( "load test names to run from a file" )
+            .bind( &loadTestNamesFromFile, "filename" );
+
+        cli["-#"]["--filenames-as-tags"]
+            .describe( "adds a tag for the filename" )
+            .bind( &ConfigData::filenamesAsTags );
+
+        cli["-c"]["--section"]
+                .describe( "specify section to run" )
+                .bind( &addSectionToRun, "section name" );
+
+        // Less common commands which don't have a short form
+        cli["--list-test-names-only"]
+            .describe( "list all/matching test cases names only" )
+            .bind( &ConfigData::listTestNamesOnly );
+
+        cli["--list-extra-info"]
+            .describe( "list all/matching test cases with more info" )
+            .bind( &ConfigData::listExtraInfo );
+
+        cli["--list-reporters"]
+            .describe( "list all reporters" )
+            .bind( &ConfigData::listReporters );
+
+        cli["--order"]
+            .describe( "test case order (defaults to decl)" )
+            .bind( &setOrder, "decl|lex|rand" );
+
+        cli["--rng-seed"]
+            .describe( "set a specific seed for random numbers" )
+            .bind( &setRngSeed, "'time'|number" );
+
+        cli["--force-colour"]
+            .describe( "force colourised output (deprecated)" )
+            .bind( &forceColour );
+
+        cli["--use-colour"]
+            .describe( "should output be colourised" )
+            .bind( &setUseColour, "yes|no" );
+
+        return cli;
+    }
+
+} // end namespace Catch
+
+// #included from: internal/catch_list.hpp
+#define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED
+
+// #included from: catch_text.h
+#define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED
+
+#define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
+
+#define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch
+// #included from: ../external/tbc_text_format.h
+// Only use header guard if we are not using an outer namespace
+#ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+# ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
+#  ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
+#   define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
+#  endif
+# else
+#  define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
+# endif
+#endif
+#ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
+#include <string>
+#include <vector>
+#include <sstream>
+
+// Use optional outer namespace
+#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
+#endif
+
+namespace Tbc {
+
+#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
+    const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
+#else
+    const unsigned int consoleWidth = 80;
+#endif
+
+    struct TextAttributes {
+        TextAttributes()
+        :   initialIndent( std::string::npos ),
+            indent( 0 ),
+            width( consoleWidth-1 )
+        {}
+
+        TextAttributes& setInitialIndent( std::size_t _value )  { initialIndent = _value; return *this; }
+        TextAttributes& setIndent( std::size_t _value )         { indent = _value; return *this; }
+        TextAttributes& setWidth( std::size_t _value )          { width = _value; return *this; }
+
+        std::size_t initialIndent;  // indent of first line, or npos
+        std::size_t indent;         // indent of subsequent lines, or all if initialIndent is npos
+        std::size_t width;          // maximum width of text, including indent. Longer text will wrap
+    };
+
+    class Text {
+    public:
+        Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
+        : attr( _attr )
+        {
+            const std::string wrappableBeforeChars = "[({<\t";
+            const std::string wrappableAfterChars = "])}>-,./|\\";
+            const std::string wrappableInsteadOfChars = " \n\r";
+            std::string indent = _attr.initialIndent != std::string::npos
+                ? std::string( _attr.initialIndent, ' ' )
+                : std::string( _attr.indent, ' ' );
+
+            typedef std::string::const_iterator iterator;
+            iterator it = _str.begin();
+            const iterator strEnd = _str.end();
+
+            while( it != strEnd ) {
+
+                if( lines.size() >= 1000 ) {
+                    lines.push_back( "... message truncated due to excessive size" );
+                    return;
+                }
+
+                std::string suffix;
+                std::size_t width = (std::min)( static_cast<size_t>( strEnd-it ), _attr.width-static_cast<size_t>( indent.size() ) );
+                iterator itEnd = it+width;
+                iterator itNext = _str.end();
+
+                iterator itNewLine = std::find( it, itEnd, '\n' );
+                if( itNewLine != itEnd )
+                    itEnd = itNewLine;
+
+                if( itEnd != strEnd  ) {
+                    bool foundWrapPoint = false;
+                    iterator findIt = itEnd;
+                    do {
+                        if( wrappableAfterChars.find( *findIt ) != std::string::npos && findIt != itEnd ) {
+                            itEnd = findIt+1;
+                            itNext = findIt+1;
+                            foundWrapPoint = true;
+                        }
+                        else if( findIt > it && wrappableBeforeChars.find( *findIt ) != std::string::npos ) {
+                            itEnd = findIt;
+                            itNext = findIt;
+                            foundWrapPoint = true;
+                        }
+                        else if( wrappableInsteadOfChars.find( *findIt ) != std::string::npos ) {
+                            itNext = findIt+1;
+                            itEnd = findIt;
+                            foundWrapPoint = true;
+                        }
+                        if( findIt == it )
+                            break;
+                        else
+                            --findIt;
+                    }
+                    while( !foundWrapPoint );
+
+                    if( !foundWrapPoint ) {
+                        // No good wrap char, so we'll break mid word and add a hyphen
+                        --itEnd;
+                        itNext = itEnd;
+                        suffix = "-";
+                    }
+                    else {
+                        while( itEnd > it && wrappableInsteadOfChars.find( *(itEnd-1) ) != std::string::npos )
+                            --itEnd;
+                    }
+                }
+                lines.push_back( indent + std::string( it, itEnd ) + suffix );
+
+                if( indent.size() != _attr.indent )
+                    indent = std::string( _attr.indent, ' ' );
+                it = itNext;
+            }
+        }
+
+        typedef std::vector<std::string>::const_iterator const_iterator;
+
+        const_iterator begin() const { return lines.begin(); }
+        const_iterator end() const { return lines.end(); }
+        std::string const& last() const { return lines.back(); }
+        std::size_t size() const { return lines.size(); }
+        std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
+        std::string toString() const {
+            std::ostringstream oss;
+            oss << *this;
+            return oss.str();
+        }
+
+        inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
+            for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
+                it != itEnd; ++it ) {
+                if( it != _text.begin() )
+                    _stream << "\n";
+                _stream << *it;
+            }
+            return _stream;
+        }
+
+    private:
+        std::string str;
+        TextAttributes attr;
+        std::vector<std::string> lines;
+    };
+
+} // end namespace Tbc
+
+#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+} // end outer namespace
+#endif
+
+#endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
+#undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+
+namespace Catch {
+    using Tbc::Text;
+    using Tbc::TextAttributes;
+}
+
+// #included from: catch_console_colour.hpp
+#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED
+
+namespace Catch {
+
+    struct Colour {
+        enum Code {
+            None = 0,
+
+            White,
+            Red,
+            Green,
+            Blue,
+            Cyan,
+            Yellow,
+            Grey,
+
+            Bright = 0x10,
+
+            BrightRed = Bright | Red,
+            BrightGreen = Bright | Green,
+            LightGrey = Bright | Grey,
+            BrightWhite = Bright | White,
+
+            // By intention
+            FileName = LightGrey,
+            Warning = Yellow,
+            ResultError = BrightRed,
+            ResultSuccess = BrightGreen,
+            ResultExpectedFailure = Warning,
+
+            Error = BrightRed,
+            Success = Green,
+
+            OriginalExpression = Cyan,
+            ReconstructedExpression = Yellow,
+
+            SecondaryText = LightGrey,
+            Headers = White
+        };
+
+        // Use constructed object for RAII guard
+        Colour( Code _colourCode );
+        Colour( Colour const& other );
+        ~Colour();
+
+        // Use static method for one-shot changes
+        static void use( Code _colourCode );
+
+    private:
+        bool m_moved;
+    };
+
+    inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; }
+
+} // end namespace Catch
+
+// #included from: catch_interfaces_reporter.h
+#define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
+
+#include <string>
+#include <ostream>
+#include <map>
+
+namespace Catch
+{
+    struct ReporterConfig {
+        explicit ReporterConfig( Ptr<IConfig const> const& _fullConfig )
+        :   m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
+
+        ReporterConfig( Ptr<IConfig const> const& _fullConfig, std::ostream& _stream )
+        :   m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
+
+        std::ostream& stream() const    { return *m_stream; }
+        Ptr<IConfig const> fullConfig() const { return m_fullConfig; }
+
+    private:
+        std::ostream* m_stream;
+        Ptr<IConfig const> m_fullConfig;
+    };
+
+    struct ReporterPreferences {
+        ReporterPreferences()
+        : shouldRedirectStdOut( false )
+        {}
+
+        bool shouldRedirectStdOut;
+    };
+
+    template<typename T>
+    struct LazyStat : Option<T> {
+        LazyStat() : used( false ) {}
+        LazyStat& operator=( T const& _value ) {
+            Option<T>::operator=( _value );
+            used = false;
+            return *this;
+        }
+        void reset() {
+            Option<T>::reset();
+            used = false;
+        }
+        bool used;
+    };
+
+    struct TestRunInfo {
+        TestRunInfo( std::string const& _name ) : name( _name ) {}
+        std::string name;
+    };
+    struct GroupInfo {
+        GroupInfo(  std::string const& _name,
+                    std::size_t _groupIndex,
+                    std::size_t _groupsCount )
+        :   name( _name ),
+            groupIndex( _groupIndex ),
+            groupsCounts( _groupsCount )
+        {}
+
+        std::string name;
+        std::size_t groupIndex;
+        std::size_t groupsCounts;
+    };
+
+    struct AssertionStats {
+        AssertionStats( AssertionResult const& _assertionResult,
+                        std::vector<MessageInfo> const& _infoMessages,
+                        Totals const& _totals )
+        :   assertionResult( _assertionResult ),
+            infoMessages( _infoMessages ),
+            totals( _totals )
+        {
+            if( assertionResult.hasMessage() ) {
+                // Copy message into messages list.
+                // !TBD This should have been done earlier, somewhere
+                MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
+                builder << assertionResult.getMessage();
+                builder.m_info.message = builder.m_stream.str();
+
+                infoMessages.push_back( builder.m_info );
+            }
+        }
+        virtual ~AssertionStats();
+
+#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+        AssertionStats( AssertionStats const& )              = default;
+        AssertionStats( AssertionStats && )                  = default;
+        AssertionStats& operator = ( AssertionStats const& ) = default;
+        AssertionStats& operator = ( AssertionStats && )     = default;
+#  endif
+
+        AssertionResult assertionResult;
+        std::vector<MessageInfo> infoMessages;
+        Totals totals;
+    };
+
+    struct SectionStats {
+        SectionStats(   SectionInfo const& _sectionInfo,
+                        Counts const& _assertions,
+                        double _durationInSeconds,
+                        bool _missingAssertions )
+        :   sectionInfo( _sectionInfo ),
+            assertions( _assertions ),
+            durationInSeconds( _durationInSeconds ),
+            missingAssertions( _missingAssertions )
+        {}
+        virtual ~SectionStats();
+#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+        SectionStats( SectionStats const& )              = default;
+        SectionStats( SectionStats && )                  = default;
+        SectionStats& operator = ( SectionStats const& ) = default;
+        SectionStats& operator = ( SectionStats && )     = default;
+#  endif
+
+        SectionInfo sectionInfo;
+        Counts assertions;
+        double durationInSeconds;
+        bool missingAssertions;
+    };
+
+    struct TestCaseStats {
+        TestCaseStats(  TestCaseInfo const& _testInfo,
+                        Totals const& _totals,
+                        std::string const& _stdOut,
+                        std::string const& _stdErr,
+                        bool _aborting )
+        : testInfo( _testInfo ),
+            totals( _totals ),
+            stdOut( _stdOut ),
+            stdErr( _stdErr ),
+            aborting( _aborting )
+        {}
+        virtual ~TestCaseStats();
+
+#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+        TestCaseStats( TestCaseStats const& )              = default;
+        TestCaseStats( TestCaseStats && )                  = default;
+        TestCaseStats& operator = ( TestCaseStats const& ) = default;
+        TestCaseStats& operator = ( TestCaseStats && )     = default;
+#  endif
+
+        TestCaseInfo testInfo;
+        Totals totals;
+        std::string stdOut;
+        std::string stdErr;
+        bool aborting;
+    };
+
+    struct TestGroupStats {
+        TestGroupStats( GroupInfo const& _groupInfo,
+                        Totals const& _totals,
+                        bool _aborting )
+        :   groupInfo( _groupInfo ),
+            totals( _totals ),
+            aborting( _aborting )
+        {}
+        TestGroupStats( GroupInfo const& _groupInfo )
+        :   groupInfo( _groupInfo ),
+            aborting( false )
+        {}
+        virtual ~TestGroupStats();
+
+#  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+        TestGroupStats( TestGroupStats const& )              = default;
+        TestGroupStats( TestGroupStats && )                  = default;
+        TestGroupStats& operator = ( TestGroupStats const& ) = default;
+        TestGroupStats& operator = ( TestGroupStats && )     = default;
+#  endif
+
+        GroupInfo groupInfo;
+        Totals totals;
+        bool aborting;
+    };
+
+    struct TestRunStats {
+        TestRunStats(   TestRunInfo const& _runInfo,
+                        Totals const& _totals,
+                        bool _aborting )
+        :   runInfo( _runInfo ),
+            totals( _totals ),
+            aborting( _aborting )
+        {}
+        virtual ~TestRunStats();
+
+#  ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS
+        TestRunStats( TestRunStats const& _other )
+        :   runInfo( _other.runInfo ),
+            totals( _other.totals ),
+            aborting( _other.aborting )
+        {}
+#  else
+        TestRunStats( TestRunStats const& )              = default;
+        TestRunStats( TestRunStats && )                  = default;
+        TestRunStats& operator = ( TestRunStats const& ) = default;
+        TestRunStats& operator = ( TestRunStats && )     = default;
+#  endif
+
+        TestRunInfo runInfo;
+        Totals totals;
+        bool aborting;
+    };
+
+    class MultipleReporters;
+
+    struct IStreamingReporter : IShared {
+        virtual ~IStreamingReporter();
+
+        // Implementing class must also provide the following static method:
+        // static std::string getDescription();
+
+        virtual ReporterPreferences getPreferences() const = 0;
+
+        virtual void noMatchingTestCases( std::string const& spec ) = 0;
+
+        virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
+        virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
+
+        virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
+        virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
+
+        virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
+
+        // The return value indicates if the messages buffer should be cleared:
+        virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
+
+        virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
+        virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
+        virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
+        virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
+
+        virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
+
+        virtual MultipleReporters* tryAsMulti() { return CATCH_NULL; }
+    };
+
+    struct IReporterFactory : IShared {
+        virtual ~IReporterFactory();
+        virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0;
+        virtual std::string getDescription() const = 0;
+    };
+
+    struct IReporterRegistry {
+        typedef std::map<std::string, Ptr<IReporterFactory> > FactoryMap;
+        typedef std::vector<Ptr<IReporterFactory> > Listeners;
+
+        virtual ~IReporterRegistry();
+        virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const = 0;
+        virtual FactoryMap const& getFactories() const = 0;
+        virtual Listeners const& getListeners() const = 0;
+    };
+
+    Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter );
+
+}
+
+#include <limits>
+#include <algorithm>
+
+namespace Catch {
+
+    inline std::size_t listTests( Config const& config ) {
+
+        TestSpec testSpec = config.testSpec();
+        if( config.testSpec().hasFilters() )
+            Catch::cout() << "Matching test cases:\n";
+        else {
+            Catch::cout() << "All available test cases:\n";
+            testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
+        }
+
+        std::size_t matchedTests = 0;
+        TextAttributes nameAttr, descAttr, tagsAttr;
+        nameAttr.setInitialIndent( 2 ).setIndent( 4 );
+        descAttr.setIndent( 4 );
+        tagsAttr.setIndent( 6 );
+
+        std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
+        for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
+                it != itEnd;
+                ++it ) {
+            matchedTests++;
+            TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
+            Colour::Code colour = testCaseInfo.isHidden()
+                ? Colour::SecondaryText
+                : Colour::None;
+            Colour colourGuard( colour );
+
+            Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl;
+            if( config.listExtraInfo() ) {
+                Catch::cout() << "    " << testCaseInfo.lineInfo << std::endl;
+                std::string description = testCaseInfo.description;
+                if( description.empty() )
+                    description = "(NO DESCRIPTION)";
+                Catch::cout() << Text( description, descAttr ) << std::endl;
+            }
+            if( !testCaseInfo.tags.empty() )
+                Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl;
+        }
+
+        if( !config.testSpec().hasFilters() )
+            Catch::cout() << pluralise( matchedTests, "test case" ) << '\n' << std::endl;
+        else
+            Catch::cout() << pluralise( matchedTests, "matching test case" ) << '\n' << std::endl;
+        return matchedTests;
+    }
+
+    inline std::size_t listTestsNamesOnly( Config const& config ) {
+        TestSpec testSpec = config.testSpec();
+        if( !config.testSpec().hasFilters() )
+            testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
+        std::size_t matchedTests = 0;
+        std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
+        for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
+                it != itEnd;
+                ++it ) {
+            matchedTests++;
+            TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
+            if( startsWith( testCaseInfo.name, '#' ) )
+               Catch::cout() << '"' << testCaseInfo.name << '"';
+            else
+               Catch::cout() << testCaseInfo.name;
+            if ( config.listExtraInfo() )
+                Catch::cout() << "\t@" << testCaseInfo.lineInfo;
+            Catch::cout() << std::endl;
+        }
+        return matchedTests;
+    }
+
+    struct TagInfo {
+        TagInfo() : count ( 0 ) {}
+        void add( std::string const& spelling ) {
+            ++count;
+            spellings.insert( spelling );
+        }
+        std::string all() const {
+            std::string out;
+            for( std::set<std::string>::const_iterator it = spellings.begin(), itEnd = spellings.end();
+                        it != itEnd;
+                        ++it )
+                out += "[" + *it + "]";
+            return out;
+        }
+        std::set<std::string> spellings;
+        std::size_t count;
+    };
+
+    inline std::size_t listTags( Config const& config ) {
+        TestSpec testSpec = config.testSpec();
+        if( config.testSpec().hasFilters() )
+            Catch::cout() << "Tags for matching test cases:\n";
+        else {
+            Catch::cout() << "All available tags:\n";
+            testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
+        }
+
+        std::map<std::string, TagInfo> tagCounts;
+
+        std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
+        for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
+                it != itEnd;
+                ++it ) {
+            for( std::set<std::string>::const_iterator  tagIt = it->getTestCaseInfo().tags.begin(),
+                                                        tagItEnd = it->getTestCaseInfo().tags.end();
+                    tagIt != tagItEnd;
+                    ++tagIt ) {
+                std::string tagName = *tagIt;
+                std::string lcaseTagName = toLower( tagName );
+                std::map<std::string, TagInfo>::iterator countIt = tagCounts.find( lcaseTagName );
+                if( countIt == tagCounts.end() )
+                    countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
+                countIt->second.add( tagName );
+            }
+        }
+
+        for( std::map<std::string, TagInfo>::const_iterator countIt = tagCounts.begin(),
+                                                            countItEnd = tagCounts.end();
+                countIt != countItEnd;
+                ++countIt ) {
+            std::ostringstream oss;
+            oss << "  " << std::setw(2) << countIt->second.count << "  ";
+            Text wrapper( countIt->second.all(), TextAttributes()
+                                                    .setInitialIndent( 0 )
+                                                    .setIndent( oss.str().size() )
+                                                    .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) );
+            Catch::cout() << oss.str() << wrapper << '\n';
+        }
+        Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl;
+        return tagCounts.size();
+    }
+
+    inline std::size_t listReporters( Config const& /*config*/ ) {
+        Catch::cout() << "Available reporters:\n";
+        IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
+        IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it;
+        std::size_t maxNameLen = 0;
+        for(it = itBegin; it != itEnd; ++it )
+            maxNameLen = (std::max)( maxNameLen, it->first.size() );
+
+        for(it = itBegin; it != itEnd; ++it ) {
+            Text wrapper( it->second->getDescription(), TextAttributes()
+                                                        .setInitialIndent( 0 )
+                                                        .setIndent( 7+maxNameLen )
+                                                        .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) );
+            Catch::cout() << "  "
+                    << it->first
+                    << ':'
+                    << std::string( maxNameLen - it->first.size() + 2, ' ' )
+                    << wrapper << '\n';
+        }
+        Catch::cout() << std::endl;
+        return factories.size();
+    }
+
+    inline Option<std::size_t> list( Config const& config ) {
+        Option<std::size_t> listedCount;
+        if( config.listTests() || ( config.listExtraInfo() && !config.listTestNamesOnly() ) )
+            listedCount = listedCount.valueOr(0) + listTests( config );
+        if( config.listTestNamesOnly() )
+            listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
+        if( config.listTags() )
+            listedCount = listedCount.valueOr(0) + listTags( config );
+        if( config.listReporters() )
+            listedCount = listedCount.valueOr(0) + listReporters( config );
+        return listedCount;
+    }
+
+} // end namespace Catch
+
+// #included from: internal/catch_run_context.hpp
+#define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
+
+// #included from: catch_test_case_tracker.hpp
+#define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
+
+#include <algorithm>
+#include <string>
+#include <assert.h>
+#include <vector>
+#include <stdexcept>
+
+CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS
+
+namespace Catch {
+namespace TestCaseTracking {
+
+    struct NameAndLocation {
+        std::string name;
+        SourceLineInfo location;
+
+        NameAndLocation( std::string const& _name, SourceLineInfo const& _location )
+        :   name( _name ),
+            location( _location )
+        {}
+    };
+
+    struct ITracker : SharedImpl<> {
+        virtual ~ITracker();
+
+        // static queries
+        virtual NameAndLocation const& nameAndLocation() const = 0;
+
+        // dynamic queries
+        virtual bool isComplete() const = 0; // Successfully completed or failed
+        virtual bool isSuccessfullyCompleted() const = 0;
+        virtual bool isOpen() const = 0; // Started but not complete
+        virtual bool hasChildren() const = 0;
+
+        virtual ITracker& parent() = 0;
+
+        // actions
+        virtual void close() = 0; // Successfully complete
+        virtual void fail() = 0;
+        virtual void markAsNeedingAnotherRun() = 0;
+
+        virtual void addChild( Ptr<ITracker> const& child ) = 0;
+        virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) = 0;
+        virtual void openChild() = 0;
+
+        // Debug/ checking
+        virtual bool isSectionTracker() const = 0;
+        virtual bool isIndexTracker() const = 0;
+    };
+
+    class  TrackerContext {
+
+        enum RunState {
+            NotStarted,
+            Executing,
+            CompletedCycle
+        };
+
+        Ptr<ITracker> m_rootTracker;
+        ITracker* m_currentTracker;
+        RunState m_runState;
+
+    public:
+
+        static TrackerContext& instance() {
+            static TrackerContext s_instance;
+            return s_instance;
+        }
+
+        TrackerContext()
+        :   m_currentTracker( CATCH_NULL ),
+            m_runState( NotStarted )
+        {}
+
+        ITracker& startRun();
+
+        void endRun() {
+            m_rootTracker.reset();
+            m_currentTracker = CATCH_NULL;
+            m_runState = NotStarted;
+        }
+
+        void startCycle() {
+            m_currentTracker = m_rootTracker.get();
+            m_runState = Executing;
+        }
+        void completeCycle() {
+            m_runState = CompletedCycle;
+        }
+
+        bool completedCycle() const {
+            return m_runState == CompletedCycle;
+        }
+        ITracker& currentTracker() {
+            return *m_currentTracker;
+        }
+        void setCurrentTracker( ITracker* tracker ) {
+            m_currentTracker = tracker;
+        }
+    };
+
+    class TrackerBase : public ITracker {
+    protected:
+        enum CycleState {
+            NotStarted,
+            Executing,
+            ExecutingChildren,
+            NeedsAnotherRun,
+            CompletedSuccessfully,
+            Failed
+        };
+        class TrackerHasName {
+            NameAndLocation m_nameAndLocation;
+        public:
+            TrackerHasName( NameAndLocation const& nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {}
+            bool operator ()( Ptr<ITracker> const& tracker ) {
+                return
+                    tracker->nameAndLocation().name == m_nameAndLocation.name &&
+                    tracker->nameAndLocation().location == m_nameAndLocation.location;
+            }
+        };
+        typedef std::vector<Ptr<ITracker> > Children;
+        NameAndLocation m_nameAndLocation;
+        TrackerContext& m_ctx;
+        ITracker* m_parent;
+        Children m_children;
+        CycleState m_runState;
+    public:
+        TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
+        :   m_nameAndLocation( nameAndLocation ),
+            m_ctx( ctx ),
+            m_parent( parent ),
+            m_runState( NotStarted )
+        {}
+        virtual ~TrackerBase();
+
+        virtual NameAndLocation const& nameAndLocation() const CATCH_OVERRIDE {
+            return m_nameAndLocation;
+        }
+        virtual bool isComplete() const CATCH_OVERRIDE {
+            return m_runState == CompletedSuccessfully || m_runState == Failed;
+        }
+        virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE {
+            return m_runState == CompletedSuccessfully;
+        }
+        virtual bool isOpen() const CATCH_OVERRIDE {
+            return m_runState != NotStarted && !isComplete();
+        }
+        virtual bool hasChildren() const CATCH_OVERRIDE {
+            return !m_children.empty();
+        }
+
+        virtual void addChild( Ptr<ITracker> const& child ) CATCH_OVERRIDE {
+            m_children.push_back( child );
+        }
+
+        virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) CATCH_OVERRIDE {
+            Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( nameAndLocation ) );
+            return( it != m_children.end() )
+                ? it->get()
+                : CATCH_NULL;
+        }
+        virtual ITracker& parent() CATCH_OVERRIDE {
+            assert( m_parent ); // Should always be non-null except for root
+            return *m_parent;
+        }
+
+        virtual void openChild() CATCH_OVERRIDE {
+            if( m_runState != ExecutingChildren ) {
+                m_runState = ExecutingChildren;
+                if( m_parent )
+                    m_parent->openChild();
+            }
+        }
+
+        virtual bool isSectionTracker() const CATCH_OVERRIDE { return false; }
+        virtual bool isIndexTracker() const CATCH_OVERRIDE { return false; }
+
+        void open() {
+            m_runState = Executing;
+            moveToThis();
+            if( m_parent )
+                m_parent->openChild();
+        }
+
+        virtual void close() CATCH_OVERRIDE {
+
+            // Close any still open children (e.g. generators)
+            while( &m_ctx.currentTracker() != this )
+                m_ctx.currentTracker().close();
+
+            switch( m_runState ) {
+                case NotStarted:
+                case CompletedSuccessfully:
+                case Failed:
+                    throw std::logic_error( "Illogical state" );
+
+                case NeedsAnotherRun:
+                    break;;
+
+                case Executing:
+                    m_runState = CompletedSuccessfully;
+                    break;
+                case ExecutingChildren:
+                    if( m_children.empty() || m_children.back()->isComplete() )
+                        m_runState = CompletedSuccessfully;
+                    break;
+
+                default:
+                    throw std::logic_error( "Unexpected state" );
+            }
+            moveToParent();
+            m_ctx.completeCycle();
+        }
+        virtual void fail() CATCH_OVERRIDE {
+            m_runState = Failed;
+            if( m_parent )
+                m_parent->markAsNeedingAnotherRun();
+            moveToParent();
+            m_ctx.completeCycle();
+        }
+        virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE {
+            m_runState = NeedsAnotherRun;
+        }
+    private:
+        void moveToParent() {
+            assert( m_parent );
+            m_ctx.setCurrentTracker( m_parent );
+        }
+        void moveToThis() {
+            m_ctx.setCurrentTracker( this );
+        }
+    };
+
+    class SectionTracker : public TrackerBase {
+        std::vector<std::string> m_filters;
+    public:
+        SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
+        :   TrackerBase( nameAndLocation, ctx, parent )
+        {
+            if( parent ) {
+                while( !parent->isSectionTracker() )
+                    parent = &parent->parent();
+
+                SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );
+                addNextFilters( parentSection.m_filters );
+            }
+        }
+        virtual ~SectionTracker();
+
+        virtual bool isSectionTracker() const CATCH_OVERRIDE { return true; }
+
+        static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {
+            SectionTracker* section = CATCH_NULL;
+
+            ITracker& currentTracker = ctx.currentTracker();
+            if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) {
+                assert( childTracker );
+                assert( childTracker->isSectionTracker() );
+                section = static_cast<SectionTracker*>( childTracker );
+            }
+            else {
+                section = new SectionTracker( nameAndLocation, ctx, &currentTracker );
+                currentTracker.addChild( section );
+            }
+            if( !ctx.completedCycle() )
+                section->tryOpen();
+            return *section;
+        }
+
+        void tryOpen() {
+            if( !isComplete() && (m_filters.empty() || m_filters[0].empty() ||  m_filters[0] == m_nameAndLocation.name ) )
+                open();
+        }
+
+        void addInitialFilters( std::vector<std::string> const& filters ) {
+            if( !filters.empty() ) {
+                m_filters.push_back(""); // Root - should never be consulted
+                m_filters.push_back(""); // Test Case - not a section filter
+                m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
+            }
+        }
+        void addNextFilters( std::vector<std::string> const& filters ) {
+            if( filters.size() > 1 )
+                m_filters.insert( m_filters.end(), ++filters.begin(), filters.end() );
+        }
+    };
+
+    class IndexTracker : public TrackerBase {
+        int m_size;
+        int m_index;
+    public:
+        IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size )
+        :   TrackerBase( nameAndLocation, ctx, parent ),
+            m_size( size ),
+            m_index( -1 )
+        {}
+        virtual ~IndexTracker();
+
+        virtual bool isIndexTracker() const CATCH_OVERRIDE { return true; }
+
+        static IndexTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size ) {
+            IndexTracker* tracker = CATCH_NULL;
+
+            ITracker& currentTracker = ctx.currentTracker();
+            if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) {
+                assert( childTracker );
+                assert( childTracker->isIndexTracker() );
+                tracker = static_cast<IndexTracker*>( childTracker );
+            }
+            else {
+                tracker = new IndexTracker( nameAndLocation, ctx, &currentTracker, size );
+                currentTracker.addChild( tracker );
+            }
+
+            if( !ctx.completedCycle() && !tracker->isComplete() ) {
+                if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
+                    tracker->moveNext();
+                tracker->open();
+            }
+
+            return *tracker;
+        }
+
+        int index() const { return m_index; }
+
+        void moveNext() {
+            m_index++;
+            m_children.clear();
+        }
+
+        virtual void close() CATCH_OVERRIDE {
+            TrackerBase::close();
+            if( m_runState == CompletedSuccessfully && m_index < m_size-1 )
+                m_runState = Executing;
+        }
+    };
+
+    inline ITracker& TrackerContext::startRun() {
+        m_rootTracker = new SectionTracker( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, CATCH_NULL );
+        m_currentTracker = CATCH_NULL;
+        m_runState = Executing;
+        return *m_rootTracker;
+    }
+
+} // namespace TestCaseTracking
+
+using TestCaseTracking::ITracker;
+using TestCaseTracking::TrackerContext;
+using TestCaseTracking::SectionTracker;
+using TestCaseTracking::IndexTracker;
+
+} // namespace Catch
+
+CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
+
+// #included from: catch_fatal_condition.hpp
+#define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
+
+namespace Catch {
+
+    // Report the error condition
+    inline void reportFatal( std::string const& message ) {
+        IContext& context = Catch::getCurrentContext();
+        IResultCapture* resultCapture = context.getResultCapture();
+        resultCapture->handleFatalErrorCondition( message );
+    }
+
+} // namespace Catch
+
+#if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
+// #included from: catch_windows_h_proxy.h
+
+#define TWOBLUECUBES_CATCH_WINDOWS_H_PROXY_H_INCLUDED
+
+#ifdef CATCH_DEFINES_NOMINMAX
+#  define NOMINMAX
+#endif
+#ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN
+#  define WIN32_LEAN_AND_MEAN
+#endif
+
+#ifdef __AFXDLL
+#include <AfxWin.h>
+#else
+#include <windows.h>
+#endif
+
+#ifdef CATCH_DEFINES_NOMINMAX
+#  undef NOMINMAX
+#endif
+#ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN
+#  undef WIN32_LEAN_AND_MEAN
+#endif
+
+
+#  if !defined ( CATCH_CONFIG_WINDOWS_SEH )
+
+namespace Catch {
+    struct FatalConditionHandler {
+        void reset() {}
+    };
+}
+
+#  else // CATCH_CONFIG_WINDOWS_SEH is defined
+
+namespace Catch {
+
+    struct SignalDefs { DWORD id; const char* name; };
+    extern SignalDefs signalDefs[];
+    // There is no 1-1 mapping between signals and windows exceptions.
+    // Windows can easily distinguish between SO and SigSegV,
+    // but SigInt, SigTerm, etc are handled differently.
+    SignalDefs signalDefs[] = {
+        { EXCEPTION_ILLEGAL_INSTRUCTION,  "SIGILL - Illegal instruction signal" },
+        { EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" },
+        { EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" },
+        { EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" },
+    };
+
+    struct FatalConditionHandler {
+
+        static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {
+            for (int i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
+                if (ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) {
+                    reportFatal(signalDefs[i].name);
+                }
+            }
+            // If its not an exception we care about, pass it along.
+            // This stops us from eating debugger breaks etc.
+            return EXCEPTION_CONTINUE_SEARCH;
+        }
+
+        FatalConditionHandler() {
+            isSet = true;
+            // 32k seems enough for Catch to handle stack overflow,
+            // but the value was found experimentally, so there is no strong guarantee
+            guaranteeSize = 32 * 1024;
+            exceptionHandlerHandle = CATCH_NULL;
+            // Register as first handler in current chain
+            exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
+            // Pass in guarantee size to be filled
+            SetThreadStackGuarantee(&guaranteeSize);
+        }
+
+        static void reset() {
+            if (isSet) {
+                // Unregister handler and restore the old guarantee
+                RemoveVectoredExceptionHandler(exceptionHandlerHandle);
+                SetThreadStackGuarantee(&guaranteeSize);
+                exceptionHandlerHandle = CATCH_NULL;
+                isSet = false;
+            }
+        }
+
+        ~FatalConditionHandler() {
+            reset();
+        }
+    private:
+        static bool isSet;
+        static ULONG guaranteeSize;
+        static PVOID exceptionHandlerHandle;
+    };
+
+    bool FatalConditionHandler::isSet = false;
+    ULONG FatalConditionHandler::guaranteeSize = 0;
+    PVOID FatalConditionHandler::exceptionHandlerHandle = CATCH_NULL;
+
+} // namespace Catch
+
+#  endif // CATCH_CONFIG_WINDOWS_SEH
+
+#else // Not Windows - assumed to be POSIX compatible //////////////////////////
+
+#  if !defined(CATCH_CONFIG_POSIX_SIGNALS)
+
+namespace Catch {
+    struct FatalConditionHandler {
+        void reset() {}
+    };
+}
+
+#  else // CATCH_CONFIG_POSIX_SIGNALS is defined
+
+#include <signal.h>
+
+namespace Catch {
+
+    struct SignalDefs {
+        int id;
+        const char* name;
+    };
+    extern SignalDefs signalDefs[];
+    SignalDefs signalDefs[] = {
+            { SIGINT,  "SIGINT - Terminal interrupt signal" },
+            { SIGILL,  "SIGILL - Illegal instruction signal" },
+            { SIGFPE,  "SIGFPE - Floating point error signal" },
+            { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
+            { SIGTERM, "SIGTERM - Termination request signal" },
+            { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
+    };
+
+    struct FatalConditionHandler {
+
+        static bool isSet;
+        static struct sigaction oldSigActions [sizeof(signalDefs)/sizeof(SignalDefs)];
+        static stack_t oldSigStack;
+        static char altStackMem[SIGSTKSZ];
+
+        static void handleSignal( int sig ) {
+            std::string name = "<unknown signal>";
+            for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {
+                SignalDefs &def = signalDefs[i];
+                if (sig == def.id) {
+                    name = def.name;
+                    break;
+                }
+            }
+            reset();
+            reportFatal(name);
+            raise( sig );
+        }
+
+        FatalConditionHandler() {
+            isSet = true;
+            stack_t sigStack;
+            sigStack.ss_sp = altStackMem;
+            sigStack.ss_size = SIGSTKSZ;
+            sigStack.ss_flags = 0;
+            sigaltstack(&sigStack, &oldSigStack);
+            struct sigaction sa = { 0 };
+
+            sa.sa_handler = handleSignal;
+            sa.sa_flags = SA_ONSTACK;
+            for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) {
+                sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
+            }
+        }
+
+        ~FatalConditionHandler() {
+            reset();
+        }
+        static void reset() {
+            if( isSet ) {
+                // Set signals back to previous values -- hopefully nobody overwrote them in the meantime
+                for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) {
+                    sigaction(signalDefs[i].id, &oldSigActions[i], CATCH_NULL);
+                }
+                // Return the old stack
+                sigaltstack(&oldSigStack, CATCH_NULL);
+                isSet = false;
+            }
+        }
+    };
+
+    bool FatalConditionHandler::isSet = false;
+    struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
+    stack_t FatalConditionHandler::oldSigStack = {};
+    char FatalConditionHandler::altStackMem[SIGSTKSZ] = {};
+
+} // namespace Catch
+
+#  endif // CATCH_CONFIG_POSIX_SIGNALS
+
+#endif // not Windows
+
+#include <set>
+#include <string>
+
+namespace Catch {
+
+    class StreamRedirect {
+
+    public:
+        StreamRedirect( std::ostream& stream, std::string& targetString )
+        :   m_stream( stream ),
+            m_prevBuf( stream.rdbuf() ),
+            m_targetString( targetString )
+        {
+            stream.rdbuf( m_oss.rdbuf() );
+        }
+
+        ~StreamRedirect() {
+            m_targetString += m_oss.str();
+            m_stream.rdbuf( m_prevBuf );
+        }
+
+    private:
+        std::ostream& m_stream;
+        std::streambuf* m_prevBuf;
+        std::ostringstream m_oss;
+        std::string& m_targetString;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    class RunContext : public IResultCapture, public IRunner {
+
+        RunContext( RunContext const& );
+        void operator =( RunContext const& );
+
+    public:
+
+        explicit RunContext( Ptr<IConfig const> const& _config, Ptr<IStreamingReporter> const& reporter )
+        :   m_runInfo( _config->name() ),
+            m_context( getCurrentMutableContext() ),
+            m_activeTestCase( CATCH_NULL ),
+            m_config( _config ),
+            m_reporter( reporter ),
+            m_shouldReportUnexpected ( true )
+        {
+            m_context.setRunner( this );
+            m_context.setConfig( m_config );
+            m_context.setResultCapture( this );
+            m_reporter->testRunStarting( m_runInfo );
+        }
+
+        virtual ~RunContext() {
+            m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) );
+        }
+
+        void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
+            m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) );
+        }
+        void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) {
+            m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) );
+        }
+
+        Totals runTest( TestCase const& testCase ) {
+            Totals prevTotals = m_totals;
+
+            std::string redirectedCout;
+            std::string redirectedCerr;
+
+            TestCaseInfo testInfo = testCase.getTestCaseInfo();
+
+            m_reporter->testCaseStarting( testInfo );
+
+            m_activeTestCase = &testCase;
+
+            do {
+                ITracker& rootTracker = m_trackerContext.startRun();
+                assert( rootTracker.isSectionTracker() );
+                static_cast<SectionTracker&>( rootTracker ).addInitialFilters( m_config->getSectionsToRun() );
+                do {
+                    m_trackerContext.startCycle();
+                    m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( testInfo.name, testInfo.lineInfo ) );
+                    runCurrentTest( redirectedCout, redirectedCerr );
+                }
+                while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() );
+            }
+            // !TBD: deprecated - this will be replaced by indexed trackers
+            while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
+
+            Totals deltaTotals = m_totals.delta( prevTotals );
+            if( testInfo.expectedToFail() && deltaTotals.testCases.passed > 0 ) {
+                deltaTotals.assertions.failed++;
+                deltaTotals.testCases.passed--;
+                deltaTotals.testCases.failed++;
+            }
+            m_totals.testCases += deltaTotals.testCases;
+            m_reporter->testCaseEnded( TestCaseStats(   testInfo,
+                                                        deltaTotals,
+                                                        redirectedCout,
+                                                        redirectedCerr,
+                                                        aborting() ) );
+
+            m_activeTestCase = CATCH_NULL;
+            m_testCaseTracker = CATCH_NULL;
+
+            return deltaTotals;
+        }
+
+        Ptr<IConfig const> config() const {
+            return m_config;
+        }
+
+    private: // IResultCapture
+
+        virtual void assertionEnded( AssertionResult const& result ) {
+            if( result.getResultType() == ResultWas::Ok ) {
+                m_totals.assertions.passed++;
+            }
+            else if( !result.isOk() ) {
+                m_totals.assertions.failed++;
+            }
+
+            // We have no use for the return value (whether messages should be cleared), because messages were made scoped
+            // and should be let to clear themselves out.
+            static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
+
+            // Reset working state
+            m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
+            m_lastResult = result;
+        }
+
+        virtual bool sectionStarted (
+            SectionInfo const& sectionInfo,
+            Counts& assertions
+        )
+        {
+            ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( sectionInfo.name, sectionInfo.lineInfo ) );
+            if( !sectionTracker.isOpen() )
+                return false;
+            m_activeSections.push_back( &sectionTracker );
+
+            m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
+
+            m_reporter->sectionStarting( sectionInfo );
+
+            assertions = m_totals.assertions;
+
+            return true;
+        }
+        bool testForMissingAssertions( Counts& assertions ) {
+            if( assertions.total() != 0 )
+                return false;
+            if( !m_config->warnAboutMissingAssertions() )
+                return false;
+            if( m_trackerContext.currentTracker().hasChildren() )
+                return false;
+            m_totals.assertions.failed++;
+            assertions.failed++;
+            return true;
+        }
+
+        virtual void sectionEnded( SectionEndInfo const& endInfo ) {
+            Counts assertions = m_totals.assertions - endInfo.prevAssertions;
+            bool missingAssertions = testForMissingAssertions( assertions );
+
+            if( !m_activeSections.empty() ) {
+                m_activeSections.back()->close();
+                m_activeSections.pop_back();
+            }
+
+            m_reporter->sectionEnded( SectionStats( endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions ) );
+            m_messages.clear();
+        }
+
+        virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) {
+            if( m_unfinishedSections.empty() )
+                m_activeSections.back()->fail();
+            else
+                m_activeSections.back()->close();
+            m_activeSections.pop_back();
+
+            m_unfinishedSections.push_back( endInfo );
+        }
+
+        virtual void pushScopedMessage( MessageInfo const& message ) {
+            m_messages.push_back( message );
+        }
+
+        virtual void popScopedMessage( MessageInfo const& message ) {
+            m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() );
+        }
+
+        virtual std::string getCurrentTestName() const {
+            return m_activeTestCase
+                ? m_activeTestCase->getTestCaseInfo().name
+                : std::string();
+        }
+
+        virtual const AssertionResult* getLastResult() const {
+            return &m_lastResult;
+        }
+
+        virtual void exceptionEarlyReported() {
+            m_shouldReportUnexpected = false;
+        }
+
+        virtual void handleFatalErrorCondition( std::string const& message ) {
+            // Don't rebuild the result -- the stringification itself can cause more fatal errors
+            // Instead, fake a result data.
+            AssertionResultData tempResult;
+            tempResult.resultType = ResultWas::FatalErrorCondition;
+            tempResult.message = message;
+            AssertionResult result(m_lastAssertionInfo, tempResult);
+
+            getResultCapture().assertionEnded(result);
+
+            handleUnfinishedSections();
+
+            // Recreate section for test case (as we will lose the one that was in scope)
+            TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
+            SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
+
+            Counts assertions;
+            assertions.failed = 1;
+            SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false );
+            m_reporter->sectionEnded( testCaseSectionStats );
+
+            TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo();
+
+            Totals deltaTotals;
+            deltaTotals.testCases.failed = 1;
+            m_reporter->testCaseEnded( TestCaseStats(   testInfo,
+                                                        deltaTotals,
+                                                        std::string(),
+                                                        std::string(),
+                                                        false ) );
+            m_totals.testCases.failed++;
+            testGroupEnded( std::string(), m_totals, 1, 1 );
+            m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) );
+        }
+
+    public:
+        // !TBD We need to do this another way!
+        bool aborting() const {
+            return m_totals.assertions.failed == static_cast<std::size_t>( m_config->abortAfter() );
+        }
+
+    private:
+
+        void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
+            TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
+            SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
+            m_reporter->sectionStarting( testCaseSection );
+            Counts prevAssertions = m_totals.assertions;
+            double duration = 0;
+            m_shouldReportUnexpected = true;
+            try {
+                m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
+
+                seedRng( *m_config );
+
+                Timer timer;
+                timer.start();
+                if( m_reporter->getPreferences().shouldRedirectStdOut ) {
+                    StreamRedirect coutRedir( Catch::cout(), redirectedCout );
+                    StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr );
+                    invokeActiveTestCase();
+                }
+                else {
+                    invokeActiveTestCase();
+                }
+                duration = timer.getElapsedSeconds();
+            }
+            catch( TestFailureException& ) {
+                // This just means the test was aborted due to failure
+            }
+            catch(...) {
+                // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
+                // are reported without translation at the point of origin.
+                if (m_shouldReportUnexpected) {
+                    makeUnexpectedResultBuilder().useActiveException();
+                }
+            }
+            m_testCaseTracker->close();
+            handleUnfinishedSections();
+            m_messages.clear();
+
+            Counts assertions = m_totals.assertions - prevAssertions;
+            bool missingAssertions = testForMissingAssertions( assertions );
+
+            if( testCaseInfo.okToFail() ) {
+                std::swap( assertions.failedButOk, assertions.failed );
+                m_totals.assertions.failed -= assertions.failedButOk;
+                m_totals.assertions.failedButOk += assertions.failedButOk;
+            }
+
+            SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions );
+            m_reporter->sectionEnded( testCaseSectionStats );
+        }
+
+        void invokeActiveTestCase() {
+            FatalConditionHandler fatalConditionHandler; // Handle signals
+            m_activeTestCase->invoke();
+            fatalConditionHandler.reset();
+        }
+
+    private:
+
+        ResultBuilder makeUnexpectedResultBuilder() const {
+            return ResultBuilder(   m_lastAssertionInfo.macroName,
+                                    m_lastAssertionInfo.lineInfo,
+                                    m_lastAssertionInfo.capturedExpression,
+                                    m_lastAssertionInfo.resultDisposition );
+        }
+
+        void handleUnfinishedSections() {
+            // If sections ended prematurely due to an exception we stored their
+            // infos here so we can tear them down outside the unwind process.
+            for( std::vector<SectionEndInfo>::const_reverse_iterator it = m_unfinishedSections.rbegin(),
+                        itEnd = m_unfinishedSections.rend();
+                    it != itEnd;
+                    ++it )
+                sectionEnded( *it );
+            m_unfinishedSections.clear();
+        }
+
+        TestRunInfo m_runInfo;
+        IMutableContext& m_context;
+        TestCase const* m_activeTestCase;
+        ITracker* m_testCaseTracker;
+        ITracker* m_currentSectionTracker;
+        AssertionResult m_lastResult;
+
+        Ptr<IConfig const> m_config;
+        Totals m_totals;
+        Ptr<IStreamingReporter> m_reporter;
+        std::vector<MessageInfo> m_messages;
+        AssertionInfo m_lastAssertionInfo;
+        std::vector<SectionEndInfo> m_unfinishedSections;
+        std::vector<ITracker*> m_activeSections;
+        TrackerContext m_trackerContext;
+        bool m_shouldReportUnexpected;
+    };
+
+    IResultCapture& getResultCapture() {
+        if( IResultCapture* capture = getCurrentContext().getResultCapture() )
+            return *capture;
+        else
+            throw std::logic_error( "No result capture instance" );
+    }
+
+} // end namespace Catch
+
+// #included from: internal/catch_version.h
+#define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED
+
+namespace Catch {
+
+    // Versioning information
+    struct Version {
+        Version(    unsigned int _majorVersion,
+                    unsigned int _minorVersion,
+                    unsigned int _patchNumber,
+                    char const * const _branchName,
+                    unsigned int _buildNumber );
+
+        unsigned int const majorVersion;
+        unsigned int const minorVersion;
+        unsigned int const patchNumber;
+
+        // buildNumber is only used if branchName is not null
+        char const * const branchName;
+        unsigned int const buildNumber;
+
+        friend std::ostream& operator << ( std::ostream& os, Version const& version );
+
+    private:
+        void operator=( Version const& );
+    };
+
+    inline Version libraryVersion();
+}
+
+#include <fstream>
+#include <stdlib.h>
+#include <limits>
+
+namespace Catch {
+
+    Ptr<IStreamingReporter> createReporter( std::string const& reporterName, Ptr<Config> const& config ) {
+        Ptr<IStreamingReporter> reporter = getRegistryHub().getReporterRegistry().create( reporterName, config.get() );
+        if( !reporter ) {
+            std::ostringstream oss;
+            oss << "No reporter registered with name: '" << reporterName << "'";
+            throw std::domain_error( oss.str() );
+        }
+        return reporter;
+    }
+
+    Ptr<IStreamingReporter> makeReporter( Ptr<Config> const& config ) {
+        std::vector<std::string> reporters = config->getReporterNames();
+        if( reporters.empty() )
+            reporters.push_back( "console" );
+
+        Ptr<IStreamingReporter> reporter;
+        for( std::vector<std::string>::const_iterator it = reporters.begin(), itEnd = reporters.end();
+                it != itEnd;
+                ++it )
+            reporter = addReporter( reporter, createReporter( *it, config ) );
+        return reporter;
+    }
+    Ptr<IStreamingReporter> addListeners( Ptr<IConfig const> const& config, Ptr<IStreamingReporter> reporters ) {
+        IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners();
+        for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end();
+                it != itEnd;
+                ++it )
+            reporters = addReporter(reporters, (*it)->create( ReporterConfig( config ) ) );
+        return reporters;
+    }
+
+    Totals runTests( Ptr<Config> const& config ) {
+
+        Ptr<IConfig const> iconfig = config.get();
+
+        Ptr<IStreamingReporter> reporter = makeReporter( config );
+        reporter = addListeners( iconfig, reporter );
+
+        RunContext context( iconfig, reporter );
+
+        Totals totals;
+
+        context.testGroupStarting( config->name(), 1, 1 );
+
+        TestSpec testSpec = config->testSpec();
+        if( !testSpec.hasFilters() )
+            testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests
+
+        std::vector<TestCase> const& allTestCases = getAllTestCasesSorted( *iconfig );
+        for( std::vector<TestCase>::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end();
+                it != itEnd;
+                ++it ) {
+            if( !context.aborting() && matchTest( *it, testSpec, *iconfig ) )
+                totals += context.runTest( *it );
+            else
+                reporter->skipTest( *it );
+        }
+
+        context.testGroupEnded( iconfig->name(), totals, 1, 1 );
+        return totals;
+    }
+
+    void applyFilenamesAsTags( IConfig const& config ) {
+        std::vector<TestCase> const& tests = getAllTestCasesSorted( config );
+        for(std::size_t i = 0; i < tests.size(); ++i ) {
+            TestCase& test = const_cast<TestCase&>( tests[i] );
+            std::set<std::string> tags = test.tags;
+
+            std::string filename = test.lineInfo.file;
+            std::string::size_type lastSlash = filename.find_last_of( "\\/" );
+            if( lastSlash != std::string::npos )
+                filename = filename.substr( lastSlash+1 );
+
+            std::string::size_type lastDot = filename.find_last_of( "." );
+            if( lastDot != std::string::npos )
+                filename = filename.substr( 0, lastDot );
+
+            tags.insert( "#" + filename );
+            setTags( test, tags );
+        }
+    }
+
+    class Session : NonCopyable {
+        static bool alreadyInstantiated;
+
+    public:
+
+        struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; };
+
+        Session()
+        : m_cli( makeCommandLineParser() ) {
+            if( alreadyInstantiated ) {
+                std::string msg = "Only one instance of Catch::Session can ever be used";
+                Catch::cerr() << msg << std::endl;
+                throw std::logic_error( msg );
+            }
+            alreadyInstantiated = true;
+        }
+        ~Session() {
+            Catch::cleanUp();
+        }
+
+        void showHelp( std::string const& processName ) {
+            Catch::cout() << "\nCatch v" << libraryVersion() << "\n";
+
+            m_cli.usage( Catch::cout(), processName );
+            Catch::cout() << "For more detail usage please see the project docs\n" << std::endl;
+        }
+
+        int applyCommandLine( int argc, char const* const* const argv, OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
+            try {
+                m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );
+                m_unusedTokens = m_cli.parseInto( Clara::argsToVector( argc, argv ), m_configData );
+                if( m_configData.showHelp )
+                    showHelp( m_configData.processName );
+                m_config.reset();
+            }
+            catch( std::exception& ex ) {
+                {
+                    Colour colourGuard( Colour::Red );
+                    Catch::cerr()
+                        << "\nError(s) in input:\n"
+                        << Text( ex.what(), TextAttributes().setIndent(2) )
+                        << "\n\n";
+                }
+                m_cli.usage( Catch::cout(), m_configData.processName );
+                return (std::numeric_limits<int>::max)();
+            }
+            return 0;
+        }
+
+        void useConfigData( ConfigData const& _configData ) {
+            m_configData = _configData;
+            m_config.reset();
+        }
+
+        int run( int argc, char const* const* const argv ) {
+
+            int returnCode = applyCommandLine( argc, argv );
+            if( returnCode == 0 )
+                returnCode = run();
+            return returnCode;
+        }
+
+    #if defined(WIN32) && defined(UNICODE)
+        int run( int argc, wchar_t const* const* const argv ) {
+
+            char **utf8Argv = new char *[ argc ];
+
+            for ( int i = 0; i < argc; ++i ) {
+                int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL );
+
+                utf8Argv[ i ] = new char[ bufSize ];
+
+                WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL );
+            }
+
+            int returnCode = applyCommandLine( argc, utf8Argv );
+            if( returnCode == 0 )
+                returnCode = run();
+
+            for ( int i = 0; i < argc; ++i )
+                delete [] utf8Argv[ i ];
+
+            delete [] utf8Argv;
+
+            return returnCode;
+        }
+    #endif
+
+        int run() {
+            if( m_configData.showHelp )
+                return 0;
+
+            try
+            {
+                config(); // Force config to be constructed
+
+                seedRng( *m_config );
+
+                if( m_configData.filenamesAsTags )
+                    applyFilenamesAsTags( *m_config );
+
+                // Handle list request
+                if( Option<std::size_t> listed = list( config() ) )
+                    return static_cast<int>( *listed );
+
+                return static_cast<int>( runTests( m_config ).assertions.failed );
+            }
+            catch( std::exception& ex ) {
+                Catch::cerr() << ex.what() << std::endl;
+                return (std::numeric_limits<int>::max)();
+            }
+        }
+
+        Clara::CommandLine<ConfigData> const& cli() const {
+            return m_cli;
+        }
+        std::vector<Clara::Parser::Token> const& unusedTokens() const {
+            return m_unusedTokens;
+        }
+        ConfigData& configData() {
+            return m_configData;
+        }
+        Config& config() {
+            if( !m_config )
+                m_config = new Config( m_configData );
+            return *m_config;
+        }
+    private:
+        Clara::CommandLine<ConfigData> m_cli;
+        std::vector<Clara::Parser::Token> m_unusedTokens;
+        ConfigData m_configData;
+        Ptr<Config> m_config;
+    };
+
+    bool Session::alreadyInstantiated = false;
+
+} // end namespace Catch
+
+// #included from: catch_registry_hub.hpp
+#define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED
+
+// #included from: catch_test_case_registry_impl.hpp
+#define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
+
+#include <vector>
+#include <set>
+#include <sstream>
+#include <algorithm>
+
+namespace Catch {
+
+    struct RandomNumberGenerator {
+        typedef std::ptrdiff_t result_type;
+
+        result_type operator()( result_type n ) const { return std::rand() % n; }
+
+#ifdef CATCH_CONFIG_CPP11_SHUFFLE
+        static constexpr result_type min() { return 0; }
+        static constexpr result_type max() { return 1000000; }
+        result_type operator()() const { return std::rand() % max(); }
+#endif
+        template<typename V>
+        static void shuffle( V& vector ) {
+            RandomNumberGenerator rng;
+#ifdef CATCH_CONFIG_CPP11_SHUFFLE
+            std::shuffle( vector.begin(), vector.end(), rng );
+#else
+            std::random_shuffle( vector.begin(), vector.end(), rng );
+#endif
+        }
+    };
+
+    inline std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
+
+        std::vector<TestCase> sorted = unsortedTestCases;
+
+        switch( config.runOrder() ) {
+            case RunTests::InLexicographicalOrder:
+                std::sort( sorted.begin(), sorted.end() );
+                break;
+            case RunTests::InRandomOrder:
+                {
+                    seedRng( config );
+                    RandomNumberGenerator::shuffle( sorted );
+                }
+                break;
+            case RunTests::InDeclarationOrder:
+                // already in declaration order
+                break;
+        }
+        return sorted;
+    }
+    bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
+        return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );
+    }
+
+    void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
+        std::set<TestCase> seenFunctions;
+        for( std::vector<TestCase>::const_iterator it = functions.begin(), itEnd = functions.end();
+            it != itEnd;
+            ++it ) {
+            std::pair<std::set<TestCase>::const_iterator, bool> prev = seenFunctions.insert( *it );
+            if( !prev.second ) {
+                std::ostringstream ss;
+
+                ss  << Colour( Colour::Red )
+                    << "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n"
+                    << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << '\n'
+                    << "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl;
+
+                throw std::runtime_error(ss.str());
+            }
+        }
+    }
+
+    std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
+        std::vector<TestCase> filtered;
+        filtered.reserve( testCases.size() );
+        for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end();
+                it != itEnd;
+                ++it )
+            if( matchTest( *it, testSpec, config ) )
+                filtered.push_back( *it );
+        return filtered;
+    }
+    std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
+        return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
+    }
+
+    class TestRegistry : public ITestCaseRegistry {
+    public:
+        TestRegistry()
+        :   m_currentSortOrder( RunTests::InDeclarationOrder ),
+            m_unnamedCount( 0 )
+        {}
+        virtual ~TestRegistry();
+
+        virtual void registerTest( TestCase const& testCase ) {
+            std::string name = testCase.getTestCaseInfo().name;
+            if( name.empty() ) {
+                std::ostringstream oss;
+                oss << "Anonymous test case " << ++m_unnamedCount;
+                return registerTest( testCase.withName( oss.str() ) );
+            }
+            m_functions.push_back( testCase );
+        }
+
+        virtual std::vector<TestCase> const& getAllTests() const {
+            return m_functions;
+        }
+        virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const {
+            if( m_sortedFunctions.empty() )
+                enforceNoDuplicateTestCases( m_functions );
+
+            if(  m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
+                m_sortedFunctions = sortTests( config, m_functions );
+                m_currentSortOrder = config.runOrder();
+            }
+            return m_sortedFunctions;
+        }
+
+    private:
+        std::vector<TestCase> m_functions;
+        mutable RunTests::InWhatOrder m_currentSortOrder;
+        mutable std::vector<TestCase> m_sortedFunctions;
+        size_t m_unnamedCount;
+        std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    class FreeFunctionTestCase : public SharedImpl<ITestCase> {
+    public:
+
+        FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {}
+
+        virtual void invoke() const {
+            m_fun();
+        }
+
+    private:
+        virtual ~FreeFunctionTestCase();
+
+        TestFunction m_fun;
+    };
+
+    inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) {
+        std::string className = classOrQualifiedMethodName;
+        if( startsWith( className, '&' ) )
+        {
+            std::size_t lastColons = className.rfind( "::" );
+            std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
+            if( penultimateColons == std::string::npos )
+                penultimateColons = 1;
+            className = className.substr( penultimateColons, lastColons-penultimateColons );
+        }
+        return className;
+    }
+
+    void registerTestCase
+        (   ITestCase* testCase,
+            char const* classOrQualifiedMethodName,
+            NameAndDesc const& nameAndDesc,
+            SourceLineInfo const& lineInfo ) {
+
+        getMutableRegistryHub().registerTest
+            ( makeTestCase
+                (   testCase,
+                    extractClassName( classOrQualifiedMethodName ),
+                    nameAndDesc.name,
+                    nameAndDesc.description,
+                    lineInfo ) );
+    }
+    void registerTestCaseFunction
+        (   TestFunction function,
+            SourceLineInfo const& lineInfo,
+            NameAndDesc const& nameAndDesc ) {
+        registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo );
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    AutoReg::AutoReg
+        (   TestFunction function,
+            SourceLineInfo const& lineInfo,
+            NameAndDesc const& nameAndDesc ) {
+        registerTestCaseFunction( function, lineInfo, nameAndDesc );
+    }
+
+    AutoReg::~AutoReg() {}
+
+} // end namespace Catch
+
+// #included from: catch_reporter_registry.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED
+
+#include <map>
+
+namespace Catch {
+
+    class ReporterRegistry : public IReporterRegistry {
+
+    public:
+
+        virtual ~ReporterRegistry() CATCH_OVERRIDE {}
+
+        virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const CATCH_OVERRIDE {
+            FactoryMap::const_iterator it =  m_factories.find( name );
+            if( it == m_factories.end() )
+                return CATCH_NULL;
+            return it->second->create( ReporterConfig( config ) );
+        }
+
+        void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) {
+            m_factories.insert( std::make_pair( name, factory ) );
+        }
+        void registerListener( Ptr<IReporterFactory> const& factory ) {
+            m_listeners.push_back( factory );
+        }
+
+        virtual FactoryMap const& getFactories() const CATCH_OVERRIDE {
+            return m_factories;
+        }
+        virtual Listeners const& getListeners() const CATCH_OVERRIDE {
+            return m_listeners;
+        }
+
+    private:
+        FactoryMap m_factories;
+        Listeners m_listeners;
+    };
+}
+
+// #included from: catch_exception_translator_registry.hpp
+#define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
+
+#ifdef __OBJC__
+#import "Foundation/Foundation.h"
+#endif
+
+namespace Catch {
+
+    class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
+    public:
+        ~ExceptionTranslatorRegistry() {
+            deleteAll( m_translators );
+        }
+
+        virtual void registerTranslator( const IExceptionTranslator* translator ) {
+            m_translators.push_back( translator );
+        }
+
+        virtual std::string translateActiveException() const {
+            try {
+#ifdef __OBJC__
+                // In Objective-C try objective-c exceptions first
+                @try {
+                    return tryTranslators();
+                }
+                @catch (NSException *exception) {
+                    return Catch::toString( [exception description] );
+                }
+#else
+                return tryTranslators();
+#endif
+            }
+            catch( TestFailureException& ) {
+                throw;
+            }
+            catch( std::exception& ex ) {
+                return ex.what();
+            }
+            catch( std::string& msg ) {
+                return msg;
+            }
+            catch( const char* msg ) {
+                return msg;
+            }
+            catch(...) {
+                return "Unknown exception";
+            }
+        }
+
+        std::string tryTranslators() const {
+            if( m_translators.empty() )
+                throw;
+            else
+                return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() );
+        }
+
+    private:
+        std::vector<const IExceptionTranslator*> m_translators;
+    };
+}
+
+// #included from: catch_tag_alias_registry.h
+#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED
+
+#include <map>
+
+namespace Catch {
+
+    class TagAliasRegistry : public ITagAliasRegistry {
+    public:
+        virtual ~TagAliasRegistry();
+        virtual Option<TagAlias> find( std::string const& alias ) const;
+        virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const;
+        void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );
+
+    private:
+        std::map<std::string, TagAlias> m_registry;
+    };
+
+} // end namespace Catch
+
+namespace Catch {
+
+    namespace {
+
+        class RegistryHub : public IRegistryHub, public IMutableRegistryHub {
+
+            RegistryHub( RegistryHub const& );
+            void operator=( RegistryHub const& );
+
+        public: // IRegistryHub
+            RegistryHub() {
+            }
+            virtual IReporterRegistry const& getReporterRegistry() const CATCH_OVERRIDE {
+                return m_reporterRegistry;
+            }
+            virtual ITestCaseRegistry const& getTestCaseRegistry() const CATCH_OVERRIDE {
+                return m_testCaseRegistry;
+            }
+            virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() CATCH_OVERRIDE {
+                return m_exceptionTranslatorRegistry;
+            }
+            virtual ITagAliasRegistry const& getTagAliasRegistry() const CATCH_OVERRIDE {
+                return m_tagAliasRegistry;
+            }
+
+        public: // IMutableRegistryHub
+            virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
+                m_reporterRegistry.registerReporter( name, factory );
+            }
+            virtual void registerListener( Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
+                m_reporterRegistry.registerListener( factory );
+            }
+            virtual void registerTest( TestCase const& testInfo ) CATCH_OVERRIDE {
+                m_testCaseRegistry.registerTest( testInfo );
+            }
+            virtual void registerTranslator( const IExceptionTranslator* translator ) CATCH_OVERRIDE {
+                m_exceptionTranslatorRegistry.registerTranslator( translator );
+            }
+            virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) CATCH_OVERRIDE {
+                m_tagAliasRegistry.add( alias, tag, lineInfo );
+            }
+
+        private:
+            TestRegistry m_testCaseRegistry;
+            ReporterRegistry m_reporterRegistry;
+            ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
+            TagAliasRegistry m_tagAliasRegistry;
+        };
+
+        // Single, global, instance
+        inline RegistryHub*& getTheRegistryHub() {
+            static RegistryHub* theRegistryHub = CATCH_NULL;
+            if( !theRegistryHub )
+                theRegistryHub = new RegistryHub();
+            return theRegistryHub;
+        }
+    }
+
+    IRegistryHub& getRegistryHub() {
+        return *getTheRegistryHub();
+    }
+    IMutableRegistryHub& getMutableRegistryHub() {
+        return *getTheRegistryHub();
+    }
+    void cleanUp() {
+        delete getTheRegistryHub();
+        getTheRegistryHub() = CATCH_NULL;
+        cleanUpContext();
+    }
+    std::string translateActiveException() {
+        return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
+    }
+
+} // end namespace Catch
+
+// #included from: catch_notimplemented_exception.hpp
+#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED
+
+#include <sstream>
+
+namespace Catch {
+
+    NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo )
+    :   m_lineInfo( lineInfo ) {
+        std::ostringstream oss;
+        oss << lineInfo << ": function ";
+        oss << "not implemented";
+        m_what = oss.str();
+    }
+
+    const char* NotImplementedException::what() const CATCH_NOEXCEPT {
+        return m_what.c_str();
+    }
+
+} // end namespace Catch
+
+// #included from: catch_context_impl.hpp
+#define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED
+
+// #included from: catch_stream.hpp
+#define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
+
+#include <stdexcept>
+#include <cstdio>
+#include <iostream>
+
+namespace Catch {
+
+    template<typename WriterF, size_t bufferSize=256>
+    class StreamBufImpl : public StreamBufBase {
+        char data[bufferSize];
+        WriterF m_writer;
+
+    public:
+        StreamBufImpl() {
+            setp( data, data + sizeof(data) );
+        }
+
+        ~StreamBufImpl() CATCH_NOEXCEPT {
+            sync();
+        }
+
+    private:
+        int overflow( int c ) {
+            sync();
+
+            if( c != EOF ) {
+                if( pbase() == epptr() )
+                    m_writer( std::string( 1, static_cast<char>( c ) ) );
+                else
+                    sputc( static_cast<char>( c ) );
+            }
+            return 0;
+        }
+
+        int sync() {
+            if( pbase() != pptr() ) {
+                m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
+                setp( pbase(), epptr() );
+            }
+            return 0;
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    FileStream::FileStream( std::string const& filename ) {
+        m_ofs.open( filename.c_str() );
+        if( m_ofs.fail() ) {
+            std::ostringstream oss;
+            oss << "Unable to open file: '" << filename << '\'';
+            throw std::domain_error( oss.str() );
+        }
+    }
+
+    std::ostream& FileStream::stream() const {
+        return m_ofs;
+    }
+
+    struct OutputDebugWriter {
+
+        void operator()( std::string const&str ) {
+            writeToDebugConsole( str );
+        }
+    };
+
+    DebugOutStream::DebugOutStream()
+    :   m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
+        m_os( m_streamBuf.get() )
+    {}
+
+    std::ostream& DebugOutStream::stream() const {
+        return m_os;
+    }
+
+    // Store the streambuf from cout up-front because
+    // cout may get redirected when running tests
+    CoutStream::CoutStream()
+    :   m_os( Catch::cout().rdbuf() )
+    {}
+
+    std::ostream& CoutStream::stream() const {
+        return m_os;
+    }
+
+#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
+    std::ostream& cout() {
+        return std::cout;
+    }
+    std::ostream& cerr() {
+        return std::cerr;
+    }
+#endif
+}
+
+namespace Catch {
+
+    class Context : public IMutableContext {
+
+        Context() : m_config( CATCH_NULL ), m_runner( CATCH_NULL ), m_resultCapture( CATCH_NULL ) {}
+        Context( Context const& );
+        void operator=( Context const& );
+
+    public:
+        virtual ~Context() {
+            deleteAllValues( m_generatorsByTestName );
+        }
+
+    public: // IContext
+        virtual IResultCapture* getResultCapture() {
+            return m_resultCapture;
+        }
+        virtual IRunner* getRunner() {
+            return m_runner;
+        }
+        virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) {
+            return getGeneratorsForCurrentTest()
+            .getGeneratorInfo( fileInfo, totalSize )
+            .getCurrentIndex();
+        }
+        virtual bool advanceGeneratorsForCurrentTest() {
+            IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
+            return generators && generators->moveNext();
+        }
+
+        virtual Ptr<IConfig const> getConfig() const {
+            return m_config;
+        }
+
+    public: // IMutableContext
+        virtual void setResultCapture( IResultCapture* resultCapture ) {
+            m_resultCapture = resultCapture;
+        }
+        virtual void setRunner( IRunner* runner ) {
+            m_runner = runner;
+        }
+        virtual void setConfig( Ptr<IConfig const> const& config ) {
+            m_config = config;
+        }
+
+        friend IMutableContext& getCurrentMutableContext();
+
+    private:
+        IGeneratorsForTest* findGeneratorsForCurrentTest() {
+            std::string testName = getResultCapture()->getCurrentTestName();
+
+            std::map<std::string, IGeneratorsForTest*>::const_iterator it =
+                m_generatorsByTestName.find( testName );
+            return it != m_generatorsByTestName.end()
+                ? it->second
+                : CATCH_NULL;
+        }
+
+        IGeneratorsForTest& getGeneratorsForCurrentTest() {
+            IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
+            if( !generators ) {
+                std::string testName = getResultCapture()->getCurrentTestName();
+                generators = createGeneratorsForTest();
+                m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
+            }
+            return *generators;
+        }
+
+    private:
+        Ptr<IConfig const> m_config;
+        IRunner* m_runner;
+        IResultCapture* m_resultCapture;
+        std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
+    };
+
+    namespace {
+        Context* currentContext = CATCH_NULL;
+    }
+    IMutableContext& getCurrentMutableContext() {
+        if( !currentContext )
+            currentContext = new Context();
+        return *currentContext;
+    }
+    IContext& getCurrentContext() {
+        return getCurrentMutableContext();
+    }
+
+    void cleanUpContext() {
+        delete currentContext;
+        currentContext = CATCH_NULL;
+    }
+}
+
+// #included from: catch_console_colour_impl.hpp
+#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
+
+// #included from: catch_errno_guard.hpp
+#define TWOBLUECUBES_CATCH_ERRNO_GUARD_HPP_INCLUDED
+
+#include <cerrno>
+
+namespace Catch {
+
+    class ErrnoGuard {
+    public:
+        ErrnoGuard():m_oldErrno(errno){}
+        ~ErrnoGuard() { errno = m_oldErrno; }
+    private:
+        int m_oldErrno;
+    };
+
+}
+
+namespace Catch {
+    namespace {
+
+        struct IColourImpl {
+            virtual ~IColourImpl() {}
+            virtual void use( Colour::Code _colourCode ) = 0;
+        };
+
+        struct NoColourImpl : IColourImpl {
+            void use( Colour::Code ) {}
+
+            static IColourImpl* instance() {
+                static NoColourImpl s_instance;
+                return &s_instance;
+            }
+        };
+
+    } // anon namespace
+} // namespace Catch
+
+#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
+#   ifdef CATCH_PLATFORM_WINDOWS
+#       define CATCH_CONFIG_COLOUR_WINDOWS
+#   else
+#       define CATCH_CONFIG_COLOUR_ANSI
+#   endif
+#endif
+
+#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
+
+namespace Catch {
+namespace {
+
+    class Win32ColourImpl : public IColourImpl {
+    public:
+        Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
+        {
+            CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
+            GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
+            originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
+            originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
+        }
+
+        virtual void use( Colour::Code _colourCode ) {
+            switch( _colourCode ) {
+                case Colour::None:      return setTextAttribute( originalForegroundAttributes );
+                case Colour::White:     return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
+                case Colour::Red:       return setTextAttribute( FOREGROUND_RED );
+                case Colour::Green:     return setTextAttribute( FOREGROUND_GREEN );
+                case Colour::Blue:      return setTextAttribute( FOREGROUND_BLUE );
+                case Colour::Cyan:      return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
+                case Colour::Yellow:    return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
+                case Colour::Grey:      return setTextAttribute( 0 );
+
+                case Colour::LightGrey:     return setTextAttribute( FOREGROUND_INTENSITY );
+                case Colour::BrightRed:     return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
+                case Colour::BrightGreen:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
+                case Colour::BrightWhite:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
+
+                case Colour::Bright: throw std::logic_error( "not a colour" );
+            }
+        }
+
+    private:
+        void setTextAttribute( WORD _textAttribute ) {
+            SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
+        }
+        HANDLE stdoutHandle;
+        WORD originalForegroundAttributes;
+        WORD originalBackgroundAttributes;
+    };
+
+    IColourImpl* platformColourInstance() {
+        static Win32ColourImpl s_instance;
+
+        Ptr<IConfig const> config = getCurrentContext().getConfig();
+        UseColour::YesOrNo colourMode = config
+            ? config->useColour()
+            : UseColour::Auto;
+        if( colourMode == UseColour::Auto )
+            colourMode = !isDebuggerActive()
+                ? UseColour::Yes
+                : UseColour::No;
+        return colourMode == UseColour::Yes
+            ? &s_instance
+            : NoColourImpl::instance();
+    }
+
+} // end anon namespace
+} // end namespace Catch
+
+#elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
+
+#include <unistd.h>
+
+namespace Catch {
+namespace {
+
+    // use POSIX/ ANSI console terminal codes
+    // Thanks to Adam Strzelecki for original contribution
+    // (http://github.com/nanoant)
+    // https://github.com/philsquared/Catch/pull/131
+    class PosixColourImpl : public IColourImpl {
+    public:
+        virtual void use( Colour::Code _colourCode ) {
+            switch( _colourCode ) {
+                case Colour::None:
+                case Colour::White:     return setColour( "[0m" );
+                case Colour::Red:       return setColour( "[0;31m" );
+                case Colour::Green:     return setColour( "[0;32m" );
+                case Colour::Blue:      return setColour( "[0;34m" );
+                case Colour::Cyan:      return setColour( "[0;36m" );
+                case Colour::Yellow:    return setColour( "[0;33m" );
+                case Colour::Grey:      return setColour( "[1;30m" );
+
+                case Colour::LightGrey:     return setColour( "[0;37m" );
+                case Colour::BrightRed:     return setColour( "[1;31m" );
+                case Colour::BrightGreen:   return setColour( "[1;32m" );
+                case Colour::BrightWhite:   return setColour( "[1;37m" );
+
+                case Colour::Bright: throw std::logic_error( "not a colour" );
+            }
+        }
+        static IColourImpl* instance() {
+            static PosixColourImpl s_instance;
+            return &s_instance;
+        }
+
+    private:
+        void setColour( const char* _escapeCode ) {
+            Catch::cout() << '\033' << _escapeCode;
+        }
+    };
+
+    IColourImpl* platformColourInstance() {
+        ErrnoGuard guard;
+        Ptr<IConfig const> config = getCurrentContext().getConfig();
+        UseColour::YesOrNo colourMode = config
+            ? config->useColour()
+            : UseColour::Auto;
+        if( colourMode == UseColour::Auto )
+            colourMode = (!isDebuggerActive() && isatty(STDOUT_FILENO) )
+                ? UseColour::Yes
+                : UseColour::No;
+        return colourMode == UseColour::Yes
+            ? PosixColourImpl::instance()
+            : NoColourImpl::instance();
+    }
+
+} // end anon namespace
+} // end namespace Catch
+
+#else  // not Windows or ANSI ///////////////////////////////////////////////
+
+namespace Catch {
+
+    static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
+
+} // end namespace Catch
+
+#endif // Windows/ ANSI/ None
+
+namespace Catch {
+
+    Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); }
+    Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast<Colour&>( _other ).m_moved = true; }
+    Colour::~Colour(){ if( !m_moved ) use( None ); }
+
+    void Colour::use( Code _colourCode ) {
+        static IColourImpl* impl = platformColourInstance();
+        impl->use( _colourCode );
+    }
+
+} // end namespace Catch
+
+// #included from: catch_generators_impl.hpp
+#define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED
+
+#include <vector>
+#include <string>
+#include <map>
+
+namespace Catch {
+
+    struct GeneratorInfo : IGeneratorInfo {
+
+        GeneratorInfo( std::size_t size )
+        :   m_size( size ),
+            m_currentIndex( 0 )
+        {}
+
+        bool moveNext() {
+            if( ++m_currentIndex == m_size ) {
+                m_currentIndex = 0;
+                return false;
+            }
+            return true;
+        }
+
+        std::size_t getCurrentIndex() const {
+            return m_currentIndex;
+        }
+
+        std::size_t m_size;
+        std::size_t m_currentIndex;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    class GeneratorsForTest : public IGeneratorsForTest {
+
+    public:
+        ~GeneratorsForTest() {
+            deleteAll( m_generatorsInOrder );
+        }
+
+        IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) {
+            std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo );
+            if( it == m_generatorsByName.end() ) {
+                IGeneratorInfo* info = new GeneratorInfo( size );
+                m_generatorsByName.insert( std::make_pair( fileInfo, info ) );
+                m_generatorsInOrder.push_back( info );
+                return *info;
+            }
+            return *it->second;
+        }
+
+        bool moveNext() {
+            std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();
+            std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end();
+            for(; it != itEnd; ++it ) {
+                if( (*it)->moveNext() )
+                    return true;
+            }
+            return false;
+        }
+
+    private:
+        std::map<std::string, IGeneratorInfo*> m_generatorsByName;
+        std::vector<IGeneratorInfo*> m_generatorsInOrder;
+    };
+
+    IGeneratorsForTest* createGeneratorsForTest()
+    {
+        return new GeneratorsForTest();
+    }
+
+} // end namespace Catch
+
+// #included from: catch_assertionresult.hpp
+#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED
+
+namespace Catch {
+
+    AssertionInfo::AssertionInfo(   char const * _macroName,
+                                    SourceLineInfo const& _lineInfo,
+                                    char const * _capturedExpression,
+                                    ResultDisposition::Flags _resultDisposition,
+                                    char const * _secondArg)
+    :   macroName( _macroName ),
+        lineInfo( _lineInfo ),
+        capturedExpression( _capturedExpression ),
+        resultDisposition( _resultDisposition ),
+        secondArg( _secondArg )
+    {}
+
+    AssertionResult::AssertionResult() {}
+
+    AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
+    :   m_info( info ),
+        m_resultData( data )
+    {}
+
+    AssertionResult::~AssertionResult() {}
+
+    // Result was a success
+    bool AssertionResult::succeeded() const {
+        return Catch::isOk( m_resultData.resultType );
+    }
+
+    // Result was a success, or failure is suppressed
+    bool AssertionResult::isOk() const {
+        return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
+    }
+
+    ResultWas::OfType AssertionResult::getResultType() const {
+        return m_resultData.resultType;
+    }
+
+    bool AssertionResult::hasExpression() const {
+        return m_info.capturedExpression[0] != 0;
+    }
+
+    bool AssertionResult::hasMessage() const {
+        return !m_resultData.message.empty();
+    }
+
+    std::string capturedExpressionWithSecondArgument( char const * capturedExpression, char const * secondArg ) {
+        return (secondArg[0] == 0 || secondArg[0] == '"' && secondArg[1] == '"')
+            ? capturedExpression
+            : std::string(capturedExpression) + ", " + secondArg;
+    }
+
+    std::string AssertionResult::getExpression() const {
+        if( isFalseTest( m_info.resultDisposition ) )
+            return '!' + capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg);
+        else
+            return capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg);
+    }
+    std::string AssertionResult::getExpressionInMacro() const {
+        if( m_info.macroName[0] == 0 )
+            return capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg);
+        else
+            return std::string(m_info.macroName) + "( " + capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg) + " )";
+    }
+
+    bool AssertionResult::hasExpandedExpression() const {
+        return hasExpression() && getExpandedExpression() != getExpression();
+    }
+
+    std::string AssertionResult::getExpandedExpression() const {
+        return m_resultData.reconstructExpression();
+    }
+
+    std::string AssertionResult::getMessage() const {
+        return m_resultData.message;
+    }
+    SourceLineInfo AssertionResult::getSourceInfo() const {
+        return m_info.lineInfo;
+    }
+
+    std::string AssertionResult::getTestMacroName() const {
+        return m_info.macroName;
+    }
+
+    void AssertionResult::discardDecomposedExpression() const {
+        m_resultData.decomposedExpression = CATCH_NULL;
+    }
+
+    void AssertionResult::expandDecomposedExpression() const {
+        m_resultData.reconstructExpression();
+    }
+
+} // end namespace Catch
+
+// #included from: catch_test_case_info.hpp
+#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED
+
+#include <cctype>
+
+namespace Catch {
+
+    inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
+        if( startsWith( tag, '.' ) ||
+            tag == "hide" ||
+            tag == "!hide" )
+            return TestCaseInfo::IsHidden;
+        else if( tag == "!throws" )
+            return TestCaseInfo::Throws;
+        else if( tag == "!shouldfail" )
+            return TestCaseInfo::ShouldFail;
+        else if( tag == "!mayfail" )
+            return TestCaseInfo::MayFail;
+        else if( tag == "!nonportable" )
+            return TestCaseInfo::NonPortable;
+        else
+            return TestCaseInfo::None;
+    }
+    inline bool isReservedTag( std::string const& tag ) {
+        return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( tag[0] );
+    }
+    inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
+        if( isReservedTag( tag ) ) {
+            std::ostringstream ss;
+            ss << Colour(Colour::Red)
+               << "Tag name [" << tag << "] not allowed.\n"
+               << "Tag names starting with non alpha-numeric characters are reserved\n"
+               << Colour(Colour::FileName)
+               << _lineInfo << '\n';
+            throw std::runtime_error(ss.str());
+        }
+    }
+
+    TestCase makeTestCase(  ITestCase* _testCase,
+                            std::string const& _className,
+                            std::string const& _name,
+                            std::string const& _descOrTags,
+                            SourceLineInfo const& _lineInfo )
+    {
+        bool isHidden( startsWith( _name, "./" ) ); // Legacy support
+
+        // Parse out tags
+        std::set<std::string> tags;
+        std::string desc, tag;
+        bool inTag = false;
+        for( std::size_t i = 0; i < _descOrTags.size(); ++i ) {
+            char c = _descOrTags[i];
+            if( !inTag ) {
+                if( c == '[' )
+                    inTag = true;
+                else
+                    desc += c;
+            }
+            else {
+                if( c == ']' ) {
+                    TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
+                    if( prop == TestCaseInfo::IsHidden )
+                        isHidden = true;
+                    else if( prop == TestCaseInfo::None )
+                        enforceNotReservedTag( tag, _lineInfo );
+
+                    tags.insert( tag );
+                    tag.clear();
+                    inTag = false;
+                }
+                else
+                    tag += c;
+            }
+        }
+        if( isHidden ) {
+            tags.insert( "hide" );
+            tags.insert( "." );
+        }
+
+        TestCaseInfo info( _name, _className, desc, tags, _lineInfo );
+        return TestCase( _testCase, info );
+    }
+
+    void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags )
+    {
+        testCaseInfo.tags = tags;
+        testCaseInfo.lcaseTags.clear();
+
+        std::ostringstream oss;
+        for( std::set<std::string>::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) {
+            oss << '[' << *it << ']';
+            std::string lcaseTag = toLower( *it );
+            testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
+            testCaseInfo.lcaseTags.insert( lcaseTag );
+        }
+        testCaseInfo.tagsAsString = oss.str();
+    }
+
+    TestCaseInfo::TestCaseInfo( std::string const& _name,
+                                std::string const& _className,
+                                std::string const& _description,
+                                std::set<std::string> const& _tags,
+                                SourceLineInfo const& _lineInfo )
+    :   name( _name ),
+        className( _className ),
+        description( _description ),
+        lineInfo( _lineInfo ),
+        properties( None )
+    {
+        setTags( *this, _tags );
+    }
+
+    TestCaseInfo::TestCaseInfo( TestCaseInfo const& other )
+    :   name( other.name ),
+        className( other.className ),
+        description( other.description ),
+        tags( other.tags ),
+        lcaseTags( other.lcaseTags ),
+        tagsAsString( other.tagsAsString ),
+        lineInfo( other.lineInfo ),
+        properties( other.properties )
+    {}
+
+    bool TestCaseInfo::isHidden() const {
+        return ( properties & IsHidden ) != 0;
+    }
+    bool TestCaseInfo::throws() const {
+        return ( properties & Throws ) != 0;
+    }
+    bool TestCaseInfo::okToFail() const {
+        return ( properties & (ShouldFail | MayFail ) ) != 0;
+    }
+    bool TestCaseInfo::expectedToFail() const {
+        return ( properties & (ShouldFail ) ) != 0;
+    }
+
+    TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {}
+
+    TestCase::TestCase( TestCase const& other )
+    :   TestCaseInfo( other ),
+        test( other.test )
+    {}
+
+    TestCase TestCase::withName( std::string const& _newName ) const {
+        TestCase other( *this );
+        other.name = _newName;
+        return other;
+    }
+
+    void TestCase::swap( TestCase& other ) {
+        test.swap( other.test );
+        name.swap( other.name );
+        className.swap( other.className );
+        description.swap( other.description );
+        tags.swap( other.tags );
+        lcaseTags.swap( other.lcaseTags );
+        tagsAsString.swap( other.tagsAsString );
+        std::swap( TestCaseInfo::properties, static_cast<TestCaseInfo&>( other ).properties );
+        std::swap( lineInfo, other.lineInfo );
+    }
+
+    void TestCase::invoke() const {
+        test->invoke();
+    }
+
+    bool TestCase::operator == ( TestCase const& other ) const {
+        return  test.get() == other.test.get() &&
+                name == other.name &&
+                className == other.className;
+    }
+
+    bool TestCase::operator < ( TestCase const& other ) const {
+        return name < other.name;
+    }
+    TestCase& TestCase::operator = ( TestCase const& other ) {
+        TestCase temp( other );
+        swap( temp );
+        return *this;
+    }
+
+    TestCaseInfo const& TestCase::getTestCaseInfo() const
+    {
+        return *this;
+    }
+
+} // end namespace Catch
+
+// #included from: catch_version.hpp
+#define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED
+
+namespace Catch {
+
+    Version::Version
+        (   unsigned int _majorVersion,
+            unsigned int _minorVersion,
+            unsigned int _patchNumber,
+            char const * const _branchName,
+            unsigned int _buildNumber )
+    :   majorVersion( _majorVersion ),
+        minorVersion( _minorVersion ),
+        patchNumber( _patchNumber ),
+        branchName( _branchName ),
+        buildNumber( _buildNumber )
+    {}
+
+    std::ostream& operator << ( std::ostream& os, Version const& version ) {
+        os  << version.majorVersion << '.'
+            << version.minorVersion << '.'
+            << version.patchNumber;
+        // branchName is never null -> 0th char is \0 if it is empty
+        if (version.branchName[0]) {
+            os << '-' << version.branchName
+               << '.' << version.buildNumber;
+        }
+        return os;
+    }
+
+    inline Version libraryVersion() {
+        static Version version( 1, 9, 6, "", 0 );
+        return version;
+    }
+
+}
+
+// #included from: catch_message.hpp
+#define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED
+
+namespace Catch {
+
+    MessageInfo::MessageInfo(   std::string const& _macroName,
+                                SourceLineInfo const& _lineInfo,
+                                ResultWas::OfType _type )
+    :   macroName( _macroName ),
+        lineInfo( _lineInfo ),
+        type( _type ),
+        sequence( ++globalCount )
+    {}
+
+    // This may need protecting if threading support is added
+    unsigned int MessageInfo::globalCount = 0;
+
+    ////////////////////////////////////////////////////////////////////////////
+
+    ScopedMessage::ScopedMessage( MessageBuilder const& builder )
+    : m_info( builder.m_info )
+    {
+        m_info.message = builder.m_stream.str();
+        getResultCapture().pushScopedMessage( m_info );
+    }
+    ScopedMessage::ScopedMessage( ScopedMessage const& other )
+    : m_info( other.m_info )
+    {}
+
+    ScopedMessage::~ScopedMessage() {
+        if ( !std::uncaught_exception() ){
+            getResultCapture().popScopedMessage(m_info);
+        }
+    }
+
+} // end namespace Catch
+
+// #included from: catch_legacy_reporter_adapter.hpp
+#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED
+
+// #included from: catch_legacy_reporter_adapter.h
+#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED
+
+namespace Catch
+{
+    // Deprecated
+    struct IReporter : IShared {
+        virtual ~IReporter();
+
+        virtual bool shouldRedirectStdout() const = 0;
+
+        virtual void StartTesting() = 0;
+        virtual void EndTesting( Totals const& totals ) = 0;
+        virtual void StartGroup( std::string const& groupName ) = 0;
+        virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0;
+        virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0;
+        virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0;
+        virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0;
+        virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0;
+        virtual void NoAssertionsInSection( std::string const& sectionName ) = 0;
+        virtual void NoAssertionsInTestCase( std::string const& testName ) = 0;
+        virtual void Aborted() = 0;
+        virtual void Result( AssertionResult const& result ) = 0;
+    };
+
+    class LegacyReporterAdapter : public SharedImpl<IStreamingReporter>
+    {
+    public:
+        LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter );
+        virtual ~LegacyReporterAdapter();
+
+        virtual ReporterPreferences getPreferences() const;
+        virtual void noMatchingTestCases( std::string const& );
+        virtual void testRunStarting( TestRunInfo const& );
+        virtual void testGroupStarting( GroupInfo const& groupInfo );
+        virtual void testCaseStarting( TestCaseInfo const& testInfo );
+        virtual void sectionStarting( SectionInfo const& sectionInfo );
+        virtual void assertionStarting( AssertionInfo const& );
+        virtual bool assertionEnded( AssertionStats const& assertionStats );
+        virtual void sectionEnded( SectionStats const& sectionStats );
+        virtual void testCaseEnded( TestCaseStats const& testCaseStats );
+        virtual void testGroupEnded( TestGroupStats const& testGroupStats );
+        virtual void testRunEnded( TestRunStats const& testRunStats );
+        virtual void skipTest( TestCaseInfo const& );
+
+    private:
+        Ptr<IReporter> m_legacyReporter;
+    };
+}
+
+namespace Catch
+{
+    LegacyReporterAdapter::LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter )
+    :   m_legacyReporter( legacyReporter )
+    {}
+    LegacyReporterAdapter::~LegacyReporterAdapter() {}
+
+    ReporterPreferences LegacyReporterAdapter::getPreferences() const {
+        ReporterPreferences prefs;
+        prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout();
+        return prefs;
+    }
+
+    void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {}
+    void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) {
+        m_legacyReporter->StartTesting();
+    }
+    void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) {
+        m_legacyReporter->StartGroup( groupInfo.name );
+    }
+    void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) {
+        m_legacyReporter->StartTestCase( testInfo );
+    }
+    void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) {
+        m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description );
+    }
+    void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) {
+        // Not on legacy interface
+    }
+
+    bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) {
+        if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
+            for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
+                    it != itEnd;
+                    ++it ) {
+                if( it->type == ResultWas::Info ) {
+                    ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal );
+                    rb << it->message;
+                    rb.setResultType( ResultWas::Info );
+                    AssertionResult result = rb.build();
+                    m_legacyReporter->Result( result );
+                }
+            }
+        }
+        m_legacyReporter->Result( assertionStats.assertionResult );
+        return true;
+    }
+    void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) {
+        if( sectionStats.missingAssertions )
+            m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name );
+        m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions );
+    }
+    void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) {
+        m_legacyReporter->EndTestCase
+            (   testCaseStats.testInfo,
+                testCaseStats.totals,
+                testCaseStats.stdOut,
+                testCaseStats.stdErr );
+    }
+    void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) {
+        if( testGroupStats.aborting )
+            m_legacyReporter->Aborted();
+        m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals );
+    }
+    void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) {
+        m_legacyReporter->EndTesting( testRunStats.totals );
+    }
+    void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) {
+    }
+}
+
+// #included from: catch_timer.hpp
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wc++11-long-long"
+#endif
+
+#ifdef CATCH_PLATFORM_WINDOWS
+
+#else
+
+#include <sys/time.h>
+
+#endif
+
+namespace Catch {
+
+    namespace {
+#ifdef CATCH_PLATFORM_WINDOWS
+        UInt64 getCurrentTicks() {
+            static UInt64 hz=0, hzo=0;
+            if (!hz) {
+                QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>( &hz ) );
+                QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &hzo ) );
+            }
+            UInt64 t;
+            QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &t ) );
+            return ((t-hzo)*1000000)/hz;
+        }
+#else
+        UInt64 getCurrentTicks() {
+            timeval t;
+            gettimeofday(&t,CATCH_NULL);
+            return static_cast<UInt64>( t.tv_sec ) * 1000000ull + static_cast<UInt64>( t.tv_usec );
+        }
+#endif
+    }
+
+    void Timer::start() {
+        m_ticks = getCurrentTicks();
+    }
+    unsigned int Timer::getElapsedMicroseconds() const {
+        return static_cast<unsigned int>(getCurrentTicks() - m_ticks);
+    }
+    unsigned int Timer::getElapsedMilliseconds() const {
+        return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
+    }
+    double Timer::getElapsedSeconds() const {
+        return getElapsedMicroseconds()/1000000.0;
+    }
+
+} // namespace Catch
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+// #included from: catch_common.hpp
+#define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED
+
+#include <cstring>
+#include <cctype>
+
+namespace Catch {
+
+    bool startsWith( std::string const& s, std::string const& prefix ) {
+        return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
+    }
+    bool startsWith( std::string const& s, char prefix ) {
+        return !s.empty() && s[0] == prefix;
+    }
+    bool endsWith( std::string const& s, std::string const& suffix ) {
+        return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
+    }
+    bool endsWith( std::string const& s, char suffix ) {
+        return !s.empty() && s[s.size()-1] == suffix;
+    }
+    bool contains( std::string const& s, std::string const& infix ) {
+        return s.find( infix ) != std::string::npos;
+    }
+    char toLowerCh(char c) {
+        return static_cast<char>( std::tolower( c ) );
+    }
+    void toLowerInPlace( std::string& s ) {
+        std::transform( s.begin(), s.end(), s.begin(), toLowerCh );
+    }
+    std::string toLower( std::string const& s ) {
+        std::string lc = s;
+        toLowerInPlace( lc );
+        return lc;
+    }
+    std::string trim( std::string const& str ) {
+        static char const* whitespaceChars = "\n\r\t ";
+        std::string::size_type start = str.find_first_not_of( whitespaceChars );
+        std::string::size_type end = str.find_last_not_of( whitespaceChars );
+
+        return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();
+    }
+
+    bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
+        bool replaced = false;
+        std::size_t i = str.find( replaceThis );
+        while( i != std::string::npos ) {
+            replaced = true;
+            str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
+            if( i < str.size()-withThis.size() )
+                i = str.find( replaceThis, i+withThis.size() );
+            else
+                i = std::string::npos;
+        }
+        return replaced;
+    }
+
+    pluralise::pluralise( std::size_t count, std::string const& label )
+    :   m_count( count ),
+        m_label( label )
+    {}
+
+    std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
+        os << pluraliser.m_count << ' ' << pluraliser.m_label;
+        if( pluraliser.m_count != 1 )
+            os << 's';
+        return os;
+    }
+
+    SourceLineInfo::SourceLineInfo() : file(""), line( 0 ){}
+    SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line )
+    :   file( _file ),
+        line( _line )
+    {}
+    bool SourceLineInfo::empty() const {
+        return file[0] == '\0';
+    }
+    bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const {
+        return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
+    }
+    bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const {
+        return line < other.line || ( line == other.line && (std::strcmp(file, other.file) < 0));
+    }
+
+    void seedRng( IConfig const& config ) {
+        if( config.rngSeed() != 0 )
+            std::srand( config.rngSeed() );
+    }
+    unsigned int rngSeed() {
+        return getCurrentContext().getConfig()->rngSeed();
+    }
+
+    std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
+#ifndef __GNUG__
+        os << info.file << '(' << info.line << ')';
+#else
+        os << info.file << ':' << info.line;
+#endif
+        return os;
+    }
+
+    void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {
+        std::ostringstream oss;
+        oss << locationInfo << ": Internal Catch error: '" << message << '\'';
+        if( alwaysTrue() )
+            throw std::logic_error( oss.str() );
+    }
+}
+
+// #included from: catch_section.hpp
+#define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
+
+namespace Catch {
+
+    SectionInfo::SectionInfo
+        (   SourceLineInfo const& _lineInfo,
+            std::string const& _name,
+            std::string const& _description )
+    :   name( _name ),
+        description( _description ),
+        lineInfo( _lineInfo )
+    {}
+
+    Section::Section( SectionInfo const& info )
+    :   m_info( info ),
+        m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
+    {
+        m_timer.start();
+    }
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable:4996) // std::uncaught_exception is deprecated in C++17
+#endif
+    Section::~Section() {
+        if( m_sectionIncluded ) {
+            SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
+            if( std::uncaught_exception() )
+                getResultCapture().sectionEndedEarly( endInfo );
+            else
+                getResultCapture().sectionEnded( endInfo );
+        }
+    }
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+    // This indicates whether the section should be executed or not
+    Section::operator bool() const {
+        return m_sectionIncluded;
+    }
+
+} // end namespace Catch
+
+// #included from: catch_debugger.hpp
+#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
+
+#ifdef CATCH_PLATFORM_MAC
+
+    #include <assert.h>
+    #include <stdbool.h>
+    #include <sys/types.h>
+    #include <unistd.h>
+    #include <sys/sysctl.h>
+
+    namespace Catch{
+
+        // The following function is taken directly from the following technical note:
+        // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
+
+        // Returns true if the current process is being debugged (either
+        // running under the debugger or has a debugger attached post facto).
+        bool isDebuggerActive(){
+
+            int                 mib[4];
+            struct kinfo_proc   info;
+            size_t              size;
+
+            // Initialize the flags so that, if sysctl fails for some bizarre
+            // reason, we get a predictable result.
+
+            info.kp_proc.p_flag = 0;
+
+            // Initialize mib, which tells sysctl the info we want, in this case
+            // we're looking for information about a specific process ID.
+
+            mib[0] = CTL_KERN;
+            mib[1] = KERN_PROC;
+            mib[2] = KERN_PROC_PID;
+            mib[3] = getpid();
+
+            // Call sysctl.
+
+            size = sizeof(info);
+            if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, CATCH_NULL, 0) != 0 ) {
+                Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
+                return false;
+            }
+
+            // We're being debugged if the P_TRACED flag is set.
+
+            return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
+        }
+    } // namespace Catch
+
+#elif defined(CATCH_PLATFORM_LINUX)
+    #include <fstream>
+    #include <string>
+
+    namespace Catch{
+        // The standard POSIX way of detecting a debugger is to attempt to
+        // ptrace() the process, but this needs to be done from a child and not
+        // this process itself to still allow attaching to this process later
+        // if wanted, so is rather heavy. Under Linux we have the PID of the
+        // "debugger" (which doesn't need to be gdb, of course, it could also
+        // be strace, for example) in /proc/$PID/status, so just get it from
+        // there instead.
+        bool isDebuggerActive(){
+            // Libstdc++ has a bug, where std::ifstream sets errno to 0
+            // This way our users can properly assert over errno values
+            ErrnoGuard guard;
+            std::ifstream in("/proc/self/status");
+            for( std::string line; std::getline(in, line); ) {
+                static const int PREFIX_LEN = 11;
+                if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) {
+                    // We're traced if the PID is not 0 and no other PID starts
+                    // with 0 digit, so it's enough to check for just a single
+                    // character.
+                    return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
+                }
+            }
+
+            return false;
+        }
+    } // namespace Catch
+#elif defined(_MSC_VER)
+    extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
+    namespace Catch {
+        bool isDebuggerActive() {
+            return IsDebuggerPresent() != 0;
+        }
+    }
+#elif defined(__MINGW32__)
+    extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
+    namespace Catch {
+        bool isDebuggerActive() {
+            return IsDebuggerPresent() != 0;
+        }
+    }
+#else
+    namespace Catch {
+       inline bool isDebuggerActive() { return false; }
+    }
+#endif // Platform
+
+#ifdef CATCH_PLATFORM_WINDOWS
+
+    namespace Catch {
+        void writeToDebugConsole( std::string const& text ) {
+            ::OutputDebugStringA( text.c_str() );
+        }
+    }
+#else
+    namespace Catch {
+        void writeToDebugConsole( std::string const& text ) {
+            // !TBD: Need a version for Mac/ XCode and other IDEs
+            Catch::cout() << text;
+        }
+    }
+#endif // Platform
+
+// #included from: catch_tostring.hpp
+#define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED
+
+namespace Catch {
+
+namespace Detail {
+
+    const std::string unprintableString = "{?}";
+
+    namespace {
+        const int hexThreshold = 255;
+
+        struct Endianness {
+            enum Arch { Big, Little };
+
+            static Arch which() {
+                union _{
+                    int asInt;
+                    char asChar[sizeof (int)];
+                } u;
+
+                u.asInt = 1;
+                return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
+            }
+        };
+    }
+
+    std::string rawMemoryToString( const void *object, std::size_t size )
+    {
+        // Reverse order for little endian architectures
+        int i = 0, end = static_cast<int>( size ), inc = 1;
+        if( Endianness::which() == Endianness::Little ) {
+            i = end-1;
+            end = inc = -1;
+        }
+
+        unsigned char const *bytes = static_cast<unsigned char const *>(object);
+        std::ostringstream os;
+        os << "0x" << std::setfill('0') << std::hex;
+        for( ; i != end; i += inc )
+             os << std::setw(2) << static_cast<unsigned>(bytes[i]);
+       return os.str();
+    }
+}
+
+std::string toString( std::string const& value ) {
+    std::string s = value;
+    if( getCurrentContext().getConfig()->showInvisibles() ) {
+        for(size_t i = 0; i < s.size(); ++i ) {
+            std::string subs;
+            switch( s[i] ) {
+            case '\n': subs = "\\n"; break;
+            case '\t': subs = "\\t"; break;
+            default: break;
+            }
+            if( !subs.empty() ) {
+                s = s.substr( 0, i ) + subs + s.substr( i+1 );
+                ++i;
+            }
+        }
+    }
+    return '"' + s + '"';
+}
+std::string toString( std::wstring const& value ) {
+
+    std::string s;
+    s.reserve( value.size() );
+    for(size_t i = 0; i < value.size(); ++i )
+        s += value[i] <= 0xff ? static_cast<char>( value[i] ) : '?';
+    return Catch::toString( s );
+}
+
+std::string toString( const char* const value ) {
+    return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" );
+}
+
+std::string toString( char* const value ) {
+    return Catch::toString( static_cast<const char*>( value ) );
+}
+
+std::string toString( const wchar_t* const value )
+{
+    return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" );
+}
+
+std::string toString( wchar_t* const value )
+{
+    return Catch::toString( static_cast<const wchar_t*>( value ) );
+}
+
+std::string toString( int value ) {
+    std::ostringstream oss;
+    oss << value;
+    if( value > Detail::hexThreshold )
+        oss << " (0x" << std::hex << value << ')';
+    return oss.str();
+}
+
+std::string toString( unsigned long value ) {
+    std::ostringstream oss;
+    oss << value;
+    if( value > Detail::hexThreshold )
+        oss << " (0x" << std::hex << value << ')';
+    return oss.str();
+}
+
+std::string toString( unsigned int value ) {
+    return Catch::toString( static_cast<unsigned long>( value ) );
+}
+
+template<typename T>
+std::string fpToString( T value, int precision ) {
+    std::ostringstream oss;
+    oss << std::setprecision( precision )
+        << std::fixed
+        << value;
+    std::string d = oss.str();
+    std::size_t i = d.find_last_not_of( '0' );
+    if( i != std::string::npos && i != d.size()-1 ) {
+        if( d[i] == '.' )
+            i++;
+        d = d.substr( 0, i+1 );
+    }
+    return d;
+}
+
+std::string toString( const double value ) {
+    return fpToString( value, 10 );
+}
+std::string toString( const float value ) {
+    return fpToString( value, 5 ) + 'f';
+}
+
+std::string toString( bool value ) {
+    return value ? "true" : "false";
+}
+
+std::string toString( char value ) {
+    if ( value == '\r' )
+        return "'\\r'";
+    if ( value == '\f' )
+        return "'\\f'";
+    if ( value == '\n' )
+        return "'\\n'";
+    if ( value == '\t' )
+        return "'\\t'";
+    if ( '\0' <= value && value < ' ' )
+        return toString( static_cast<unsigned int>( value ) );
+    char chstr[] = "' '";
+    chstr[1] = value;
+    return chstr;
+}
+
+std::string toString( signed char value ) {
+    return toString( static_cast<char>( value ) );
+}
+
+std::string toString( unsigned char value ) {
+    return toString( static_cast<char>( value ) );
+}
+
+#ifdef CATCH_CONFIG_CPP11_LONG_LONG
+std::string toString( long long value ) {
+    std::ostringstream oss;
+    oss << value;
+    if( value > Detail::hexThreshold )
+        oss << " (0x" << std::hex << value << ')';
+    return oss.str();
+}
+std::string toString( unsigned long long value ) {
+    std::ostringstream oss;
+    oss << value;
+    if( value > Detail::hexThreshold )
+        oss << " (0x" << std::hex << value << ')';
+    return oss.str();
+}
+#endif
+
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+std::string toString( std::nullptr_t ) {
+    return "nullptr";
+}
+#endif
+
+#ifdef __OBJC__
+    std::string toString( NSString const * const& nsstring ) {
+        if( !nsstring )
+            return "nil";
+        return "@" + toString([nsstring UTF8String]);
+    }
+    std::string toString( NSString * CATCH_ARC_STRONG & nsstring ) {
+        if( !nsstring )
+            return "nil";
+        return "@" + toString([nsstring UTF8String]);
+    }
+    std::string toString( NSObject* const& nsObject ) {
+        return toString( [nsObject description] );
+    }
+#endif
+
+} // end namespace Catch
+
+// #included from: catch_result_builder.hpp
+#define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED
+
+namespace Catch {
+
+    ResultBuilder::ResultBuilder(   char const* macroName,
+                                    SourceLineInfo const& lineInfo,
+                                    char const* capturedExpression,
+                                    ResultDisposition::Flags resultDisposition,
+                                    char const* secondArg )
+    :   m_assertionInfo( macroName, lineInfo, capturedExpression, resultDisposition, secondArg ),
+        m_shouldDebugBreak( false ),
+        m_shouldThrow( false ),
+        m_guardException( false )
+    {
+        m_stream().oss.str("");
+    }
+
+    ResultBuilder::~ResultBuilder() {
+#if defined(CATCH_CONFIG_FAST_COMPILE)
+        if ( m_guardException ) {
+            m_stream().oss << "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE";
+            captureResult( ResultWas::ThrewException );
+            getCurrentContext().getResultCapture()->exceptionEarlyReported();
+        }
+#endif
+    }
+
+    ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) {
+        m_data.resultType = result;
+        return *this;
+    }
+    ResultBuilder& ResultBuilder::setResultType( bool result ) {
+        m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed;
+        return *this;
+    }
+
+    void ResultBuilder::endExpression( DecomposedExpression const& expr ) {
+        AssertionResult result = build( expr );
+        handleResult( result );
+    }
+
+    void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) {
+        m_assertionInfo.resultDisposition = resultDisposition;
+        m_stream().oss << Catch::translateActiveException();
+        captureResult( ResultWas::ThrewException );
+    }
+
+    void ResultBuilder::captureResult( ResultWas::OfType resultType ) {
+        setResultType( resultType );
+        captureExpression();
+    }
+
+    void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) {
+        if( expectedMessage.empty() )
+            captureExpectedException( Matchers::Impl::MatchAllOf<std::string>() );
+        else
+            captureExpectedException( Matchers::Equals( expectedMessage ) );
+    }
+
+    void ResultBuilder::captureExpectedException( Matchers::Impl::MatcherBase<std::string> const& matcher ) {
+
+        assert( !isFalseTest( m_assertionInfo.resultDisposition ) );
+        AssertionResultData data = m_data;
+        data.resultType = ResultWas::Ok;
+        data.reconstructedExpression = capturedExpressionWithSecondArgument(m_assertionInfo.capturedExpression, m_assertionInfo.secondArg);
+
+        std::string actualMessage = Catch::translateActiveException();
+        if( !matcher.match( actualMessage ) ) {
+            data.resultType = ResultWas::ExpressionFailed;
+            data.reconstructedExpression = actualMessage;
+        }
+        AssertionResult result( m_assertionInfo, data );
+        handleResult( result );
+    }
+
+    void ResultBuilder::captureExpression() {
+        AssertionResult result = build();
+        handleResult( result );
+    }
+
+    void ResultBuilder::handleResult( AssertionResult const& result )
+    {
+        getResultCapture().assertionEnded( result );
+
+        if( !result.isOk() ) {
+            if( getCurrentContext().getConfig()->shouldDebugBreak() )
+                m_shouldDebugBreak = true;
+            if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) )
+                m_shouldThrow = true;
+        }
+    }
+
+    void ResultBuilder::react() {
+#if defined(CATCH_CONFIG_FAST_COMPILE)
+        if (m_shouldDebugBreak) {
+            ///////////////////////////////////////////////////////////////////
+            // To inspect the state during test, you need to go one level up the callstack
+            // To go back to the test and change execution, jump over the throw statement
+            ///////////////////////////////////////////////////////////////////
+            CATCH_BREAK_INTO_DEBUGGER();
+        }
+#endif
+        if( m_shouldThrow )
+            throw Catch::TestFailureException();
+    }
+
+    bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; }
+    bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); }
+
+    AssertionResult ResultBuilder::build() const
+    {
+        return build( *this );
+    }
+
+    // CAVEAT: The returned AssertionResult stores a pointer to the argument expr,
+    //         a temporary DecomposedExpression, which in turn holds references to
+    //         operands, possibly temporary as well.
+    //         It should immediately be passed to handleResult; if the expression
+    //         needs to be reported, its string expansion must be composed before
+    //         the temporaries are destroyed.
+    AssertionResult ResultBuilder::build( DecomposedExpression const& expr ) const
+    {
+        assert( m_data.resultType != ResultWas::Unknown );
+        AssertionResultData data = m_data;
+
+        // Flip bool results if FalseTest flag is set
+        if( isFalseTest( m_assertionInfo.resultDisposition ) ) {
+            data.negate( expr.isBinaryExpression() );
+        }
+
+        data.message = m_stream().oss.str();
+        data.decomposedExpression = &expr; // for lazy reconstruction
+        return AssertionResult( m_assertionInfo, data );
+    }
+
+    void ResultBuilder::reconstructExpression( std::string& dest ) const {
+        dest = capturedExpressionWithSecondArgument(m_assertionInfo.capturedExpression, m_assertionInfo.secondArg);
+    }
+
+    void ResultBuilder::setExceptionGuard() {
+        m_guardException = true;
+    }
+    void ResultBuilder::unsetExceptionGuard() {
+        m_guardException = false;
+    }
+
+} // end namespace Catch
+
+// #included from: catch_tag_alias_registry.hpp
+#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
+
+namespace Catch {
+
+    TagAliasRegistry::~TagAliasRegistry() {}
+
+    Option<TagAlias> TagAliasRegistry::find( std::string const& alias ) const {
+        std::map<std::string, TagAlias>::const_iterator it = m_registry.find( alias );
+        if( it != m_registry.end() )
+            return it->second;
+        else
+            return Option<TagAlias>();
+    }
+
+    std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
+        std::string expandedTestSpec = unexpandedTestSpec;
+        for( std::map<std::string, TagAlias>::const_iterator it = m_registry.begin(), itEnd = m_registry.end();
+                it != itEnd;
+                ++it ) {
+            std::size_t pos = expandedTestSpec.find( it->first );
+            if( pos != std::string::npos ) {
+                expandedTestSpec =  expandedTestSpec.substr( 0, pos ) +
+                                    it->second.tag +
+                                    expandedTestSpec.substr( pos + it->first.size() );
+            }
+        }
+        return expandedTestSpec;
+    }
+
+    void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) {
+
+        if( !startsWith( alias, "[@" ) || !endsWith( alias, ']' ) ) {
+            std::ostringstream oss;
+            oss << Colour( Colour::Red )
+                << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n"
+                << Colour( Colour::FileName )
+                << lineInfo << '\n';
+            throw std::domain_error( oss.str().c_str() );
+        }
+        if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) {
+            std::ostringstream oss;
+            oss << Colour( Colour::Red )
+                << "error: tag alias, \"" << alias << "\" already registered.\n"
+                << "\tFirst seen at "
+                << Colour( Colour::Red ) << find(alias)->lineInfo << '\n'
+                << Colour( Colour::Red ) << "\tRedefined at "
+                << Colour( Colour::FileName) << lineInfo << '\n';
+            throw std::domain_error( oss.str().c_str() );
+        }
+    }
+
+    ITagAliasRegistry::~ITagAliasRegistry() {}
+
+    ITagAliasRegistry const& ITagAliasRegistry::get() {
+        return getRegistryHub().getTagAliasRegistry();
+    }
+
+    RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
+        getMutableRegistryHub().registerTagAlias( alias, tag, lineInfo );
+    }
+
+} // end namespace Catch
+
+// #included from: catch_matchers_string.hpp
+
+namespace Catch {
+namespace Matchers {
+
+    namespace StdString {
+
+        CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
+        :   m_caseSensitivity( caseSensitivity ),
+            m_str( adjustString( str ) )
+        {}
+        std::string CasedString::adjustString( std::string const& str ) const {
+            return m_caseSensitivity == CaseSensitive::No
+                   ? toLower( str )
+                   : str;
+        }
+        std::string CasedString::caseSensitivitySuffix() const {
+            return m_caseSensitivity == CaseSensitive::No
+                   ? " (case insensitive)"
+                   : std::string();
+        }
+
+        StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator )
+        : m_comparator( comparator ),
+          m_operation( operation ) {
+        }
+
+        std::string StringMatcherBase::describe() const {
+            std::string description;
+            description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +
+                                        m_comparator.caseSensitivitySuffix().size());
+            description += m_operation;
+            description += ": \"";
+            description += m_comparator.m_str;
+            description += "\"";
+            description += m_comparator.caseSensitivitySuffix();
+            return description;
+        }
+
+        EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {}
+
+        bool EqualsMatcher::match( std::string const& source ) const {
+            return m_comparator.adjustString( source ) == m_comparator.m_str;
+        }
+
+        ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {}
+
+        bool ContainsMatcher::match( std::string const& source ) const {
+            return contains( m_comparator.adjustString( source ), m_comparator.m_str );
+        }
+
+        StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {}
+
+        bool StartsWithMatcher::match( std::string const& source ) const {
+            return startsWith( m_comparator.adjustString( source ), m_comparator.m_str );
+        }
+
+        EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {}
+
+        bool EndsWithMatcher::match( std::string const& source ) const {
+            return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );
+        }
+
+    } // namespace StdString
+
+    StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
+        return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) );
+    }
+    StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
+        return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) );
+    }
+    StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
+        return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) );
+    }
+    StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {
+        return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );
+    }
+
+} // namespace Matchers
+} // namespace Catch
+// #included from: ../reporters/catch_reporter_multi.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED
+
+namespace Catch {
+
+class MultipleReporters : public SharedImpl<IStreamingReporter> {
+    typedef std::vector<Ptr<IStreamingReporter> > Reporters;
+    Reporters m_reporters;
+
+public:
+    void add( Ptr<IStreamingReporter> const& reporter ) {
+        m_reporters.push_back( reporter );
+    }
+
+public: // IStreamingReporter
+
+    virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
+        return m_reporters[0]->getPreferences();
+    }
+
+    virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
+        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+                it != itEnd;
+                ++it )
+            (*it)->noMatchingTestCases( spec );
+    }
+
+    virtual void testRunStarting( TestRunInfo const& testRunInfo ) CATCH_OVERRIDE {
+        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+                it != itEnd;
+                ++it )
+            (*it)->testRunStarting( testRunInfo );
+    }
+
+    virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
+        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+                it != itEnd;
+                ++it )
+            (*it)->testGroupStarting( groupInfo );
+    }
+
+    virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
+        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+                it != itEnd;
+                ++it )
+            (*it)->testCaseStarting( testInfo );
+    }
+
+    virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
+        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+                it != itEnd;
+                ++it )
+            (*it)->sectionStarting( sectionInfo );
+    }
+
+    virtual void assertionStarting( AssertionInfo const& assertionInfo ) CATCH_OVERRIDE {
+        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+                it != itEnd;
+                ++it )
+            (*it)->assertionStarting( assertionInfo );
+    }
+
+    // The return value indicates if the messages buffer should be cleared:
+    virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
+        bool clearBuffer = false;
+        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+                it != itEnd;
+                ++it )
+            clearBuffer |= (*it)->assertionEnded( assertionStats );
+        return clearBuffer;
+    }
+
+    virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
+        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+                it != itEnd;
+                ++it )
+            (*it)->sectionEnded( sectionStats );
+    }
+
+    virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
+        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+                it != itEnd;
+                ++it )
+            (*it)->testCaseEnded( testCaseStats );
+    }
+
+    virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
+        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+                it != itEnd;
+                ++it )
+            (*it)->testGroupEnded( testGroupStats );
+    }
+
+    virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
+        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+                it != itEnd;
+                ++it )
+            (*it)->testRunEnded( testRunStats );
+    }
+
+    virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
+        for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+                it != itEnd;
+                ++it )
+            (*it)->skipTest( testInfo );
+    }
+
+    virtual MultipleReporters* tryAsMulti() CATCH_OVERRIDE {
+        return this;
+    }
+
+};
+
+Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter ) {
+    Ptr<IStreamingReporter> resultingReporter;
+
+    if( existingReporter ) {
+        MultipleReporters* multi = existingReporter->tryAsMulti();
+        if( !multi ) {
+            multi = new MultipleReporters;
+            resultingReporter = Ptr<IStreamingReporter>( multi );
+            if( existingReporter )
+                multi->add( existingReporter );
+        }
+        else
+            resultingReporter = existingReporter;
+        multi->add( additionalReporter );
+    }
+    else
+        resultingReporter = additionalReporter;
+
+    return resultingReporter;
+}
+
+} // end namespace Catch
+
+// #included from: ../reporters/catch_reporter_xml.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED
+
+// #included from: catch_reporter_bases.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
+
+#include <cstring>
+#include <cfloat>
+#include <cstdio>
+#include <assert.h>
+
+namespace Catch {
+
+    namespace {
+        // Because formatting using c++ streams is stateful, drop down to C is required
+        // Alternatively we could use stringstream, but its performance is... not good.
+        std::string getFormattedDuration( double duration ) {
+            // Max exponent + 1 is required to represent the whole part
+            // + 1 for decimal point
+            // + 3 for the 3 decimal places
+            // + 1 for null terminator
+            const size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;
+            char buffer[maxDoubleSize];
+
+            // Save previous errno, to prevent sprintf from overwriting it
+            ErrnoGuard guard;
+#ifdef _MSC_VER
+            sprintf_s(buffer, "%.3f", duration);
+#else
+            sprintf(buffer, "%.3f", duration);
+#endif
+            return std::string(buffer);
+        }
+    }
+
+    struct StreamingReporterBase : SharedImpl<IStreamingReporter> {
+
+        StreamingReporterBase( ReporterConfig const& _config )
+        :   m_config( _config.fullConfig() ),
+            stream( _config.stream() )
+        {
+            m_reporterPrefs.shouldRedirectStdOut = false;
+        }
+
+        virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
+            return m_reporterPrefs;
+        }
+
+        virtual ~StreamingReporterBase() CATCH_OVERRIDE;
+
+        virtual void noMatchingTestCases( std::string const& ) CATCH_OVERRIDE {}
+
+        virtual void testRunStarting( TestRunInfo const& _testRunInfo ) CATCH_OVERRIDE {
+            currentTestRunInfo = _testRunInfo;
+        }
+        virtual void testGroupStarting( GroupInfo const& _groupInfo ) CATCH_OVERRIDE {
+            currentGroupInfo = _groupInfo;
+        }
+
+        virtual void testCaseStarting( TestCaseInfo const& _testInfo ) CATCH_OVERRIDE {
+            currentTestCaseInfo = _testInfo;
+        }
+        virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
+            m_sectionStack.push_back( _sectionInfo );
+        }
+
+        virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) CATCH_OVERRIDE {
+            m_sectionStack.pop_back();
+        }
+        virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) CATCH_OVERRIDE {
+            currentTestCaseInfo.reset();
+        }
+        virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) CATCH_OVERRIDE {
+            currentGroupInfo.reset();
+        }
+        virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) CATCH_OVERRIDE {
+            currentTestCaseInfo.reset();
+            currentGroupInfo.reset();
+            currentTestRunInfo.reset();
+        }
+
+        virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {
+            // Don't do anything with this by default.
+            // It can optionally be overridden in the derived class.
+        }
+
+        Ptr<IConfig const> m_config;
+        std::ostream& stream;
+
+        LazyStat<TestRunInfo> currentTestRunInfo;
+        LazyStat<GroupInfo> currentGroupInfo;
+        LazyStat<TestCaseInfo> currentTestCaseInfo;
+
+        std::vector<SectionInfo> m_sectionStack;
+        ReporterPreferences m_reporterPrefs;
+    };
+
+    struct CumulativeReporterBase : SharedImpl<IStreamingReporter> {
+        template<typename T, typename ChildNodeT>
+        struct Node : SharedImpl<> {
+            explicit Node( T const& _value ) : value( _value ) {}
+            virtual ~Node() {}
+
+            typedef std::vector<Ptr<ChildNodeT> > ChildNodes;
+            T value;
+            ChildNodes children;
+        };
+        struct SectionNode : SharedImpl<> {
+            explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {}
+            virtual ~SectionNode();
+
+            bool operator == ( SectionNode const& other ) const {
+                return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
+            }
+            bool operator == ( Ptr<SectionNode> const& other ) const {
+                return operator==( *other );
+            }
+
+            SectionStats stats;
+            typedef std::vector<Ptr<SectionNode> > ChildSections;
+            typedef std::vector<AssertionStats> Assertions;
+            ChildSections childSections;
+            Assertions assertions;
+            std::string stdOut;
+            std::string stdErr;
+        };
+
+        struct BySectionInfo {
+            BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
+            BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
+            bool operator() ( Ptr<SectionNode> const& node ) const {
+                return node->stats.sectionInfo.lineInfo == m_other.lineInfo;
+            }
+        private:
+            void operator=( BySectionInfo const& );
+            SectionInfo const& m_other;
+        };
+
+        typedef Node<TestCaseStats, SectionNode> TestCaseNode;
+        typedef Node<TestGroupStats, TestCaseNode> TestGroupNode;
+        typedef Node<TestRunStats, TestGroupNode> TestRunNode;
+
+        CumulativeReporterBase( ReporterConfig const& _config )
+        :   m_config( _config.fullConfig() ),
+            stream( _config.stream() )
+        {
+            m_reporterPrefs.shouldRedirectStdOut = false;
+        }
+        ~CumulativeReporterBase();
+
+        virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
+            return m_reporterPrefs;
+        }
+
+        virtual void testRunStarting( TestRunInfo const& ) CATCH_OVERRIDE {}
+        virtual void testGroupStarting( GroupInfo const& ) CATCH_OVERRIDE {}
+
+        virtual void testCaseStarting( TestCaseInfo const& ) CATCH_OVERRIDE {}
+
+        virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
+            SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
+            Ptr<SectionNode> node;
+            if( m_sectionStack.empty() ) {
+                if( !m_rootSection )
+                    m_rootSection = new SectionNode( incompleteStats );
+                node = m_rootSection;
+            }
+            else {
+                SectionNode& parentNode = *m_sectionStack.back();
+                SectionNode::ChildSections::const_iterator it =
+                    std::find_if(   parentNode.childSections.begin(),
+                                    parentNode.childSections.end(),
+                                    BySectionInfo( sectionInfo ) );
+                if( it == parentNode.childSections.end() ) {
+                    node = new SectionNode( incompleteStats );
+                    parentNode.childSections.push_back( node );
+                }
+                else
+                    node = *it;
+            }
+            m_sectionStack.push_back( node );
+            m_deepestSection = node;
+        }
+
+        virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
+
+        virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
+            assert( !m_sectionStack.empty() );
+            SectionNode& sectionNode = *m_sectionStack.back();
+            sectionNode.assertions.push_back( assertionStats );
+            // AssertionResult holds a pointer to a temporary DecomposedExpression,
+            // which getExpandedExpression() calls to build the expression string.
+            // Our section stack copy of the assertionResult will likely outlive the
+            // temporary, so it must be expanded or discarded now to avoid calling
+            // a destroyed object later.
+            prepareExpandedExpression( sectionNode.assertions.back().assertionResult );
+            return true;
+        }
+        virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
+            assert( !m_sectionStack.empty() );
+            SectionNode& node = *m_sectionStack.back();
+            node.stats = sectionStats;
+            m_sectionStack.pop_back();
+        }
+        virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
+            Ptr<TestCaseNode> node = new TestCaseNode( testCaseStats );
+            assert( m_sectionStack.size() == 0 );
+            node->children.push_back( m_rootSection );
+            m_testCases.push_back( node );
+            m_rootSection.reset();
+
+            assert( m_deepestSection );
+            m_deepestSection->stdOut = testCaseStats.stdOut;
+            m_deepestSection->stdErr = testCaseStats.stdErr;
+        }
+        virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
+            Ptr<TestGroupNode> node = new TestGroupNode( testGroupStats );
+            node->children.swap( m_testCases );
+            m_testGroups.push_back( node );
+        }
+        virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
+            Ptr<TestRunNode> node = new TestRunNode( testRunStats );
+            node->children.swap( m_testGroups );
+            m_testRuns.push_back( node );
+            testRunEndedCumulative();
+        }
+        virtual void testRunEndedCumulative() = 0;
+
+        virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {}
+
+        virtual void prepareExpandedExpression( AssertionResult& result ) const {
+            if( result.isOk() )
+                result.discardDecomposedExpression();
+            else
+                result.expandDecomposedExpression();
+        }
+
+        Ptr<IConfig const> m_config;
+        std::ostream& stream;
+        std::vector<AssertionStats> m_assertions;
+        std::vector<std::vector<Ptr<SectionNode> > > m_sections;
+        std::vector<Ptr<TestCaseNode> > m_testCases;
+        std::vector<Ptr<TestGroupNode> > m_testGroups;
+
+        std::vector<Ptr<TestRunNode> > m_testRuns;
+
+        Ptr<SectionNode> m_rootSection;
+        Ptr<SectionNode> m_deepestSection;
+        std::vector<Ptr<SectionNode> > m_sectionStack;
+        ReporterPreferences m_reporterPrefs;
+
+    };
+
+    template<char C>
+    char const* getLineOfChars() {
+        static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
+        if( !*line ) {
+            std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
+            line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
+        }
+        return line;
+    }
+
+    struct TestEventListenerBase : StreamingReporterBase {
+        TestEventListenerBase( ReporterConfig const& _config )
+        :   StreamingReporterBase( _config )
+        {}
+
+        virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
+        virtual bool assertionEnded( AssertionStats const& ) CATCH_OVERRIDE {
+            return false;
+        }
+    };
+
+} // end namespace Catch
+
+// #included from: ../internal/catch_reporter_registrars.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
+
+namespace Catch {
+
+    template<typename T>
+    class LegacyReporterRegistrar {
+
+        class ReporterFactory : public IReporterFactory {
+            virtual IStreamingReporter* create( ReporterConfig const& config ) const {
+                return new LegacyReporterAdapter( new T( config ) );
+            }
+
+            virtual std::string getDescription() const {
+                return T::getDescription();
+            }
+        };
+
+    public:
+
+        LegacyReporterRegistrar( std::string const& name ) {
+            getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
+        }
+    };
+
+    template<typename T>
+    class ReporterRegistrar {
+
+        class ReporterFactory : public SharedImpl<IReporterFactory> {
+
+            // *** Please Note ***:
+            // - If you end up here looking at a compiler error because it's trying to register
+            // your custom reporter class be aware that the native reporter interface has changed
+            // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via
+            // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter.
+            // However please consider updating to the new interface as the old one is now
+            // deprecated and will probably be removed quite soon!
+            // Please contact me via github if you have any questions at all about this.
+            // In fact, ideally, please contact me anyway to let me know you've hit this - as I have
+            // no idea who is actually using custom reporters at all (possibly no-one!).
+            // The new interface is designed to minimise exposure to interface changes in the future.
+            virtual IStreamingReporter* create( ReporterConfig const& config ) const {
+                return new T( config );
+            }
+
+            virtual std::string getDescription() const {
+                return T::getDescription();
+            }
+        };
+
+    public:
+
+        ReporterRegistrar( std::string const& name ) {
+            getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
+        }
+    };
+
+    template<typename T>
+    class ListenerRegistrar {
+
+        class ListenerFactory : public SharedImpl<IReporterFactory> {
+
+            virtual IStreamingReporter* create( ReporterConfig const& config ) const {
+                return new T( config );
+            }
+            virtual std::string getDescription() const {
+                return std::string();
+            }
+        };
+
+    public:
+
+        ListenerRegistrar() {
+            getMutableRegistryHub().registerListener( new ListenerFactory() );
+        }
+    };
+}
+
+#define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \
+    namespace{ Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
+
+#define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \
+    namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
+
+// Deprecated - use the form without INTERNAL_
+#define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \
+    namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; }
+
+#define CATCH_REGISTER_LISTENER( listenerType ) \
+    namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; }
+
+// #included from: ../internal/catch_xmlwriter.hpp
+#define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED
+
+#include <sstream>
+#include <string>
+#include <vector>
+#include <iomanip>
+
+namespace Catch {
+
+    class XmlEncode {
+    public:
+        enum ForWhat { ForTextNodes, ForAttributes };
+
+        XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes )
+        :   m_str( str ),
+            m_forWhat( forWhat )
+        {}
+
+        void encodeTo( std::ostream& os ) const {
+
+            // Apostrophe escaping not necessary if we always use " to write attributes
+            // (see: http://www.w3.org/TR/xml/#syntax)
+
+            for( std::size_t i = 0; i < m_str.size(); ++ i ) {
+                char c = m_str[i];
+                switch( c ) {
+                    case '<':   os << "<"; break;
+                    case '&':   os << "&"; break;
+
+                    case '>':
+                        // See: http://www.w3.org/TR/xml/#syntax
+                        if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' )
+                            os << ">";
+                        else
+                            os << c;
+                        break;
+
+                    case '\"':
+                        if( m_forWhat == ForAttributes )
+                            os << """;
+                        else
+                            os << c;
+                        break;
+
+                    default:
+                        // Escape control chars - based on contribution by @espenalb in PR #465 and
+                        // by @mrpi PR #588
+                        if ( ( c >= 0 && c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' ) {
+                            // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0
+                            os << "\\x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2)
+                               << static_cast<int>( c );
+                        }
+                        else
+                            os << c;
+                }
+            }
+        }
+
+        friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
+            xmlEncode.encodeTo( os );
+            return os;
+        }
+
+    private:
+        std::string m_str;
+        ForWhat m_forWhat;
+    };
+
+    class XmlWriter {
+    public:
+
+        class ScopedElement {
+        public:
+            ScopedElement( XmlWriter* writer )
+            :   m_writer( writer )
+            {}
+
+            ScopedElement( ScopedElement const& other )
+            :   m_writer( other.m_writer ){
+                other.m_writer = CATCH_NULL;
+            }
+
+            ~ScopedElement() {
+                if( m_writer )
+                    m_writer->endElement();
+            }
+
+            ScopedElement& writeText( std::string const& text, bool indent = true ) {
+                m_writer->writeText( text, indent );
+                return *this;
+            }
+
+            template<typename T>
+            ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
+                m_writer->writeAttribute( name, attribute );
+                return *this;
+            }
+
+        private:
+            mutable XmlWriter* m_writer;
+        };
+
+        XmlWriter()
+        :   m_tagIsOpen( false ),
+            m_needsNewline( false ),
+            m_os( Catch::cout() )
+        {
+            writeDeclaration();
+        }
+
+        XmlWriter( std::ostream& os )
+        :   m_tagIsOpen( false ),
+            m_needsNewline( false ),
+            m_os( os )
+        {
+            writeDeclaration();
+        }
+
+        ~XmlWriter() {
+            while( !m_tags.empty() )
+                endElement();
+        }
+
+        XmlWriter& startElement( std::string const& name ) {
+            ensureTagClosed();
+            newlineIfNecessary();
+            m_os << m_indent << '<' << name;
+            m_tags.push_back( name );
+            m_indent += "  ";
+            m_tagIsOpen = true;
+            return *this;
+        }
+
+        ScopedElement scopedElement( std::string const& name ) {
+            ScopedElement scoped( this );
+            startElement( name );
+            return scoped;
+        }
+
+        XmlWriter& endElement() {
+            newlineIfNecessary();
+            m_indent = m_indent.substr( 0, m_indent.size()-2 );
+            if( m_tagIsOpen ) {
+                m_os << "/>";
+                m_tagIsOpen = false;
+            }
+            else {
+                m_os << m_indent << "</" << m_tags.back() << ">";
+            }
+            m_os << std::endl;
+            m_tags.pop_back();
+            return *this;
+        }
+
+        XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) {
+            if( !name.empty() && !attribute.empty() )
+                m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"';
+            return *this;
+        }
+
+        XmlWriter& writeAttribute( std::string const& name, bool attribute ) {
+            m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"';
+            return *this;
+        }
+
+        template<typename T>
+        XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
+            std::ostringstream oss;
+            oss << attribute;
+            return writeAttribute( name, oss.str() );
+        }
+
+        XmlWriter& writeText( std::string const& text, bool indent = true ) {
+            if( !text.empty() ){
+                bool tagWasOpen = m_tagIsOpen;
+                ensureTagClosed();
+                if( tagWasOpen && indent )
+                    m_os << m_indent;
+                m_os << XmlEncode( text );
+                m_needsNewline = true;
+            }
+            return *this;
+        }
+
+        XmlWriter& writeComment( std::string const& text ) {
+            ensureTagClosed();
+            m_os << m_indent << "<!--" << text << "-->";
+            m_needsNewline = true;
+            return *this;
+        }
+
+        void writeStylesheetRef( std::string const& url ) {
+            m_os << "<?xml-stylesheet type=\"text/xsl\" href=\"" << url << "\"?>\n";
+        }
+
+        XmlWriter& writeBlankLine() {
+            ensureTagClosed();
+            m_os << '\n';
+            return *this;
+        }
+
+        void ensureTagClosed() {
+            if( m_tagIsOpen ) {
+                m_os << ">" << std::endl;
+                m_tagIsOpen = false;
+            }
+        }
+
+    private:
+        XmlWriter( XmlWriter const& );
+        void operator=( XmlWriter const& );
+
+        void writeDeclaration() {
+            m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+        }
+
+        void newlineIfNecessary() {
+            if( m_needsNewline ) {
+                m_os << std::endl;
+                m_needsNewline = false;
+            }
+        }
+
+        bool m_tagIsOpen;
+        bool m_needsNewline;
+        std::vector<std::string> m_tags;
+        std::string m_indent;
+        std::ostream& m_os;
+    };
+
+}
+
+namespace Catch {
+    class XmlReporter : public StreamingReporterBase {
+    public:
+        XmlReporter( ReporterConfig const& _config )
+        :   StreamingReporterBase( _config ),
+            m_xml(_config.stream()),
+            m_sectionDepth( 0 )
+        {
+            m_reporterPrefs.shouldRedirectStdOut = true;
+        }
+
+        virtual ~XmlReporter() CATCH_OVERRIDE;
+
+        static std::string getDescription() {
+            return "Reports test results as an XML document";
+        }
+
+        virtual std::string getStylesheetRef() const {
+            return std::string();
+        }
+
+        void writeSourceInfo( SourceLineInfo const& sourceInfo ) {
+            m_xml
+                .writeAttribute( "filename", sourceInfo.file )
+                .writeAttribute( "line", sourceInfo.line );
+        }
+
+    public: // StreamingReporterBase
+
+        virtual void noMatchingTestCases( std::string const& s ) CATCH_OVERRIDE {
+            StreamingReporterBase::noMatchingTestCases( s );
+        }
+
+        virtual void testRunStarting( TestRunInfo const& testInfo ) CATCH_OVERRIDE {
+            StreamingReporterBase::testRunStarting( testInfo );
+            std::string stylesheetRef = getStylesheetRef();
+            if( !stylesheetRef.empty() )
+                m_xml.writeStylesheetRef( stylesheetRef );
+            m_xml.startElement( "Catch" );
+            if( !m_config->name().empty() )
+                m_xml.writeAttribute( "name", m_config->name() );
+        }
+
+        virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
+            StreamingReporterBase::testGroupStarting( groupInfo );
+            m_xml.startElement( "Group" )
+                .writeAttribute( "name", groupInfo.name );
+        }
+
+        virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
+            StreamingReporterBase::testCaseStarting(testInfo);
+            m_xml.startElement( "TestCase" )
+                .writeAttribute( "name", trim( testInfo.name ) )
+                .writeAttribute( "description", testInfo.description )
+                .writeAttribute( "tags", testInfo.tagsAsString );
+
+            writeSourceInfo( testInfo.lineInfo );
+
+            if ( m_config->showDurations() == ShowDurations::Always )
+                m_testCaseTimer.start();
+            m_xml.ensureTagClosed();
+        }
+
+        virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
+            StreamingReporterBase::sectionStarting( sectionInfo );
+            if( m_sectionDepth++ > 0 ) {
+                m_xml.startElement( "Section" )
+                    .writeAttribute( "name", trim( sectionInfo.name ) )
+                    .writeAttribute( "description", sectionInfo.description );
+                writeSourceInfo( sectionInfo.lineInfo );
+                m_xml.ensureTagClosed();
+            }
+        }
+
+        virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { }
+
+        virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
+
+            AssertionResult const& result = assertionStats.assertionResult;
+
+            bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
+
+            if( includeResults ) {
+                // Print any info messages in <Info> tags.
+                for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
+                     it != itEnd;
+                     ++it ) {
+                    if( it->type == ResultWas::Info ) {
+                        m_xml.scopedElement( "Info" )
+                                .writeText( it->message );
+                    } else if ( it->type == ResultWas::Warning ) {
+                        m_xml.scopedElement( "Warning" )
+                                .writeText( it->message );
+                    }
+                }
+            }
+
+            // Drop out if result was successful but we're not printing them.
+            if( !includeResults && result.getResultType() != ResultWas::Warning )
+                return true;
+
+            // Print the expression if there is one.
+            if( result.hasExpression() ) {
+                m_xml.startElement( "Expression" )
+                    .writeAttribute( "success", result.succeeded() )
+                    .writeAttribute( "type", result.getTestMacroName() );
+
+                writeSourceInfo( result.getSourceInfo() );
+
+                m_xml.scopedElement( "Original" )
+                    .writeText( result.getExpression() );
+                m_xml.scopedElement( "Expanded" )
+                    .writeText( result.getExpandedExpression() );
+            }
+
+            // And... Print a result applicable to each result type.
+            switch( result.getResultType() ) {
+                case ResultWas::ThrewException:
+                    m_xml.startElement( "Exception" );
+                    writeSourceInfo( result.getSourceInfo() );
+                    m_xml.writeText( result.getMessage() );
+                    m_xml.endElement();
+                    break;
+                case ResultWas::FatalErrorCondition:
+                    m_xml.startElement( "FatalErrorCondition" );
+                    writeSourceInfo( result.getSourceInfo() );
+                    m_xml.writeText( result.getMessage() );
+                    m_xml.endElement();
+                    break;
+                case ResultWas::Info:
+                    m_xml.scopedElement( "Info" )
+                        .writeText( result.getMessage() );
+                    break;
+                case ResultWas::Warning:
+                    // Warning will already have been written
+                    break;
+                case ResultWas::ExplicitFailure:
+                    m_xml.startElement( "Failure" );
+                    writeSourceInfo( result.getSourceInfo() );
+                    m_xml.writeText( result.getMessage() );
+                    m_xml.endElement();
+                    break;
+                default:
+                    break;
+            }
+
+            if( result.hasExpression() )
+                m_xml.endElement();
+
+            return true;
+        }
+
+        virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
+            StreamingReporterBase::sectionEnded( sectionStats );
+            if( --m_sectionDepth > 0 ) {
+                XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
+                e.writeAttribute( "successes", sectionStats.assertions.passed );
+                e.writeAttribute( "failures", sectionStats.assertions.failed );
+                e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
+
+                if ( m_config->showDurations() == ShowDurations::Always )
+                    e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
+
+                m_xml.endElement();
+            }
+        }
+
+        virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
+            StreamingReporterBase::testCaseEnded( testCaseStats );
+            XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
+            e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
+
+            if ( m_config->showDurations() == ShowDurations::Always )
+                e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
+
+            if( !testCaseStats.stdOut.empty() )
+                m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), false );
+            if( !testCaseStats.stdErr.empty() )
+                m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), false );
+
+            m_xml.endElement();
+        }
+
+        virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
+            StreamingReporterBase::testGroupEnded( testGroupStats );
+            // TODO: Check testGroupStats.aborting and act accordingly.
+            m_xml.scopedElement( "OverallResults" )
+                .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
+                .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
+                .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
+            m_xml.endElement();
+        }
+
+        virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
+            StreamingReporterBase::testRunEnded( testRunStats );
+            m_xml.scopedElement( "OverallResults" )
+                .writeAttribute( "successes", testRunStats.totals.assertions.passed )
+                .writeAttribute( "failures", testRunStats.totals.assertions.failed )
+                .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
+            m_xml.endElement();
+        }
+
+    private:
+        Timer m_testCaseTimer;
+        XmlWriter m_xml;
+        int m_sectionDepth;
+    };
+
+     INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter )
+
+} // end namespace Catch
+
+// #included from: ../reporters/catch_reporter_junit.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED
+
+#include <assert.h>
+
+namespace Catch {
+
+    namespace {
+        std::string getCurrentTimestamp() {
+            // Beware, this is not reentrant because of backward compatibility issues
+            // Also, UTC only, again because of backward compatibility (%z is C++11)
+            time_t rawtime;
+            std::time(&rawtime);
+            const size_t timeStampSize = sizeof("2017-01-16T17:06:45Z");
+
+#ifdef _MSC_VER
+            std::tm timeInfo = {};
+            gmtime_s(&timeInfo, &rawtime);
+#else
+            std::tm* timeInfo;
+            timeInfo = std::gmtime(&rawtime);
+#endif
+
+            char timeStamp[timeStampSize];
+            const char * const fmt = "%Y-%m-%dT%H:%M:%SZ";
+
+#ifdef _MSC_VER
+            std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);
+#else
+            std::strftime(timeStamp, timeStampSize, fmt, timeInfo);
+#endif
+            return std::string(timeStamp);
+        }
+
+    }
+
+    class JunitReporter : public CumulativeReporterBase {
+    public:
+        JunitReporter( ReporterConfig const& _config )
+        :   CumulativeReporterBase( _config ),
+            xml( _config.stream() ),
+            m_okToFail( false )
+        {
+            m_reporterPrefs.shouldRedirectStdOut = true;
+        }
+
+        virtual ~JunitReporter() CATCH_OVERRIDE;
+
+        static std::string getDescription() {
+            return "Reports test results in an XML format that looks like Ant's junitreport target";
+        }
+
+        virtual void noMatchingTestCases( std::string const& /*spec*/ ) CATCH_OVERRIDE {}
+
+        virtual void testRunStarting( TestRunInfo const& runInfo ) CATCH_OVERRIDE {
+            CumulativeReporterBase::testRunStarting( runInfo );
+            xml.startElement( "testsuites" );
+        }
+
+        virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
+            suiteTimer.start();
+            stdOutForSuite.str("");
+            stdErrForSuite.str("");
+            unexpectedExceptions = 0;
+            CumulativeReporterBase::testGroupStarting( groupInfo );
+        }
+
+        virtual void testCaseStarting( TestCaseInfo const& testCaseInfo ) CATCH_OVERRIDE {
+            m_okToFail = testCaseInfo.okToFail();
+        }
+        virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
+            if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )
+                unexpectedExceptions++;
+            return CumulativeReporterBase::assertionEnded( assertionStats );
+        }
+
+        virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
+            stdOutForSuite << testCaseStats.stdOut;
+            stdErrForSuite << testCaseStats.stdErr;
+            CumulativeReporterBase::testCaseEnded( testCaseStats );
+        }
+
+        virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
+            double suiteTime = suiteTimer.getElapsedSeconds();
+            CumulativeReporterBase::testGroupEnded( testGroupStats );
+            writeGroup( *m_testGroups.back(), suiteTime );
+        }
+
+        virtual void testRunEndedCumulative() CATCH_OVERRIDE {
+            xml.endElement();
+        }
+
+        void writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
+            XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
+            TestGroupStats const& stats = groupNode.value;
+            xml.writeAttribute( "name", stats.groupInfo.name );
+            xml.writeAttribute( "errors", unexpectedExceptions );
+            xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
+            xml.writeAttribute( "tests", stats.totals.assertions.total() );
+            xml.writeAttribute( "hostname", "tbd" ); // !TBD
+            if( m_config->showDurations() == ShowDurations::Never )
+                xml.writeAttribute( "time", "" );
+            else
+                xml.writeAttribute( "time", suiteTime );
+            xml.writeAttribute( "timestamp", getCurrentTimestamp() );
+
+            // Write test cases
+            for( TestGroupNode::ChildNodes::const_iterator
+                    it = groupNode.children.begin(), itEnd = groupNode.children.end();
+                    it != itEnd;
+                    ++it )
+                writeTestCase( **it );
+
+            xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false );
+            xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false );
+        }
+
+        void writeTestCase( TestCaseNode const& testCaseNode ) {
+            TestCaseStats const& stats = testCaseNode.value;
+
+            // All test cases have exactly one section - which represents the
+            // test case itself. That section may have 0-n nested sections
+            assert( testCaseNode.children.size() == 1 );
+            SectionNode const& rootSection = *testCaseNode.children.front();
+
+            std::string className = stats.testInfo.className;
+
+            if( className.empty() ) {
+                if( rootSection.childSections.empty() )
+                    className = "global";
+            }
+            writeSection( className, "", rootSection );
+        }
+
+        void writeSection(  std::string const& className,
+                            std::string const& rootName,
+                            SectionNode const& sectionNode ) {
+            std::string name = trim( sectionNode.stats.sectionInfo.name );
+            if( !rootName.empty() )
+                name = rootName + '/' + name;
+
+            if( !sectionNode.assertions.empty() ||
+                !sectionNode.stdOut.empty() ||
+                !sectionNode.stdErr.empty() ) {
+                XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
+                if( className.empty() ) {
+                    xml.writeAttribute( "classname", name );
+                    xml.writeAttribute( "name", "root" );
+                }
+                else {
+                    xml.writeAttribute( "classname", className );
+                    xml.writeAttribute( "name", name );
+                }
+                xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) );
+
+                writeAssertions( sectionNode );
+
+                if( !sectionNode.stdOut.empty() )
+                    xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
+                if( !sectionNode.stdErr.empty() )
+                    xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
+            }
+            for( SectionNode::ChildSections::const_iterator
+                    it = sectionNode.childSections.begin(),
+                    itEnd = sectionNode.childSections.end();
+                    it != itEnd;
+                    ++it )
+                if( className.empty() )
+                    writeSection( name, "", **it );
+                else
+                    writeSection( className, name, **it );
+        }
+
+        void writeAssertions( SectionNode const& sectionNode ) {
+            for( SectionNode::Assertions::const_iterator
+                    it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end();
+                    it != itEnd;
+                    ++it )
+                writeAssertion( *it );
+        }
+        void writeAssertion( AssertionStats const& stats ) {
+            AssertionResult const& result = stats.assertionResult;
+            if( !result.isOk() ) {
+                std::string elementName;
+                switch( result.getResultType() ) {
+                    case ResultWas::ThrewException:
+                    case ResultWas::FatalErrorCondition:
+                        elementName = "error";
+                        break;
+                    case ResultWas::ExplicitFailure:
+                        elementName = "failure";
+                        break;
+                    case ResultWas::ExpressionFailed:
+                        elementName = "failure";
+                        break;
+                    case ResultWas::DidntThrowException:
+                        elementName = "failure";
+                        break;
+
+                    // We should never see these here:
+                    case ResultWas::Info:
+                    case ResultWas::Warning:
+                    case ResultWas::Ok:
+                    case ResultWas::Unknown:
+                    case ResultWas::FailureBit:
+                    case ResultWas::Exception:
+                        elementName = "internalError";
+                        break;
+                }
+
+                XmlWriter::ScopedElement e = xml.scopedElement( elementName );
+
+                xml.writeAttribute( "message", result.getExpandedExpression() );
+                xml.writeAttribute( "type", result.getTestMacroName() );
+
+                std::ostringstream oss;
+                if( !result.getMessage().empty() )
+                    oss << result.getMessage() << '\n';
+                for( std::vector<MessageInfo>::const_iterator
+                        it = stats.infoMessages.begin(),
+                        itEnd = stats.infoMessages.end();
+                            it != itEnd;
+                            ++it )
+                    if( it->type == ResultWas::Info )
+                        oss << it->message << '\n';
+
+                oss << "at " << result.getSourceInfo();
+                xml.writeText( oss.str(), false );
+            }
+        }
+
+        XmlWriter xml;
+        Timer suiteTimer;
+        std::ostringstream stdOutForSuite;
+        std::ostringstream stdErrForSuite;
+        unsigned int unexpectedExceptions;
+        bool m_okToFail;
+    };
+
+    INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter )
+
+} // end namespace Catch
+
+// #included from: ../reporters/catch_reporter_console.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED
+
+#include <cfloat>
+#include <cstdio>
+
+namespace Catch {
+
+    struct ConsoleReporter : StreamingReporterBase {
+        ConsoleReporter( ReporterConfig const& _config )
+        :   StreamingReporterBase( _config ),
+            m_headerPrinted( false )
+        {}
+
+        virtual ~ConsoleReporter() CATCH_OVERRIDE;
+        static std::string getDescription() {
+            return "Reports test results as plain lines of text";
+        }
+
+        virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
+            stream << "No test cases matched '" << spec << '\'' << std::endl;
+        }
+
+        virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {
+        }
+
+        virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE {
+            AssertionResult const& result = _assertionStats.assertionResult;
+
+            bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
+
+            // Drop out if result was successful but we're not printing them.
+            if( !includeResults && result.getResultType() != ResultWas::Warning )
+                return false;
+
+            lazyPrint();
+
+            AssertionPrinter printer( stream, _assertionStats, includeResults );
+            printer.print();
+            stream << std::endl;
+            return true;
+        }
+
+        virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
+            m_headerPrinted = false;
+            StreamingReporterBase::sectionStarting( _sectionInfo );
+        }
+        virtual void sectionEnded( SectionStats const& _sectionStats ) CATCH_OVERRIDE {
+            if( _sectionStats.missingAssertions ) {
+                lazyPrint();
+                Colour colour( Colour::ResultError );
+                if( m_sectionStack.size() > 1 )
+                    stream << "\nNo assertions in section";
+                else
+                    stream << "\nNo assertions in test case";
+                stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
+            }
+            if( m_config->showDurations() == ShowDurations::Always ) {
+                stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
+            }
+            if( m_headerPrinted ) {
+                m_headerPrinted = false;
+            }
+            StreamingReporterBase::sectionEnded( _sectionStats );
+        }
+
+        virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE {
+            StreamingReporterBase::testCaseEnded( _testCaseStats );
+            m_headerPrinted = false;
+        }
+        virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) CATCH_OVERRIDE {
+            if( currentGroupInfo.used ) {
+                printSummaryDivider();
+                stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
+                printTotals( _testGroupStats.totals );
+                stream << '\n' << std::endl;
+            }
+            StreamingReporterBase::testGroupEnded( _testGroupStats );
+        }
+        virtual void testRunEnded( TestRunStats const& _testRunStats ) CATCH_OVERRIDE {
+            printTotalsDivider( _testRunStats.totals );
+            printTotals( _testRunStats.totals );
+            stream << std::endl;
+            StreamingReporterBase::testRunEnded( _testRunStats );
+        }
+
+    private:
+
+        class AssertionPrinter {
+            void operator= ( AssertionPrinter const& );
+        public:
+            AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
+            :   stream( _stream ),
+                stats( _stats ),
+                result( _stats.assertionResult ),
+                colour( Colour::None ),
+                message( result.getMessage() ),
+                messages( _stats.infoMessages ),
+                printInfoMessages( _printInfoMessages )
+            {
+                switch( result.getResultType() ) {
+                    case ResultWas::Ok:
+                        colour = Colour::Success;
+                        passOrFail = "PASSED";
+                        //if( result.hasMessage() )
+                        if( _stats.infoMessages.size() == 1 )
+                            messageLabel = "with message";
+                        if( _stats.infoMessages.size() > 1 )
+                            messageLabel = "with messages";
+                        break;
+                    case ResultWas::ExpressionFailed:
+                        if( result.isOk() ) {
+                            colour = Colour::Success;
+                            passOrFail = "FAILED - but was ok";
+                        }
+                        else {
+                            colour = Colour::Error;
+                            passOrFail = "FAILED";
+                        }
+                        if( _stats.infoMessages.size() == 1 )
+                            messageLabel = "with message";
+                        if( _stats.infoMessages.size() > 1 )
+                            messageLabel = "with messages";
+                        break;
+                    case ResultWas::ThrewException:
+                        colour = Colour::Error;
+                        passOrFail = "FAILED";
+                        messageLabel = "due to unexpected exception with ";
+                        if (_stats.infoMessages.size() == 1)
+                            messageLabel += "message";
+                        if (_stats.infoMessages.size() > 1)
+                            messageLabel += "messages";
+                        break;
+                    case ResultWas::FatalErrorCondition:
+                        colour = Colour::Error;
+                        passOrFail = "FAILED";
+                        messageLabel = "due to a fatal error condition";
+                        break;
+                    case ResultWas::DidntThrowException:
+                        colour = Colour::Error;
+                        passOrFail = "FAILED";
+                        messageLabel = "because no exception was thrown where one was expected";
+                        break;
+                    case ResultWas::Info:
+                        messageLabel = "info";
+                        break;
+                    case ResultWas::Warning:
+                        messageLabel = "warning";
+                        break;
+                    case ResultWas::ExplicitFailure:
+                        passOrFail = "FAILED";
+                        colour = Colour::Error;
+                        if( _stats.infoMessages.size() == 1 )
+                            messageLabel = "explicitly with message";
+                        if( _stats.infoMessages.size() > 1 )
+                            messageLabel = "explicitly with messages";
+                        break;
+                    // These cases are here to prevent compiler warnings
+                    case ResultWas::Unknown:
+                    case ResultWas::FailureBit:
+                    case ResultWas::Exception:
+                        passOrFail = "** internal error **";
+                        colour = Colour::Error;
+                        break;
+                }
+            }
+
+            void print() const {
+                printSourceInfo();
+                if( stats.totals.assertions.total() > 0 ) {
+                    if( result.isOk() )
+                        stream << '\n';
+                    printResultType();
+                    printOriginalExpression();
+                    printReconstructedExpression();
+                }
+                else {
+                    stream << '\n';
+                }
+                printMessage();
+            }
+
+        private:
+            void printResultType() const {
+                if( !passOrFail.empty() ) {
+                    Colour colourGuard( colour );
+                    stream << passOrFail << ":\n";
+                }
+            }
+            void printOriginalExpression() const {
+                if( result.hasExpression() ) {
+                    Colour colourGuard( Colour::OriginalExpression );
+                    stream  << "  ";
+                    stream << result.getExpressionInMacro();
+                    stream << '\n';
+                }
+            }
+            void printReconstructedExpression() const {
+                if( result.hasExpandedExpression() ) {
+                    stream << "with expansion:\n";
+                    Colour colourGuard( Colour::ReconstructedExpression );
+                    stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << '\n';
+                }
+            }
+            void printMessage() const {
+                if( !messageLabel.empty() )
+                    stream << messageLabel << ':' << '\n';
+                for( std::vector<MessageInfo>::const_iterator it = messages.begin(), itEnd = messages.end();
+                        it != itEnd;
+                        ++it ) {
+                    // If this assertion is a warning ignore any INFO messages
+                    if( printInfoMessages || it->type != ResultWas::Info )
+                        stream << Text( it->message, TextAttributes().setIndent(2) ) << '\n';
+                }
+            }
+            void printSourceInfo() const {
+                Colour colourGuard( Colour::FileName );
+                stream << result.getSourceInfo() << ": ";
+            }
+
+            std::ostream& stream;
+            AssertionStats const& stats;
+            AssertionResult const& result;
+            Colour::Code colour;
+            std::string passOrFail;
+            std::string messageLabel;
+            std::string message;
+            std::vector<MessageInfo> messages;
+            bool printInfoMessages;
+        };
+
+        void lazyPrint() {
+
+            if( !currentTestRunInfo.used )
+                lazyPrintRunInfo();
+            if( !currentGroupInfo.used )
+                lazyPrintGroupInfo();
+
+            if( !m_headerPrinted ) {
+                printTestCaseAndSectionHeader();
+                m_headerPrinted = true;
+            }
+        }
+        void lazyPrintRunInfo() {
+            stream  << '\n' << getLineOfChars<'~'>() << '\n';
+            Colour colour( Colour::SecondaryText );
+            stream  << currentTestRunInfo->name
+                    << " is a Catch v"  << libraryVersion() << " host application.\n"
+                    << "Run with -? for options\n\n";
+
+            if( m_config->rngSeed() != 0 )
+                stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
+
+            currentTestRunInfo.used = true;
+        }
+        void lazyPrintGroupInfo() {
+            if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) {
+                printClosedHeader( "Group: " + currentGroupInfo->name );
+                currentGroupInfo.used = true;
+            }
+        }
+        void printTestCaseAndSectionHeader() {
+            assert( !m_sectionStack.empty() );
+            printOpenHeader( currentTestCaseInfo->name );
+
+            if( m_sectionStack.size() > 1 ) {
+                Colour colourGuard( Colour::Headers );
+
+                std::vector<SectionInfo>::const_iterator
+                    it = m_sectionStack.begin()+1, // Skip first section (test case)
+                    itEnd = m_sectionStack.end();
+                for( ; it != itEnd; ++it )
+                    printHeaderString( it->name, 2 );
+            }
+
+            SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
+
+            if( !lineInfo.empty() ){
+                stream << getLineOfChars<'-'>() << '\n';
+                Colour colourGuard( Colour::FileName );
+                stream << lineInfo << '\n';
+            }
+            stream << getLineOfChars<'.'>() << '\n' << std::endl;
+        }
+
+        void printClosedHeader( std::string const& _name ) {
+            printOpenHeader( _name );
+            stream << getLineOfChars<'.'>() << '\n';
+        }
+        void printOpenHeader( std::string const& _name ) {
+            stream  << getLineOfChars<'-'>() << '\n';
+            {
+                Colour colourGuard( Colour::Headers );
+                printHeaderString( _name );
+            }
+        }
+
+        // if string has a : in first line will set indent to follow it on
+        // subsequent lines
+        void printHeaderString( std::string const& _string, std::size_t indent = 0 ) {
+            std::size_t i = _string.find( ": " );
+            if( i != std::string::npos )
+                i+=2;
+            else
+                i = 0;
+            stream << Text( _string, TextAttributes()
+                                        .setIndent( indent+i)
+                                        .setInitialIndent( indent ) ) << '\n';
+        }
+
+        struct SummaryColumn {
+
+            SummaryColumn( std::string const& _label, Colour::Code _colour )
+            :   label( _label ),
+                colour( _colour )
+            {}
+            SummaryColumn addRow( std::size_t count ) {
+                std::ostringstream oss;
+                oss << count;
+                std::string row = oss.str();
+                for( std::vector<std::string>::iterator it = rows.begin(); it != rows.end(); ++it ) {
+                    while( it->size() < row.size() )
+                        *it = ' ' + *it;
+                    while( it->size() > row.size() )
+                        row = ' ' + row;
+                }
+                rows.push_back( row );
+                return *this;
+            }
+
+            std::string label;
+            Colour::Code colour;
+            std::vector<std::string> rows;
+
+        };
+
+        void printTotals( Totals const& totals ) {
+            if( totals.testCases.total() == 0 ) {
+                stream << Colour( Colour::Warning ) << "No tests ran\n";
+            }
+            else if( totals.assertions.total() > 0 && totals.testCases.allPassed() ) {
+                stream << Colour( Colour::ResultSuccess ) << "All tests passed";
+                stream << " ("
+                        << pluralise( totals.assertions.passed, "assertion" ) << " in "
+                        << pluralise( totals.testCases.passed, "test case" ) << ')'
+                        << '\n';
+            }
+            else {
+
+                std::vector<SummaryColumn> columns;
+                columns.push_back( SummaryColumn( "", Colour::None )
+                                        .addRow( totals.testCases.total() )
+                                        .addRow( totals.assertions.total() ) );
+                columns.push_back( SummaryColumn( "passed", Colour::Success )
+                                        .addRow( totals.testCases.passed )
+                                        .addRow( totals.assertions.passed ) );
+                columns.push_back( SummaryColumn( "failed", Colour::ResultError )
+                                        .addRow( totals.testCases.failed )
+                                        .addRow( totals.assertions.failed ) );
+                columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure )
+                                        .addRow( totals.testCases.failedButOk )
+                                        .addRow( totals.assertions.failedButOk ) );
+
+                printSummaryRow( "test cases", columns, 0 );
+                printSummaryRow( "assertions", columns, 1 );
+            }
+        }
+        void printSummaryRow( std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row ) {
+            for( std::vector<SummaryColumn>::const_iterator it = cols.begin(); it != cols.end(); ++it ) {
+                std::string value = it->rows[row];
+                if( it->label.empty() ) {
+                    stream << label << ": ";
+                    if( value != "0" )
+                        stream << value;
+                    else
+                        stream << Colour( Colour::Warning ) << "- none -";
+                }
+                else if( value != "0" ) {
+                    stream  << Colour( Colour::LightGrey ) << " | ";
+                    stream  << Colour( it->colour )
+                            << value << ' ' << it->label;
+                }
+            }
+            stream << '\n';
+        }
+
+        static std::size_t makeRatio( std::size_t number, std::size_t total ) {
+            std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0;
+            return ( ratio == 0 && number > 0 ) ? 1 : ratio;
+        }
+        static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) {
+            if( i > j && i > k )
+                return i;
+            else if( j > k )
+                return j;
+            else
+                return k;
+        }
+
+        void printTotalsDivider( Totals const& totals ) {
+            if( totals.testCases.total() > 0 ) {
+                std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() );
+                std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() );
+                std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() );
+                while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 )
+                    findMax( failedRatio, failedButOkRatio, passedRatio )++;
+                while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 )
+                    findMax( failedRatio, failedButOkRatio, passedRatio )--;
+
+                stream << Colour( Colour::Error ) << std::string( failedRatio, '=' );
+                stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' );
+                if( totals.testCases.allPassed() )
+                    stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' );
+                else
+                    stream << Colour( Colour::Success ) << std::string( passedRatio, '=' );
+            }
+            else {
+                stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' );
+            }
+            stream << '\n';
+        }
+        void printSummaryDivider() {
+            stream << getLineOfChars<'-'>() << '\n';
+        }
+
+    private:
+        bool m_headerPrinted;
+    };
+
+    INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter )
+
+} // end namespace Catch
+
+// #included from: ../reporters/catch_reporter_compact.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED
+
+namespace Catch {
+
+    struct CompactReporter : StreamingReporterBase {
+
+        CompactReporter( ReporterConfig const& _config )
+        : StreamingReporterBase( _config )
+        {}
+
+        virtual ~CompactReporter();
+
+        static std::string getDescription() {
+            return "Reports test results on a single line, suitable for IDEs";
+        }
+
+        virtual ReporterPreferences getPreferences() const {
+            ReporterPreferences prefs;
+            prefs.shouldRedirectStdOut = false;
+            return prefs;
+        }
+
+        virtual void noMatchingTestCases( std::string const& spec ) {
+            stream << "No test cases matched '" << spec << '\'' << std::endl;
+        }
+
+        virtual void assertionStarting( AssertionInfo const& ) {}
+
+        virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
+            AssertionResult const& result = _assertionStats.assertionResult;
+
+            bool printInfoMessages = true;
+
+            // Drop out if result was successful and we're not printing those
+            if( !m_config->includeSuccessfulResults() && result.isOk() ) {
+                if( result.getResultType() != ResultWas::Warning )
+                    return false;
+                printInfoMessages = false;
+            }
+
+            AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
+            printer.print();
+
+            stream << std::endl;
+            return true;
+        }
+
+        virtual void sectionEnded(SectionStats const& _sectionStats) CATCH_OVERRIDE {
+            if (m_config->showDurations() == ShowDurations::Always) {
+                stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
+            }
+        }
+
+        virtual void testRunEnded( TestRunStats const& _testRunStats ) {
+            printTotals( _testRunStats.totals );
+            stream << '\n' << std::endl;
+            StreamingReporterBase::testRunEnded( _testRunStats );
+        }
+
+    private:
+        class AssertionPrinter {
+            void operator= ( AssertionPrinter const& );
+        public:
+            AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
+            : stream( _stream )
+            , stats( _stats )
+            , result( _stats.assertionResult )
+            , messages( _stats.infoMessages )
+            , itMessage( _stats.infoMessages.begin() )
+            , printInfoMessages( _printInfoMessages )
+            {}
+
+            void print() {
+                printSourceInfo();
+
+                itMessage = messages.begin();
+
+                switch( result.getResultType() ) {
+                    case ResultWas::Ok:
+                        printResultType( Colour::ResultSuccess, passedString() );
+                        printOriginalExpression();
+                        printReconstructedExpression();
+                        if ( ! result.hasExpression() )
+                            printRemainingMessages( Colour::None );
+                        else
+                            printRemainingMessages();
+                        break;
+                    case ResultWas::ExpressionFailed:
+                        if( result.isOk() )
+                            printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) );
+                        else
+                            printResultType( Colour::Error, failedString() );
+                        printOriginalExpression();
+                        printReconstructedExpression();
+                        printRemainingMessages();
+                        break;
+                    case ResultWas::ThrewException:
+                        printResultType( Colour::Error, failedString() );
+                        printIssue( "unexpected exception with message:" );
+                        printMessage();
+                        printExpressionWas();
+                        printRemainingMessages();
+                        break;
+                    case ResultWas::FatalErrorCondition:
+                        printResultType( Colour::Error, failedString() );
+                        printIssue( "fatal error condition with message:" );
+                        printMessage();
+                        printExpressionWas();
+                        printRemainingMessages();
+                        break;
+                    case ResultWas::DidntThrowException:
+                        printResultType( Colour::Error, failedString() );
+                        printIssue( "expected exception, got none" );
+                        printExpressionWas();
+                        printRemainingMessages();
+                        break;
+                    case ResultWas::Info:
+                        printResultType( Colour::None, "info" );
+                        printMessage();
+                        printRemainingMessages();
+                        break;
+                    case ResultWas::Warning:
+                        printResultType( Colour::None, "warning" );
+                        printMessage();
+                        printRemainingMessages();
+                        break;
+                    case ResultWas::ExplicitFailure:
+                        printResultType( Colour::Error, failedString() );
+                        printIssue( "explicitly" );
+                        printRemainingMessages( Colour::None );
+                        break;
+                    // These cases are here to prevent compiler warnings
+                    case ResultWas::Unknown:
+                    case ResultWas::FailureBit:
+                    case ResultWas::Exception:
+                        printResultType( Colour::Error, "** internal error **" );
+                        break;
+                }
+            }
+
+        private:
+            // Colour::LightGrey
+
+            static Colour::Code dimColour() { return Colour::FileName; }
+
+#ifdef CATCH_PLATFORM_MAC
+            static const char* failedString() { return "FAILED"; }
+            static const char* passedString() { return "PASSED"; }
+#else
+            static const char* failedString() { return "failed"; }
+            static const char* passedString() { return "passed"; }
+#endif
+
+            void printSourceInfo() const {
+                Colour colourGuard( Colour::FileName );
+                stream << result.getSourceInfo() << ':';
+            }
+
+            void printResultType( Colour::Code colour, std::string const& passOrFail ) const {
+                if( !passOrFail.empty() ) {
+                    {
+                        Colour colourGuard( colour );
+                        stream << ' ' << passOrFail;
+                    }
+                    stream << ':';
+                }
+            }
+
+            void printIssue( std::string const& issue ) const {
+                stream << ' ' << issue;
+            }
+
+            void printExpressionWas() {
+                if( result.hasExpression() ) {
+                    stream << ';';
+                    {
+                        Colour colour( dimColour() );
+                        stream << " expression was:";
+                    }
+                    printOriginalExpression();
+                }
+            }
+
+            void printOriginalExpression() const {
+                if( result.hasExpression() ) {
+                    stream << ' ' << result.getExpression();
+                }
+            }
+
+            void printReconstructedExpression() const {
+                if( result.hasExpandedExpression() ) {
+                    {
+                        Colour colour( dimColour() );
+                        stream << " for: ";
+                    }
+                    stream << result.getExpandedExpression();
+                }
+            }
+
+            void printMessage() {
+                if ( itMessage != messages.end() ) {
+                    stream << " '" << itMessage->message << '\'';
+                    ++itMessage;
+                }
+            }
+
+            void printRemainingMessages( Colour::Code colour = dimColour() ) {
+                if ( itMessage == messages.end() )
+                    return;
+
+                // using messages.end() directly yields compilation error:
+                std::vector<MessageInfo>::const_iterator itEnd = messages.end();
+                const std::size_t N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) );
+
+                {
+                    Colour colourGuard( colour );
+                    stream << " with " << pluralise( N, "message" ) << ':';
+                }
+
+                for(; itMessage != itEnd; ) {
+                    // If this assertion is a warning ignore any INFO messages
+                    if( printInfoMessages || itMessage->type != ResultWas::Info ) {
+                        stream << " '" << itMessage->message << '\'';
+                        if ( ++itMessage != itEnd ) {
+                            Colour colourGuard( dimColour() );
+                            stream << " and";
+                        }
+                    }
+                }
+            }
+
+        private:
+            std::ostream& stream;
+            AssertionStats const& stats;
+            AssertionResult const& result;
+            std::vector<MessageInfo> messages;
+            std::vector<MessageInfo>::const_iterator itMessage;
+            bool printInfoMessages;
+        };
+
+        // Colour, message variants:
+        // - white: No tests ran.
+        // -   red: Failed [both/all] N test cases, failed [both/all] M assertions.
+        // - white: Passed [both/all] N test cases (no assertions).
+        // -   red: Failed N tests cases, failed M assertions.
+        // - green: Passed [both/all] N tests cases with M assertions.
+
+        std::string bothOrAll( std::size_t count ) const {
+            return count == 1 ? std::string() : count == 2 ? "both " : "all " ;
+        }
+
+        void printTotals( const Totals& totals ) const {
+            if( totals.testCases.total() == 0 ) {
+                stream << "No tests ran.";
+            }
+            else if( totals.testCases.failed == totals.testCases.total() ) {
+                Colour colour( Colour::ResultError );
+                const std::string qualify_assertions_failed =
+                    totals.assertions.failed == totals.assertions.total() ?
+                        bothOrAll( totals.assertions.failed ) : std::string();
+                stream <<
+                    "Failed " << bothOrAll( totals.testCases.failed )
+                              << pluralise( totals.testCases.failed, "test case"  ) << ", "
+                    "failed " << qualify_assertions_failed <<
+                                 pluralise( totals.assertions.failed, "assertion" ) << '.';
+            }
+            else if( totals.assertions.total() == 0 ) {
+                stream <<
+                    "Passed " << bothOrAll( totals.testCases.total() )
+                              << pluralise( totals.testCases.total(), "test case" )
+                              << " (no assertions).";
+            }
+            else if( totals.assertions.failed ) {
+                Colour colour( Colour::ResultError );
+                stream <<
+                    "Failed " << pluralise( totals.testCases.failed, "test case"  ) << ", "
+                    "failed " << pluralise( totals.assertions.failed, "assertion" ) << '.';
+            }
+            else {
+                Colour colour( Colour::ResultSuccess );
+                stream <<
+                    "Passed " << bothOrAll( totals.testCases.passed )
+                              << pluralise( totals.testCases.passed, "test case"  ) <<
+                    " with "  << pluralise( totals.assertions.passed, "assertion" ) << '.';
+            }
+        }
+    };
+
+    INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter )
+
+} // end namespace Catch
+
+namespace Catch {
+    // These are all here to avoid warnings about not having any out of line
+    // virtual methods
+    NonCopyable::~NonCopyable() {}
+    IShared::~IShared() {}
+    IStream::~IStream() CATCH_NOEXCEPT {}
+    FileStream::~FileStream() CATCH_NOEXCEPT {}
+    CoutStream::~CoutStream() CATCH_NOEXCEPT {}
+    DebugOutStream::~DebugOutStream() CATCH_NOEXCEPT {}
+    StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {}
+    IContext::~IContext() {}
+    IResultCapture::~IResultCapture() {}
+    ITestCase::~ITestCase() {}
+    ITestCaseRegistry::~ITestCaseRegistry() {}
+    IRegistryHub::~IRegistryHub() {}
+    IMutableRegistryHub::~IMutableRegistryHub() {}
+    IExceptionTranslator::~IExceptionTranslator() {}
+    IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {}
+    IReporter::~IReporter() {}
+    IReporterFactory::~IReporterFactory() {}
+    IReporterRegistry::~IReporterRegistry() {}
+    IStreamingReporter::~IStreamingReporter() {}
+    AssertionStats::~AssertionStats() {}
+    SectionStats::~SectionStats() {}
+    TestCaseStats::~TestCaseStats() {}
+    TestGroupStats::~TestGroupStats() {}
+    TestRunStats::~TestRunStats() {}
+    CumulativeReporterBase::SectionNode::~SectionNode() {}
+    CumulativeReporterBase::~CumulativeReporterBase() {}
+
+    StreamingReporterBase::~StreamingReporterBase() {}
+    ConsoleReporter::~ConsoleReporter() {}
+    CompactReporter::~CompactReporter() {}
+    IRunner::~IRunner() {}
+    IMutableContext::~IMutableContext() {}
+    IConfig::~IConfig() {}
+    XmlReporter::~XmlReporter() {}
+    JunitReporter::~JunitReporter() {}
+    TestRegistry::~TestRegistry() {}
+    FreeFunctionTestCase::~FreeFunctionTestCase() {}
+    IGeneratorInfo::~IGeneratorInfo() {}
+    IGeneratorsForTest::~IGeneratorsForTest() {}
+    WildcardPattern::~WildcardPattern() {}
+    TestSpec::Pattern::~Pattern() {}
+    TestSpec::NamePattern::~NamePattern() {}
+    TestSpec::TagPattern::~TagPattern() {}
+    TestSpec::ExcludedPattern::~ExcludedPattern() {}
+    Matchers::Impl::MatcherUntypedBase::~MatcherUntypedBase() {}
+
+    void Config::dummy() {}
+
+    namespace TestCaseTracking {
+        ITracker::~ITracker() {}
+        TrackerBase::~TrackerBase() {}
+        SectionTracker::~SectionTracker() {}
+        IndexTracker::~IndexTracker() {}
+    }
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+#endif
+
+#ifdef CATCH_CONFIG_MAIN
+// #included from: internal/catch_default_main.hpp
+#define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED
+
+#ifndef __OBJC__
+
+#if defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
+// Standard C/C++ Win32 Unicode wmain entry point
+extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
+#else
+// Standard C/C++ main entry point
+int main (int argc, char * argv[]) {
+#endif
+
+    int result = Catch::Session().run( argc, argv );
+    return ( result < 0xff ? result : 0xff );
+}
+
+#else // __OBJC__
+
+// Objective-C entry point
+int main (int argc, char * const argv[]) {
+#if !CATCH_ARC_ENABLED
+    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+#endif
+
+    Catch::registerTestMethods();
+    int result = Catch::Session().run( argc, (char* const*)argv );
+
+#if !CATCH_ARC_ENABLED
+    [pool drain];
+#endif
+
+    return ( result < 0xff ? result : 0xff );
+}
+
+#endif // __OBJC__
+
+#endif
+
+#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
+#  undef CLARA_CONFIG_MAIN
+#endif
+
+//////
+
+// If this config identifier is defined then all CATCH macros are prefixed with CATCH_
+#ifdef CATCH_CONFIG_PREFIX_ALL
+
+#if defined(CATCH_CONFIG_FAST_COMPILE)
+#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, expr )
+#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr )
+#else
+#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, expr )
+#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr  )
+#endif
+
+#define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", expr )
+#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
+#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
+#define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, expr )
+
+#define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, expr )
+#define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, expr )
+#define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, expr )
+#define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, expr )
+#define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, expr )
+
+#define CATCH_CHECK_THROWS( expr )  INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", expr )
+#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
+#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
+#define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, expr )
+
+#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
+
+#if defined(CATCH_CONFIG_FAST_COMPILE)
+#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT_NO_TRY( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
+#else
+#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
+#endif
+
+#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
+#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
+#define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg )
+#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << Catch::toString(msg) )
+#define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << Catch::toString(msg) )
+
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+    #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
+    #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
+    #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
+    #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
+    #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
+    #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
+    #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+    #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+#else
+    #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
+    #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
+    #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
+    #define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description )
+    #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
+    #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, msg )
+    #define CATCH_FAIL_CHECK( msg ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, msg )
+    #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, msg )
+#endif
+#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
+
+#define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
+#define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
+
+#define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
+
+// "BDD-style" convenience wrappers
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
+#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
+#else
+#define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags )
+#define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
+#endif
+#define CATCH_GIVEN( desc )    CATCH_SECTION( std::string( "Given: ") + desc, "" )
+#define CATCH_WHEN( desc )     CATCH_SECTION( std::string( " When: ") + desc, "" )
+#define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc, "" )
+#define CATCH_THEN( desc )     CATCH_SECTION( std::string( " Then: ") + desc, "" )
+#define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc, "" )
+
+// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
+#else
+
+#if defined(CATCH_CONFIG_FAST_COMPILE)
+#define REQUIRE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "REQUIRE", Catch::ResultDisposition::Normal, expr )
+#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr )
+
+#else
+#define REQUIRE( expr ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, expr  )
+#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr )
+#endif
+
+#define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", expr )
+#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr )
+#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr )
+#define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, expr )
+
+#define CHECK( expr ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, expr )
+#define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, expr )
+#define CHECKED_IF( expr ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, expr )
+#define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, expr )
+#define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, expr )
+
+#define CHECK_THROWS( expr )  INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", expr )
+#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )
+#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )
+#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, expr )
+
+#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )
+
+#if defined(CATCH_CONFIG_FAST_COMPILE)
+#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT_NO_TRY( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
+#else
+#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg )
+#endif
+
+#define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
+#define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
+#define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
+#define CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << Catch::toString(msg) )
+#define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << Catch::toString(msg) )
+
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
+#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
+#define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
+#define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
+#define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
+#define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )
+#define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+#define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
+#else
+#define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
+    #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
+    #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
+    #define REGISTER_TEST_CASE( method, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( method, name, description )
+    #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
+    #define FAIL( msg ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, msg )
+    #define FAIL_CHECK( msg ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, msg )
+    #define SUCCEED( msg ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, msg )
+#endif
+#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
+
+#define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
+#define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
+
+#define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
+
+#endif
+
+#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
+
+// "BDD-style" convenience wrappers
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
+#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
+#else
+#define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags )
+#define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
+#endif
+#define GIVEN( desc )    SECTION( std::string("   Given: ") + desc, "" )
+#define WHEN( desc )     SECTION( std::string("    When: ") + desc, "" )
+#define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc, "" )
+#define THEN( desc )     SECTION( std::string("    Then: ") + desc, "" )
+#define AND_THEN( desc ) SECTION( std::string("     And: ") + desc, "" )
+
+using Catch::Detail::Approx;
+
+// #included from: internal/catch_reenable_warnings.h
+
+#define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED
+
+#ifdef __clang__
+#    ifdef __ICC // icpc defines the __clang__ macro
+#        pragma warning(pop)
+#    else
+#        pragma clang diagnostic pop
+#    endif
+#elif defined __GNUC__
+#    pragma GCC diagnostic pop
+#endif
+
+#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+
diff --git a/test/unit/cpp/common/SubSystemsManager.cpp b/test/unit/cpp/common/SubSystemsManager.cpp
index 660dad5..405e799 100644
--- a/test/unit/cpp/common/SubSystemsManager.cpp
+++ b/test/unit/cpp/common/SubSystemsManager.cpp
@@ -21,26 +21,25 @@
 // Unit tests for SubSystemsManager
 
 #include <dolfin.h>
-#include <gtest/gtest.h>
+#include <catch.hpp>
 
-using namespace dolfin;
-
-// Test rewritten using Google Test
-TEST(TestSubSystemsManager, test_petsc_user_init)
+namespace
 {
-  // Test user initialisation of PETSc
+  void init_petsc()
+  {
+    // Test user initialisation of PETSc
 #ifdef HAS_PETSC
-  int argc = 0;
-  char **argv = NULL;
-  PetscInitialize(&argc, &argv, NULL, NULL);
+    int argc = 0;
+    char **argv = NULL;
+    PetscInitialize(&argc, &argv, NULL, NULL);
 
-  UnitSquareMesh(12, 12);
-  PETScVector(MPI_COMM_WORLD, 30);
+    dolfin::UnitSquareMesh(12, 12);
+    dolfin::PETScVector(MPI_COMM_WORLD, 30);
 #endif
+  }
 }
 
-// Test all
-int SubSystemsManager_main(int argc, char **argv) {
-    testing::InitGoogleTest(&argc, argv);
-    return RUN_ALL_TESTS();
+TEST_CASE( "Initialise PETSc", "[petsc_init]" )
+{
+  CHECK_NOTHROW(init_petsc());
 }
diff --git a/test/unit/cpp/function/Expression.cpp b/test/unit/cpp/function/Expression.cpp
index 468b216..b2e6966 100644
--- a/test/unit/cpp/function/Expression.cpp
+++ b/test/unit/cpp/function/Expression.cpp
@@ -15,78 +15,71 @@
 // You should have received a copy of the GNU Lesser General Public License
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 //
-// Modified by Garth N. Wells, 2008.
-// Modified by Johannes Ring, 2009.
-// Modified by Benjamin Kehlet 2012
-//
-// First added:  2007-05-24
-// Last changed: 2014-08-12
-//
 // Unit tests for the function library
 
 #include <dolfin.h>
 #include "Projection.h"
-#include <gtest/gtest.h>
+#include <catch.hpp>
 
 using namespace dolfin;
 
-//-----------------------------------------------------------------------------
-TEST(Eval, testArbitraryEval)
+namespace
 {
-  class F0 : public Expression
+  void arbitrary_eval()
   {
-  public:
-    F0() {}
-    void eval(Array<double>& values, const Array<double>& x) const
-    { values[0] = sin(3.0*x[0])*sin(3.0*x[1])*sin(3.0*x[2]); }
-  };
+    class F0 : public Expression
+    {
+    public:
+      F0() {}
+      void eval(Array<double>& values, const Array<double>& x) const
+      { values[0] = sin(3.0*x[0])*sin(3.0*x[1])*sin(3.0*x[2]); }
+    };
 
-  class F1 : public Expression
-  {
-  public:
-    F1() {}
-    void eval(Array<double>& values, const Array<double>& x) const
-    { values[0] = 1.0 + 3.0*x[0] + 4.0*x[1] + 0.5*x[2]; }
-  };
+    class F1 : public Expression
+    {
+    public:
+      F1() {}
+      void eval(Array<double>& values, const Array<double>& x) const
+      { values[0] = 1.0 + 3.0*x[0] + 4.0*x[1] + 0.5*x[2]; }
+    };
 
-  auto mesh = std::make_shared<UnitCubeMesh>(8, 8, 8);
+    auto mesh = std::make_shared<UnitCubeMesh>(8, 8, 8);
 
-  Array<double> x(3);
-  x[0] = 0.31; x[1] = 0.32; x[2] = 0.33;
+    Array<double> x(3);
+    x[0] = 0.31; x[1] = 0.32; x[2] = 0.33;
 
-  Array<double> u0(1);
-  Array<double> u1(1);
+    Array<double> u0(1);
+    Array<double> u1(1);
 
-  // User-defined functions (one from finite element space, one not)
-  F0 f0;
-  auto f1 = std::make_shared<F1>();
+    // User-defined functions (one from finite element space, one not)
+    F0 f0;
+    auto f1 = std::make_shared<F1>();
 
-  // Test evaluation of a user-defined function
-  f0.eval(u0, x);
-  ASSERT_NEAR(u0[0],
-              sin(3.0*x[0])*sin(3.0*x[1])*sin(3.0*x[2]),
-              DOLFIN_EPS);
+    // Test evaluation of a user-defined function
+    f0.eval(u0, x);
+    CHECK(u0[0] == Approx(sin(3.0*x[0])*sin(3.0*x[1])*sin(3.0*x[2])));
 
-  // Test for single core only
-  if (dolfin::MPI::size(mesh->mpi_comm()) == 1)
-  {
+    // Test for single core only
+    if (dolfin::MPI::size(mesh->mpi_comm()) == 1)
+    {
     // Test evaluation of a discrete function
-    auto V = std::make_shared<Projection::FunctionSpace>(mesh);
-    Projection::BilinearForm a(V, V);
-    Projection::LinearForm L(V);
-    L.f = f1;
-    Function g(V);
-    solve(a == L, g);
+      auto V = std::make_shared<Projection::FunctionSpace>(mesh);
+      Projection::BilinearForm a(V, V);
+      Projection::LinearForm L(V);
+      L.f = f1;
+      Function g(V);
+      solve(a == L, g);
 
-    const double tol = 1.0e-6;
-    f1->eval(u0, x);
-    g.eval(u1, x);
-    ASSERT_NEAR(u0[0], u1[0], tol);
+      const double tol = 1.0e-6;
+      f1->eval(u0, x);
+      g.eval(u1, x);
+      CHECK(std::abs(u0[0] - u1[0]) < tol);
+    }
   }
 }
 
-// Test all
-int Expression_main(int argc, char **argv) {
-    testing::InitGoogleTest(&argc, argv);
-    return RUN_ALL_TESTS();
+//-----------------------------------------------------------------------------
+TEST_CASE( "Test arbitray eval", "[eval]" )
+{
+  CHECK_NOTHROW(arbitrary_eval());
 }
diff --git a/test/unit/cpp/geometry/ConvexTriangulation.cpp b/test/unit/cpp/geometry/ConvexTriangulation.cpp
new file mode 100644
index 0000000..973c533
--- /dev/null
+++ b/test/unit/cpp/geometry/ConvexTriangulation.cpp
@@ -0,0 +1,287 @@
+// Copyright (C) 2017 Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN 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 Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// Unit tests for convex triangulation
+
+#include <dolfin/geometry/ConvexTriangulation.h>
+#include <dolfin/geometry/CollisionPredicates.h>
+#include <dolfin/geometry/predicates.h>
+#include <catch.hpp>
+
+using namespace dolfin;
+
+namespace
+{
+  bool pure_triangular(const std::vector<std::vector<Point>>& triangulation, std::size_t dim)
+  {
+    for (const std::vector<Point>& tri : triangulation)
+    {
+
+      if (tri.size() != dim+1)
+	return false;
+    }
+
+    return true;
+  }
+
+  bool has_degenerate(const std::vector<std::vector<Point>>& triangulation, std::size_t dim)
+  {
+    for (const std::vector<Point>& tri : triangulation)
+    {
+      if (orient3d(tri[0], tri[1], tri[2], tri[3]) == 0)
+	return true;
+    }
+    return false;
+  }
+
+  bool triangulation_selfintersects(const std::vector<std::vector<Point>>& triangulation,
+				    std::size_t dim)
+  {
+    for (std::size_t i = 0; i < triangulation.size(); i++)
+    {
+      const auto& t1 = triangulation[i];
+      for (std::size_t j = i+1; j < triangulation.size(); j++)
+      {
+	const auto& t2 = triangulation[j];
+
+	// Count number of shared vertices
+	std::size_t shared_vertices = 0;
+	std::set<std::size_t> t1_shared;
+	std::set<std::size_t> t2_shared;
+	for (std::size_t v1 = 0; v1 < dim+1; v1++)
+	{
+	  for (std::size_t v2 = 0; v2 < dim+1; v2++)
+	  {
+	    if (t1[v1] == t2[v2])
+	    {
+	      shared_vertices++;
+	      t1_shared.insert(v1);
+	      t2_shared.insert(v2);
+	    }
+	  }
+	}
+
+	if (dim == 3)
+	{
+	  if (shared_vertices == 0 &&
+	      CollisionPredicates::collides_tetrahedron_tetrahedron_3d(t1[0], t1[1], t1[2], t1[3],
+								       t2[0], t2[1], t2[2], t2[3]))
+	  {
+	    return true;
+	  }
+	  else if (shared_vertices > 0)
+	  {
+
+	    for (std::size_t a = 0; a < dim+1; a++)
+	    {
+	      // None of the non-shared vertices should collide with the other tet
+	      if (t1_shared.count(a) == 0 &&
+		  CollisionPredicates::collides_tetrahedron_point_3d(t2[0], t2[1], t2[2], t2[3],
+								     t1[a]))
+	      {
+		return true;
+	      }
+
+	      if (t2_shared.count(a) == 0 &&
+		  CollisionPredicates::collides_tetrahedron_point_3d(t1[0], t1[1], t1[2], t1[3],
+								     t2[a]))
+	      {
+		return true;
+	      }
+	    }
+	  }
+	}
+	else if(dim == 2)
+	{
+	  if (shared_vertices == 0 &&
+	      CollisionPredicates::collides_triangle_triangle_2d(t1[0],
+								 t1[1],
+								 t1[2],
+								 t2[0],
+								 t2[1],
+								 t2[2]))
+	  {
+	    return true;
+	  }
+	}
+      }
+    }
+    return false;
+  }
+  //-----------------------------------------------------------------------------
+  double triangulation_volume(const std::vector<std::vector<dolfin::Point>>& triangulation)
+  {
+    double vol = 0;
+    for (const std::vector<dolfin::Point>& tri : triangulation)
+    {
+      const Point& x0 = tri[0];
+      const Point& x1 = tri[1];
+      const Point& x2 = tri[2];
+      const Point& x3 = tri[3];
+      // Formula for volume from http://mathworld.wolfram.com
+      const double v = (x0[0]*(x1[1]*x2[2] + x3[1]*x1[2] + x2[1]*x3[2]
+			     - x2[1]*x1[2] - x1[1]*x3[2] - x3[1]*x2[2])
+		      - x1[0]*(x0[1]*x2[2] + x3[1]*x0[2] + x2[1]*x3[2]
+			     - x2[1]*x0[2] - x0[1]*x3[2] - x3[1]*x2[2])
+                      + x2[0]*(x0[1]*x1[2] + x3[1]*x0[2] + x1[1]*x3[2]
+			     - x1[1]*x0[2] - x0[1]*x3[2] - x3[1]*x1[2])
+		      - x3[0]*(x0[1]*x1[2] + x1[1]*x2[2] + x2[1]*x0[2]
+			     - x1[1]*x0[2] - x2[1]*x1[2] - x0[1]*x2[2]));
+      vol += std::abs(v);
+    }
+
+    return vol/6;
+  }
+}
+
+//-----------------------------------------------------------------------------
+TEST_CASE("Convex triangulation test")
+{
+  SECTION("test trivial case]")
+  {
+    std::vector<Point> input = {{Point(0,0,0),
+                                 Point(0,0,1),
+                                 Point(0,1,0),
+                                 Point(1,0,0)}};
+
+    std::vector<std::vector<Point>> tri = ConvexTriangulation::triangulate_graham_scan_3d(input);
+    std::size_t expected_size = 1;
+
+    CHECK(tri.size() == expected_size);
+    CHECK(triangulation_volume(tri) == Approx(1.0/6.0));
+  }
+
+  SECTION("test trivial case 2")
+  {
+    std::vector<Point> input = {{Point(0,0,0),
+                                 Point(0,0,1),
+                                 Point(0,1,0),
+                                 Point(0,1,1),
+                                 Point(1,0,0),
+                                 Point(1,0,1),
+                                 Point(1,1,0),
+                                 Point(1,1,1)}};
+
+    std::vector<std::vector<Point>> tri = ConvexTriangulation::triangulate_graham_scan_3d(input);
+
+    CHECK(pure_triangular(tri, 3));
+    CHECK_FALSE(has_degenerate(tri, 3));
+    CHECK_FALSE(triangulation_selfintersects(tri, 3));
+    CHECK(triangulation_volume(tri) == Approx(1.0));
+  }
+
+  SECTION("test coplanar points")
+  {
+    std::vector<Point> input {
+      Point(0,   0,   0),
+        Point(0,   0,   1),
+        Point(0,   1,   0),
+        Point(0,   1,   1),
+        Point(1,   0,   0),
+        Point(1,   0,   1),
+        Point(1,   1,   0),
+        Point(1,   1,   1),
+        Point(0.1, 0.1, 0)};
+
+    std::vector<std::vector<Point>> tri = ConvexTriangulation::triangulate_graham_scan_3d(input);
+
+    CHECK(pure_triangular(tri, 3));
+    CHECK_FALSE(has_degenerate(tri, 3));
+    CHECK_FALSE(triangulation_selfintersects(tri, 3));
+    CHECK(triangulation_volume(tri) == Approx(1.0));
+  }
+
+  SECTION("test coplanar colinear points]")
+  {
+    std::vector<Point> input {
+      Point(0, 0,   0),
+        Point(0, 0,   1),
+        Point(0, 1,   0),
+        Point(0, 1,   1),
+        Point(1, 0,   0),
+        Point(1, 0,   1),
+        Point(1, 1,   0),
+        Point(1, 1,   1),
+        Point(0, 0.1, 0)};
+
+    std::vector<std::vector<Point>> tri = ConvexTriangulation::triangulate_graham_scan_3d(input);
+
+    CHECK(pure_triangular(tri, 3));
+    CHECK_FALSE(has_degenerate(tri, 3));
+    CHECK_FALSE(triangulation_selfintersects(tri, 3));
+    CHECK(triangulation_volume(tri) == Approx(1.0));
+  }
+
+  SECTION("test failing case")
+  {
+    std::vector<Point> input {
+      Point(0.7, 0.6, 0.1),
+        Point(0.7, 0.6, 0.5),
+        Point(0.1, 0.1, 0.1),
+        Point(0.8333333333333333, 0.8333333333333333, 0),
+        Point(0.1, 0.15, 0.1),
+        Point(0.1, 0.45, 0.1),
+        Point(0.16, 0.15, 0.1),
+        Point(0.61, 0.525, 0.1),
+        Point(0.46, 0.6, 0.100000000000000006) };
+
+    std::vector<std::vector<Point>> tri = ConvexTriangulation::triangulate_graham_scan_3d(input);
+
+    CHECK(pure_triangular(tri, 3));
+    CHECK_FALSE(has_degenerate(tri, 3));
+    CHECK_FALSE(triangulation_selfintersects(tri, 3));
+  }
+
+  SECTION("test failing case 2")
+  {
+    std::vector<Point> input {
+      Point(0.7, 0.6, 0.5),
+        Point(0.7, 0.1, 0.1),
+        Point(0.8, 0, 0),
+        Point (0.1, 0.1, 0.1),
+        Point(0.16, 0.1, 0.1),
+        Point(0.592, 0.1, 0.1),
+        Point (0.16, 0.1, 0.14),
+        Point (0.52, 0.1, 0.38),
+        Point (0.7, 0.1, 0.38)};
+
+    std::vector<std::vector<Point>> tri = ConvexTriangulation::triangulate_graham_scan_3d(input);
+
+    CHECK(pure_triangular(tri, 3));
+    CHECK_FALSE(has_degenerate(tri, 3));
+    CHECK_FALSE(triangulation_selfintersects(tri, 3));
+  }
+
+  SECTION("test failing case 3")
+  {
+    std::vector<Point> input {
+      Point (0.495926, 0.512037, 0.144444),
+        Point (0.376482, 0.519121, 0.284321),
+        Point (0.386541, 0.599783, 0.0609262),
+        Point (0.388086, 0.60059, 0.0607155),
+        Point (0.7, 0.6, 0.5),
+        Point (0.504965, 0.504965, 0.0447775),
+        Point (0.833333, 0.833333, 0)};
+
+    std::vector<std::vector<Point>> tri = ConvexTriangulation::triangulate_graham_scan_3d(input);
+
+    CHECK(pure_triangular(tri, 3));
+    CHECK_FALSE(has_degenerate(tri, 3));
+    CHECK_FALSE(triangulation_selfintersects(tri, 3));
+  }
+}
+//-----------------------------------------------------------------------------
diff --git a/test/unit/cpp/io/XMLMeshData.cpp b/test/unit/cpp/io/XMLMeshData.cpp
index 5027374..709ca70 100644
--- a/test/unit/cpp/io/XMLMeshData.cpp
+++ b/test/unit/cpp/io/XMLMeshData.cpp
@@ -14,62 +14,60 @@
 //
 // You should have received a copy of the GNU Lesser General Public License
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
-//
-// First added:  2012-05-25
-// Last changed:
-//
 
 #include <dolfin.h>
-#include <gtest/gtest.h>
+#include <catch.hpp>
 
 using namespace dolfin;
 
-//-----------------------------------------------------------------------------
-TEST(XMLMeshDataIO, test_write_read)
+namespace
 {
-  // XML mesh output is not supported in parallel. Add test for
-  // parallel with HDF5 when ready.
-  if (dolfin::MPI::size(MPI_COMM_WORLD) == 1)
+  void xml_mesh_data()
   {
-    const std::size_t value = 10;
+    // XML mesh output is not supported in parallel. Add test for
+    // parallel with HDF5 when ready.
+    if (dolfin::MPI::size(MPI_COMM_WORLD) == 1)
     {
-      UnitSquareMesh mesh(2, 2);
+      const std::size_t value = 10;
+      {
+        UnitSquareMesh mesh(2, 2);
 
-      // Create some mesh data
-      std::vector<std::size_t>& data0 = mesh.data().create_array("v", 0);
-      data0.resize(mesh.num_entities(0), value);
+        // Create some mesh data
+        std::vector<std::size_t>& data0 = mesh.data().create_array("v", 0);
+        data0.resize(mesh.num_entities(0), value);
 
-      mesh.init(1);
-      std::vector<std::size_t>& data1 = mesh.data().create_array("e", 1);
-      data1.resize(mesh.num_entities(1), value);
+        mesh.init(1);
+        std::vector<std::size_t>& data1 = mesh.data().create_array("e", 1);
+        data1.resize(mesh.num_entities(1), value);
 
-      std::vector<std::size_t>& data2 = mesh.data().create_array("c", 2);
-      data2.resize(mesh.num_entities(2), value);
+        std::vector<std::size_t>& data2 = mesh.data().create_array("c", 2);
+        data2.resize(mesh.num_entities(2), value);
 
-      File file("mesh_data.xml");
-      file << mesh;
-    }
+        File file("mesh_data.xml");
+        file << mesh;
+      }
 
-    {
-      // Read mesh from file
-      Mesh mesh("mesh_data.xml");
+      {
+        // Read mesh from file
+        Mesh mesh("mesh_data.xml");
 
-      // Access mesh data and check
-      const std::vector<std::size_t>& data0 = mesh.data().array("v", 0);
-      ASSERT_EQ(data0.size(), mesh.num_entities(0));
-      ASSERT_EQ(data0[2], value);
-      const std::vector<std::size_t>& data1 = mesh.data().array("e", 1);
-      ASSERT_EQ(data1.size(), mesh.num_entities(1));
-      ASSERT_EQ(data1[2], value);
-      const std::vector<std::size_t>& data2 = mesh.data().array("c", 2);
-      ASSERT_EQ(data2.size(), mesh.num_entities(2));
-      ASSERT_EQ(data2[2], value);
+        // Access mesh data and check
+        const std::vector<std::size_t>& data0 = mesh.data().array("v", 0);
+        CHECK(data0.size() == mesh.num_entities(0));
+        CHECK(data0[2] == value);
+        const std::vector<std::size_t>& data1 = mesh.data().array("e", 1);
+        CHECK(data1.size() == mesh.num_entities(1));
+        CHECK(data1[2] == value);
+        const std::vector<std::size_t>& data2 = mesh.data().array("c", 2);
+        CHECK(data2.size() == mesh.num_entities(2));
+        CHECK(data2[2] == value);
+      }
     }
   }
 }
 
-// Test all
-int XMLMeshData_main(int argc, char **argv) {
-    testing::InitGoogleTest(&argc, argv);
-    return RUN_ALL_TESTS();
-}
\ No newline at end of file
+//-----------------------------------------------------------------------------
+TEST_CASE("Test XML mesh data", "[xml_mesh_data]")
+{
+  CHECK_NOTHROW(xml_mesh_data());
+}
diff --git a/test/unit/cpp/io/XMLMeshValueCollection.cpp b/test/unit/cpp/io/XMLMeshValueCollection.cpp
index d177b0e..0e6b48d 100644
--- a/test/unit/cpp/io/XMLMeshValueCollection.cpp
+++ b/test/unit/cpp/io/XMLMeshValueCollection.cpp
@@ -14,28 +14,24 @@
 //
 // You should have received a copy of the GNU Lesser General Public License
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
-//
-// First added:  2007-05-29
-// Last changed: 2012-01-12
-//
 
 #include <dolfin.h>
-#include <gtest/gtest.h>
+#include <catch.hpp>
 
 using namespace dolfin;
 
 //-----------------------------------------------------------------------------
-TEST(MeshValueCollectionIO, test_read)
+TEST_CASE("MeshValueCollection IO test", "[!hide][meshvaluecollection_io]")
 {
   // Create mesh and read file
   // Link to the mesh is quite long...
   auto mesh = std::make_shared<UnitCubeMesh>(5, 5, 5);
-  MeshValueCollection<std::size_t>
-    markers(mesh, "./test/unit/cpp/io/xml_value_collection_ref.xml");
+  MeshValueCollection<std::size_t> markers(mesh, "./io/xml_value_collection_ref.xml");
+  //MeshValueCollection<std::size_t>
+  //  markers(mesh, "./test/unit/cpp/io/xml_value_collection_ref.xml");
 
   // Check size
-  ASSERT_EQ(dolfin::MPI::sum(mesh->mpi_comm(), markers.size()),
-            (std::size_t) 6);
+  CHECK(dolfin::MPI::sum(mesh->mpi_comm(), markers.size()) == (std::size_t) 6);
 
   // Check sum of values
   const std::map<std::pair<std::size_t, std::size_t>, std::size_t>&
@@ -43,11 +39,6 @@ TEST(MeshValueCollectionIO, test_read)
   std::size_t sum = 0;
   for (auto it = values.begin(); it != values.end(); ++it)
     sum += it->second;
-  ASSERT_EQ(dolfin::MPI::sum(mesh->mpi_comm(), sum), (std::size_t) 48);
-}
 
-// Test all
-int XMLMeshValueCollection_main(int argc, char **argv) {
-    testing::InitGoogleTest(&argc, argv);
-    return RUN_ALL_TESTS();
+  CHECK(dolfin::MPI::sum(mesh->mpi_comm(), sum) == (std::size_t) 48);
 }
diff --git a/test/unit/cpp/la/LinearOperator.cpp b/test/unit/cpp/la/LinearOperator.cpp
index 9a4da01..28ec42e 100644
--- a/test/unit/cpp/la/LinearOperator.cpp
+++ b/test/unit/cpp/la/LinearOperator.cpp
@@ -15,27 +15,22 @@
 // You should have received a copy of the GNU Lesser General Public License
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 //
-// Modified by Johannes Ring 2012
-//
-// First added:  2012-08-21
-// Last changed: 2012-09-19
-//
 // Unit tests for matrix-free linear solvers (LinearOperator)
 
 #include <dolfin.h>
 #include "forms/ReactionDiffusion.h"
 #include "forms/ReactionDiffusionAction.h"
-
-#include <gtest/gtest.h>
+#include <catch.hpp>
 
 using namespace dolfin;
 
-// Backends supporting the LinearOperator interface
-static std::vector<std::string> backends = {"PETSc", "Eigen"};
-
 //-----------------------------------------------------------------------------
-TEST(TestLinearOperator, test_linear_operator)
+TEST_CASE("Testing LinearOperator", "[linear_operator]")
 {
+  // Backends supporting the LinearOperator interface
+  //std::vector<std::string> backends = {"PETSc", "Eigen"};
+  std::vector<std::string> backends = {"PETSc"};
+
   // Define linear operator
   class MyLinearOperator : public LinearOperator
   {
@@ -68,59 +63,53 @@ TEST(TestLinearOperator, test_linear_operator)
 
   };
 
-  // Iterate over backends supporting linear operators
-  for (std::size_t i = 0; i < backends.size(); i++)
+  SECTION("using linear operator")
   {
-    // Check whether backend is available
-    if (!has_linear_algebra_backend(backends[i]))
-      continue;
-
-    // Skip testing Eigen in parallel
-    if (dolfin::MPI::size(MPI_COMM_WORLD) > 1
-        && backends[i] == "Eigen")
+    // Iterate over backends supporting linear operators
+    for (std::size_t i = 0; i < backends.size(); i++)
     {
-      info("Not running Eigen test in parallel");
-      continue;
+      // Check whether backend is available
+      if (!has_linear_algebra_backend(backends[i]))
+        continue;
+
+      // Skip testing Eigen in parallel
+      if (dolfin::MPI::size(MPI_COMM_WORLD) > 1
+          && backends[i] == "Eigen")
+      {
+        info("Not running Eigen test in parallel");
+        continue;
+      }
+
+      // Set linear algebra backend
+      parameters["linear_algebra_backend"] = backends[i];
+
+      // Compute reference value by solving ordinary linear system
+      auto mesh = std::make_shared<UnitSquareMesh>(8, 8);
+      auto V = std::make_shared<ReactionDiffusion::FunctionSpace>(mesh);
+      ReactionDiffusion::BilinearForm a(V, V);
+      ReactionDiffusion::LinearForm L(V);
+      auto f = std::make_shared<Constant>(1.0);
+      L.f = f;
+      Matrix A;
+      Vector x, b;
+      assemble(A, a);
+      assemble(b, L);
+      solve(A, x, b, "gmres", "none");
+      const double norm_ref = norm(x, "l2");
+
+      //continue;
+
+      // Solve using linear operator defined by form action
+      ReactionDiffusionAction::LinearForm a_action(V);
+      auto u = std::make_shared<Function>(V);
+      a_action.u = u;
+      MyLinearOperator O(a_action, *u);
+      solve(O, x, b, "gmres", "none");
+      const double norm_action = norm(x, "l2");
+
+      // Check results
+      CHECK(norm_ref == Approx(norm_action));
     }
-
-    // Set linear algebra backend
-    parameters["linear_algebra_backend"] = backends[i];
-
-    // Compute reference value by solving ordinary linear system
-    auto mesh = std::make_shared<UnitSquareMesh>(8, 8);
-    auto V = std::make_shared<ReactionDiffusion::FunctionSpace>(mesh);
-    ReactionDiffusion::BilinearForm a(V, V);
-    ReactionDiffusion::LinearForm L(V);
-    auto f = std::make_shared<Constant>(1.0);
-    L.f = f;
-    Matrix A;
-    Vector x, b;
-    assemble(A, a);
-    assemble(b, L);
-    solve(A, x, b, "gmres", "none");
-    const double norm_ref = norm(x, "l2");
-
-    continue;
-
-    // Solve using linear operator defined by form action
-    ReactionDiffusionAction::LinearForm a_action(V);
-    auto u = std::make_shared<Function>(V);
-    a_action.u = u;
-    MyLinearOperator O(a_action, *u);
-    solve(O, x, b, "gmres", "none");
-    const double norm_action = norm(x, "l2");
-
-    // Check results
-      ASSERT_NEAR(norm_ref, norm_action, 1e-10);
   }
 }
-
-// Test all
-int LinearOperator_main(int argc, char **argv) {
-    // Add backends supporting the LinearOperator interface
-    backends.push_back("PETSc");
-    backends.push_back("Eigen");
-    testing::InitGoogleTest(&argc, argv);
-    return RUN_ALL_TESTS();
-}
 //-----------------------------------------------------------------------------
diff --git a/test/unit/cpp/la/Vector.cpp b/test/unit/cpp/la/Vector.cpp
index 31b70b3..570fb3a 100644
--- a/test/unit/cpp/la/Vector.cpp
+++ b/test/unit/cpp/la/Vector.cpp
@@ -15,164 +15,161 @@
 // You should have received a copy of the GNU Lesser General Public License
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 //
-// First added:  2008-09-30
-// Last changed: 2012-08-21
-//
 // Unit tests Selected methods for GenericVector
 
 #include <dolfin.h>
-#include <gtest/gtest.h>
+#include <catch.hpp>
 
 using namespace dolfin;
 
-//----------------------------------------------------
-void _test_operators(MPI_Comm comm)
+namespace
 {
-  Vector v(comm, 10), u(comm, 10);
-  v = 0.0;
-  u = 0.0;
-  ASSERT_EQ(v.sum(), 0.0);
+  void _test_operators(MPI_Comm comm)
+  {
+    Vector v(comm, 10), u(comm, 10);
+    v = 0.0;
+    u = 0.0;
+    CHECK(v.sum() == 0.0);
 
-  // operator=(double a)
-  v = 1.0;
-  ASSERT_EQ(v.sum(), v.size());
+    // operator=(double a)
+    v = 1.0;
+    CHECK(v.sum() == v.size());
 
-  // operator=(const GenericVector& x)
-  u = v;
-  ASSERT_EQ(u.sum(), u.size());
+    // operator=(const GenericVector& x)
+    u = v;
+    CHECK(u.sum() == u.size());
 
-  // operator+=(const GenericVector& x)
-  u += v;
-  ASSERT_EQ(u.sum(), 2*u.size());
+    // operator+=(const GenericVector& x)
+    u += v;
+    CHECK(u.sum() == 2*u.size());
 
-  // operator-=(const GenericVector& x)
-  u -= v;
-  u -= v;
-  ASSERT_EQ(u.sum(), 0.0);
+    // operator-=(const GenericVector& x)
+    u -= v;
+    u -= v;
+    CHECK(u.sum() == 0.0);
 
   // operator*=(double a)
-  v *= 5.0;
-  ASSERT_EQ(v.sum(), v.size()*5.0);
+    v *= 5.0;
+    CHECK(v.sum() == v.size()*5.0);
 
-  // operator/=(double a)
-  v /= 2.0;
-  ASSERT_EQ(v.sum(), 2.5*v.size());
+    // operator/=(double a)
+    v /= 2.0;
+    CHECK(v.sum() == 2.5*v.size());
 
-  // operator*=(const GenericVector& x)
-  u = 2.0;
-  v*=u;
-  ASSERT_EQ(v.sum(), v.size()*5.0);
+    // operator*=(const GenericVector& x)
+    u = 2.0;
+    v*=u;
+    CHECK(v.sum() == v.size()*5.0);
+  }
 }
-//----------------------------------------------------
-TEST(TestVector, test_backends)
-{
-  // Eigen
-  parameters["linear_algebra_backend"] = "Eigen";
-  _test_operators(MPI_COMM_SELF);
 
-  // PETSc
-#ifdef HAS_PETSC
-  parameters["linear_algebra_backend"] = "PETSc";
-  _test_operators(MPI_COMM_WORLD);
-#endif
-}
-//----------------------------------------------------
-TEST(TestVector, test_init)
+
+TEST_CASE("Test Vector", "[test_vector]")
 {
-  // Create local and distributed vector layouts
-
-  // Create local vector layout
-  TensorLayout layout_local(MPI_COMM_SELF, 0, TensorLayout::Sparsity::DENSE);
-  std::vector<std::shared_ptr<const IndexMap>> index_maps(1);
-  index_maps[0].reset(new IndexMap(MPI_COMM_SELF, 203, 1));
-  layout_local.init(index_maps, TensorLayout::Ghosts::UNGHOSTED);
-
-  // Create distributed vector layout
-  TensorLayout layout_distributed(MPI_COMM_WORLD, 0, TensorLayout::Sparsity::DENSE);
-  auto lrange = dolfin::MPI::local_range(MPI_COMM_WORLD, 203);
-  std::size_t nlocal = lrange.second - lrange.first;
-  index_maps[0].reset(new IndexMap(MPI_COMM_SELF, nlocal, 1));
-  layout_distributed.init(index_maps, TensorLayout::Ghosts::UNGHOSTED);
-
-  // Vector
-#ifdef HAS_PETSC
-  parameters["linear_algebra_backend"] = "PETSc";
+  SECTION("backends")
   {
-    Vector x;
-    x.init(layout_local);
-    ASSERT_EQ(x.size(), (std::size_t) 203);
+    // Eigen
+    parameters["linear_algebra_backend"] = "Eigen";
+    _test_operators(MPI_COMM_SELF);
 
-    Vector y;
-    y.init(layout_distributed);
-    ASSERT_EQ(x.size(), (std::size_t) 203);
-    }
+    // PETSc
+#ifdef HAS_PETSC
+    parameters["linear_algebra_backend"] = "PETSc";
+    _test_operators(MPI_COMM_WORLD);
 #endif
-
-  // Eigen
-  {
-    EigenVector x;
-    x.init(layout_local);
-    ASSERT_EQ(x.size(), (std::size_t) 203);
   }
 
-  // PETSc
-#ifdef HAS_PETSC
+  SECTION("init")
   {
-    PETScVector x;
-    x.init(layout_local);
-    ASSERT_EQ(x.size(), (std::size_t) 203);
-
-    PETScVector y;
-    y.init(layout_distributed);
-    ASSERT_EQ(y.size(), (std::size_t) 203);
-  }
-#endif
-}
-//-----------------------------------------------------------------------------
-TEST(TestVector, test_get_local_empty)
-{
-  // Create local and distributed vector layouts
-  const std::vector<std::size_t> dims(1, 203);
-
-  // Create local vector layout
-  TensorLayout layout_local(MPI_COMM_SELF, 0, TensorLayout::Sparsity::DENSE);
-  std::vector<std::shared_ptr<const IndexMap>> index_maps(1);
-  index_maps[0].reset(new IndexMap(MPI_COMM_SELF, 203, 1));
-  layout_local.init(index_maps, TensorLayout::Ghosts::UNGHOSTED);
-
-  // Create distributed vector layout
-  TensorLayout layout_distributed(MPI_COMM_WORLD, 0, TensorLayout::Sparsity::DENSE);
-  auto lrange = dolfin::MPI::local_range(MPI_COMM_WORLD, 203);
-  std::size_t nlocal = lrange.second - lrange.first;
-  index_maps[0].reset(new IndexMap(MPI_COMM_SELF, nlocal, 1));
-  layout_distributed.init(index_maps, TensorLayout::Ghosts::UNGHOSTED);
-
-  // Vector
+    // Create local and distributed vector layouts
+
+    // Create local vector layout
+    TensorLayout layout_local(MPI_COMM_SELF, 0, TensorLayout::Sparsity::DENSE);
+    std::vector<std::shared_ptr<const IndexMap>> index_maps(1);
+    index_maps[0].reset(new IndexMap(MPI_COMM_SELF, 203, 1));
+    layout_local.init(index_maps, TensorLayout::Ghosts::UNGHOSTED);
+
+    // Create distributed vector layout
+    TensorLayout layout_distributed(MPI_COMM_WORLD, 0, TensorLayout::Sparsity::DENSE);
+    auto lrange = dolfin::MPI::local_range(MPI_COMM_WORLD, 203);
+    std::size_t nlocal = lrange.second - lrange.first;
+    index_maps[0].reset(new IndexMap(MPI_COMM_SELF, nlocal, 1));
+    layout_distributed.init(index_maps, TensorLayout::Ghosts::UNGHOSTED);
+
+    // Vector
 #ifdef HAS_PETSC
-  parameters["linear_algebra_backend"] = "PETSc";
-  {
-    Vector x;
-    x.init(layout_local);
-    ASSERT_EQ(x.size(), (std::size_t) 203);
-
-    Vector y;
-    y.init(layout_distributed);
-    ASSERT_EQ(y.size(), (std::size_t) 203);
-
-    //:get_local(double* block, std::size_t m,
-    //           const dolfin::la_index* rows) const
+    parameters["linear_algebra_backend"] = "PETSc";
+    {
+      Vector x;
+      x.init(layout_local);
+      CHECK(x.size() == (std::size_t) 203);
+
+      Vector y;
+      y.init(layout_distributed);
+      CHECK(x.size() == (std::size_t) 203);
+    }
+#endif
 
-    double* block = NULL;
-    dolfin::la_index* rows = NULL;
-    x.get_local(block, 0, rows);
-    y.get_local(block, 0, rows);
+    // Eigen
+    {
+      EigenVector x;
+      x.init(layout_local);
+      CHECK(x.size() == (std::size_t) 203);
+    }
 
+    // PETSc
+#ifdef HAS_PETSC
+    {
+      PETScVector x;
+      x.init(layout_local);
+      CHECK(x.size() == (std::size_t) 203);
+
+      PETScVector y;
+      y.init(layout_distributed);
+      CHECK(y.size() == (std::size_t) 203);
+    }
+#endif
   }
+
+  SECTION("test_get_local_empty")
+  {
+    // Create local and distributed vector layouts
+    const std::vector<std::size_t> dims(1, 203);
+
+    // Create local vector layout
+    TensorLayout layout_local(MPI_COMM_SELF, 0, TensorLayout::Sparsity::DENSE);
+    std::vector<std::shared_ptr<const IndexMap>> index_maps(1);
+    index_maps[0].reset(new IndexMap(MPI_COMM_SELF, 203, 1));
+    layout_local.init(index_maps, TensorLayout::Ghosts::UNGHOSTED);
+
+    // Create distributed vector layout
+    TensorLayout layout_distributed(MPI_COMM_WORLD, 0, TensorLayout::Sparsity::DENSE);
+    auto lrange = dolfin::MPI::local_range(MPI_COMM_WORLD, 203);
+    std::size_t nlocal = lrange.second - lrange.first;
+    index_maps[0].reset(new IndexMap(MPI_COMM_SELF, nlocal, 1));
+    layout_distributed.init(index_maps, TensorLayout::Ghosts::UNGHOSTED);
+
+    // Vector
+#ifdef HAS_PETSC
+    parameters["linear_algebra_backend"] = "PETSc";
+    {
+      Vector x;
+      x.init(layout_local);
+      CHECK(x.size() == (std::size_t) 203);
+
+      Vector y;
+      y.init(layout_distributed);
+      CHECK(y.size() == (std::size_t) 203);
+
+      //:get_local(double* block, std::size_t m,
+      //           const dolfin::la_index* rows) const
+
+      double* block = NULL;
+      dolfin::la_index* rows = NULL;
+      x.get_local(block, 0, rows);
+      y.get_local(block, 0, rows);
+    }
 #endif
-}
+  }
 
-// Test all
-int Vector_main(int argc, char **argv) {
-    testing::InitGoogleTest(&argc, argv);
-    return RUN_ALL_TESTS();
 }
diff --git a/test/unit/cpp/main.cpp b/test/unit/cpp/main.cpp
new file mode 100644
index 0000000..1c77b13
--- /dev/null
+++ b/test/unit/cpp/main.cpp
@@ -0,0 +1,2 @@
+#define CATCH_CONFIG_MAIN
+#include "catch/catch.hpp"
diff --git a/test/unit/cpp/mesh/Mesh.cpp b/test/unit/cpp/mesh/Mesh.cpp
index 74bb211..5ad7ab8 100644
--- a/test/unit/cpp/mesh/Mesh.cpp
+++ b/test/unit/cpp/mesh/Mesh.cpp
@@ -15,237 +15,238 @@
 // You should have received a copy of the GNU Lesser General Public License
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 //
-// Modified by Benjamin Kehlet 2012
-//
-// First added:  2007-05-14
-// Last changed: 2012-11-12
-//
 // Unit tests for the mesh library
 
 #include <dolfin.h>
-#include <gtest/gtest.h>
+#include <catch.hpp>
 
 using namespace dolfin;
 
 //-----------------------------------------------------------------------------
-TEST(SimpleShapesTest, testUnitSquareMesh)
+TEST_CASE("Simple shapes test")
 {
-  // Create mesh of unit square
-  UnitSquareMesh mesh(5, 7);
-  ASSERT_EQ(mesh.num_vertices(), (std::size_t) 48);
-  ASSERT_EQ(mesh.num_cells(), (std::size_t) 70);
+  SECTION("Test UnitSquareMesh")
+  {
+    // Create mesh of unit square
+    UnitSquareMesh mesh(5, 7);
+    CHECK(mesh.num_vertices() == (std::size_t) 48);
+    CHECK(mesh.num_cells() == (std::size_t) 70);
 
-  // Create mesh of unit square
-  auto mesh1 = UnitSquareMesh::create({{5, 7}});
-  ASSERT_EQ(mesh1.num_vertices(), (std::size_t) 48);
-  ASSERT_EQ(mesh1.num_cells(), (std::size_t) 70);
+    // Create mesh of unit square
+    auto mesh1 = UnitSquareMesh::create({{5, 7}}, CellType::Type::triangle);
+    CHECK(mesh1.num_vertices() == (std::size_t) 48);
+    CHECK(mesh1.num_cells() == (std::size_t) 70);
+  }
 
+  SECTION("Test UnitCubeMesh")
+  {
+    // Create mesh of unit cube
+    UnitCubeMesh mesh(5, 7, 9);
+    CHECK(mesh.num_vertices() == (std::size_t) 480);
+    CHECK(mesh.num_cells() == (std::size_t) 1890);
+
+    // Create mesh of unit cube
+    auto mesh1 = UnitCubeMesh::create({{5, 7, 9}}, CellType::Type::tetrahedron);
+    CHECK(mesh1.num_vertices() == (std::size_t) 480);
+    CHECK(mesh1.num_cells() == (std::size_t) 1890);
+  }
 }
-//-----------------------------------------------------------------------------
-TEST(SimpleShapesTest, testUnitCubeMesh)
-{
-  // Create mesh of unit cube
-  UnitCubeMesh mesh(5, 7, 9);
-  ASSERT_EQ(mesh.num_vertices(), (std::size_t) 480);
-  ASSERT_EQ(mesh.num_cells(), (std::size_t) 1890);
-
-  // Create mesh of unit cube
-  auto mesh1 = UnitCubeMesh::create({{5, 7, 9}});
-  ASSERT_EQ(mesh1.num_vertices(), (std::size_t) 480);
-  ASSERT_EQ(mesh1.num_cells(), (std::size_t) 1890);
-}
-//-----------------------------------------------------------------------------
-TEST(MeshRefinement, testRefineUnitSquareMesh)
-{
-  // Refine mesh of unit square
-  UnitSquareMesh mesh0(5, 7);
-  Mesh mesh1 = refine(mesh0);
-  ASSERT_EQ(mesh1.num_vertices(), (std::size_t) 165);
-  ASSERT_EQ(mesh1.num_cells(), (std::size_t) 280);
-}
-//-----------------------------------------------------------------------------
-TEST(MeshRefinement, testRefineUnitCubeMesh)
-{
-  // Refine mesh of unit cube
-  UnitCubeMesh mesh0(5, 7, 9);
-  Mesh mesh1 = refine(mesh0);
-  ASSERT_EQ(mesh1.num_vertices(), (std::size_t) 3135);
-  ASSERT_EQ(mesh1.num_cells(), (std::size_t) 15120);
-}
-//-----------------------------------------------------------------------------
-TEST(MeshIterators, testVertexIterators)
-{
-  // Iterate over vertices
-  UnitCubeMesh mesh(5, 5, 5);
-  unsigned int n = 0;
-  for (VertexIterator v(mesh); !v.end(); ++v)
-    n++;
-  ASSERT_EQ(n, mesh.num_vertices());
-}
-//-----------------------------------------------------------------------------
-TEST(MeshIterators, testEdgeIterators)
-{
-  // Iterate over edges
-  UnitCubeMesh mesh(5, 5, 5);
-  unsigned int n = 0;
-  for (EdgeIterator e(mesh); !e.end(); ++e)
-    n++;
-  ASSERT_EQ(n, mesh.num_edges());
-}
-//-----------------------------------------------------------------------------
-TEST(MeshIterators, testFaceIterators)
-{
-  // Iterate over faces
-  UnitCubeMesh mesh(5, 5, 5);
-  unsigned int n = 0;
-  for (FaceIterator f(mesh); !f.end(); ++f)
-    n++;
-  ASSERT_EQ(n, mesh.num_faces());
-}
-//-----------------------------------------------------------------------------
-TEST(MeshIterators, testFacetIterators)
-{
-  // Iterate over facets
-  UnitCubeMesh mesh(5, 5, 5);
-  unsigned int n = 0;
-  for (FacetIterator f(mesh); !f.end(); ++f)
-    n++;
-  ASSERT_EQ(n, mesh.num_facets());
-}
-//-----------------------------------------------------------------------------
-TEST(MeshIterators, testCellIterators)
-{
-  // Iterate over cells
-  UnitCubeMesh mesh(5, 5, 5);
-  unsigned int n = 0;
-  for (CellIterator c(mesh); !c.end(); ++c)
-    n++;
-  ASSERT_EQ(n, mesh.num_cells());
+
+TEST_CASE("Mesh refinement")
+{
+  SECTION("Test refine UnitSquareMesh")
+  {
+    // Refine mesh of unit square
+    UnitSquareMesh mesh0(5, 7);
+    Mesh mesh1 = refine(mesh0);
+    CHECK(mesh1.num_vertices() == (std::size_t) 165);
+    CHECK(mesh1.num_cells() == (std::size_t) 280);
+  }
+
+  SECTION("Test refine UnitCubeMesh")
+  {
+    // Refine mesh of unit cube
+    UnitCubeMesh mesh0(5, 7, 9);
+    Mesh mesh1 = refine(mesh0);
+    CHECK(mesh1.num_vertices() == (std::size_t) 3135);
+    CHECK(mesh1.num_cells() == (std::size_t) 15120);
+  }
 }
-//-----------------------------------------------------------------------------
-TEST(MeshIterators, testMixedIterators)
-{
-  // Iterate over vertices of cells
-  UnitCubeMesh mesh(5, 5, 5);
-  unsigned int n = 0;
-  for (CellIterator c(mesh); !c.end(); ++c)
-    for (VertexIterator v(*c); !v.end(); ++v)
+
+TEST_CASE("Mesh iterators")
+{
+  SECTION("Test vertex iterators")
+  {
+    // Iterate over vertices
+    UnitCubeMesh mesh(5, 5, 5);
+    unsigned int n = 0;
+    for (VertexIterator v(mesh); !v.end(); ++v)
       n++;
-  ASSERT_EQ(n, 4*mesh.num_cells());
-}
-//-----------------------------------------------------------------------------
-TEST(BoundaryExtraction, testBoundaryComputation)
-{
-  // Compute boundary of mesh
-  UnitCubeMesh mesh(2, 2, 2);
-  BoundaryMesh boundary(mesh, "exterior");
-  ASSERT_EQ(boundary.num_vertices(), (std::size_t) 26);
-  ASSERT_EQ(boundary.num_cells(), (std::size_t) 48);
-}
-//-----------------------------------------------------------------------------
-TEST(BoundaryExtraction, testBoundaryBoundary)
-{
-  // Compute boundary of boundary
-  //
-  // Note that we can't do
-  //
-  //   BoundaryMesh b0(mesh);
-  //   BoundaryMesh b1(b0);
-  //
-  // since b1 would then be a copy of b0 (copy
-  // constructor in Mesh will be used).
-
-  UnitCubeMesh mesh(2, 2, 2);
-  BoundaryMesh b0(mesh, "exterior");
-  b0.order();
-  BoundaryMesh b1(b0, "exterior");
-  ASSERT_EQ(b1.num_vertices(), (std::size_t) 0);
-  ASSERT_EQ(b1.num_cells(), (std::size_t) 0);
-}
-//-----------------------------------------------------------------------------
-TEST(MeshFunctions, testAssign)
-{
-  /// Assign value of mesh function
-  auto mesh = std::make_shared<UnitSquareMesh>(3, 3);
-  MeshFunction<int> f(mesh, 0);
-  f[3] = 10;
-  Vertex v(*mesh, 3);
-  ASSERT_EQ(f[v], 10);
-}
-//-----------------------------------------------------------------------------
-TEST(InputOutput, testMeshXML2D)
-{
-  // Write and read 2D mesh to/from file
-  UnitSquareMesh mesh_out(3, 3);
-  Mesh mesh_in;
-  File file("unitsquare.xml");
-  file << mesh_out;
-  file >> mesh_in;
-  ASSERT_EQ(mesh_in.num_vertices(), (std::size_t) 16);
-}
-//-----------------------------------------------------------------------------
-TEST(InputOutput, testMeshXML3D)
-{
-  // Write and read 3D mesh to/from file
-  UnitCubeMesh mesh_out(3, 3, 3);
-  Mesh mesh_in;
-  File file("unitcube.xml");
-  file << mesh_out;
-  file >> mesh_in;
-  ASSERT_EQ(mesh_in.num_vertices(), (std::size_t) 64);
-}
-//-----------------------------------------------------------------------------
-TEST(InputOutput, testMeshFunction)
-{
-  // Write and read mesh function to/from file
-  auto mesh = std::make_shared<UnitSquareMesh>(1, 1);
-  MeshFunction<int> f(mesh, 0);
-  f[0] = 2;
-  f[1] = 4;
-  f[2] = 6;
-  f[3] = 8;
-  File file("meshfunction.xml");
-  file << f;
-  MeshFunction<int> g(mesh, 0);
-  file >> g;
-  for (VertexIterator v(*mesh); !v.end(); ++v)
-    ASSERT_EQ(f[*v], g[*v]);
-}
 
-//-----------------------------------------------
-TEST(PyCCInterface, testGetGeometricalDimension)
-{
-  // Get geometrical dimension of mesh
-  UnitSquareMesh mesh(5, 5);
-  ASSERT_EQ(mesh.geometry().dim(), (std::size_t) 2);
+    CHECK(n == mesh.num_vertices());
+  }
+
+  SECTION("Test edge iterators")
+  {
+    // Iterate over edges
+    UnitCubeMesh mesh(5, 5, 5);
+    unsigned int n = 0;
+    for (EdgeIterator e(mesh); !e.end(); ++e)
+      n++;
+
+    CHECK(n == mesh.num_edges());
+  }
+
+  SECTION("Test face iterators")
+  {
+    // Iterate over faces
+    UnitCubeMesh mesh(5, 5, 5);
+    unsigned int n = 0;
+    for (FaceIterator f(mesh); !f.end(); ++f)
+      n++;
+
+    CHECK(n == mesh.num_faces());
+  }
+
+  SECTION("Test facet iterators")
+  {
+    // Iterate over facets
+    UnitCubeMesh mesh(5, 5, 5);
+    unsigned int n = 0;
+    for (FacetIterator f(mesh); !f.end(); ++f)
+      n++;
+
+    CHECK(n == mesh.num_facets());
+  }
+
+  SECTION("Test cell iterators")
+  {
+    // Iterate over cells
+    UnitCubeMesh mesh(5, 5, 5);
+    unsigned int n = 0;
+    for (CellIterator c(mesh); !c.end(); ++c)
+      n++;
+
+    CHECK(n == mesh.num_cells());
+  }
+
+  SECTION("Test mixed iterators")
+  {
+    // Iterate over vertices of cells
+    UnitCubeMesh mesh(5, 5, 5);
+    unsigned int n = 0;
+    for (CellIterator c(mesh); !c.end(); ++c)
+      for (VertexIterator v(*c); !v.end(); ++v)
+        n++;
+
+    CHECK(n == 4*mesh.num_cells());
+  }
+
+  SECTION("Test boundary computation")
+  {
+    // Compute boundary of mesh
+    UnitCubeMesh mesh(2, 2, 2);
+    BoundaryMesh boundary(mesh, "exterior");
+    CHECK(boundary.num_vertices() == (std::size_t) 26);
+    CHECK(boundary.num_cells() == (std::size_t) 48);
+  }
 }
-//-----------------------------------------------------------------------------
-TEST(PyCCInterface, testGetCoordinates)
-{
-  // Get coordinates of vertices
-  UnitSquareMesh mesh(5, 5);
-  ASSERT_EQ(mesh.geometry().num_vertices(), (std::size_t) 36);
+
+TEST_CASE("Boundary extraction")
+{
+  SECTION("Test boundary of boundary")
+  {
+    // Compute boundary of boundary
+    //
+    // Note that we can't do
+    //
+    //   BoundaryMesh b0(mesh);
+    //   BoundaryMesh b1(b0);
+    //
+    // since b1 would then be a copy of b0 (copy
+    // constructor in Mesh will be used).
+
+    UnitCubeMesh mesh(2, 2, 2);
+    BoundaryMesh b0(mesh, "exterior");
+    b0.order();
+    BoundaryMesh b1(b0, "exterior");
+    CHECK(b1.num_vertices() == (std::size_t) 0);
+    CHECK(b1.num_cells() == (std::size_t) 0);
+  }
+
+  SECTION("Test assign")
+  {
+    /// Assign value of mesh function
+    auto mesh = std::make_shared<UnitSquareMesh>(3, 3);
+    MeshFunction<int> f(mesh, 0);
+    f[3] = 10;
+    Vertex v(*mesh, 3);
+    CHECK(f[v] == 10);
+  }
 }
-//-----------------------------------------------------------------------------
-TEST(PyCCInterface, testGetCells)
-{
-  // Get cells of mesh
-  UnitSquareMesh mesh(5, 5);
-  ASSERT_EQ(mesh.topology().size(2), (std::size_t) 50);
+
+TEST_CASE("InputOutput")
+{
+  SECTION("Test mesh XML 2D")
+  {
+    // Write and read 2D mesh to/from file
+    UnitSquareMesh mesh_out(3, 3);
+    Mesh mesh_in;
+    File file("unitsquare.xml");
+    file << mesh_out;
+    file >> mesh_in;
+    CHECK(mesh_in.num_vertices() == (std::size_t) 16);
+  }
+
+  SECTION("Test mesh XML 3D")
+  {
+    // Write and read 3D mesh to/from file
+    UnitCubeMesh mesh_out(3, 3, 3);
+    Mesh mesh_in;
+    File file("unitcube.xml");
+    file << mesh_out;
+    file >> mesh_in;
+    CHECK(mesh_in.num_vertices() == (std::size_t) 64);
+  }
+
+  SECTION("Test MeshFunction")
+  {
+    // Write and read mesh function to/from file
+    auto mesh = std::make_shared<UnitSquareMesh>(1, 1);
+    MeshFunction<int> f(mesh, 0);
+    f[0] = 2;
+    f[1] = 4;
+    f[2] = 6;
+    f[3] = 8;
+    File file("meshfunction.xml");
+    file << f;
+    MeshFunction<int> g(mesh, 0);
+    file >> g;
+    for (VertexIterator v(*mesh); !v.end(); ++v)
+      CHECK(f[*v] == g[*v]);
+  }
 }
 
-// Test all
-int Mesh_main(int argc, char **argv) {
-    testing::InitGoogleTest(&argc, argv);
+TEST_CASE("PyCCInterface")
+{
+  SECTION("Test get geometrical dimension")
+  {
+    // Get geometrical dimension of mesh
+    UnitSquareMesh mesh(5, 5);
+    CHECK(mesh.geometry().dim() == (std::size_t) 2);
+  }
 
-    // FIXME: Only the following test works in Parallel
-    // Failed: SimpleShapes; MeshRefinement; BoundaryExtraction
-    // MeshFunctions; InputOutput; PyCCInterface
-    if (dolfin::MPI::size(MPI_COMM_WORLD) != 1)
-    {
-      ::testing::GTEST_FLAG(filter) = "MeshIterators.*";
-    }
-    return RUN_ALL_TESTS();
+  SECTION("Test get coordinates")
+  {
+    // Get coordinates of vertices
+    UnitSquareMesh mesh(5, 5);
+    CHECK(mesh.geometry().num_vertices() == (std::size_t) 36);
+  }
 
+  SECTION("Test get cells")
+  {
+    // Get cells of mesh
+    UnitSquareMesh mesh(5, 5);
+    CHECK(mesh.topology().size(2) == (std::size_t) 50);
+  }
 }
-//-----------------------------------------------------------------------------
diff --git a/test/unit/cpp/mesh/MeshColoring.cpp b/test/unit/cpp/mesh/MeshColoring.cpp
index d62af9a..1952e3b 100644
--- a/test/unit/cpp/mesh/MeshColoring.cpp
+++ b/test/unit/cpp/mesh/MeshColoring.cpp
@@ -18,46 +18,42 @@
 // Unit tests for MeshColoring
 
 #include <dolfin.h>
-#include <gtest/gtest.h>
+#include <catch.hpp>
 
 using namespace dolfin;
 
-//-----------------------------------------------------------------------------
-TEST(MeshColoring, test_mesh_coloring)
+TEST_CASE("MeshColoring")
 {
-  // Create mesh
-  auto mesh = std::make_shared<UnitCubeMesh>(24, 24, 24);
-
-  // Compute vertex-based coloring
-  mesh->color("vertex");
-  const MeshFunction<std::size_t> colors_vertex
-    = MeshColoring::cell_colors(mesh, "vertex");
-
-  // Compute edge-based coloring
-  mesh->color("edge");
-  const CellFunction<std::size_t> colors_edge
-    = MeshColoring::cell_colors(mesh, "edge");
-
-  // Compute facet-based coloring
-  mesh->color("facet");
-  const CellFunction<std::size_t> colors_facet
-    = MeshColoring::cell_colors(mesh, "facet");
-
-  // Compute facet-based coloring with distance 2
-  std::vector<std::size_t> coloring_type
-    = {{mesh->topology().dim(),
-        mesh->topology().dim() - 1,
-        mesh->topology().dim(),
-        mesh->topology().dim() - 1,
-        mesh->topology().dim()}};
-  mesh->color(coloring_type);
-  const CellFunction<std::size_t> colors_vertex_2
-    = MeshColoring::cell_colors(mesh, coloring_type);
-}
 
-// Test all
-int MeshColoring_main(int argc, char **argv)
-{
-  testing::InitGoogleTest(&argc, argv);
-  return RUN_ALL_TESTS();
+  SECTION("mesh coloring computation")
+  {
+    // Create mesh
+    auto mesh = std::make_shared<UnitCubeMesh>(24, 24, 24);
+
+    // Compute vertex-based coloring
+    mesh->color("vertex");
+    const MeshFunction<std::size_t> colors_vertex
+      = MeshColoring::cell_colors(mesh, "vertex");
+
+    // Compute edge-based coloring
+    mesh->color("edge");
+    const MeshFunction<std::size_t> colors_edge
+      = MeshColoring::cell_colors(mesh, "edge");
+
+    // Compute facet-based coloring
+    mesh->color("facet");
+    const MeshFunction<std::size_t> colors_facet
+      = MeshColoring::cell_colors(mesh, "facet");
+
+    // Compute facet-based coloring with distance 2
+    std::vector<std::size_t> coloring_type
+      = {{mesh->topology().dim(),
+          mesh->topology().dim() - 1,
+          mesh->topology().dim(),
+          mesh->topology().dim() - 1,
+          mesh->topology().dim()}};
+    mesh->color(coloring_type);
+    const MeshFunction<std::size_t> colors_vertex_2
+      = MeshColoring::cell_colors(mesh, coloring_type);
+  }
 }
diff --git a/test/unit/cpp/mesh/MeshFunction.cpp b/test/unit/cpp/mesh/MeshFunction.cpp
index e099363..85526ca 100644
--- a/test/unit/cpp/mesh/MeshFunction.cpp
+++ b/test/unit/cpp/mesh/MeshFunction.cpp
@@ -15,71 +15,64 @@
 // You should have received a copy of the GNU Lesser General Public License
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 //
-// First added:  2013-05-30
-// Last changed:
-//
 // Unit tests for MeshFunction
 
 #include <dolfin.h>
-#include <gtest/gtest.h>
+#include <catch.hpp>
 
 using namespace dolfin;
 
-//-----------------------------------------------------------------------------
-TEST(MeshFunctions, test_create_from_domains)
+TEST_CASE("MeshFunctions")
 {
-  // Create mesh
-  std::shared_ptr<Mesh> mesh(new UnitSquareMesh(3, 3));
-  dolfin_assert(mesh);
+  SECTION("Test create from domains")
+  {
+    // Create mesh
+    std::shared_ptr<Mesh> mesh(new UnitSquareMesh(3, 3));
+    dolfin_assert(mesh);
 
-  const std::size_t D = mesh->topology().dim();
+    const std::size_t D = mesh->topology().dim();
 
-  // Test setting all values
-  for (std::size_t d = 0; d <= D; ++d)
-  {
-    // Create MeshDomains object
-    MeshDomains mesh_domains;
-    mesh_domains.init(D);
+    // Test setting all values
+    for (std::size_t d = 0; d <= D; ++d)
+    {
+      // Create MeshDomains object
+      MeshDomains mesh_domains;
+      mesh_domains.init(D);
 
-    mesh->init(d);
+      mesh->init(d);
 
-    // Build mesh domain
-    std::map<std::size_t, std::size_t>& domain = mesh_domains.markers(d);
-    for (std::size_t i = 0; i < mesh->num_entities(d); ++i)
-      domain.insert(std::make_pair(i, i));
+      // Build mesh domain
+      std::map<std::size_t, std::size_t>& domain = mesh_domains.markers(d);
+      for (std::size_t i = 0; i < mesh->num_entities(d); ++i)
+        domain.insert(std::make_pair(i, i));
 
-    // Create MeshFunction and test values
-    MeshFunction<std::size_t> mf(mesh, d, mesh_domains);
-    for (std::size_t i = 0; i < mf.size(); ++i)
-      ASSERT_EQ(mf[i], i);
-  }
+      // Create MeshFunction and test values
+      MeshFunction<std::size_t> mf(mesh, d, mesh_domains);
+      for (std::size_t i = 0; i < mf.size(); ++i)
+        CHECK(mf[i] == i);
+    }
 
-  // Test setting some values only
-  for (std::size_t d = 0; d <= D; ++d)
-  {
-    // Create MeshDomains object
-    MeshDomains mesh_domains;
-    mesh_domains.init(D);
+    // Test setting some values only
+    for (std::size_t d = 0; d <= D; ++d)
+    {
+      // Create MeshDomains object
+      MeshDomains mesh_domains;
+      mesh_domains.init(D);
 
-    mesh->init(d);
+      mesh->init(d);
 
-    // Build mesh domain
-    std::map<std::size_t, std::size_t>& domain = mesh_domains.markers(d);
-    const std::size_t num_entities = mesh->num_entities(d);
-    for (std::size_t i = num_entities/2; i < num_entities; ++i)
-      domain.insert(std::make_pair(i, i));
+      // Build mesh domain
+      std::map<std::size_t, std::size_t>& domain = mesh_domains.markers(d);
+      const std::size_t num_entities = mesh->num_entities(d);
+      for (std::size_t i = num_entities/2; i < num_entities; ++i)
+        domain.insert(std::make_pair(i, i));
 
-    // Create MeshFunction and test values
-    MeshFunction<std::size_t> mf(mesh, d, mesh_domains);
-    for (std::size_t i = 0; i < num_entities/2; ++i)
-      ASSERT_EQ(mf[i], std::numeric_limits<std::size_t>::max());
-    for (std::size_t i = num_entities/2; i < mf.size(); ++i)
-      ASSERT_EQ(mf[i], i);
+      // Create MeshFunction and test values
+      MeshFunction<std::size_t> mf(mesh, d, mesh_domains);
+      for (std::size_t i = 0; i < num_entities/2; ++i)
+        CHECK(mf[i] == std::numeric_limits<std::size_t>::max());
+      for (std::size_t i = num_entities/2; i < mf.size(); ++i)
+        CHECK(mf[i] == i);
+    }
   }
 }
-
-// Test all
-int MeshFunction_main(int argc, char **argv) {
-    testing::InitGoogleTest(&argc, argv);
-    return RUN_ALL_TESTS();
-}
\ No newline at end of file
diff --git a/test/unit/cpp/mesh/MeshValueCollection.cpp b/test/unit/cpp/mesh/MeshValueCollection.cpp
index eac0477..8e2ef3b 100644
--- a/test/unit/cpp/mesh/MeshValueCollection.cpp
+++ b/test/unit/cpp/mesh/MeshValueCollection.cpp
@@ -15,160 +15,151 @@
 // You should have received a copy of the GNU Lesser General Public License
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 //
-// First added:  2007-05-14
-// Last changed: 2012-01-11
-//
 // Unit tests for the mesh library
 
 #include <dolfin.h>
-#include <gtest/gtest.h>
+#include <catch.hpp>
 
 using namespace dolfin;
 
-//-----------------------------------------------------------------------------
-TEST(MeshValueCollections, testAssign2DCells)
-{
-  auto mesh = std::make_shared<UnitSquareMesh>(3, 3);
-  const std::size_t ncells = mesh->num_cells();
-  MeshValueCollection<int> f(mesh, 2);
-  bool all_new = true;
-  for (CellIterator cell(*mesh); !cell.end(); ++cell)
-  {
-    bool this_new;
-    const int value = ncells - cell->index();
-    this_new = f.set_value(cell->index(), value);
-    all_new = all_new && this_new;
-  }
-  MeshValueCollection<int> g(mesh, 2);
-  g = f;
-  ASSERT_EQ(ncells, f.size());
-  ASSERT_EQ(ncells, g.size());
-  ASSERT_TRUE(all_new);
-  for (CellIterator cell(*mesh); !cell.end(); ++cell)
-  {
-    const int value = ncells - cell->index();
-    ASSERT_EQ(value, g.get_value(cell->index(), 0));
-  }
-}
-//-----------------------------------------------------------------------------
-TEST(MeshValueCollections, testAssign2DFacets)
+TEST_CASE("MeshValueCollections")
 {
-  auto mesh = std::make_shared<UnitSquareMesh>(3, 3);
-  mesh->init(2,1);
-  const std::size_t ncells = mesh->num_cells();
-  MeshValueCollection<int> f(mesh, 1);
-  bool all_new = true;
-  for (CellIterator cell(*mesh); !cell.end(); ++cell)
+  SECTION("Test assign 2D cells")
   {
-    const int value = ncells - cell->index();
-    for (std::size_t i = 0; i < cell->num_entities(1); ++i)
+    auto mesh = std::make_shared<UnitSquareMesh>(3, 3);
+    const std::size_t ncells = mesh->num_cells();
+    MeshValueCollection<int> f(mesh, 2);
+    bool all_new = true;
+    for (CellIterator cell(*mesh); !cell.end(); ++cell)
     {
       bool this_new;
-      this_new = f.set_value(cell->index(), i, value + i);
+      const int value = ncells - cell->index();
+      this_new = f.set_value(cell->index(), value);
       all_new = all_new && this_new;
     }
-  }
-  MeshValueCollection<int> g(mesh, 1);
-  g = f;
-  ASSERT_EQ(ncells*3, f.size());
-  ASSERT_EQ(ncells*3, g.size());
-  ASSERT_TRUE(all_new);
-  for (CellIterator cell(*mesh); !cell.end(); ++cell)
-  {
-    for (std::size_t i = 0; i < cell->num_entities(1); ++i)
+    MeshValueCollection<int> g(mesh, 2);
+    g = f;
+    CHECK(ncells == f.size());
+    CHECK(ncells == g.size());
+    CHECK(all_new);
+    for (CellIterator cell(*mesh); !cell.end(); ++cell)
     {
-      const int value = ncells - cell->index() + i;
-      ASSERT_EQ(value, g.get_value(cell->index(), i));
+      const int value = ncells - cell->index();
+      CHECK(value == g.get_value(cell->index(), 0));
     }
   }
-}
-//-----------------------------------------------------------------------------
-TEST(MeshValueCollections, testAssign2DVertices)
-{
-  auto mesh = std::make_shared<UnitSquareMesh>(3, 3);
-  mesh->init(2, 0);
-  const std::size_t ncells = mesh->num_cells();
-  MeshValueCollection<int> f(mesh, 0);
-  bool all_new = true;
-  for (CellIterator cell(*mesh); !cell.end(); ++cell)
+
+  SECTION("Test assign 2D facets")
   {
-    const int value = ncells - cell->index();
-    for (std::size_t i = 0; i < cell->num_entities(0); ++i)
+    auto mesh = std::make_shared<UnitSquareMesh>(3, 3);
+    mesh->init(2,1);
+    const std::size_t ncells = mesh->num_cells();
+    MeshValueCollection<int> f(mesh, 1);
+    bool all_new = true;
+    for (CellIterator cell(*mesh); !cell.end(); ++cell)
     {
-      bool this_new;
-      this_new = f.set_value(cell->index(), i, value+i);
-      all_new = all_new && this_new;
+      const int value = ncells - cell->index();
+      for (std::size_t i = 0; i < cell->num_entities(1); ++i)
+      {
+        bool this_new;
+        this_new = f.set_value(cell->index(), i, value + i);
+        all_new = all_new && this_new;
+      }
+    }
+    MeshValueCollection<int> g(mesh, 1);
+    g = f;
+    CHECK(ncells*3 == f.size());
+    CHECK(ncells*3 == g.size());
+    CHECK(all_new);
+    for (CellIterator cell(*mesh); !cell.end(); ++cell)
+    {
+      for (std::size_t i = 0; i < cell->num_entities(1); ++i)
+      {
+        const int value = ncells - cell->index() + i;
+        CHECK(value == g.get_value(cell->index(), i));
+      }
     }
   }
-  MeshValueCollection<int> g(mesh, 0);
-  g = f;
-  ASSERT_EQ(ncells*3, f.size());
-  ASSERT_EQ(ncells*3, g.size());
-  ASSERT_TRUE(all_new);
-  for (CellIterator cell(*mesh); !cell.end(); ++cell)
+
+  SECTION("Test assign 2D vertices")
   {
-    for (std::size_t i = 0; i < cell->num_entities(0); ++i)
+    auto mesh = std::make_shared<UnitSquareMesh>(3, 3);
+    mesh->init(2, 0);
+    const std::size_t ncells = mesh->num_cells();
+    MeshValueCollection<int> f(mesh, 0);
+    bool all_new = true;
+    for (CellIterator cell(*mesh); !cell.end(); ++cell)
+    {
+      const int value = ncells - cell->index();
+      for (std::size_t i = 0; i < cell->num_entities(0); ++i)
+      {
+        bool this_new;
+        this_new = f.set_value(cell->index(), i, value+i);
+        all_new = all_new && this_new;
+      }
+    }
+    MeshValueCollection<int> g(mesh, 0);
+    g = f;
+    CHECK(ncells*3 == f.size());
+    CHECK(ncells*3 == g.size());
+    CHECK(all_new);
+    for (CellIterator cell(*mesh); !cell.end(); ++cell)
     {
-      const int value = ncells - cell->index() + i;
-      ASSERT_EQ(value, g.get_value(cell->index(), i));
+      for (std::size_t i = 0; i < cell->num_entities(0); ++i)
+      {
+        const int value = ncells - cell->index() + i;
+        CHECK(value == g.get_value(cell->index(), i));
+      }
     }
   }
-}
-//-----------------------------------------------------------------------------
-TEST(MeshValueCollections, testMeshFunctionAssign2DCells)
-{
-  auto mesh = std::make_shared<UnitSquareMesh>(3, 3);
-  const std::size_t ncells = mesh->num_cells();
-  MeshFunction<int> f(mesh, 2, 0);
-  for (CellIterator cell(*mesh); !cell.end(); ++cell)
-    f[cell->index()] = ncells - cell->index();
-  MeshValueCollection<int> g(mesh, 2);
-  g = f;
-  ASSERT_EQ(ncells, f.size());
-  ASSERT_EQ(ncells, g.size());
-  for (CellIterator cell(*mesh); !cell.end(); ++cell)
+
+  SECTION("Test MeshFunction assign 2D cells")
   {
-    const int value = ncells - cell->index();
-    ASSERT_EQ(value, g.get_value(cell->index(), 0));
+    auto mesh = std::make_shared<UnitSquareMesh>(3, 3);
+    const std::size_t ncells = mesh->num_cells();
+    MeshFunction<int> f(mesh, 2, 0);
+    for (CellIterator cell(*mesh); !cell.end(); ++cell)
+      f[cell->index()] = ncells - cell->index();
+    MeshValueCollection<int> g(mesh, 2);
+    g = f;
+    CHECK(ncells == f.size());
+    CHECK(ncells == g.size());
+    for (CellIterator cell(*mesh); !cell.end(); ++cell)
+    {
+      const int value = ncells - cell->index();
+      CHECK(value == g.get_value(cell->index(), 0));
+    }
   }
-}
-//-----------------------------------------------------------------------------
-TEST(MeshValueCollections, testMeshFunctionAssign2DFacets)
-{
-  auto mesh = std::make_shared<UnitSquareMesh>(3, 3);
-  mesh->init(1);
-  MeshFunction<int> f(mesh, 1, 25);
-  MeshValueCollection<int> g(mesh, 1);
-  g = f;
-  ASSERT_EQ(mesh->num_facets(), f.size());
-  ASSERT_EQ(mesh->num_cells()*3, g.size());
-  for (CellIterator cell(*mesh); !cell.end(); ++cell)
+
+  SECTION("Test MeshFunction assign 2D facets")
   {
-    for (std::size_t i = 0; i < cell->num_entities(1); ++i)
-      ASSERT_EQ(25, g.get_value(cell->index(), i));
+    auto mesh = std::make_shared<UnitSquareMesh>(3, 3);
+    mesh->init(1);
+    MeshFunction<int> f(mesh, 1, 25);
+    MeshValueCollection<int> g(mesh, 1);
+    g = f;
+    CHECK(mesh->num_facets() == f.size());
+    CHECK(mesh->num_cells()*3 == g.size());
+    for (CellIterator cell(*mesh); !cell.end(); ++cell)
+    {
+      for (std::size_t i = 0; i < cell->num_entities(1); ++i)
+        CHECK(25 == g.get_value(cell->index(), i));
+    }
   }
-}
-//-----------------------------------------------------------------------------
-TEST(MeshValueCollections, testMeshFunctionAssign2DVertices)
-{
-  auto mesh = std::make_shared<UnitSquareMesh>(3, 3);
-  mesh->init(0);
-  MeshFunction<int> f(mesh, 0, 25);
-  MeshValueCollection<int> g(mesh, 0);
-  g = f;
-  ASSERT_EQ(mesh->num_vertices(), f.size());
-  ASSERT_EQ(mesh->num_cells()*3, g.size());
-  for (CellIterator cell(*mesh); !cell.end(); ++cell)
+
+  SECTION("Test MeshFunction assign 2D vertices")
   {
-    for (std::size_t i = 0; i < cell->num_entities(0); ++i)
-      ASSERT_EQ(25, g.get_value(cell->index(), i));
+    auto mesh = std::make_shared<UnitSquareMesh>(3, 3);
+    mesh->init(0);
+    MeshFunction<int> f(mesh, 0, 25);
+    MeshValueCollection<int> g(mesh, 0);
+    g = f;
+    CHECK(mesh->num_vertices() == f.size());
+    CHECK(mesh->num_cells()*3 == g.size());
+    for (CellIterator cell(*mesh); !cell.end(); ++cell)
+    {
+      for (std::size_t i = 0; i < cell->num_entities(0); ++i)
+        CHECK(25 == g.get_value(cell->index(), i));
+    }
   }
 }
-
-
-// Test all
-int MeshValueCollection_main(int argc, char **argv) {
-    testing::InitGoogleTest(&argc, argv);
-    return RUN_ALL_TESTS();
-}
-
diff --git a/test/unit/cpp/mesh/MultiMesh.cpp b/test/unit/cpp/mesh/MultiMesh.cpp
new file mode 100644
index 0000000..bebef70
--- /dev/null
+++ b/test/unit/cpp/mesh/MultiMesh.cpp
@@ -0,0 +1,91 @@
+// Copyright (C) 2017 August Johansson, Benjamin Kehlet
+//
+// This file is part of DOLFIN.
+//
+// DOLFIN is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// DOLFIN 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 Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+//
+// Unit tests for the multimesh functionality
+
+// These tests currently only instantiates and initializes some
+// multimesh objects, ie. the only thing that is tested is that it
+// doesn't crash
+
+#include <dolfin.h>
+#include <catch.hpp>
+
+using namespace dolfin;
+
+TEST_CASE("MultiMesh", "[!hide]")
+{
+  SECTION("Trivial test case 3D")
+  {
+    // DISABLED
+
+    // FIXME: Enable this test when it is working
+
+    std::shared_ptr<Mesh> background(new Mesh(UnitTetrahedronMesh::create()));
+    std::shared_ptr<Mesh> overlapping(new Mesh(UnitTetrahedronMesh::create()));
+    overlapping->translate(Point(.1, .1, .1));
+
+    MultiMesh multimesh(background, overlapping, 1);
+  }
+
+  SECTION("Trivial case 3D 2")
+  {
+    // FIXME: Enable this test when it is working
+
+    std::shared_ptr<Mesh> background = std::make_shared<UnitCubeMesh>(1,1,1);
+
+    std::shared_ptr<Mesh> refmesh = std::make_shared<BoxMesh>(Point(0.394383, 0.783099, 0.197551),
+                                                              Point(0.840188, 0.79844, 0.911647),
+                                                              1,1,1);
+    const std::vector<double>& refmeshcoords = refmesh->coordinates();
+
+    std::shared_ptr<Mesh> tetmesh(new Mesh(UnitTetrahedronMesh::create()));
+    std::vector<double>& tetmesh_coords = tetmesh->coordinates();
+
+    for (CellIterator cell(*refmesh); !cell.end(); ++cell)
+    {
+      const unsigned int* vertex_indices = cell->entities(0);
+
+      for (int i = 0; i < 4; i++)
+      {
+        tetmesh_coords[i*3] = refmeshcoords[vertex_indices[i]];
+        tetmesh_coords[i*3 + 1] = refmeshcoords[vertex_indices[i] + 1];
+        tetmesh_coords[i*3 + 2] = refmeshcoords[vertex_indices[i] + 2];
+      }
+
+      MultiMesh multimesh(background, tetmesh, 1);
+    }
+  }
+
+  SECTION("Takes forever")
+  {
+    // FIXME: Enable this test when it is working
+
+    std::shared_ptr<Mesh> background(new Mesh(UnitTetrahedronMesh::create()));
+    {
+      std::vector<double>& coords = background->coordinates();
+      coords = { 0, 0, 0,
+                 0, 0, 1,
+                 1, 0, 1,
+                 1, 1, 1 };
+    }
+
+    std::shared_ptr<Mesh> overlapping = std::make_shared<BoxMesh>(Point(0.394383, 0.783099, 0.197551),
+                                                                  Point(0.840188, 0.79844,  0.911647),
+                                                                  1,1,1);
+    MultiMesh multimesh(background, overlapping, 1);
+  }
+}
diff --git a/test/unit/cpp/multimesh/MultiMesh.cpp b/test/unit/cpp/multimesh/MultiMesh.cpp
deleted file mode 100644
index 99a46d7..0000000
--- a/test/unit/cpp/multimesh/MultiMesh.cpp
+++ /dev/null
@@ -1,307 +0,0 @@
-// Copyright (C) 2014 August Johansson and Anders Logg
-//
-// This file is part of DOLFIN.
-//
-// DOLFIN is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// DOLFIN 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 Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
-//
-// First added:  2014-03-10
-// Last changed: 2015-06-04
-//
-// Unit tests for MultiMesh
-
-#include <dolfin.h>
-#include <dolfin/geometry/SimplexQuadrature.h>
-#include <gtest/gtest.h>
-
-using namespace dolfin;
-
-// This test was commented out in the original file
-// TEST(MultiMeshes, test_multiple_meshes_quadrature) {
-//     set_log_level(DBG);
-
-//     // Create multimesh from three triangle meshes of the unit square
-
-//     // Many meshes, but not more than three overlap => this works
-//     UnitCubeMesh mesh_0(11, 12, 13);
-//     BoxMesh mesh_1(Point(0.1, 0.1, 0.1),    Point(0.9, 0.9, 0.9),    13, 11, 12);
-//     BoxMesh mesh_2(Point(0.2, 0.2, 0.2),    Point(0.95, 0.95, 0.8),  11, 13, 11);
-//     BoxMesh mesh_3(Point(0.94, 0.01, 0.01), Point(0.98, 0.99, 0.99), 1, 11, 11);
-//     BoxMesh mesh_4(Point(0.01, 0.01, 0.01), Point(0.02, 0.02, 0.02), 1, 1, 1);
-
-//     // // Completely nested 2D: can't do no more than three meshes
-//     // UnitSquareMesh mesh_0(1, 1);
-//     // RectangleMesh mesh_1(Point(0.1, 0.1), Point(0.9, 0.9, 1, 1);
-//     // RectangleMesh mesh_2(Point(0.2, 0.2), Point(0.8, 0.8, 1, 1);
-//     // RectangleMesh mesh_3(Point(0.3, 0.3), Point(0.7, 0.7, 1, 1);
-//     // RectangleMesh mesh_4(Point(0.4, 0.4), Point(0.6, 0.6, 1, 1);
-
-//     // // Completely nested 3D: can't do no more than three meshes
-//     // UnitCubeMesh mesh_0(2, 3, 4);
-//     // BoxMesh mesh_1(Point(0.1, 0.1, 0.1),    Point(0.9, 0.9, 0.9),    4, 3, 2);
-//     // BoxMesh mesh_2(Point(0.2, 0.2, 0.2),    Point(0.8, 0.8, 0.8),    3, 4, 3);
-//     // BoxMesh mesh_3(Point(0.8, 0.01, 0.01),  Point(0.9, 0.99, 0.99),  4, 2, 3);
-//     // BoxMesh mesh_4(Point(0.01, 0.01, 0.01), Point(0.02, 0.02, 0.02), 1, 1, 1);
-
-//     // Build the multimesh
-//     MultiMesh multimesh;
-//     multimesh.add(mesh_0);
-//     multimesh.add(mesh_1);
-//     multimesh.add(mesh_2);
-//     multimesh.add(mesh_3);
-//     multimesh.add(mesh_4);
-//     multimesh.build();
-
-//     // Exact volume is known
-//     const double exact_volume = 1;
-//     double volume = 0;
-
-//     // Sum contribution from all parts
-//     std::cout << "Sum contributions\n";
-//     for (std::size_t part = 0; part < multimesh.num_parts(); part++)
-//     {
-//       std::cout << "% part " << part;
-//       double part_volume = 0;
-
-//       // Uncut cell volume given by function volume
-//       const auto uncut_cells = multimesh.uncut_cells(part);
-//       for (auto it = uncut_cells.begin(); it != uncut_cells.end(); ++it)
-//       {
-//         const Cell cell(*multimesh.part(part), *it);
-//         volume += cell.volume();
-//         part_volume += cell.volume();
-//       }
-
-//       std::cout << "\t uncut volume "<< part_volume<<' ';
-
-//       // Cut cell volume given by quadrature rule
-//       const auto& cut_cells = multimesh.cut_cells(part);
-//       for (auto it = cut_cells.begin(); it != cut_cells.end(); ++it)
-//       {
-//         const auto& qr = multimesh.quadrature_rule_cut_cell(part, *it);
-//         for (std::size_t i = 0; i < qr.second.size(); ++i)
-//         {
-//           volume += qr.second[i];
-//           part_volume += qr.second[i];
-//         }
-//       }
-//       std::cout << "\ttotal volume " << part_volume << std::endl;
-//     }
-
-//     std::cout<<std::setprecision(13) << "exact volume " << exact_volume<<'\n'
-//               << "volume " << volume<<std::endl;
-//     ASSERT_NEAR(exact_volume, volume, DOLFIN_EPS_LARGE);
-// }
-
-//-----------------------------------------------------------------------------
-TEST(MultiMeshes, test_multiple_meshes_interface_quadrature)
-{
-  // // These three meshes are ok
-  // UnitSquareMesh mesh_0(1, 1);
-  // RectangleMesh mesh_1(Point(0.1, 0.1), Point(0.9, 0.9), 1, 1);
-  // RectangleMesh mesh_2(Point(0.2, 0.2), Point(0.8, 0.8), 1, 1);
-  // double exact_volume = 4*(0.9-0.1); // mesh0 and mesh1
-  // exact_volume += 4*(0.8-0.2); // mesh1 and mesh2
-  
-  // UnitCubeMesh mesh_0(1, 2, 3);
-  // BoxMesh mesh_1(Point(0.1, 0.1, 0.1),    Point(0.9, 0.9, 0.9),  2,3,4); //2, 3, 4);
-  // BoxMesh mesh_2(Point(-0.1, -0.1, -0.1), Point(0.7, 0.7, 0.7),  4, 3, 2);
-  // BoxMesh mesh_3(Point(0.51, 0.51, 0.51), Point( 0.7, 0.7, 0.7), 1, 1, 1); //4, 3, 2);
-  // BoxMesh mesh_4(Point(0.3, 0.3, 0.3),    Point(0.7, 0.7, 0.7),  1, 1, 1);
-  // double exact_volume = 0.8*0.8*6; // for mesh_0 and mesh_1
-  // exact_volume += 0.4*0.4*6; // for mesh_1 and mesh_4
-  
-  auto mesh_0 = std::make_shared<UnitCubeMesh>(1, 1, 1);
-  auto mesh_1 = std::make_shared<BoxMesh>(Point(0.1, 0.1, 0.1), Point(0.9, 0.9, 0.9), 1, 1, 1);
-  auto mesh_2 = std::make_shared<BoxMesh>(Point(0.2, 0.2, 0.2), Point(0.8, 0.8, 0.8), 1, 1, 1);
-  // BoxMesh mesh_3(Point(0.51, 0.51, 0.51), Point(0.7, 0.7, 0.7), 1, 1, 1); //4, 3, 2);
-  // BoxMesh mesh_4(Point(0.3, 0.3, 0.3),    Point(0.7, 0.7, 0.7), 1, 1, 1);
-  double exact_volume = (0.9 - 0.1)*(0.9 - 0.1)*6; // for mesh_0 and mesh_1
-  exact_volume += (0.8 - 0.2)*(0.8 - 0.2)*6; // mesh_1 and mesh_2
-  
-  // UnitCubeMesh mesh_0(1, 1, 1);
-  // MeshEditor editor;
-  // Mesh mesh_1;
-  // editor.open(mesh_1, 3, 3);
-  // editor.init_vertices(4);
-  // editor.init_cells(1);
-  // editor.add_vertex(0, Point(0.7, 0.1, -0.1));
-  // editor.add_vertex(1, Point(0.7, 0.3, -0.1));
-  // editor.add_vertex(2, Point(0.5, 0.1, -0.1));
-  // editor.add_vertex(3, Point(0.7, 0.1, 0.1));
-  // editor.add_cell(0, 0,1,2,3);
-  // editor.close();
-  
-  // Mesh mesh_2;
-  // editor.open(mesh_2, 3,3);
-  // editor.init_vertices(4);
-  // editor.init_cells(1);
-  // editor.add_vertex(0, Point(0.7, 0.1, -0.2));
-  // editor.add_vertex(1, Point(0.7, 0.3, -0.2));
-  // editor.add_vertex(2, Point(0.5, 0.1, -0.2));
-  // editor.add_vertex(3, Point(0.7, 0.1, 0.05));
-  // editor.add_cell(0, 0,1,2,3);
-  // editor.close();
-  
-  //double exact_volume = 0.8*0.8*6; // for mesh_0 and mesh_1
-  //exact_volume += 0.4*0.4*6; // for mesh_1 and mesh_4
-  
-  // MeshEditor editor;
-  // Mesh mesh_0;
-  // editor.open(mesh_0, 2, 2);
-  // editor.init_vertices(3);
-  // editor.init_cells(1);
-  // editor.add_vertex(0, Point(0.,0.));
-  // editor.add_vertex(1, Point(2.,0.));
-  // editor.add_vertex(2, Point(1.,2.));
-  // editor.add_cell(0, 0,1,2);
-  // editor.close();
-  
-  // Mesh mesh_1;
-  // editor.open(mesh_1, 2, 2);
-  // editor.init_vertices(3);
-  // editor.init_cells(1);
-  // editor.add_vertex(0, Point(0.,-0.5));
-  // editor.add_vertex(1, Point(2.,-0.5));
-  // editor.add_vertex(2, Point(1.,1.5));
-  // editor.add_cell(0, 0,1,2);
-  // editor.close();
-  
-  // Mesh mesh_2;
-  // editor.open(mesh_2, 2, 2);
-  // editor.init_vertices(3);
-  // editor.init_cells(1);
-  // editor.add_vertex(0, Point(0.,-1.));
-  // editor.add_vertex(1, Point(2.,-1.));
-  // editor.add_vertex(2, Point(1.,1.));
-  // editor.add_cell(0, 0,1,2);
-  // editor.close();
-  
-  // double exact_volume = 2*std::sqrt(0.75*0.75 + 1.5*1.5); // mesh_0 and mesh_1
-  // exact_volume += 2*std::sqrt(0.5*0.5 + 1*1); // mesh_0 and mesh_2
-  // exact_volume += 2*std::sqrt(0.75*0.75 + 1.5*1.5); // mesh_1and mesh_2
-  // double volume = 0;
-  
-  // // These three meshes are ok.
-  // MeshEditor editor;
-  // Mesh mesh_0;
-  // editor.open(mesh_0, 2, 2);
-  // editor.init_vertices(3);
-  // editor.init_cells(1);
-  // editor.add_vertex(0, Point(0.,0.));
-  // editor.add_vertex(1, Point(2.,0.));
-  // editor.add_vertex(2, Point(1.,2.));
-  // editor.add_cell(0, 0,1,2);
-  // editor.close();
-  
-  // Mesh mesh_1;
-  // editor.open(mesh_1, 2, 2);
-  // editor.init_vertices(3);
-  // editor.init_cells(1);
-  // editor.add_vertex(0, Point(1.5,-2.));
-  // editor.add_vertex(1, Point(4.,0.));
-  // editor.add_vertex(2, Point(1.5,2));
-  // editor.add_cell(0, 0,1,2);
-  // editor.close();
-  
-  // Mesh mesh_2;
-  // editor.open(mesh_2, 2, 2);
-  // editor.init_vertices(3);
-  // editor.init_cells(1);
-  // editor.add_vertex(0, Point(3.,0.5));
-  // editor.add_vertex(1, Point(-1.,0.5));
-  // editor.add_vertex(2, Point(1.,-1.5));
-  // editor.add_cell(0, 0,1,2);
-  // editor.close();
-  
-  // double exact_volume = (1.5-0.25) + (1-0.5); // mesh_0, mesh_1 and mesh_2
-  // exact_volume += (3-1.5) + std::sqrt(1.5*1.5 + 1.5*1.5); // mesh_1 and mesh_2
-  
-  File("mesh_0.xml") << *mesh_0;
-  File("mesh_1.xml") << *mesh_1;
-  File("mesh_2.xml") << *mesh_2;
-
-  // Build the multimesh
-  MultiMesh multimesh;
-  multimesh.add(mesh_0);
-  multimesh.add(mesh_1);
-  multimesh.add(mesh_2);
-  //multimesh.add(mesh_3);
-  //multimesh.add(mesh_4);
-  multimesh.build();
-
-  // Sum contribution from all parts
-  std::cout << "\n\n Sum up\n\n";
-  double volume = 0;
-  for (std::size_t part = 0; part < multimesh.num_parts(); part++)
-  {
-    std::cout << "% part " << part << '\n';
-    double part_volume = 0;
-    
-    const auto& quadrature_rules = multimesh.quadrature_rule_interface(part);
-    
-    // Get collision map
-    const auto& cmap = multimesh.collision_map_cut_cells(part);
-    for (auto it = cmap.begin(); it != cmap.end(); ++it)
-    {
-      const unsigned int cut_cell_index = it->first;
-      
-      // Iterate over cutting cells
-      const auto& cutting_cells = it->second;
-      for (auto jt = cutting_cells.begin(); jt != cutting_cells.end(); jt++)
-      {
-        //const std::size_t cutting_part = jt->first;
-        //const std::size_t cutting_cell_index = jt->second;
-        
-        // Get quadrature rule for interface part defined by
-        // intersection of the cut and cutting cells
-        const std::size_t k = jt - cutting_cells.begin();
-        dolfin_assert(k < quadrature_rules.at(cut_cell_index).size());
-        const auto& qr = quadrature_rules.at(cut_cell_index)[k];
-        
-        for (std::size_t j = 0; j < qr.second.size(); ++j)
-        {
-          volume += qr.second[j];
-          part_volume += qr.second[j];
-        }
-        
-      }
-    }
-    
-    std::cout<<"part volume " << part_volume<<std::endl;
-  }
-  
-  std::cout << "exact volume " << exact_volume<<'\n'
-            << "volume " << volume<<std::endl;
-  ASSERT_NEAR(exact_volume, volume, 10*DOLFIN_EPS_LARGE);
-}
-//-----------------------------------------------------------------------------
-TEST(MultiMeshes, test_assembly)
-{
- // FIXME: Reimplement when functionals are in place again
-}
-
-// Test all
-int MultiMesh_main(int argc, char **argv) {
-  // Test not working in parallel
-  if (dolfin::MPI::size(MPI_COMM_WORLD) > 1)
-  {
-    info("Skipping unit test in parallel.");
-    info("OK");
-    return 0;
-  }
-
-  testing::InitGoogleTest(&argc, argv);
-  return RUN_ALL_TESTS();
-}
-//-----------------------------------------------------------------------------
diff --git a/test/unit/cpp/parameter/Parameters.cpp b/test/unit/cpp/parameter/Parameters.cpp
index dde817c..61d1283 100644
--- a/test/unit/cpp/parameter/Parameters.cpp
+++ b/test/unit/cpp/parameter/Parameters.cpp
@@ -15,18 +15,20 @@
 // You should have received a copy of the GNU Lesser General Public License
 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 //
-// First added:  2011-03-28
-// Last changed: 2011-03-31
-//
 // Unit tests for the parameter library
 
 #include <dolfin.h>
-#include <gtest/gtest.h>
+#include <catch.hpp>
 
 using namespace dolfin;
 
-TEST(InputOutput, test_simple)
+TEST_CASE("parameters io", "[test_parameter_io]" )
 {
+  SECTION("flat parameters" )
+  {
+    if (dolfin::MPI::size(MPI_COMM_WORLD) > 1)
+      return;
+
     // Create some parameters
     Parameters p0("test");
     p0.add("filename", "foo.txt");
@@ -50,14 +52,17 @@ TEST(InputOutput, test_simple)
     bool monitor_convergence(p1["monitor_convergence"]);
 
     // Check values
-    ASSERT_EQ(filename, "foo.txt");
-    ASSERT_EQ(maxiter, (std::size_t) 100);
-    ASSERT_DOUBLE_EQ(tolerance, 0.001);
-    ASSERT_TRUE(monitor_convergence);
-}
+    CHECK(filename == "foo.txt");
+    CHECK(maxiter ==  (std::size_t) 100);
+    CHECK(tolerance == Approx(0.001));
+    CHECK(monitor_convergence);
+  }
+
+  SECTION("nested parameters" )
+  {
+    if (dolfin::MPI::size(MPI_COMM_WORLD) > 1)
+      return;
 
-TEST(InputOutput, test_nested)
-{
     // Create some nested parameters
     Parameters p0("test");
     Parameters p00("sub0");
@@ -88,25 +93,10 @@ TEST(InputOutput, test_nested)
     bool monitor_convergence(p1("sub0")["monitor_convergence"]);
 
     // Check values
-    ASSERT_EQ(foo, "bar");
-    ASSERT_EQ(filename, "foo.txt");
-    ASSERT_EQ(maxiter, (std::size_t) 100);
-    ASSERT_DOUBLE_EQ(tolerance, 0.001);
-    ASSERT_TRUE(monitor_convergence);
-}
-
-// Test all
-int Parameter_main(int argc, char **argv) {
-
-    // Not working in parallel, even if only process 0 writes and
-    // others wait for a barrier. Skipping this in parallel for now.
-      if (dolfin::MPI::size(MPI_COMM_WORLD) > 1)
-      {
-        info("Skipping unit test in parallel.");
-        info("OK");
-        return 0;
-      }
-
-  testing::InitGoogleTest(&argc, argv);
-  return RUN_ALL_TESTS();
+    CHECK(foo == "bar");
+    CHECK(filename == "foo.txt");
+    CHECK(maxiter == (std::size_t) 100);
+    CHECK(tolerance == Approx(0.001));
+    CHECK(monitor_convergence);
+  }
 }
diff --git a/test/unit/pytest.ini b/test/unit/pytest.ini
index d9d13d9..5bdbf4c 100644
--- a/test/unit/pytest.ini
+++ b/test/unit/pytest.ini
@@ -5,3 +5,6 @@ minversion = 2.4
 norecursedirs = .* __pycache__ test_*_tempdir
 # Make pytest ignore the book files and other utility .py files
 python_files = test_*.py
+# Prevent output being flooded
+filterwarnings =
+    ignore::ffc.quadrature.deprecation.QuadratureRepresentationDeprecationWarning
diff --git a/test/unit/python/adaptivity/test_error_control.py b/test/unit/python/adaptivity/test_error_control.py
index d0c7625..f9dc9cc 100755
--- a/test/unit/python/adaptivity/test_error_control.py
+++ b/test/unit/python/adaptivity/test_error_control.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for error control"""
 
 # Copyright (C) 2011 Marie E. Rognes
diff --git a/test/unit/python/adaptivity/test_time_series.py b/test/unit/python/adaptivity/test_time_series.py
index 02b594b..5996306 100755
--- a/test/unit/python/adaptivity/test_time_series.py
+++ b/test/unit/python/adaptivity/test_time_series.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for TimeSeries"""
 
 # Copyright (C) 2011-2014 Marie E. Rognes
diff --git a/test/unit/python/ale/test_harmonic_smoothing.py b/test/unit/python/ale/test_harmonic_smoothing.py
index a2eb70b..f26b85d 100755
--- a/test/unit/python/ale/test_harmonic_smoothing.py
+++ b/test/unit/python/ale/test_harmonic_smoothing.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit test for HarmonicSmoothing and ALE"""
 
 # Copyright (C) 2013 Jan Blechta
@@ -22,7 +20,7 @@
 from __future__ import print_function
 import pytest
 from dolfin import UnitSquareMesh, BoundaryMesh, Expression, \
-                   CellFunction, SubMesh, Constant, MPI, MeshQuality,\
+                   MeshFunction, SubMesh, Constant, MPI, MeshQuality,\
                    mpi_comm_world, ALE
 from dolfin_utils.test import skip_in_parallel
 
@@ -63,7 +61,7 @@ def test_ale():
     # Make some cell function
     # FIXME: Initialization by array indexing is probably
     #        not a good way for parallel test
-    cellfunc = CellFunction('size_t', mesh)
+    cellfunc = MeshFunction('size_t', mesh, mesh.topology().dim())
     cellfunc.array()[0:4] = 0
     cellfunc.array()[4:]  = 1
 
diff --git a/test/unit/python/common/test_mpi.py b/test/unit/python/common/test_mpi.py
new file mode 100644
index 0000000..39a714a
--- /dev/null
+++ b/test/unit/python/common/test_mpi.py
@@ -0,0 +1,52 @@
+"""Unit tests for MPI facilities"""
+
+# Copyright (C) 2017 Garth N. Wells
+#
+# This file is part of DOLFIN.
+#
+# DOLFIN is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# DOLFIN 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+
+import dolfin
+from dolfin import mpi_comm_world, mpi_comm_self
+from dolfin_utils.test import skip_if_not_petsc4py, skip_if_pybind11, skip_if_not_pybind11 
+
+
+ at skip_if_pybind11
+ at skip_if_not_petsc4py
+def test_mpi_comm_type_petsc4py():
+    import petsc4py
+    assert isinstance(mpi_comm_world(), petsc4py.PETSc.Comm)
+    assert isinstance(mpi_comm_self(), petsc4py.PETSc.Comm)
+
+
+ at skip_if_not_pybind11
+def test_mpi_comm_wrapper():
+    """
+    Test MPICommWrapper <-> mpi4py.MPI.Comm conversion
+    """
+    if dolfin.has_mpi4py():
+        from mpi4py import MPI
+        w1 = MPI.COMM_WORLD
+    else:
+        w1 = dolfin.MPI.comm_world
+
+    m = dolfin.UnitSquareMesh(w1, 4, 4)
+    w2 = m.mpi_comm()
+
+    if dolfin.has_mpi4py():
+        assert isinstance(w1, MPI.Comm)
+        assert isinstance(w2, MPI.Comm)
+    else:
+        assert isinstance(w1, dolfin.cpp.MPICommWrapper)
+        assert isinstance(w2, dolfin.cpp.MPICommWrapper)
diff --git a/test/unit/python/fem/test_assembler.py b/test/unit/python/fem/test_assembler.py
index 869d67a..65fb2f9 100644
--- a/test/unit/python/fem/test_assembler.py
+++ b/test/unit/python/fem/test_assembler.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for assembly"""
 
 # Copyright (C) 2011-2014 Garth N. Wells
@@ -33,7 +31,8 @@ from dolfin_utils.test import skip_in_parallel, filedir, pushpop_parameters
 
 def test_cell_size_assembly_1D():
     mesh = UnitIntervalMesh(10)
-    assert round(assemble(CellSize(mesh)*dx) - 0.1, 12) == 0
+    assert round(assemble(2*Circumradius(mesh)*dx) - 0.1, 12) == 0
+    assert round(assemble(CellDiameter(mesh)*dx) - 0.1, 12) == 0
     assert round(assemble(CellVolume(mesh)*dx) - 0.1, 12) == 0
 
 
@@ -89,7 +88,7 @@ def test_facet_assembly(pushpop_parameters):
 
     # Define normal component, mesh size and right-hand side
     n = FacetNormal(mesh)
-    h = CellSize(mesh)
+    h = 2*Circumradius(mesh)
     h_avg = (h('+') + h('-'))/2
     f = Expression("500.0*exp(-(pow(x[0] - 0.5, 2) + pow(x[1] - 0.5, 2)) / 0.02)", degree=1)
 
@@ -118,7 +117,7 @@ def test_ghost_mode_handling(pushpop_parameters):
     def _form():
         # Return form with trivial interior facet integral
         mesh = UnitSquareMesh(10, 10)
-        ff = FacetFunction('size_t', mesh, 0)
+        ff = MeshFunction('size_t', mesh, mesh.topology().dim()-1, 0)
         AutoSubDomain(lambda x: near(x[0], 0.5)).mark(ff, 1)
         return Constant(1.0)*dS(domain=mesh, subdomain_data=ff, subdomain_id=1)
 
@@ -140,8 +139,8 @@ def test_ghost_mode_handling(pushpop_parameters):
 
 @pytest.mark.parametrize('mesh_factory, facet_area', [((UnitSquareMesh, (4, 4)), 4.0),
                                                       ((UnitCubeMesh, (2, 2, 2)), 6.0),
-                                                      ((UnitQuadMesh.create, (4, 4)), 4.0),
-                                                      ((UnitHexMesh.create, (2, 2, 2)), 6.0)])
+                                                      ((UnitSquareMesh.create, (4, 4, CellType.Type_quadrilateral)), 4.0),
+                                                      ((UnitCubeMesh.create, (2, 2, 2, CellType.Type_hexahedron)), 6.0)])
 def test_functional_assembly(mesh_factory, facet_area):
     func, args = mesh_factory
     mesh = func(*args)
@@ -154,7 +153,7 @@ def test_functional_assembly(mesh_factory, facet_area):
     assert round(assemble(M1) - facet_area, 7) == 0
 
 
- at pytest.mark.parametrize('mesh_factory', [(UnitCubeMesh, (4, 4, 4)), (UnitHexMesh.create, (4, 4, 4))])
+ at pytest.mark.parametrize('mesh_factory', [(UnitCubeMesh, (4, 4, 4)), (UnitCubeMesh.create, (4, 4, 4, CellType.Type_hexahedron))])
 def test_subdomain_and_fulldomain_assembly_meshdomains(mesh_factory):
     """Test assembly over subdomains AND the full domain with markers
     stored as part of the mesh.
@@ -228,7 +227,7 @@ def test_subdomain_assembly_form_1():
     class Left(SubDomain):
         def inside(self, x, on_boundary):
             return x[0] < 0.49
-    subdomains = CellFunction("size_t", mesh)
+    subdomains = MeshFunction("size_t", mesh, mesh.topology().dim())
     subdomains.set_all(0)
     left = Left()
     left.mark(subdomains, 1)
@@ -236,7 +235,7 @@ def test_subdomain_assembly_form_1():
     class RightBoundary(SubDomain):
         def inside(self, x, on_boundary):
             return x[0] > 0.95
-    boundaries = FacetFunction("size_t", mesh)
+    boundaries = MeshFunction("size_t", mesh, mesh.topology().dim()-1)
     boundaries.set_all(0)
     right = RightBoundary()
     right.mark(boundaries, 1)
diff --git a/test/unit/python/fem/test_dirichlet_bc.py b/test/unit/python/fem/test_dirichlet_bc.py
index 2dcdd77..14af470 100644
--- a/test/unit/python/fem/test_dirichlet_bc.py
+++ b/test/unit/python/fem/test_dirichlet_bc.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for Dirichlet boundary conditions"""
 
 # Copyright (C) 2011-2017 Garth N. Wells
@@ -112,12 +110,12 @@ def test_user_meshfunction_domains():
     mesh1 = UnitSquareMesh(12, 12)
     V = FunctionSpace(mesh0, "CG", 1)
 
-    DirichletBC(V, Constant(0.0), EdgeFunction("size_t", mesh0), 0)
-    DirichletBC(V, Constant(0.0), FacetFunction("size_t", mesh0), 0)
+    DirichletBC(V, Constant(0.0), MeshFunction("size_t", mesh0, 1), 0)
+    DirichletBC(V, Constant(0.0), MeshFunction("size_t", mesh0, mesh0.topology().dim()-1), 0)
     with pytest.raises(RuntimeError):
-        DirichletBC(V, 0.0, CellFunction("size_t", mesh0), 0)
-        DirichletBC(V, 0.0, VertexFunction("size_t", mesh0), 0)
-        DirichletBC(V, 0.0, FacetFunction("size_t", mesh1), 0)
+        DirichletBC(V, 0.0, MeshFunction("size_t", mesh0, mesh0.topology().dim()), 0)
+        DirichletBC(V, 0.0, MeshFunction("size_t", mesh0, 0), 0)
+        DirichletBC(V, 0.0, MeshFunction("size_t", mesh1, mesh1.topology().dim()-1), 0)
 
 
 @skip_in_parallel
@@ -272,9 +270,9 @@ def test_nocaching_values():
         x.zero()
         bc.set_value(Constant(1.0))
         bc.apply(x)
-        assert numpy.allclose(x.array(), 1.0)
+        assert numpy.allclose(x.get_local(), 1.0)
 
         x.zero()
         bc.set_value(Constant(2.0))
         bc.apply(x)
-        assert numpy.allclose(x.array(), 2.0)
+        assert numpy.allclose(x.get_local(), 2.0)
diff --git a/test/unit/python/fem/test_discrete_operators.py b/test/unit/python/fem/test_discrete_operators.py
index 3623030..28903bf 100644
--- a/test/unit/python/fem/test_discrete_operators.py
+++ b/test/unit/python/fem/test_discrete_operators.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the DiscreteOperator class"""
 
 # Copyright (C) 2015 Garth N. Wells
@@ -36,9 +34,9 @@ def test_gradient():
         W = FunctionSpace(mesh, "Nedelec 1st kind H(curl)", 1)
 
         G = DiscreteOperators.build_gradient(W, V)
-        num_edges = mesh.size_global(1)
+        num_edges = mesh.num_entities_global(1)
         assert G.size(0) == num_edges
-        assert G.size(1) == mesh.size_global(0)
+        assert G.size(1) == mesh.num_entities_global(0)
         assert round(G.norm("frobenius") - sqrt(2.0*num_edges), 8) == 0.0
 
     meshes = [UnitSquareMesh(11, 6), UnitCubeMesh(4, 3, 7)]
diff --git a/test/unit/python/fem/test_dofmap.py b/test/unit/python/fem/test_dofmap.py
index 2b422ee..c1eccae 100644
--- a/test/unit/python/fem/test_dofmap.py
+++ b/test/unit/python/fem/test_dofmap.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the fem interface"""
 
 # Copyright (C) 2009-2014 Garth N. Wells
@@ -22,8 +20,10 @@
 from __future__ import print_function
 import pytest
 import numpy as np
-from dolfin import *
 
+import sys
+
+from dolfin import *
 from dolfin_utils.test import *
 
 
@@ -42,8 +42,8 @@ reorder_dofs = set_parameters_fixture("reorder_dofs_serial", [True, False])
                                           (UnitCubeMesh, (2, 2, 2)),
                                           # cell.contains(Point) does not work correctly
                                           # for quad/hex cells once it is fixed, this test will pass
-                                          xfail((UnitQuadMesh.create, (4, 4))),
-                                          xfail((UnitHexMesh.create, (2, 2, 2)))])
+                                          xfail((UnitSquareMesh.create, (4, 4, CellType.Type_quadrilateral))),
+                                          xfail((UnitCubeMesh.create, (2, 2, 2, CellType.Type_hexahedron)))])
 def test_tabulate_all_coordinates(mesh_factory):
     func, args = mesh_factory
     mesh = func(*args)
@@ -88,7 +88,7 @@ def test_tabulate_all_coordinates(mesh_factory):
     assert all(checked_W)
 
 
- at pytest.mark.parametrize('mesh_factory', [(UnitSquareMesh, (4, 4)), (UnitQuadMesh.create, (4, 4))])
+ at pytest.mark.parametrize('mesh_factory', [(UnitSquareMesh, (4, 4)), (UnitSquareMesh.create, (4, 4, CellType.Type_quadrilateral))])
 def test_tabulate_dofs(mesh_factory):
     func, args = mesh_factory
     mesh = func(*args)
@@ -118,7 +118,7 @@ def test_tabulate_dofs(mesh_factory):
         assert np.array_equal(np.append(dofs1, dofs2), dofs3)
 
 
- at pytest.mark.parametrize('mesh_factory', [(UnitSquareMesh, (4, 4)), (UnitQuadMesh.create, (4, 4))])
+ at pytest.mark.parametrize('mesh_factory', [(UnitSquareMesh, (4, 4)), (UnitSquareMesh.create, (4, 4, CellType.Type_quadrilateral))])
 def test_tabulate_coord_periodic(mesh_factory):
 
     class PeriodicBoundary2(SubDomain):
@@ -167,7 +167,7 @@ def test_tabulate_coord_periodic(mesh_factory):
         assert (coord4[sdim:] == coord0).all()
 
 
- at pytest.mark.parametrize('mesh_factory', [(UnitSquareMesh, (5, 5)), (UnitQuadMesh.create, (5, 5))])
+ at pytest.mark.parametrize('mesh_factory', [(UnitSquareMesh, (5, 5)), (UnitSquareMesh.create, (5, 5, CellType.Type_quadrilateral))])
 def test_tabulate_dofs_periodic(mesh_factory):
 
     class PeriodicBoundary2(SubDomain):
@@ -222,7 +222,7 @@ def test_tabulate_dofs_periodic(mesh_factory):
         assert np.array_equal(np.append(dofs1, dofs2), dofs3)
 
 
- at pytest.mark.parametrize('mesh_factory', [(UnitSquareMesh, (3, 3)), (UnitQuadMesh.create, (3, 3))])
+ at pytest.mark.parametrize('mesh_factory', [(UnitSquareMesh, (3, 3)), (UnitSquareMesh.create, (3, 3, CellType.Type_quadrilateral))])
 def test_global_dof_builder(mesh_factory):
     func, args = mesh_factory
     mesh = func(*args)
@@ -237,7 +237,7 @@ def test_global_dof_builder(mesh_factory):
     W = FunctionSpace(mesh, R*V)
 
 
- at pytest.mark.parametrize('mesh_factory', [(UnitSquareMesh, (3, 3)), (UnitQuadMesh.create, (3, 3))])
+ at pytest.mark.parametrize('mesh_factory', [(UnitSquareMesh, (3, 3)), (UnitSquareMesh.create, (3, 3, CellType.Type_quadrilateral))])
 def test_dof_to_vertex_map(mesh_factory, reorder_dofs):
     func, args = mesh_factory
     mesh = func(*args)
@@ -349,7 +349,7 @@ def test_entity_dofs(mesh):
 
 
 @skip_in_parallel
- at pytest.mark.parametrize('mesh_factory', [(UnitSquareMesh, (2, 2)), (UnitQuadMesh.create, (2, 2))])
+ at pytest.mark.parametrize('mesh_factory', [(UnitSquareMesh, (2, 2)), (UnitSquareMesh.create, (2, 2, CellType.Type_quadrilateral))])
 def test_entity_closure_dofs(mesh_factory):
     func, args = mesh_factory
     mesh = func(*args)
@@ -414,7 +414,9 @@ def test_clear_sub_map_data_vector(mesh):
 
 
 def test_block_size(mesh):
-    meshes = [UnitSquareMesh(8, 8), UnitCubeMesh(4, 4, 4), UnitQuadMesh.create(8, 8), UnitHexMesh.create(4, 4, 4)]
+    meshes = [UnitSquareMesh(8, 8), UnitCubeMesh(4, 4, 4),
+              UnitSquareMesh.create(8, 8, CellType.Type_quadrilateral),
+              UnitCubeMesh.create(4, 4, 4, CellType.Type_hexahedron)]
     for mesh in meshes:
         P2 = FiniteElement("Lagrange", mesh.ufl_cell(), 2)
 
@@ -444,8 +446,8 @@ def test_block_size_real(mesh):
 @pytest.mark.parametrize('mesh_factory', [(UnitIntervalMesh, (8,)),
                                           (UnitSquareMesh, (4, 4)),
                                           (UnitCubeMesh, (2, 2, 2)),
-                                          (UnitQuadMesh.create, (4, 4)),
-                                          (UnitHexMesh.create, (2, 2, 2))])
+                                          (UnitSquareMesh.create, (4, 4, CellType.Type_quadrilateral)),
+                                          (UnitCubeMesh.create, (2, 2, 2, CellType.Type_hexahedron))])
 def test_mpi_dofmap_stats(mesh_factory):
     func, args = mesh_factory
     mesh = func(*args)
@@ -460,7 +462,7 @@ def test_mpi_dofmap_stats(mesh_factory):
     for owner in V.dofmap().off_process_owner():
         assert owner in neighbours
 
- at pytest.mark.parametrize('mesh_factory', [(UnitSquareMesh, (4, 4)), (UnitQuadMesh.create, (4, 4))])
+ at pytest.mark.parametrize('mesh_factory', [(UnitSquareMesh, (4, 4)), (UnitSquareMesh.create, (4, 4, CellType.Type_quadrilateral))])
 def test_local_dimension(mesh_factory):
     func, args = mesh_factory
     mesh = func(*args)
@@ -487,34 +489,82 @@ def test_local_dimension(mesh_factory):
         #    dofmap.index_map().size('foo')
 
 
+# Failures in FFC on quads/hexes
+xfail_ffc = pytest.mark.xfail(raises=Exception, strict=True)
+
 @skip_in_parallel
-def test_dofs_dim():
+ at pytest.mark.parametrize('space', [
+    "FunctionSpace(UnitIntervalMesh.create(10),                                        'P', 1)",
+    "FunctionSpace(UnitSquareMesh.create(6, 6, CellType.Type_triangle),                'P', 1)",
+    "FunctionSpace(UnitCubeMesh.create(2, 2, 2, CellType.Type_tetrahedron),            'P', 1)",
+    "FunctionSpace(UnitSquareMesh.create(6, 6, CellType.Type_quadrilateral),           'Q', 1)",
+    "FunctionSpace(UnitCubeMesh.create(2, 2, 2, CellType.Type_hexahedron),             'Q', 1)",
+    "FunctionSpace(UnitIntervalMesh.create(10),                                        'P', 2)",
+    "FunctionSpace(UnitSquareMesh.create(6, 6, CellType.Type_triangle),                'P', 2)",
+    "FunctionSpace(UnitCubeMesh.create(2, 2, 2, CellType.Type_tetrahedron),            'P', 2)",
+    "FunctionSpace(UnitSquareMesh.create(6, 6, CellType.Type_quadrilateral),           'Q', 2)",
+    "FunctionSpace(UnitCubeMesh.create(2, 2, 2, CellType.Type_hexahedron),             'Q', 2)",
+    "FunctionSpace(UnitIntervalMesh.create(10),                                        'P', 3)",
+    "FunctionSpace(UnitSquareMesh.create(6, 6, CellType.Type_triangle),                'P', 3)",
+    "FunctionSpace(UnitCubeMesh.create(2, 2, 2, CellType.Type_tetrahedron),            'P', 3)",
+    "FunctionSpace(UnitSquareMesh.create(6, 6, CellType.Type_quadrilateral),           'Q', 3)",
+    "FunctionSpace(UnitCubeMesh.create(2, 2, 2, CellType.Type_hexahedron),             'Q', 3)",
+    "FunctionSpace(UnitIntervalMesh.create(10),                                        'DP', 1)",
+    "FunctionSpace(UnitSquareMesh.create(6, 6, CellType.Type_triangle),                'DP', 1)",
+    "FunctionSpace(UnitCubeMesh.create(2, 2, 2, CellType.Type_tetrahedron),            'DP', 1)",
+    xfail_ffc("FunctionSpace(UnitSquareMesh.create(6, 6, CellType.Type_quadrilateral), 'DQ', 1)"),
+    xfail_ffc("FunctionSpace(UnitCubeMesh.create(2, 2, 2, CellType.Type_hexahedron),   'DQ', 1)"),
+    "FunctionSpace(UnitIntervalMesh.create(10),                                        'DP', 2)",
+    "FunctionSpace(UnitSquareMesh.create(6, 6, CellType.Type_triangle),                'DP', 2)",
+    "FunctionSpace(UnitCubeMesh.create(2, 2, 2, CellType.Type_tetrahedron),            'DP', 2)",
+    xfail_ffc("FunctionSpace(UnitSquareMesh.create(6, 6, CellType.Type_quadrilateral), 'DQ', 2)"),
+    xfail_ffc("FunctionSpace(UnitCubeMesh.create(2, 2, 2, CellType.Type_hexahedron),   'DQ', 2)"),
+    "FunctionSpace(UnitSquareMesh.create(6, 6, CellType.Type_triangle),                'N1curl', 1)",
+    "FunctionSpace(UnitCubeMesh.create(2, 2, 2, CellType.Type_tetrahedron),            'N1curl', 1)",
+    xfail_ffc("FunctionSpace(UnitSquareMesh.create(6, 6, CellType.Type_quadrilateral), 'N1curl', 1)"),
+    xfail_ffc("FunctionSpace(UnitCubeMesh.create(2, 2, 2, CellType.Type_hexahedron),   'N1curl', 1)"),
+    "FunctionSpace(UnitSquareMesh.create(6, 6, CellType.Type_triangle),                'N1curl', 2)",
+    "FunctionSpace(UnitCubeMesh.create(2, 2, 2, CellType.Type_tetrahedron),            'N1curl', 2)",
+    xfail_ffc("FunctionSpace(UnitSquareMesh.create(6, 6, CellType.Type_quadrilateral), 'N1curl', 2)"),
+    xfail_ffc("FunctionSpace(UnitCubeMesh.create(2, 2, 2, CellType.Type_hexahedron),   'N1curl', 2)"),
+    "FunctionSpace(UnitSquareMesh.create(6, 6, CellType.Type_triangle),                'RT', 1)",
+    "FunctionSpace(UnitCubeMesh.create(2, 2, 2, CellType.Type_tetrahedron),            'RT', 1)",
+    xfail_ffc("FunctionSpace(UnitSquareMesh.create(6, 6, CellType.Type_quadrilateral), 'RT', 1)"),
+    xfail_ffc("FunctionSpace(UnitCubeMesh.create(2, 2, 2, CellType.Type_hexahedron),   'RT', 1)"),
+])
+def test_dofs_dim(space):
     """Test function GenericDofMap::dofs(mesh, dim)"""
-    meshes = [UnitIntervalMesh(10),
-              UnitSquareMesh(6, 6),
-              UnitCubeMesh(2, 2, 2),
-              UnitQuadMesh.create(6, 6),
-              UnitHexMesh.create(2, 2, 2)]
-
-    for mesh in meshes:
-        tdim = mesh.topology().dim()
-        spaces = [FunctionSpace(mesh, "Discontinuous Lagrange", 1),
-                  FunctionSpace(mesh, "Discontinuous Lagrange", 2),
-                  FunctionSpace(mesh, "Lagrange", 1),
-                  FunctionSpace(mesh, "Lagrange", 2),
-                  FunctionSpace(mesh, "Lagrange", 3)]
-
-        if tdim > 1 and mesh.ufl_cell().cellname() not in ['quadrilateral', 'hexahedron']:
-            N1 = "Nedelec 1st kind H(curl)"
-            vspaces = [VectorFunctionSpace(mesh, N1, 1),
-                       VectorFunctionSpace(mesh, N1, 2),
-                       VectorFunctionSpace(mesh, "RT", 1)]
-            spaces = spaces + vspaces
-
-        for V in spaces:
-            dofmap = V.dofmap()
-            for dim in range(0, mesh.topology().dim()):
-                edofs = dofmap.dofs(mesh, dim)
-                num_mesh_entities = mesh.num_entities(dim)
-                dofs_per_entity = dofmap.num_entity_dofs(dim)
-                assert len(edofs) == dofs_per_entity*num_mesh_entities
+    V = eval(space)
+    dofmap = V.dofmap()
+    mesh = V.mesh()
+    for dim in range(0, mesh.topology().dim()):
+        edofs = dofmap.dofs(mesh, dim)
+        num_mesh_entities = mesh.num_entities(dim)
+        dofs_per_entity = dofmap.num_entity_dofs(dim)
+        assert len(edofs) == dofs_per_entity*num_mesh_entities
+
+
+ at skip_if_not_pybind11
+def test_readonly_view_local_to_global_unwoned(mesh):
+    """Test that local_to_global_unwoned() returns readonly
+    view into the data; in particular test lifetime of data
+    owner"""
+    V = FunctionSpace(mesh, "P", 1)
+    dofmap = V.dofmap()
+    index_map = dofmap.index_map()
+
+    rc = sys.getrefcount(dofmap)
+    l2gu = dofmap.local_to_global_unowned()
+    assert sys.getrefcount(dofmap) == rc + 1 if l2gu.size else rc
+    assert not l2gu.flags.writeable
+    assert all(l2gu < V.dofmap().global_dimension())
+    del l2gu
+    assert sys.getrefcount(dofmap) == rc
+
+    rc = sys.getrefcount(index_map)
+    l2gu = index_map.local_to_global_unowned()
+    assert sys.getrefcount(index_map) == rc + 1 if l2gu.size else rc
+    assert not l2gu.flags.writeable
+    assert all(l2gu < V.dofmap().global_dimension())
+    del l2gu
+    assert sys.getrefcount(index_map) == rc
diff --git a/test/unit/python/fem/test_dp_assemble.py b/test/unit/python/fem/test_dp_assemble.py
index 6d692af..199a346 100644
--- a/test/unit/python/fem/test_dp_assemble.py
+++ b/test/unit/python/fem/test_dp_assemble.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for dP assembly"""
 
 # Copyright (C) 2014 Johan Hake
@@ -65,7 +63,7 @@ def _create_dp_problem(dim):
     # Subdomains
     subdomain = AutoSubDomain(lambda x, on_boundary: x[0] <= 0.5)
     disjoint_subdomain = AutoSubDomain(lambda x, on_boundary: x[0] > 0.5)
-    vertex_domain = VertexFunction("size_t", mesh, 0)
+    vertex_domain = MeshFunction("size_t", mesh, 0, 0)
     subdomain.mark(vertex_domain, 1)
     bc = DirichletBC(VV, Constant((0, 0)), disjoint_subdomain)
     dPP = dP(subdomain_data=vertex_domain)
@@ -94,16 +92,16 @@ def test_vector_assemble(dim):
 
     (u, uu), (v, vv), (U, UU), dPP, bc = _create_dp_problem(dim)
 
-    # In parallel vec.array() will return only local to process values
+    # In parallel vec.get_local() will return only local to process values
     vec = assemble(u*v*dPP)
-    assert sum(np.absolute(vec.array() - u.vector().array())) < eps
+    assert sum(np.absolute(vec.get_local() - u.vector().get_local())) < eps
 
     vec = assemble(inner(uu, vv)*dP)
-    assert sum(np.absolute(vec.array() - uu.vector().array())) < eps
+    assert sum(np.absolute(vec.get_local() - uu.vector().get_local())) < eps
 
     vec = assemble(inner(uu, vv)*dPP(1))
     bc.apply(uu.vector())
-    assert sum(np.absolute(vec.array() - uu.vector().array())) < eps
+    assert sum(np.absolute(vec.get_local() - uu.vector().get_local())) < eps
 
 
 def test_matrix_assemble(dim):
@@ -119,7 +117,7 @@ def test_matrix_assemble(dim):
     loc_range = u.vector().local_range()
     vec_mat = np.zeros_like(mat.array())
     vec_mat[range(loc_range[1] - loc_range[0]),
-            range(loc_range[0], loc_range[1])] = u.vector().array()
+            range(loc_range[0], loc_range[1])] = u.vector().get_local()
 
     assert np.sum(np.absolute(mat.array() - vec_mat)) < eps
 
@@ -131,6 +129,6 @@ def test_matrix_assemble(dim):
     loc_range = uu.vector().local_range()
     vec_mat = np.zeros_like(mat.array())
     vec_mat[range(loc_range[1] - loc_range[0]),
-            range(loc_range[0], loc_range[1])] = uu.vector().array()
+            range(loc_range[0], loc_range[1])] = uu.vector().get_local()
 
     assert np.sum(np.absolute(mat.array() - vec_mat)) < eps
diff --git a/test/unit/python/fem/test_finite_element.py b/test/unit/python/fem/test_finite_element.py
index 919d836..d6b35a7 100644
--- a/test/unit/python/fem/test_finite_element.py
+++ b/test/unit/python/fem/test_finite_element.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the fem interface"""
 
 # Copyright (C) 2009 Garth N. Wells
@@ -34,10 +32,10 @@ xfail = pytest.mark.xfail(strict=True)
 
 @pytest.mark.parametrize('mesh_factory', [(UnitSquareMesh, (4, 4)),
                                           (UnitCubeMesh, (2, 2, 2)),
-                                          (UnitQuadMesh.create, (4, 4)),
+                                          (UnitSquareMesh.create, (4, 4, CellType.Type_quadrilateral)),
                                           # cell_normal has not been implemented for hex cell
                                           # cell.orientation() does not work
-                                          xfail((UnitHexMesh.create, (2, 2, 2)))])
+                                          xfail((UnitCubeMesh.create, (2, 2, 2, CellType.Type_hexahedron)))])
 def test_evaluate_dofs(mesh_factory):
 
     func, args = mesh_factory
@@ -139,8 +137,8 @@ def test_evaluate_dofs_manifolds_affine():
 
 @pytest.mark.parametrize('mesh_factory', [(UnitSquareMesh, (4, 4)),
                                           (UnitCubeMesh, (2, 2, 2)),
-                                          (UnitQuadMesh.create, (4, 4)),
-                                          (UnitHexMesh.create, (2, 2, 2))])
+                                          (UnitSquareMesh.create, (4, 4, CellType.Type_quadrilateral)),
+                                          (UnitCubeMesh.create, (2, 2, 2, CellType.Type_hexahedron))])
 def test_tabulate_coord(mesh_factory):
 
     func, args = mesh_factory
diff --git a/test/unit/python/fem/test_form.py b/test/unit/python/fem/test_form.py
index 8704aec..1975cb0 100644
--- a/test/unit/python/fem/test_form.py
+++ b/test/unit/python/fem/test_form.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the fem interface"""
 
 # Copyright (C) 2011-2014 Johan Hake
@@ -112,7 +110,7 @@ def test_assemble_linear(V1, Q1, square_boundary, V2, Q2, cube_boundary):
     w = TestFunction(Q1)
     u.vector()[:] = 0.5
     facetareas = MPI.sum(square_boundary.mpi_comm(),
-                         assemble(u*w*dx).array().sum())
+                         assemble(u*w*dx).get_local().sum())
     assert round(facetareas - 2.0, 7) == 0
 
     u = Function(V2)
@@ -121,7 +119,7 @@ def test_assemble_linear(V1, Q1, square_boundary, V2, Q2, cube_boundary):
     a = u*w*dx
     b = assemble(a)
     facetareas = MPI.sum(cube_boundary.mpi_comm(),
-                         assemble(u*w*dx).array().sum())
+                         assemble(u*w*dx).get_local().sum())
     assert round(facetareas - 3.0, 7) == 0
 
     mesh = UnitSquareMesh(8, 8)
@@ -159,7 +157,7 @@ def test_assemble_bilinear_1D_2D(square, V1, square_boundary):
 
     # Assemble over subset of mesh facets
     subdomain = CompiledSubDomain("near(x[1], 0.0)")
-    bottom = FacetFunction("size_t", square)
+    bottom = MeshFunction("size_t", square, square.topology().dim()-1)
     bottom.set_all(0)
     subdomain.mark(bottom, 1)
     dss = ds(subdomain_data=bottom)
@@ -169,7 +167,7 @@ def test_assemble_bilinear_1D_2D(square, V1, square_boundary):
 
     # Assemble over all cells of submesh created from subset of
     # boundary mesh
-    bottom2 = CellFunction("size_t", square_boundary)
+    bottom2 = MeshFunction("size_t", square_boundary, square_boundary.topology().dim())
     bottom2.set_all(0)
     subdomain.mark(bottom2, 1)
     BV = FunctionSpace(SubMesh(square_boundary, bottom2, 1), "CG", 1)
@@ -201,7 +199,7 @@ def test_assemble_bilinear_2D_3D(cube, V2, cube_boundary):
 
     # Assemble over subset of mesh facets
     subdomain = CompiledSubDomain("near(x[1], 0.0)")
-    bottom = FacetFunction("size_t", cube)
+    bottom = MeshFunction("size_t", cube, cube.topology().dim()-1)
     bottom.set_all(0)
     subdomain.mark(bottom, 1)
     dss = ds(subdomain_data=bottom)
@@ -211,7 +209,7 @@ def test_assemble_bilinear_2D_3D(cube, V2, cube_boundary):
 
     # Assemble over all cells of submesh created from subset of
     # boundary mesh
-    bottom2 = CellFunction("size_t", cube_boundary)
+    bottom2 = MeshFunction("size_t", cube_boundary, cube_boundary.topology().dim())
     bottom2.set_all(0)
     subdomain.mark(bottom2, 1)
     BV = FunctionSpace(SubMesh(cube_boundary, bottom2, 1), "CG", 1)
diff --git a/test/unit/python/fem/test_interior_facet_integral_sides.py b/test/unit/python/fem/test_interior_facet_integral_sides.py
index 40eb60d..9af0596 100644
--- a/test/unit/python/fem/test_interior_facet_integral_sides.py
+++ b/test/unit/python/fem/test_interior_facet_integral_sides.py
@@ -1,14 +1,12 @@
-#!/usr/bin/env py.test
 import ufl
 from dolfin import *
 from dolfin_utils.test import skip_in_parallel
 
-
 @skip_in_parallel
 def test_interior_facet_integral_sides():
     n = 1
     mesh = UnitSquareMesh(n, n)
-    markers = CellFunction("size_t", mesh)
+    markers = MeshFunction("size_t", mesh, mesh.topology().dim())
     subdomain = AutoSubDomain(lambda x, on_boundary: x[0] > x[1]-DOLFIN_EPS)
 
     V = FunctionSpace(mesh, "DG", 0)
diff --git a/test/unit/python/fem/test_local_assembler.py b/test/unit/python/fem/test_local_assembler.py
index ac6d4a9..a9257b6 100644
--- a/test/unit/python/fem/test_local_assembler.py
+++ b/test/unit/python/fem/test_local_assembler.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for local assembly"""
 
 # Copyright (C) 2015 Tormod Landet
diff --git a/test/unit/python/fem/test_local_solver.py b/test/unit/python/fem/test_local_solver.py
index 8b28535..d810d5b 100644
--- a/test/unit/python/fem/test_local_solver.py
+++ b/test/unit/python/fem/test_local_solver.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for LocalSolver"""
 
 # Copyright (C) 2013 Garth N. Wells
@@ -105,7 +103,7 @@ def test_solve_local_rhs_facet_integrals(ghost_mode):
     # Facet function is used here to verify that the proper domains
     # of the rhs are used unlike before where the rhs domains were
     # taken to be the same as the lhs domains
-    marker = FacetFunction("size_t", mesh)
+    marker = MeshFunction("size_t", mesh, mesh.topology().dim()-1, 0)
     ds0 = Measure("ds", domain=mesh, subdomain_data=marker, subdomain_id=0)
 
     Vu = VectorFunctionSpace(mesh, 'DG', 1)
diff --git a/test/unit/python/fem/test_manifolds.py b/test/unit/python/fem/test_manifolds.py
index 716c839..b1a19b8 100644
--- a/test/unit/python/fem/test_manifolds.py
+++ b/test/unit/python/fem/test_manifolds.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the solve function on manifolds
 embedded in higher dimensional spaces."""
 
diff --git a/test/unit/python/fem/test_petsc_transfer_matrix.py b/test/unit/python/fem/test_petsc_transfer_matrix.py
index 278aab1..c5af9f4 100644
--- a/test/unit/python/fem/test_petsc_transfer_matrix.py
+++ b/test/unit/python/fem/test_petsc_transfer_matrix.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the fem interface"""
 
 # Copyright (C) 2016 Chris Richardson
diff --git a/test/unit/python/fem/test_point_source.py b/test/unit/python/fem/test_point_source.py
index 98d37a7..5870e16 100644
--- a/test/unit/python/fem/test_point_source.py
+++ b/test/unit/python/fem/test_point_source.py
@@ -59,8 +59,8 @@ def test_pointsource_vector_node(mesh, point):
     for v in vertices(mesh):
         if near(v.midpoint().distance(point), 0.0):
             ind = v2d[v.index()]
-            if ind < len(b.array()):
-                assert np.round(b.array()[ind]-10.0) == 0
+            if ind < len(b.get_local()):
+                assert np.round(b.get_local()[ind]-10.0) == 0
 
 
 @pytest.mark.parametrize("mesh", meshes)
@@ -118,8 +118,8 @@ def test_pointsource_vector_fs(mesh, point):
         if near(v.midpoint().distance(point), 0.0):
             for spc_idx in range(V.num_sub_spaces()):
                 ind = v2d[v.index()*V.num_sub_spaces() + spc_idx]
-                if ind < len(b.array()):
-                    assert np.round(b.array()[ind] - 10.0) == 0
+                if ind < len(b.get_local()):
+                    assert np.round(b.get_local()[ind] - 10.0) == 0
 
 
 @pytest.mark.parametrize("mesh, point", data)
diff --git a/test/unit/python/fem/test_solving.py b/test/unit/python/fem/test_solving.py
index 2563332..d3481be 100644
--- a/test/unit/python/fem/test_solving.py
+++ b/test/unit/python/fem/test_solving.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the solve function"""
 
 # Copyright (C) 2011 Anders Logg
diff --git a/test/unit/python/fem/test_symbolic_geometry_assembly.py b/test/unit/python/fem/test_symbolic_geometry_assembly.py
index e7aaaf1..c72ea4e 100644
--- a/test/unit/python/fem/test_symbolic_geometry_assembly.py
+++ b/test/unit/python/fem/test_symbolic_geometry_assembly.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env py.test
 from dolfin import *
 import ufl
 import numpy
@@ -251,13 +250,12 @@ def test_manifold_line_geometry(mesh, uflacs_representation_only):
     assert uflacs_representation_only == "uflacs"
     assert parameters["form_compiler"]["representation"] == "uflacs"
 
+    gdim = mesh.geometry().dim()
+    tdim = mesh.topology().dim()
+
     # Create cell markers and integration measure
-    mf = CellFunction("size_t", mesh)
-    for i in range(mesh.num_cells()):
-        mf[i] = i
+    mf = MeshFunction("size_t", mesh, mesh.topology().dim())
     dx = Measure("dx", domain=mesh, subdomain_data=mf)
-    coords = mesh.coordinates()
-    cells = mesh.cells()
 
     # Create symbolic geometry for current mesh
     x = SpatialCoordinate(mesh)
@@ -268,6 +266,8 @@ def test_manifold_line_geometry(mesh, uflacs_representation_only):
     detJ = JacobianDeterminant(mesh)
     K = JacobianInverse(mesh)
     vol = CellVolume(mesh)
+    h = CellDiameter(mesh)
+    R = Circumradius(mesh)
 
     # Check that length computed via integral doesn't change with
     # refinement
@@ -288,19 +288,21 @@ def test_manifold_line_geometry(mesh, uflacs_representation_only):
     assert round(assemble((vol-abs(detJ))*dx), 7) == 0.0
     assert round(length - assemble(vol/abs(detJ)*dx), 7) == 0.0
 
-    gdim, tdim = J.ufl_shape
+    coords = mesh.coordinates()
+    cells = mesh.cells()
 
     # Checks on each cell separately
-    for i in range(mesh.num_cells()):
-        mf[i] = 0
-    for i in range(mesh.num_cells()):
-        mf[i] = 1  # mark this cell
-        x0 = Constant(tuple(coords[cells[i][0], :]))
+    for k in range(mesh.num_cells()):
+        # Mark current cell
+        mf.set_all(0)
+        mf[k] = 1
+
+        x0 = Constant(tuple(coords[cells[k][0], :]))
 
         # Integrate x components over a cell and compare with midpoint
         # computed from coords
         for j in range(gdim):
-            xm = 0.5*(coords[cells[i][0], j] + coords[cells[i][1], j])
+            xm = 0.5*(coords[cells[k][0], j] + coords[cells[k][1], j])
             assert round(assemble(x[j]/abs(detJ)*dx(1)) - xm, 7) == 0.0
 
         # Jacobian column is pointing away from x0
@@ -311,6 +313,10 @@ def test_manifold_line_geometry(mesh, uflacs_representation_only):
         assert round(assemble((X - K*(x-x0))**2*dx(1)), 7) == 0.0
         assert round(assemble((K*J - Identity(tdim))**2*dx(1)), 7) == 0.0
 
+        # Check cell diameter and circumradius
+        assert round(assemble(h/vol*dx(1)) - Cell(mesh, k).h(), 7) == 0.0
+        assert round(assemble(R/vol*dx(1)) - Cell(mesh, k).circumradius(), 7) == 0.0
+
         # Jacobian column is orthogonal to cell normal
         if gdim == 2:
             assert round(assemble(dot(J[:, 0], cn)*dx(1)), 7) == 0.0
@@ -331,7 +337,6 @@ def test_manifold_line_geometry(mesh, uflacs_representation_only):
             assert round(assemble(up**2*dx(1)), 7) > 0.0
             assert round(assemble((up[0]**2 + up[1]**2)*dx(1)), 7) == 0.0
             assert round(assemble(up[2]*dx(1)), 7) > 0.0
-        mf[i] = 0  # unmark this cell
 
 
 @skip_in_parallel
@@ -352,7 +357,7 @@ def test_manifold_dg0_functions(square3d, any_representation):
     mesh = square3d
     area = sqrt(3.0)  # known area of mesh
 
-    mf = CellFunction("size_t", mesh)
+    mf = MeshFunction("size_t", mesh, mesh.topology().dim())
     mf[0] = 0
     mf[1] = 1
     dx = Measure("dx", domain=mesh, subdomain_data=mf)
@@ -366,8 +371,8 @@ def test_manifold_dg0_functions(square3d, any_representation):
     u0 = project(1.0, U0)
     v0v = (1.0, 2.0, 3.0)
     v0 = project(as_vector(v0v), V0)
-    assert round(sum(u0.vector().array()) - 2*1, 7) == 0.0
-    assert round(sum(v0.vector().array()) - 2*(1+2+3), 7) == 0.0
+    assert round(sum(u0.vector().get_local()) - 2*1, 7) == 0.0
+    assert round(sum(v0.vector().get_local()) - 2*(1+2+3), 7) == 0.0
 
     # Integrate piecewise constant functions over manifold cells
     assert round(assemble(u0*dx(0)) - 0.5*area) == 0.0
@@ -380,8 +385,8 @@ def test_manifold_dg0_functions(square3d, any_representation):
     # Project x to scalar and vector DG0 spaces on manifold
     u0x = project(x[0], U0)  # cell averages of x[0]: 2/3, 1/3, sum = 3/3
     v0x = project(x, V0)  # cell averages of x[:]: (2/3, 1/3, 2/3), (1/3, 2/3, 2/3), sum = 10/3
-    assert round(sum(u0x.vector().array()) - 3.0/3.0, 7) == 0.0
-    assert round(sum(v0x.vector().array()) - 10.0/3.0, 7) == 0.0
+    assert round(sum(u0x.vector().get_local()) - 3.0/3.0, 7) == 0.0
+    assert round(sum(v0x.vector().get_local()) - 10.0/3.0, 7) == 0.0
 
     # Evaluate in all corners and cell midpoints, value should be the
     # same constant everywhere
@@ -402,7 +407,7 @@ def test_manifold_cg1_functions(square3d, any_representation):
     mesh = square3d
     area = sqrt(3.0)  # known area of mesh
 
-    mf = CellFunction("size_t", mesh)
+    mf = MeshFunction("size_t", mesh, mesh.topology().dim())
     mf[0] = 0
     mf[1] = 1
     dx = Measure("dx", domain=mesh, subdomain_data=mf)
@@ -420,9 +425,9 @@ def test_manifold_cg1_functions(square3d, any_representation):
     v1 = project(x, V1)
     # exact x in vertices is [0,0,0, 1,1,1, 1,0,0, 0,1,0],
     # so sum(x[0] for each vertex) is therefore sum(0 1 1 0):
-    assert round(sum(u1.vector().array()) - (0+1+1+0), 7) == 0.0
+    assert round(sum(u1.vector().get_local()) - (0+1+1+0), 7) == 0.0
     # and sum(x components for each vertex) is sum(1, 3, 1, 1):
-    assert round(sum(v1.vector().array()) - (1+3+1+1), 7) == 0.0
+    assert round(sum(v1.vector().get_local()) - (1+3+1+1), 7) == 0.0
 
     # Integrate piecewise constant functions over manifold cells,
     # computing midpoint coordinates
@@ -503,11 +508,15 @@ def test_manifold_point_evaluation(square3d, any_representation):
 @skip_in_parallel
 def test_manifold_symbolic_geometry(square3d, uflacs_representation_only):
     mesh = square3d
+    assert mesh.num_cells() == 2
+    gdim = mesh.geometry().dim()
+    tdim = mesh.topology().dim()
+
     area = sqrt(3.0)  # known area of mesh
     A = area/2.0  # area of single cell
     Aref = 0.5  # 0.5 is the area of the UFC reference triangle
 
-    mf = CellFunction("size_t", mesh)
+    mf = MeshFunction("size_t", mesh, mesh.topology().dim())
     mf[0] = 0
     mf[1] = 1
     dx = Measure("dx", domain=mesh, subdomain_data=mf)
@@ -550,56 +559,65 @@ def test_manifold_symbolic_geometry(square3d, uflacs_representation_only):
     detJ = JacobianDeterminant(mesh)  # pseudo-determinant
     K = JacobianInverse(mesh)  # pseudo-inverse
     vol = CellVolume(mesh)
+    h = CellDiameter(mesh)
+    R = Circumradius(mesh)
 
     # This is not currently implemented in uflacs:
     # x0 = CellOrigin(mesh)
     # But by happy accident, x0 is the same vertex for both our triangles:
     x0 = as_vector((0.0, 0.0, 1.0))
 
-    # Check integration area vs detJ
-    for k in range(2):
+    # Checks on each cell separately
+    for k in range(mesh.num_cells()):
+        # Mark current cell
+        mf.set_all(0)
+        mf[k] = 1
+
+        # Check integration area vs detJ
         # Validate known cell area A
-        assert round(assemble(1.0*dx(k)) - A, 7) == 0.0
-        assert round(assemble(1.0/A*dx(k)) - 1.0, 7) == 0.0
-        assert round(assemble(A*dx(k)) - A**2, 7) == 0.0
+        assert round(assemble(1.0*dx(1)) - A, 7) == 0.0
+        assert round(assemble(1.0/A*dx(1)) - 1.0, 7) == 0.0
+        assert round(assemble(A*dx(1)) - A**2, 7) == 0.0
         # Compare abs(detJ) to A
         A2 = Aref*abs(detJ)
-        assert round(assemble((A-A2)**2*dx(k)) - 0.0, 7) == 0.0
-        assert round(assemble(1.0/A2*dx(k)) - 1.0, 7) == 0.0
-        assert round(assemble(A2*dx(k)) - A**2, 7) == 0.0
+        assert round(assemble((A-A2)**2*dx(1)) - 0.0, 7) == 0.0
+        assert round(assemble(1.0/A2*dx(1)) - 1.0, 7) == 0.0
+        assert round(assemble(A2*dx(1)) - A**2, 7) == 0.0
         # Validate cell orientation
-        assert round(assemble(co*dx(k)) - A*(1 if k == 1 else -1), 7) == 0.0
+        assert round(assemble(co*dx(1)) - A*(1 if k == 1 else -1), 7) == 0.0
         # Compare co*detJ to A (detJ is pseudo-determinant with sign
         # restored, *co again is equivalent to abs())
         A3 = Aref*co*detJ
-        assert round(assemble((A-A3)**2*dx(k)) - 0.0, 7) == 0.0
-        assert round(assemble((A2-A3)**2*dx(k)) - 0.0, 7) == 0.0
-        assert round(assemble(1.0/A3*dx(k)) - 1.0, 7) == 0.0
-        assert round(assemble(A3*dx(k)) - A**2, 7) == 0.0
+        assert round(assemble((A-A3)**2*dx(1)) - 0.0, 7) == 0.0
+        assert round(assemble((A2-A3)**2*dx(1)) - 0.0, 7) == 0.0
+        assert round(assemble(1.0/A3*dx(1)) - 1.0, 7) == 0.0
+        assert round(assemble(A3*dx(1)) - A**2, 7) == 0.0
         # Compare vol to A
         A4 = vol
-        assert round(assemble((A-A4)**2*dx(k)) - 0.0, 7) == 0.0
-        assert round(assemble((A2-A4)**2*dx(k)) - 0.0, 7) == 0.0
-        assert round(assemble((A3-A4)**2*dx(k)) - 0.0, 7) == 0.0
-        assert round(assemble(1.0/A4*dx(k)) - 1.0, 7) == 0.0
-        assert round(assemble(A4*dx(k)) - A**2, 7) == 0.0
-
-    # Check integral of reference coordinate components over reference
-    # triangle: \int_0^1 \int_0^{1-x} x dy dx = 1/6
-    Xmp = (1.0/6.0, 1.0/6.0)
-    for k in range(2):
-        for j in range(2):
+        assert round(assemble((A-A4)**2*dx(1)) - 0.0, 7) == 0.0
+        assert round(assemble((A2-A4)**2*dx(1)) - 0.0, 7) == 0.0
+        assert round(assemble((A3-A4)**2*dx(1)) - 0.0, 7) == 0.0
+        assert round(assemble(1.0/A4*dx(1)) - 1.0, 7) == 0.0
+        assert round(assemble(A4*dx(1)) - A**2, 7) == 0.0
+
+        # Check cell diameter and circumradius
+        assert round(assemble(h/vol*dx(1)) - Cell(mesh, k).h(), 7) == 0.0
+        assert round(assemble(R/vol*dx(1)) - Cell(mesh, k).circumradius(), 7) == 0.0
+
+        # Check integral of reference coordinate components over reference
+        # triangle: \int_0^1 \int_0^{1-x} x dy dx = 1/6
+        Xmp = (1.0/6.0, 1.0/6.0)
+        for j in range(tdim):
             # Scale by detJ^-1 to get reference cell integral
-            assert round(assemble(X[j]/abs(detJ)*dx(k)) - Xmp[j], 7) == 0.0
-
-    # Check average of physical coordinate components over each cell:
-    xmp = [(2.0/3.0, 1.0/3.0, 2.0/3.0),  # midpoint of cell 0
-           (1.0/3.0, 2.0/3.0, 2.0/3.0),  # midpoint of cell 1
-           ]
-    for k in range(2):
-        for i in range(3):
+            assert round(assemble(X[j]/abs(detJ)*dx(1)) - Xmp[j], 7) == 0.0
+
+        # Check average of physical coordinate components over each cell:
+        xmp = [(2.0/3.0, 1.0/3.0, 2.0/3.0),  # midpoint of cell 0
+               (1.0/3.0, 2.0/3.0, 2.0/3.0),  # midpoint of cell 1
+               ]
+        for i in range(gdim):
             # Scale by A^-1 to get average of x, not integral
-            assert round(assemble(x[i]/A*dx(k)) - xmp[k][i], 7) == 0.0
+            assert round(assemble(x[i]/A*dx(1)) - xmp[k][i], 7) == 0.0
 
     # Check affine coordinate relations x=x0+J*X, X=K*(x-x0), K*J=I
     assert round(assemble((x - (x0+J*X))**2*dx), 7) == 0.0
@@ -613,7 +631,7 @@ def test_manifold_piola_mapped_functions(square3d, any_representation):
     area = sqrt(3.0)  # known area of mesh
     A = area/2.0
 
-    mf = CellFunction("size_t", mesh)
+    mf = MeshFunction("size_t", mesh, mesh.topology().dim())
     mf[0] = 0
     mf[1] = 1
     dx = Measure("dx", domain=mesh, subdomain_data=mf)
@@ -720,9 +738,7 @@ def test_tetrahedron_symbolic_geometry(uflacs_representation_only):
     A = area/6.0  # volume of single cell
     Aref = 1.0/6.0  # the volume of the UFC reference tetrahedron
 
-    mf = CellFunction("size_t", mesh)
-    for i in range(mesh.num_cells()):
-        mf[i] = i
+    mf = MeshFunction("size_t", mesh, mesh.topology().dim())
     dx = Measure("dx", domain=mesh, subdomain_data=mf)
 
     U0 = FunctionSpace(mesh, "DG", 0)
@@ -737,54 +753,62 @@ def test_tetrahedron_symbolic_geometry(uflacs_representation_only):
     detJ = JacobianDeterminant(mesh)
     K = JacobianInverse(mesh)
     vol = CellVolume(mesh)
+    h = CellDiameter(mesh)
+    R = Circumradius(mesh)
 
-    # Check integration area vs detJ
     coordinates = mesh.coordinates()
     cells = mesh.cells()
+
     for k in range(mesh.num_cells()):
+        # Mark current cell
+        mf.set_all(0)
+        mf[k] = 1
+
+        # Check integration area vs detJ
         # This is not currently implemented in uflacs:
         # x0 = CellOrigin(mesh)
         # But we can extract it from the mesh for a given cell k
         x0 = as_vector(coordinates[cells[k][0]][:])
         # Validate known cell volume A
-        assert round(assemble(1.0*dx(k)) - A, 7) == 0.0
-        assert round(assemble(1.0/A*dx(k)) - 1.0, 7) == 0.0
-        assert round(assemble(A*dx(k)) - A**2, 7) == 0.0
+        assert round(assemble(1.0*dx(1)) - A, 7) == 0.0
+        assert round(assemble(1.0/A*dx(1)) - 1.0, 7) == 0.0
+        assert round(assemble(A*dx(1)) - A**2, 7) == 0.0
         # Compare abs(detJ) to A
         A2 = Aref*abs(detJ)
-        assert round(assemble((A-A2)**2*dx(k)) - 0.0, 7) == 0.0
-        assert round(assemble(1.0/A2*dx(k)) - 1.0, 7) == 0.0
-        assert round(assemble(A2*dx(k)) - A**2, 7) == 0.0
+        assert round(assemble((A-A2)**2*dx(1)) - 0.0, 7) == 0.0
+        assert round(assemble(1.0/A2*dx(1)) - 1.0, 7) == 0.0
+        assert round(assemble(A2*dx(1)) - A**2, 7) == 0.0
         # Compare vol to A
         A4 = vol
-        assert round(assemble((A-A4)**2*dx(k)) - 0.0, 7) == 0.0
-        assert round(assemble((A2-A4)**2*dx(k)) - 0.0, 7) == 0.0
-        assert round(assemble(1.0/A4*dx(k)) - 1.0, 7) == 0.0
-        assert round(assemble(A4*dx(k)) - A**2, 7) == 0.0
-
-    # Check integral of reference coordinate components over reference
-    # tetrahedron:
-    Xmp = (1.0/24.0, 1.0/24.0, 1.0/24.0)  # not validated analytically
-    for k in range(mesh.num_cells()):
+        assert round(assemble((A-A4)**2*dx(1)) - 0.0, 7) == 0.0
+        assert round(assemble((A2-A4)**2*dx(1)) - 0.0, 7) == 0.0
+        assert round(assemble(1.0/A4*dx(1)) - 1.0, 7) == 0.0
+        assert round(assemble(A4*dx(1)) - A**2, 7) == 0.0
+
+        # Check integral of reference coordinate components over reference
+        # tetrahedron:
+        Xmp = (1.0/24.0, 1.0/24.0, 1.0/24.0)  # not validated analytically
         for j in range(tdim):
             # Scale by detJ^-1 to get reference cell integral
-            assert round(assemble(X[j]/abs(detJ)*dx(k)) - Xmp[j], 7) == 0.0
+            assert round(assemble(X[j]/abs(detJ)*dx(1)) - Xmp[j], 7) == 0.0
 
-    # Check average of physical coordinate components over each cell:
-    for k in range(mesh.num_cells()):
+        # Check average of physical coordinate components over each cell:
         # Compute average of vertex coordinates extracted from mesh
         verts = [coordinates[i][:] for i in cells[k]]
         vavg = sum(verts[1:], verts[0])/len(verts)
         for i in range(gdim):
             # Scale by A^-1 to get average of x, not integral
-            assert round(assemble(x[i]/A*dx(k)) - vavg[i], 7) == 0.0
+            assert round(assemble(x[i]/A*dx(1)) - vavg[i], 7) == 0.0
 
-    # Check affine coordinate relations x=x0+J*X, X=K*(x-x0), K*J=I
-    for k in range(mesh.num_cells()):
+        # Check affine coordinate relations x=x0+J*X, X=K*(x-x0), K*J=I
         x0 = as_vector(coordinates[cells[k][0]][:])
-        assert round(assemble((x - (x0+J*X))**2*dx(k)), 7) == 0.0
-        assert round(assemble((X - K*(x-x0))**2*dx(k)), 7) == 0.0
-        assert round(assemble((K*J - Identity(tdim))**2/A*dx(k)), 7) == 0.0
+        assert round(assemble((x - (x0+J*X))**2*dx(1)), 7) == 0.0
+        assert round(assemble((X - K*(x-x0))**2*dx(1)), 7) == 0.0
+        assert round(assemble((K*J - Identity(tdim))**2/A*dx(1)), 7) == 0.0
+
+        # Check cell diameter and circumradius
+        assert round(assemble(h/vol*dx(1)) - Cell(mesh, k).h(), 7) == 0.0
+        assert round(assemble(R/vol*dx(1)) - Cell(mesh, k).circumradius(), 7) == 0.0
 
 
 # Some symbolic quantities are only available through uflacs
@@ -799,9 +823,7 @@ def test_triangle_symbolic_geometry(uflacs_representation_only):
     A = area/2.0  # volume of single cell
     Aref = 1.0/2.0  # the volume of the UFC reference triangle
 
-    mf = CellFunction("size_t", mesh)
-    for i in range(mesh.num_cells()):
-        mf[i] = i
+    mf = MeshFunction("size_t", mesh, mesh.topology().dim())
     dx = Measure("dx", domain=mesh, subdomain_data=mf)
 
     U0 = FunctionSpace(mesh, "DG", 0)
@@ -816,51 +838,146 @@ def test_triangle_symbolic_geometry(uflacs_representation_only):
     detJ = JacobianDeterminant(mesh)
     K = JacobianInverse(mesh)
     vol = CellVolume(mesh)
+    h = CellDiameter(mesh)
+    R = Circumradius(mesh)
 
-    # Check integration area vs detJ
     coordinates = mesh.coordinates()
     cells = mesh.cells()
+
     for k in range(mesh.num_cells()):
+        # Mark current cell
+        mf.set_all(0)
+        mf[k] = 1
+
+        # Check integration area vs detJ
         # This is not currently implemented in uflacs:
         # x0 = CellOrigin(mesh)
         # But we can extract it from the mesh for a given cell k
         x0 = as_vector(coordinates[cells[k][0]][:])
         # Validate known cell volume A
-        assert round(assemble(1.0*dx(k)) - A, 7) == 0.0
-        assert round(assemble(1.0/A*dx(k)) - 1.0, 7) == 0.0
-        assert round(assemble(A*dx(k)) - A**2, 7) == 0.0
+        assert round(assemble(1.0*dx(1)) - A, 7) == 0.0
+        assert round(assemble(1.0/A*dx(1)) - 1.0, 7) == 0.0
+        assert round(assemble(A*dx(1)) - A**2, 7) == 0.0
         # Compare abs(detJ) to A
         A2 = Aref*abs(detJ)
-        assert round(assemble((A-A2)**2*dx(k)) - 0.0, 7) == 0.0
-        assert round(assemble(1.0/A2*dx(k)) - 1.0, 7) == 0.0
-        assert round(assemble(A2*dx(k)) - A**2, 7) == 0.0
+        assert round(assemble((A-A2)**2*dx(1)) - 0.0, 7) == 0.0
+        assert round(assemble(1.0/A2*dx(1)) - 1.0, 7) == 0.0
+        assert round(assemble(A2*dx(1)) - A**2, 7) == 0.0
         # Compare vol to A
         A4 = vol
-        assert round(assemble((A-A4)**2*dx(k)) - 0.0, 7) == 0.0
-        assert round(assemble((A2-A4)**2*dx(k)) - 0.0, 7) == 0.0
-        assert round(assemble(1.0/A4*dx(k)) - 1.0, 7) == 0.0
-        assert round(assemble(A4*dx(k)) - A**2, 7) == 0.0
-
-    # Check integral of reference coordinate components over reference
-    # triangle:
-    Xmp = (1.0/6.0, 1.0/6.0)
-    for k in range(mesh.num_cells()):
+        assert round(assemble((A-A4)**2*dx(1)) - 0.0, 7) == 0.0
+        assert round(assemble((A2-A4)**2*dx(1)) - 0.0, 7) == 0.0
+        assert round(assemble(1.0/A4*dx(1)) - 1.0, 7) == 0.0
+        assert round(assemble(A4*dx(1)) - A**2, 7) == 0.0
+
+        # Check integral of reference coordinate components over reference
+        # triangle:
+        Xmp = (1.0/6.0, 1.0/6.0)
         for j in range(tdim):
             # Scale by detJ^-1 to get reference cell integral
-            assert round(assemble(X[j]/abs(detJ)*dx(k)) - Xmp[j], 7) == 0.0
+            assert round(assemble(X[j]/abs(detJ)*dx(1)) - Xmp[j], 7) == 0.0
 
-    # Check average of physical coordinate components over each cell:
-    for k in range(mesh.num_cells()):
+        # Check average of physical coordinate components over each cell:
         # Compute average of vertex coordinates extracted from mesh
         verts = [coordinates[i][:] for i in cells[k]]
         vavg = sum(verts[1:], verts[0])/len(verts)
         for i in range(gdim):
             # Scale by A^-1 to get average of x, not integral
-            assert round(assemble(x[i]/A*dx(k)) - vavg[i], 7) == 0.0
+            assert round(assemble(x[i]/A*dx(1)) - vavg[i], 7) == 0.0
 
-    # Check affine coordinate relations x=x0+J*X, X=K*(x-x0), K*J=I
-    for k in range(mesh.num_cells()):
+        # Check affine coordinate relations x=x0+J*X, X=K*(x-x0), K*J=I
         x0 = as_vector(coordinates[cells[k][0]][:])
-        assert round(assemble((x - (x0+J*X))**2*dx(k)), 7) == 0.0
-        assert round(assemble((X - K*(x-x0))**2*dx(k)), 7) == 0.0
-        assert round(assemble((K*J - Identity(tdim))**2/A*dx(k)), 7) == 0.0
+        assert round(assemble((x - (x0+J*X))**2*dx(1)), 7) == 0.0
+        assert round(assemble((X - K*(x-x0))**2*dx(1)), 7) == 0.0
+        assert round(assemble((K*J - Identity(tdim))**2/A*dx(1)), 7) == 0.0
+
+        # Check cell diameter and circumradius
+        assert round(assemble(h/vol*dx(1)) - Cell(mesh, k).h(), 7) == 0.0
+        assert round(assemble(R/vol*dx(1)) - Cell(mesh, k).circumradius(), 7) == 0.0
+
+
+if has_pybind11():
+    xfail_jit = pytest.mark.xfail(raises=Exception, strict=True)
+else:
+    xfail_jit = pytest.mark.xfail(raises=RuntimeError, strict=True)
+
+ at pytest.mark.parametrize('mesh_factory', [
+    (UnitIntervalMesh, (8,)),
+    (UnitSquareMesh, (4, 4)),
+    (UnitDiscMesh.create, (mpi_comm_world(), 4, 1, 2)),
+    (UnitDiscMesh.create, (mpi_comm_world(), 4, 1, 3)),
+    (SphericalShellMesh.create, (mpi_comm_world(), 1,)),
+    (UnitCubeMesh, (2, 2, 2)),
+    (UnitSquareMesh.create, (4, 4, CellType.Type_quadrilateral)),
+    (UnitCubeMesh.create, (2, 2, 2, CellType.Type_hexahedron)),
+    (line1d, (None,)),
+    (line2d, (None,)),
+    (line3d, (None,)),
+    (rline1d, (None,)),
+    (rline2d, (None,)),
+    (rline3d, (None,)),
+    (square2d, (None,)),
+    (square3d, (None,)),
+    # Tested geometric quantities are not implemented for higher-order cells
+    xfail_jit((UnitDiscMesh.create, (mpi_comm_world(), 4, 2, 2))),
+    xfail_jit((UnitDiscMesh.create, (mpi_comm_world(), 4, 2, 3))),
+    xfail_jit((SphericalShellMesh.create, (mpi_comm_world(), 2,))),
+])
+ at skip_in_parallel
+def test_geometric_quantities(uflacs_representation_only, mesh_factory):
+    func, args = mesh_factory
+    mesh = func(*args)
+
+    tdim = mesh.ufl_cell().topological_dimension()
+
+    cf = MeshFunction('size_t', mesh, mesh.topology().dim(), 0)
+    dx = Measure("dx", domain=mesh, subdomain_data=cf)
+
+    ff = MeshFunction('size_t', mesh, mesh.topology().dim()-1, 0)
+    ds = Measure("ds", domain=mesh, subdomain_data=ff)
+    dS = Measure("dS", domain=mesh, subdomain_data=ff)
+
+    h = CellDiameter(mesh)
+    R = Circumradius(mesh)
+    max_cell_edge = MaxCellEdgeLength(mesh)
+    min_cell_edge = MinCellEdgeLength(mesh)
+    max_facet_edge = MaxFacetEdgeLength(mesh)
+    min_facet_edge = MinFacetEdgeLength(mesh)
+
+    for c in cells(mesh):
+        # Mark current cell for integration
+        cf.set_all(0)
+        cf[c] = 1
+
+        vol = assemble(1*dx(1))
+
+        # Check cell diameter
+        assert numpy.isclose(assemble(h*dx(1))/vol, c.h())
+
+        # Check max/min cell edge length
+        assert numpy.isclose(assemble(max_cell_edge*dx(1))/vol,
+                             max(e.length() for e in edges(c)))
+        assert numpy.isclose(assemble(min_cell_edge*dx(1))/vol,
+                             min(e.length() for e in edges(c)))
+
+        # Check circumradius if it makes sense
+        if mesh.ufl_domain().is_piecewise_linear_simplex_domain():
+            assert numpy.isclose(assemble(R*dx(1))/vol, c.circumradius())
+
+    # Check max/min facet edge length if it makes sense
+    if tdim >= 3:
+
+        mesh.init(tdim-1, tdim)  # for Facet.exterior()
+
+        for f in facets(mesh):
+            # Mark current facet for integration and pick facet measure
+            ff.set_all(0)
+            ff[f] = 1
+            df = ds(1) if f.exterior() else dS(1)
+
+            vol = assemble(1*df)
+
+            assert numpy.isclose(assemble(max_facet_edge*df)/vol,
+                                 max(e.length() for e in edges(f)))
+            assert numpy.isclose(assemble(min_facet_edge*df)/vol,
+                                 min(e.length() for e in edges(f)))
diff --git a/test/unit/python/fem/test_system_assembler.py b/test/unit/python/fem/test_system_assembler.py
index 6d83183..de536b7 100644
--- a/test/unit/python/fem/test_system_assembler.py
+++ b/test/unit/python/fem/test_system_assembler.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for class SystemAssembler"""
 
 # Copyright (C) 2011-2013 Garth N. Wells, 2013 Jan Blechta
@@ -131,7 +129,7 @@ def test_facet_assembly():
 
         # Define normal component, mesh size and right-hand side
         n = FacetNormal(mesh)
-        h = CellSize(mesh)
+        h = 2*Circumradius(mesh)
         h_avg = (h('+') + h('-'))/2
         f = Expression("500.0*exp(-(pow(x[0] - 0.5, 2) + pow(x[1] - 0.5, 2)) / 0.02)", degree=1)
 
@@ -197,7 +195,7 @@ def test_vertex_assembly():
         return 0.25 <= x[0] and x[0] <= 0.75 and near(x[1], 0.5)
 
     # Define domain for point integral
-    center_domain = VertexFunction("size_t", mesh, 0)
+    center_domain = MeshFunction("size_t", mesh, 0, 0)
     center = AutoSubDomain(center_func)
     center.mark(center_domain, 1)
     dPP = dP(subdomain_data=center_domain)
@@ -213,7 +211,8 @@ def test_vertex_assembly():
         A, b = assemble_system(a, L)
 
 
- at pytest.mark.parametrize('mesh_factory', [(UnitSquareMesh, (20, 20)), (UnitQuadMesh.create, (20, 20))])
+ at pytest.mark.parametrize('mesh_factory', [(UnitSquareMesh, (20, 20)),
+                                          (UnitSquareMesh.create, (20, 20, CellType.Type_quadrilateral))])
 def test_incremental_assembly(mesh_factory):
 
     for f in [Constant(0.0), Constant(1e4)]:
@@ -254,7 +253,11 @@ def test_incremental_assembly(mesh_factory):
 
 
 @skip_in_parallel
- at pytest.mark.parametrize('mesh_factory', [(UnitSquareMesh, (24, 24)), (UnitQuadMesh.create, (24, 24))])
+ at pytest.mark.parametrize('mesh_factory', [
+    (UnitSquareMesh.create, (24, 24, CellType.Type_triangle)),
+    # FFC PR #91 disables (broken) DQ elements
+    pytest.mark.xfail((UnitSquareMesh.create, (24, 24, CellType.Type_quadrilateral)), strict=True, raises=Exception),
+])
 def test_domains(mesh_factory):
 
     class RightSubDomain(SubDomain):
@@ -371,7 +374,8 @@ def test_facet_assembly_cellwise_insertion(filedir):
     run_test(Mesh(os.path.join(filedir, "gmsh_unit_interval.xml")))
 
 
- at pytest.mark.parametrize('mesh_factory', [(UnitSquareMesh, (24, 24)), (UnitQuadMesh.create, (24, 24))])
+ at pytest.mark.parametrize('mesh_factory', [(UnitSquareMesh, (24, 24)),
+                                          (UnitSquareMesh.create, (24, 24, CellType.Type_quadrilateral))])
 def test_non_square_assembly(mesh_factory):
     func, args = mesh_factory
     mesh = func(*args)
diff --git a/test/unit/python/fem/test_variational_problem.py b/test/unit/python/fem/test_variational_problem.py
index 6acd4bf..6bdd663 100644
--- a/test/unit/python/fem/test_variational_problem.py
+++ b/test/unit/python/fem/test_variational_problem.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the Nonlinear- and Linear-VariationalProblem classes"""
 
 # Copyright (C) 2016 Garth N. Wells
@@ -41,9 +39,9 @@ def test_linear_construction():
     w = Function(V)
     with pytest.raises(TypeError):
         problem = LinearVariationalProblem(a, L)
-    with pytest.raises(RuntimeError):
+    with pytest.raises(Exception):
         problem = LinearVariationalProblem(a, L, [bc])
-    with pytest.raises(RuntimeError):
+    with pytest.raises(Exception):
         problem = LinearVariationalProblem(a, L, [bc], w)
     problem = LinearVariationalProblem(a, L, w, [])
     problem = LinearVariationalProblem(a, L, w, [bc])
@@ -64,7 +62,7 @@ def test_nonlinear_construction():
     J = derivative(F, u, du)
     bc = DirichletBC(V, 0.0, DomainBoundary())
 
-    with pytest.raises(RuntimeError):
+    with pytest.raises(Exception):
         problem = NonlinearVariationalProblem(F, u, J)
     problem = NonlinearVariationalProblem(F, u)
     problem = NonlinearVariationalProblem(F, u, [])
diff --git a/test/unit/python/function/test_constant.py b/test/unit/python/function/test_constant.py
index 3828406..2646b2e 100755
--- a/test/unit/python/function/test_constant.py
+++ b/test/unit/python/function/test_constant.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the function library"""
 
 # Copyright (C) 2007 Anders Logg
@@ -72,7 +70,7 @@ def testGrad():
     assert zero == gradient(c3)
 
 
- at pytest.mark.parametrize('mesh_factory', [(UnitCubeMesh, (8, 8, 8)), (UnitHexMesh.create, (8, 8, 8))])
+ at pytest.mark.parametrize('mesh_factory', [(UnitCubeMesh, (8, 8, 8)), (UnitCubeMesh.create, (8, 8, 8, CellType.Type_hexahedron))])
 def test_compute_vertex_values(mesh_factory):
     from numpy import zeros, all, array
 
@@ -118,3 +116,15 @@ def test_str():
     c1 = Constant((1., 2., 3.))
     c1.str(False)
     c1.str(True)
+
+
+def test_assign():
+    c0 = Constant(1.)
+    assert c0.values() == (1,)
+    c0.assign(Constant(3))
+    assert c0.values() == (3,)
+
+    c1 = Constant([1, 2])
+    assert (c1.values() == (1, 2)).all()
+    c1.assign(Constant([3, 4]))
+    assert (c1.values() == (3, 4)).all()
diff --git a/test/unit/python/function/test_constrained_function_space.py b/test/unit/python/function/test_constrained_function_space.py
index dec863e..0f41f63 100755
--- a/test/unit/python/function/test_constrained_function_space.py
+++ b/test/unit/python/function/test_constrained_function_space.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for FunctionSpace with constrained domain"""
 
 # Copyright (C) 2012-2014 Garth N. Wells
diff --git a/test/unit/python/function/test_expression.py b/test/unit/python/function/test_expression.py
index 0338efc..a3f3767 100755
--- a/test/unit/python/function/test_expression.py
+++ b/test/unit/python/function/test_expression.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the function library"""
 
 # Copyright (C) 2007-2014 Anders Logg
@@ -226,11 +224,11 @@ def test_vector_valued_expression_member_function(mesh):
     for f in fs:
         u = Expression("f[0] + f[1] + f[2]", f=f, degree=1)
         v = interpolate(u, V)
-        assert np.allclose(v.vector().array(), 6.0)
+        assert np.allclose(v.vector().get_local(), 6.0)
         for g in fs:
             u.f = g
             v = interpolate(u, V)
-            assert np.allclose(v.vector().array(), 6.0)
+            assert np.allclose(v.vector().get_local(), 6.0)
 
 
 # NOTE: Do we want this to work (attaching MeshFunctions to
@@ -241,7 +239,7 @@ def test_meshfunction_expression():
     mesh = UnitSquareMesh(1, 1)
     V = FunctionSpace(mesh, "DG", 0)
 
-    c = CellFunction("size_t", mesh)
+    c = MeshFunction("size_t", mesh, mesh.topology().dim())
     c[0] = 2
     c[1] = 3
     e = Expression("(double)c", c=c, degree=0)
@@ -663,7 +661,7 @@ def test_doc_string_complex_compiled_expression(mesh):
       }
     };'''
 
-    cell_data = CellFunction('size_t', mesh)
+    cell_data = MeshFunction('size_t', mesh, mesh.topology().dim())
     cell_data.set_all(3)
     CompiledSubDomain("x[0] <= 0.25").mark(cell_data, 0)
     CompiledSubDomain("x[0] > 0.25 && x[0] < 0.75").mark(cell_data, 1)
@@ -855,7 +853,7 @@ def test_doc_string_python_expressions(mesh):
         def eval(self, values, x):
             pass
 
-    cell_data = CellFunction('size_t', square)
+    cell_data = MeshFunction('size_t', square, square.topology().dim())
 
     P1 = FiniteElement("Lagrange", square.ufl_cell(), 1)
     f3 = MyExpression2(square, cell_data, element=P1)
diff --git a/test/unit/python/function/test_function.py b/test/unit/python/function/test_function.py
index a6c74aa..906e36f 100755
--- a/test/unit/python/function/test_function.py
+++ b/test/unit/python/function/test_function.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the Function class"""
 
 # Copyright (C) 2011-2014 Garth N. Wells
@@ -76,6 +74,10 @@ def test_compute_vertex_values(V, W, mesh):
 
     assert all(u_values == 1)
 
+    u_values2 = u.compute_vertex_values()
+
+    assert all(u_values == u_values2)
+
 
 def test_assign(V, W):
     from ufl.algorithms import replace
@@ -231,7 +233,6 @@ def test_axpy(V, W):
         with pytest.raises(RuntimeError):
             axpy + u
 
-
 def test_call(R, V, W, mesh):
     from numpy import zeros, all, array
     u0 = Function(R)
@@ -268,7 +269,6 @@ def test_call(R, V, W, mesh):
     with pytest.raises(TypeError):
         u0([0, 0])
 
-
 def test_constant_float_conversion():
     c = Constant(3.45)
     assert float(c) == 3.45
@@ -388,6 +388,25 @@ def test_extrapolation(V, pushpop_parameters):
     assert f2.get_allow_extrapolation() is False
 
 
+ at skip_in_parallel
+def test_near_evaluations(R, mesh):
+    # Test that we allow point evaluation that are slightly outside
+    parameters["allow_extrapolation"] = False
+
+    u0 = Function(R)
+    u0.vector()[:] = 1.0
+    a = Vertex(mesh, 0).point()
+    offset = 0.99*DOLFIN_EPS
+
+    a_shift_x = Point(a[0] - offset, a[1], a[2])
+    assert round(u0(a) - u0(a_shift_x), 7) == 0
+
+    a_shift_xyz = Point(a[0] - offset / sqrt(3),
+                        a[1] - offset / sqrt(3),
+                        a[2] - offset / sqrt(3))
+    assert round(u0(a) - u0(a_shift_xyz), 7) == 0
+
+
 def test_interpolation_jit_rank1(W):
     f = Expression(("1.0", "1.0", "1.0"), degree=0)
     w = interpolate(f, W)
diff --git a/test/unit/python/function/test_function_assigner.py b/test/unit/python/function/test_function_assigner.py
index 250aae1..4bf6d9d 100755
--- a/test/unit/python/function/test_function_assigner.py
+++ b/test/unit/python/function/test_function_assigner.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the FunctionAssigner class"""
 
 # Copyright (C) 2013 Johan Hake
@@ -157,30 +155,30 @@ def test_1_1_assigner(w, ww, wr, wrr, q, r, qqv, u0, u1, u2, W, V, WW):
     assigner = FunctionAssigner(W.sub(0), V)
     assigner.assign(w.sub(0), u0)
 
-    assert np.all(w.sub(0, deepcopy=True).vector().array() == u0.vector().array())
+    assert np.all(w.sub(0, deepcopy=True).vector().get_local() == u0.vector().get_local())
 
     assign(w.sub(2), u2)
-    assert np.all(w.sub(2, deepcopy=True).vector().array() == u2.vector().array())
+    assert np.all(w.sub(2, deepcopy=True).vector().get_local() == u2.vector().get_local())
 
     assigner = FunctionAssigner(V, W.sub(2))
     assigner.assign(u0, w.sub(2))
 
-    assert np.all(u0.vector().array() == w.sub(2, deepcopy=True).vector().array())
+    assert np.all(u0.vector().get_local() == w.sub(2, deepcopy=True).vector().get_local())
 
     assign(u1, w.sub(1))
-    assert np.all(u1.vector().array() == w.sub(1, deepcopy=True).vector().array())
+    assert np.all(u1.vector().get_local() == w.sub(1, deepcopy=True).vector().get_local())
 
     assigner = FunctionAssigner(WW.sub(0), W)
     assigner.assign(ww.sub(0), w)
 
     assign(wr.sub(0), w)
-    assert np.all(wr.sub(0, deepcopy=True).vector().array() == w.vector().array())
+    assert np.all(wr.sub(0, deepcopy=True).vector().get_local() == w.vector().get_local())
 
     assign(wr.sub(1), r)
-    assert np.all(wr.sub(1, deepcopy=True).vector().array() == r.vector().array())
+    assert np.all(wr.sub(1, deepcopy=True).vector().get_local() == r.vector().get_local())
 
     assign(qqv.sub(0).sub(0), q)
-    assert np.all(qqv.sub(0).sub(0, deepcopy=True).vector().array() == q.vector().array())
+    assert np.all(qqv.sub(0).sub(0, deepcopy=True).vector().get_local() == q.vector().get_local())
 
     with pytest.raises(RuntimeError):
         assign(qqv.sub(0), q)
@@ -196,17 +194,17 @@ def test_N_1_assigner(u0, u1, u2, qq, qqv, rr, w, wrr, r, W, V):
     assigner = FunctionAssigner(W, [V,V,V])
     assigner.assign(vv, [u0, u1, u2])
 
-    assert np.all(vv.sub(0, deepcopy=True).vector().array() == u0.vector().array())
-    assert np.all(vv.sub(1, deepcopy=True).vector().array() == u1.vector().array())
-    assert np.all(vv.sub(2, deepcopy=True).vector().array() == u2.vector().array())
+    assert np.all(vv.sub(0, deepcopy=True).vector().get_local() == u0.vector().get_local())
+    assert np.all(vv.sub(1, deepcopy=True).vector().get_local() == u1.vector().get_local())
+    assert np.all(vv.sub(2, deepcopy=True).vector().get_local() == u2.vector().get_local())
 
     assign(qqv, [qq, u1])
-    assert np.all(qqv.sub(0, deepcopy=True).vector().array() == qq.vector().array())
-    assert np.all(qqv.sub(1, deepcopy=True).vector().array() == u1.vector().array())
+    assert np.all(qqv.sub(0, deepcopy=True).vector().get_local() == qq.vector().get_local())
+    assert np.all(qqv.sub(1, deepcopy=True).vector().get_local() == u1.vector().get_local())
 
     assign(wrr, [w, rr])
-    assert np.all(wrr.sub(0, deepcopy=True).vector().array() == w.vector().array())
-    assert np.all(wrr.sub(1, deepcopy=True).vector().array() == rr.vector().array())
+    assert np.all(wrr.sub(0, deepcopy=True).vector().get_local() == w.vector().get_local())
+    assert np.all(wrr.sub(1, deepcopy=True).vector().get_local() == rr.vector().get_local())
 
     with pytest.raises(RuntimeError):
         assign(qqv, [qq, u1, u1])
@@ -219,11 +217,11 @@ def test_1_N_assigner(u0, u1, u2, w, qq, qqv, V, W):
     assigner = FunctionAssigner([V,V,V], W)
     assigner.assign([u0, u1, u2], w)
 
-    assert np.all(w.sub(0, deepcopy=True).vector().array() == u0.vector().array())
-    assert np.all(w.sub(1, deepcopy=True).vector().array() == u1.vector().array())
-    assert np.all(w.sub(2, deepcopy=True).vector().array() == u2.vector().array())
+    assert np.all(w.sub(0, deepcopy=True).vector().get_local() == u0.vector().get_local())
+    assert np.all(w.sub(1, deepcopy=True).vector().get_local() == u1.vector().get_local())
+    assert np.all(w.sub(2, deepcopy=True).vector().get_local() == u2.vector().get_local())
 
     assign([qq, u1], qqv)
 
-    assert np.all(qqv.sub(0, deepcopy=True).vector().array() == qq.vector().array())
-    assert np.all(qqv.sub(1, deepcopy=True).vector().array() == u1.vector().array())
+    assert np.all(qqv.sub(0, deepcopy=True).vector().get_local() == qq.vector().get_local())
+    assert np.all(qqv.sub(1, deepcopy=True).vector().get_local() == u1.vector().get_local())
diff --git a/test/unit/python/function/test_function_space.py b/test/unit/python/function/test_function_space.py
index ffb0785..eda294c 100755
--- a/test/unit/python/function/test_function_space.py
+++ b/test/unit/python/function/test_function_space.py
@@ -1,6 +1,4 @@
-#!/usr/bin/env py.test
-
-"""Unit tests for the FunctionSpace class"""
+b"""Unit tests for the FunctionSpace class"""
 
 # Copyright (C) 2011 Johan Hake
 #
@@ -27,39 +25,46 @@
 import pytest
 from dolfin import *
 from ufl.log import UFLException
-
 from dolfin_utils.test import fixture
 
+
 @fixture
 def mesh():
     return UnitCubeMesh(8, 8, 8)
 
+
 @fixture
 def V(mesh):
     return FunctionSpace(mesh, 'CG', 1)
 
+
 @fixture
 def W(mesh):
     return VectorFunctionSpace(mesh, 'CG', 1)
 
+
 @fixture
 def Q(mesh):
     W = VectorElement('CG', mesh.ufl_cell(), 1)
     V = FiniteElement('CG', mesh.ufl_cell(), 1)
     return FunctionSpace(mesh, W*V)
 
+
 @fixture
 def f(V):
     return Function(V)
 
+
 @fixture
 def V2(f):
     return f.function_space()
 
+
 @fixture
 def g(W):
     return Function(W)
 
+
 @fixture
 def W2(g):
     return g.function_space()
@@ -81,6 +86,7 @@ def test_python_interface(V, V2, W, W2, Q):
     assert W.id() == W2.id()
     assert V.id() == V2.id()
 
+
 def test_component(V, W, Q):
     assert not W.component()
     assert not V.component()
@@ -89,12 +95,14 @@ def test_component(V, W, Q):
     assert Q.sub(0).component()[0] == 0
     assert Q.sub(1).component()[0] == 1
 
+
 def test_equality(V, V2, W, W2):
     assert V == V
     assert V == V2
     assert W == W
     assert W == W2
 
+
 def test_inclusion(V, Q):
     assert V.contains(V)
     assert not Q.contains(V)
@@ -143,10 +151,12 @@ def test_boundary(mesh):
     assert Vb.dim() == 768
     assert Wb.dim() == 1158
 
+
 def test_not_equal(W, V, W2, V2):
     assert W != V
     assert W2 != V2
 
+
 def test_sub_equality(W, Q):
     assert W.sub(0) == W.sub(0)
     assert W.sub(0) != W.sub(1)
@@ -154,11 +164,16 @@ def test_sub_equality(W, Q):
     assert W.sub(1) == W.extract_sub_space([1])
     assert Q.sub(0) == Q.extract_sub_space([0])
 
+
 def test_in_operator(f, g, V, V2, W, W2):
     assert f in V
     assert f in V2
     assert g in W
     assert g in W2
+    if has_pybind11():
+        with pytest.raises(RuntimeError):
+            mesh() in V
+
 
 def test_collapse(W, V):
     Vs = W.sub(2)
@@ -173,9 +188,12 @@ def test_collapse(W, V):
     f1 = Function(Vc)
     assert len(f0.vector()) == len(f1.vector())
 
+
 def test_argument_equality(mesh, V, V2, W, W2):
     """Placed this test here because it's mainly about detecting differing
-function spaces."""
+    function spaces.
+
+    """
     mesh2 = UnitCubeMesh(8, 8, 8)
     V3 = FunctionSpace(mesh2, 'CG', 1)
     W3 = VectorFunctionSpace(mesh2, 'CG', 1)
diff --git a/test/unit/python/function/test_lagrange_interpolator.py b/test/unit/python/function/test_lagrange_interpolator.py
index 23be5e0..1ea794e 100755
--- a/test/unit/python/function/test_lagrange_interpolator.py
+++ b/test/unit/python/function/test_lagrange_interpolator.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for interpolation using LagrangeInterpolator"""
 
 # Copyright (C) 2014 Mikael Mortensen
diff --git a/test/unit/python/function/test_nonmatching_interpolation.py b/test/unit/python/function/test_nonmatching_interpolation.py
index ec66348..285bac2 100755
--- a/test/unit/python/function/test_nonmatching_interpolation.py
+++ b/test/unit/python/function/test_nonmatching_interpolation.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for evaluating functions on non-matching meshes"""
 
 # Copyright (C) 2013 Garth N. Wells
diff --git a/test/unit/python/function/test_special_functions.py b/test/unit/python/function/test_special_functions.py
index efc95cd..e09449d 100755
--- a/test/unit/python/function/test_special_functions.py
+++ b/test/unit/python/function/test_special_functions.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the function library"""
 
 # Copyright (C) 2011 Kristian B. Oelgaard
diff --git a/test/unit/python/geometry/test_bounding_box_tree.py b/test/unit/python/geometry/test_bounding_box_tree.py
index 0a4e382..3d6f14c 100755
--- a/test/unit/python/geometry/test_bounding_box_tree.py
+++ b/test/unit/python/geometry/test_bounding_box_tree.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for BoundingBoxTree"""
 
 # Copyright (C) 2013-2014 Anders Logg
@@ -85,7 +83,6 @@ def test_compute_collisions_point_3d():
         if dim != tdim - 1 and dim != tdim - 2:
             assert set(entities) == reference[dim]
 
-
 #--- compute_collisions with tree ---
 
 @skip_in_parallel
@@ -172,7 +169,7 @@ def test_compute_collisions_tree_3d():
         assert set(entities_A) == references[i][0]
         assert set(entities_B) == references[i][1]
 
-#--- compute_entity_collisions ---
+#--- compute_entity_collisions with point ---
 
 @skip_in_parallel
 def test_compute_entity_collisions_1d():
@@ -307,7 +304,7 @@ def test_compute_entity_collisions_tree_3d():
         assert set(entities_A) == references[i][0]
         assert set(entities_B) == references[i][1]
 
-#--- compute_first_collision ---
+#--- compute_first_collision with point ---
 
 @skip_in_parallel
 def test_compute_first_collision_1d():
@@ -377,7 +374,7 @@ def test_compute_first_collision_3d():
     first = tree.compute_first_collision(p)
     assert first in reference[mesh.topology().dim()]
 
-#--- compute_first_entity_collision ---
+#--- compute_first_entity_collision with point ---
 
 @skip_in_parallel
 def test_compute_first_entity_collision_1d():
@@ -427,7 +424,7 @@ def test_compute_first_entity_collision_3d():
     first = tree.compute_first_entity_collision(p)
     assert first in reference
 
-#--- compute_closest_entity ---
+#--- compute_closest_entity with point ---
 
 @skip_in_parallel
 def test_compute_closest_entity_1d():
diff --git a/test/unit/python/geometry/test_collision_detection.py b/test/unit/python/geometry/test_collision_detection.py
index 366fa2e..f125292 100755
--- a/test/unit/python/geometry/test_collision_detection.py
+++ b/test/unit/python/geometry/test_collision_detection.py
@@ -1,6 +1,4 @@
-#!/usr/bin/env py.test
-
-"""Unit tests for the CollisionDetection class"""
+"""Unit tests for the CollisionPredicates class"""
 
 # Copyright (C) 2014 Anders Logg and August Johansson
 #
@@ -20,33 +18,32 @@
 # along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 #
 # First added:  2014-02-16
-# Last changed: 2014-05-30
+# Last changed: 2017-09-21
 
 import pytest
 from dolfin import *
-from dolfin_utils.test import skip_in_parallel
+from dolfin_utils.test import skip_in_parallel, skip_if_not_pybind11
 import numpy as np
 
-
 @skip_in_parallel
-def create_triangular_mesh_3D():
+def create_triangular_mesh_3D(vertices, cells):
     editor = MeshEditor()
     mesh = Mesh()
-    editor.open(mesh, 'triangle', 2, 3)
+    editor.open(mesh,"triangle", 2,3)
     editor.init_cells(2)
     editor.init_vertices(4)
-    editor.add_cell(0, np.array([0,1,2], dtype='uint'))
-    editor.add_cell(1, np.array([1,2,3], dtype='uint'))
-    editor.add_vertex(0, np.array([0,0,0.5], dtype='float'))
-    editor.add_vertex(1, np.array([1,0,0.5], dtype='float'))
-    editor.add_vertex(2, np.array([0,1,0.5], dtype='float'))
-    editor.add_vertex(3, np.array([1,1,0.5], dtype='float'))
+    editor.add_cell(0, cells[0])
+    editor.add_cell(1, cells[1])
+
+    editor.add_vertex(0, vertices[0])
+    editor.add_vertex(1, vertices[1])
+    editor.add_vertex(2, vertices[2])
+    editor.add_vertex(3, vertices[3])
     editor.close()
     return mesh;
 
-
 @skip_in_parallel
-def test_inteval_collides_point():
+def test_interval_collides_point():
     """Test if point collide with interval"""
 
     mesh = UnitIntervalMesh(1)
@@ -55,6 +52,71 @@ def test_inteval_collides_point():
     assert cell.collides(Point(0.5)) == True
     assert cell.collides(Point(1.5)) == False
 
+ at skip_in_parallel
+def test_segment_collides_point_2D():
+    """Test if segment collide with point in 2D"""
+    mesh = Mesh()
+    editor = MeshEditor()
+    editor.open(mesh, "interval", 1, 2)
+    editor.init_vertices(2)
+    editor.init_cells(1)
+    a = np.array( (1./8., 1./4.), dtype='float')
+    b = np.array( (2./8., 3./4.), dtype='float')
+    editor.add_vertex(0, a)
+    editor.add_vertex(1, b)
+    editor.add_cell(0, np.array( (0,1), dtype='uint'))
+    editor.close()
+    cell = Cell(mesh, 0)
+    mid = Point(1.5/8., 2./4.)
+    mid_average = (a + b) / 2
+    assert cell.contains(mid)
+    assert cell.contains(Point(a[0], a[1]))
+    assert cell.contains(cell.midpoint())
+
+ at skip_in_parallel
+ at skip_if_not_pybind11
+def test_point_on_segment():
+    a = Point(1e-30, 0)
+    b = Point(1e-3, 0)
+    c = Point(0, 0)
+    d = Point(-1e-30, 0)
+    q0 = Point(1, 0)
+    q1 = Point(0, 0)
+    assert cpp.geometry.CollisionPredicates.collides_segment_point_2d(q0, q1, a)
+    assert cpp.geometry.CollisionPredicates.collides_segment_point_2d(q0, q1, b)
+    assert cpp.geometry.CollisionPredicates.collides_segment_point_2d(q0, q1, c)
+    assert not cpp.geometry.CollisionPredicates.collides_segment_point_2d(q0, q1, d)
+
+ at skip_in_parallel
+ at skip_if_not_pybind11
+def test_point_on_small_segment():
+    a = Point(1e-30, 0)
+    b = Point(0, 0)
+    c = Point(1e-31, 0)
+    d = Point(-1e-30, 0)
+    q0 = Point(0, 0)
+    q1 = Point(1e-30, 0)
+    assert cpp.geometry.CollisionPredicates.collides_segment_point_2d(q0, q1, a)
+    assert cpp.geometry.CollisionPredicates.collides_segment_point_2d(q0, q1, b)
+    assert cpp.geometry.CollisionPredicates.collides_segment_point_2d(q0, q1, c)
+    assert not cpp.geometry.CollisionPredicates.collides_segment_point_2d(q0, q1, d)
+
+ at skip_in_parallel
+def test_segment_collides_point_3D():
+    """Test if segment collide with point in 3D"""
+    mesh = Mesh()
+    editor = MeshEditor()
+    editor.open(mesh, "interval", 1, 3)
+    editor.init_vertices(2)
+    editor.init_cells(1)
+    editor.add_vertex(0, np.array( (1./16., 1./8., 1./4.), dtype='float'))
+    editor.add_vertex(1, np.array( ( 2./16., 3./8., 2./4.), dtype='float'))
+    editor.add_cell(0, np.array( (0,1), dtype='uint') )
+    editor.close()
+    cell = Cell(mesh, 0)
+    mid = Point(1.5/16., 2./8., 1.5/4.)
+    assert cell.contains(mid)
+    assert cell.contains(cell.midpoint())
 
 @skip_in_parallel
 def test_triangle_collides_point():
@@ -66,16 +128,36 @@ def test_triangle_collides_point():
     assert cell.collides(Point(0.5)) == True
     assert cell.collides(Point(1.5)) == False
 
+ at skip_in_parallel
+ at skip_if_not_pybind11
+def test_degenerate_triangle_collides_point():
+    """Test a degenerate triangle that does not collide"""
+
+    p0 = Point(-0.10950608157830554745,0.14049391842169450806)
+    p1 = Point(-0.10950608157830354905,0.14049391842169650646)
+    p2 = Point(0.32853262580480108168,0.57853262580480113719)
+    q = Point(3.5952674716233090635e-06,0.25000359526747162331)
+
+    assert cpp.geometry.CollisionPredicates.collides_triangle_point_2d(p0, p1, p2, q) == False
 
 @skip_in_parallel
 @pytest.mark.xfail(strict=True, raises=RuntimeError)
 def test_quadrilateral_collides_point():
-    """Tests if point collide with triangle"""
+    mesh = UnitSquareMesh.create(1, 1, CellType.Type_quadrilateral)
+    cell = Cell(mesh, 0)
+    assert cell.collides(Point(0.5)) == True
+    assert cell.collides(Point(1.5)) == False
 
-    mesh = UnitQuadMesh.create(1, 1)
+ at skip_in_parallel
+ at pytest.mark.xfail(strict=True, raises=RuntimeError)
+def test_hexahedron_collides_point():
+    """Test if point collide with hexahedron"""
+    mesh = UnitCubeMesh.create(1, 1, 1, CellType.Type_hexahedron)
     cell = Cell(mesh, 0)
 
     assert cell.collides(Point(0.5)) == True
+    # FIXME: cell.collides(Point) returns True for any 1D, 2D Point
+    # cell.collides(Point) returns False if Point[2] != 0
     assert cell.collides(Point(1.5)) == False
 
 
@@ -93,48 +175,87 @@ def test_triangle_collides_triangle():
 
     assert c0.collides(c0) == True
     assert c0.collides(c1) == True
-    # assert c0.collides(c2) == False # touching edges
+    assert c0.collides(c2) == True # touching edges
     assert c1.collides(c0) == True
     assert c1.collides(c1) == True
-    assert c1.collides(c2) == False
-    # assert c2.collides(c0) == False # touching edges
-    assert c2.collides(c1) == False
+    assert c1.collides(c2) == True
+    assert c2.collides(c0) == True # touching edges
+    assert c2.collides(c1) == True
     assert c2.collides(c2) == True
 
 
 @skip_in_parallel
-def test_tetrahedron_collides_point():
-    """Test if point collide with tetrahedron"""
-
-    mesh = UnitCubeMesh(1, 1, 1)
-    cell = Cell(mesh, 0)
+ at skip_if_not_pybind11
+def test_triangle_triangle_collision() :
+    "Test that has been failing"
+    assert cpp.geometry.CollisionPredicates.collides_triangle_triangle_2d(Point(0.177432070718943, 0.5),
+                                                                          Point(0.176638957524249, 0.509972290857582),
+                                                                          Point(0.217189283468892, 0.550522616802225),
+                                                                          Point(0.333333333333333, 0.52399308981973),
+                                                                          Point(0.333333333333333, 0.666666666666667),
+                                                                          Point(0.211774439087554, 0.545107772420888))
 
-    assert cell.collides(Point(0.5)) == True
-    assert cell.collides(Point(1.5)) == False
 
 
 @skip_in_parallel
- at pytest.mark.xfail(strict=True, raises=RuntimeError)
-def test_hexahedron_collides_point():
-    """Test if point collide with hexahedron"""
+def test_triangle_collides_point_3D():
+    """Test if point collide with triangle (inspired by test_manifold_dg0_functions)"""
+    vertices = [ np.array( (0.0, 0.0, 1.0), dtype='float'),
+                 np.array( (1.0, 1.0, 1.0), dtype='float'),
+                 np.array( (1.0, 0.0, 0.0), dtype='float'),
+                 np.array( (0.0, 1.0, 0.0), dtype='float') ]
+    cells = [ np.array( (0, 1, 2), dtype='uint'),
+              np.array( (0, 1, 3), dtype='uint') ]
+    mesh = create_triangular_mesh_3D(vertices, cells)
+    points = [ Point(0.0, 0.0, 1.0),
+               Point(1.0, 1.0, 1.0),
+               Point(1.0, 0.0, 0.0),
+               Point(0.0, 1.0, 0.0),
+               Point(0.25, 0.5, 0.75),
+               Point(0.5, 0.25, 0.75)
+              ]
+    A = Cell(mesh, 0)
+    B = Cell(mesh, 1)
+    assert A.collides(points[0]) == True
+    assert B.collides(points[0]) == True
+    assert A.collides(points[1]) == True
+    assert B.collides(points[1]) == True
+    assert A.collides(points[2]) == True
+    assert B.collides(points[2]) == False
+    assert A.collides(points[3]) == False
+    assert B.collides(points[3]) == True
+    assert A.collides(points[4]) == False
+    assert B.collides(points[4]) == True
+    assert A.collides(points[5]) == True
+    assert B.collides(points[5]) == False
+
+#@pytest.mark.skipif(True, reason="Not implemented in 3D")
+ at skip_in_parallel
+def test_tetrahedron_collides_point():
+    """Test if point collide with tetrahedron"""
 
-    mesh = UnitHexMesh.create(1, 1, 1)
+    mesh = UnitCubeMesh(1, 1, 1)
     cell = Cell(mesh, 0)
 
     assert cell.collides(Point(0.5)) == True
-    # FIXME: cell.collides(Point) returns True for any 1D, 2D Point
-    # cell.collides(Point) returns False if Point[2] != 0
     assert cell.collides(Point(1.5)) == False
 
-
 @skip_in_parallel
+#@pytest.mark.skipif(True, reason="Not implemented in 3D")
 def test_tetrahedron_collides_triangle():
     """Test if point collide with tetrahedron"""
 
     tetmesh = UnitCubeMesh(2, 2, 2)
-    trimesh = create_triangular_mesh_3D()
+    vertices = [ np.array( (0, 0, 0.5), dtype='float'),
+                 np.array( (1, 0, 0.5), dtype='float'),
+                 np.array( (0, 1, 0.5), dtype='float'),
+                 np.array( (1, 1, 0.5), dtype='float')]
+    cells = [ np.array( (0, 1, 2), dtype='uint'),
+              np.array( (1, 2, 3), dtype='uint')]
+
+    trimesh = create_triangular_mesh_3D(vertices, cells)
     dx = Point(0.1, 0.1, -0.1)
-    trimesh_shift = create_triangular_mesh_3D()
+    trimesh_shift = create_triangular_mesh_3D(vertices, cells)
     trimesh_shift.translate(dx)
 
     tet0 = Cell(tetmesh, 18)
@@ -156,8 +277,8 @@ def test_tetrahedron_collides_triangle():
     assert tet1.collides(tri0) == True
     assert tri0.collides(tet1) == True
 
-
 @skip_in_parallel
+#@pytest.mark.skipif(True, reason="Not implemented in 3D")
 def test_tetrahedron_collides_tetrahedron():
     """Test if point collide with tetrahedron"""
 
@@ -192,48 +313,3 @@ def test_tetrahedron_collides_tetrahedron():
     # touching faces
     assert c3.collides(c43) == True
     assert c43.collides(c3) == True
-
-
-def _test_collision_robustness_2d(aspect, y, step):
-    nx = 10
-    ny = int(aspect*nx)
-    mesh = UnitSquareMesh(nx, ny, 'crossed')
-    bb = mesh.bounding_box_tree()
-
-    x = 0.0
-    p = Point(x, y)
-    while x <= 1.0:
-        c = bb.compute_first_entity_collision(Point(x, y))
-        assert c < np.uintc(-1)
-        x += step
-
-def _test_collision_robustness_3d(aspect, y, z, step):
-    nx = nz = 10
-    ny = int(aspect*nx)
-    mesh = UnitCubeMesh(nx, ny, nz)
-    bb = mesh.bounding_box_tree()
-
-    x = 0.0
-    while x <= 1.0:
-        c = bb.compute_first_entity_collision(Point(x, y, z))
-        assert c < np.uintc(-1)
-        x += step
-
- at skip_in_parallel
- at pytest.mark.slow
-def test_collision_robustness_slow():
-    """Test cases from https://bitbucket.org/fenics-project/dolfin/issue/296"""
-    _test_collision_robustness_2d( 100, 1e-14,       1e-5)
-    _test_collision_robustness_2d(  40, 1e-03,       1e-5)
-    _test_collision_robustness_2d( 100, 0.5 + 1e-14, 1e-5)
-    _test_collision_robustness_2d(4.43, 0.5,      4.03e-6)
-    _test_collision_robustness_3d( 100, 1e-14, 1e-14, 1e-5)
-
- at skip_in_parallel
- at pytest.mark.skipif(True, reason='Very slow test cases')
-def test_collision_robustness_very_slow():
-    """Test cases from https://bitbucket.org/fenics-project/dolfin/issue/296"""
-    _test_collision_robustness_2d(  10, 1e-16,       1e-7)
-    _test_collision_robustness_2d(4.43, 1e-17,    4.03e-6)
-    _test_collision_robustness_2d(  40, 0.5,         1e-6)
-    _test_collision_robustness_2d(  10, 0.5 + 1e-16, 1e-7)
diff --git a/test/unit/python/geometry/test_collision_segment_segment.py b/test/unit/python/geometry/test_collision_segment_segment.py
new file mode 100755
index 0000000..97bdf0c
--- /dev/null
+++ b/test/unit/python/geometry/test_collision_segment_segment.py
@@ -0,0 +1,137 @@
+"""Unit tests for the CollisionPredicates class"""
+
+# Copyright (C) 2014 Anders Logg and August Johansson
+  #
+# This file is part of DOLFIN.
+#
+# DOLFIN is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# DOLFIN 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+#
+# First added:  2014-02-16
+# Last changed: 2016-11-22
+
+import pytest
+from dolfin import *
+from dolfin_utils.test import skip_in_parallel, skip_if_not_pybind11
+import numpy as np
+
+ at skip_in_parallel
+def create_mesh(a, b):
+    editor = MeshEditor()
+    mesh = Mesh()
+    editor.open(mesh, "interval", 1, 2)
+    editor.init_cells(1)
+    editor.init_vertices(2)
+    editor.add_cell(0, np.array( (0, 1), dtype='uint') )
+    editor.add_vertex(0, np.array( (a.x(), a.y()), dtype='float'))
+    editor.add_vertex(1, np.array( (b.x(), b.y()), dtype='float'))
+    editor.close()
+    return mesh;
+
+ at skip_in_parallel
+def test_L_version_1():
+    mesh0 = create_mesh(Point(0., 0.), Point(1., 0.))
+    mesh1 = create_mesh(Point(0., 0.), Point(0., 1.))
+    cell0 = Cell(mesh0, 0)
+    cell1 = Cell(mesh1, 0)
+    assert cell0.collides(cell1) == True
+
+ at skip_in_parallel
+def test_L_version_2():
+    # mesh0 = create_mesh(Point(np.finfo(np.float32).eps, 0.), Point(1., 0.))
+    # mesh0 = create_mesh(Point(eps(), 0.), Point(1., 0.))
+    mesh0 = create_mesh(Point(2.23e-15, 0.), Point(1., 0.))
+    mesh1 = create_mesh(Point(0., 0.), Point(0., 1.))
+    # print(mesh0.str(True))
+    # print(mesh1.str(True))
+    cell0 = Cell(mesh0, 0)
+    cell1 = Cell(mesh1, 0)
+    assert cell0.collides(cell1) == False
+
+ at skip_in_parallel
+ at skip_if_not_pybind11
+def test_L_version_3():
+    # mesh0 = create_mesh(Point(np.finfo(np.float32).eps, 0.), Point(1., 0.))
+    # mesh0 = create_mesh(Point(eps(), 0.), Point(1., 0.))
+    a = Point(2.23e-100, 0.) # assume shewchuk works
+    b = Point(1., 0.)
+    c = Point(0., 0.)
+    d = Point(0., 1.)
+
+    assert cpp.geometry.CollisionPredicates.collides_segment_segment_2d(a, b, c, d) == False
+
+ at skip_in_parallel
+def test_aligned_version_1():
+    mesh0 = create_mesh(Point(0,0), Point(1,0))
+    mesh1 = create_mesh(Point(1,0), Point(2,0))
+    cell0 = Cell(mesh0, 0)
+    cell1 = Cell(mesh1, 0)
+    assert cell0.collides(cell1) == True
+
+ at skip_in_parallel
+def test_aligned_version_2():
+    mesh0 = create_mesh(Point(0,0), Point(1,0))
+    mesh1 = create_mesh(Point(2,0), Point(3,0))
+    cell0 = Cell(mesh0, 0)
+    cell1 = Cell(mesh1, 0)
+    assert cell0.collides(cell1) == False
+
+ at skip_in_parallel
+def test_collinear_1():
+    p0 = Point(0.05, 0.15)
+    p1 = Point(0.85, 0.95)
+    q0 = Point(0.2875, 0.3875)
+    q1 = Point(0.6125, 0.7125)
+    meshp = create_mesh(p0, p1)
+    meshq = create_mesh(q0, q1)
+    cellp = Cell(meshp, 0)
+    cellq = Cell(meshq, 0)
+    assert cellp.collides(cellq) == True
+
+ at skip_in_parallel
+ at skip_if_not_pybind11
+def test_collinear_2():
+    res = cpp.geometry.CollisionPredicates.collides_segment_segment_2d(Point(.5, .3),
+                                                                       Point(.5, .4),
+                                                                       Point(.5, .5),
+                                                                       Point(.5, .6))
+    assert not res
+
+ at skip_in_parallel
+ at skip_if_not_pybind11
+def test_segment_segment_2d():
+    # p0 is on segment q0-q1
+    p0 = Point(1e-30, 0)
+    p1 = Point(1, 2)
+    p2 = Point(2, 1)
+    q0 = Point(1, 0)
+    q1 = Point(0, 0)
+    assert cpp.geometry.CollisionPredicates.collides_segment_segment_2d(p0, p1, q0, q1)
+    assert cpp.geometry.CollisionPredicates.collides_segment_segment_2d(p1, p0, q0, q1)
+    assert cpp.geometry.CollisionPredicates.collides_segment_segment_2d(p0, p1, q1, q0)
+    assert cpp.geometry.CollisionPredicates.collides_segment_segment_2d(p1, p0, q1, q0)
+
+    assert cpp.geometry.CollisionPredicates.collides_segment_segment_2d(p0, p2, q0, q1)
+    assert cpp.geometry.CollisionPredicates.collides_segment_segment_2d(p2, p0, q0, q1)
+    assert cpp.geometry.CollisionPredicates.collides_segment_segment_2d(p0, p2, q1, q0)
+    assert cpp.geometry.CollisionPredicates.collides_segment_segment_2d(p2, p0, q1, q0)
+
+    assert cpp.geometry.CollisionPredicates.collides_segment_segment_2d(p0, p1, q1, q0)
+    assert cpp.geometry.CollisionPredicates.collides_segment_segment_2d(p1, p0, q1, q0)
+    assert cpp.geometry.CollisionPredicates.collides_segment_segment_2d(p0, p1, q0, q1)
+    assert cpp.geometry.CollisionPredicates.collides_segment_segment_2d(p1, p0, q0, q1)
+
+    assert cpp.geometry.CollisionPredicates.collides_segment_segment_2d(p0, p2, q1, q0)
+    assert cpp.geometry.CollisionPredicates.collides_segment_segment_2d(p2, p0, q1, q0)
+    assert cpp.geometry.CollisionPredicates.collides_segment_segment_2d(p0, p2, q0, q1)
+    assert cpp.geometry.CollisionPredicates.collides_segment_segment_2d(p2, p0, q0, q1)
diff --git a/test/unit/python/geometry/test_coordinates.py b/test/unit/python/geometry/test_coordinates.py
index 73f4b63..2be99d7 100755
--- a/test/unit/python/geometry/test_coordinates.py
+++ b/test/unit/python/geometry/test_coordinates.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for coordinates interface"""
 
 # Copyright (C) 2016 Jan Blechta
diff --git a/test/unit/python/geometry/test_geometry_issues.py b/test/unit/python/geometry/test_geometry_issues.py
new file mode 100755
index 0000000..4697403
--- /dev/null
+++ b/test/unit/python/geometry/test_geometry_issues.py
@@ -0,0 +1,163 @@
+"""Unit tests for intersection computation"""
+
+# Copyright (C) 2013 Anders Logg
+#
+# This file is part of DOLFIN.
+#
+# DOLFIN is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# DOLFIN 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+#
+# First added:  2013-12-09
+# Last changed: 2017-02-16
+
+from __future__ import print_function
+import pytest
+
+from dolfin import *
+from dolfin_utils.test import skip_in_parallel
+import numpy as np
+
+ at skip_in_parallel
+def test_issue_97():
+    "Test from Mikael Mortensen (issue #97)"
+
+    N = 2
+    L = 1000
+    mesh = BoxMesh(Point(0, 0, 0), Point(L, L, L), N, N, N)
+    V = FunctionSpace(mesh, 'CG', 1)
+    v = interpolate(Expression('x[0]', degree=1), V)
+    x = Point(0.5*L, 0.5*L, 0.5*L)
+    vx = v(x)
+
+ at skip_in_parallel
+def test_issue_168():
+    "Test from Torsten Wendav (issue #168)"
+
+    mesh = UnitCubeMesh(14, 14, 14)
+    V = FunctionSpace(mesh, "Lagrange", 1)
+    v = Function(V)
+    x = (0.75, 0.25, 0.125)
+    vx = v(x)
+
+
+ at pytest.mark.skipif(True, reason="Since cell.contains(point) is doing an exact calculation, we cannot assume that the midpoint is exactly in the cell")
+ at skip_in_parallel
+def test_segment_collides_point_3D_2():
+    """Test case by Oyvind from https://bitbucket.org/fenics-project/dolfin/issue/296 for segment point collision in 3D"""
+    mesh = Mesh()
+    editor = MeshEditor()
+    editor.open(mesh, 1, 3)
+    editor.init_vertices(2)
+    editor.init_cells(1)
+    editor.add_vertex(0, np.array( (41.06309891, 63.74219894, 68.10320282), dtype='float') )
+    editor.add_vertex(1, np.array( (41.45830154, 62.61560059, 66.43019867), dtype='float') )
+    editor.add_cell(0, np.array( (0,1), dtype='uint'))
+    editor.close()
+    cell = Cell(mesh, 0)
+    assert cell.contains(cell.midpoint())
+
+
+def _test_collision_robustness_2d(aspect, y, step):
+    nx = 10
+    ny = int(aspect*nx)
+    mesh = UnitSquareMesh(nx, ny, 'crossed')
+    bb = mesh.bounding_box_tree()
+
+    x = 0.0
+    p = Point(x, y)
+    while x <= 1.0:
+        c = bb.compute_first_entity_collision(Point(x, y))
+        assert c < np.uintc(-1)
+        x += step
+
+#@pytest.mark.skipif(True, reason="Not implemented in 3D")
+ at skip_in_parallel
+def _test_collision_robustness_3d(aspect, y, z, step):
+    nx = nz = 10
+    ny = int(aspect*nx)
+    mesh = UnitCubeMesh(nx, ny, nz)
+    bb = mesh.bounding_box_tree()
+
+    x = 0.0
+    while x <= 1.0:
+        c = bb.compute_first_entity_collision(Point(x, y, z))
+        assert c < np.uintc(-1)
+        x += step
+
+ at skip_in_parallel
+ at pytest.mark.slow
+def test_collision_robustness_slow():
+    """Test cases from https://bitbucket.org/fenics-project/dolfin/issue/296"""
+    _test_collision_robustness_2d( 100, 1e-14,       1e-5)
+    _test_collision_robustness_2d(  40, 1e-03,       1e-5)
+    _test_collision_robustness_2d( 100, 0.5 + 1e-14, 1e-5)
+    _test_collision_robustness_2d(4.43, 0.5,      4.03e-6)
+    _test_collision_robustness_3d( 100, 1e-14, 1e-14, 1e-5)
+
+ at skip_in_parallel
+ at pytest.mark.slow
+ at pytest.mark.skipif(True, reason='Very slow test cases')
+def test_collision_robustness_very_slow():
+    """Test cases from https://bitbucket.org/fenics-project/dolfin/issue/296"""
+    _test_collision_robustness_2d(  10, 1e-16,       1e-7)
+    _test_collision_robustness_2d(4.43, 1e-17,    4.03e-6)
+    _test_collision_robustness_2d(  40, 0.5,         1e-6)
+    _test_collision_robustness_2d(  10, 0.5 + 1e-16, 1e-7)
+
+ at skip_in_parallel
+def test_points_on_line():
+    """Test case from https://bitbucket.org/fenics-project/dolfin/issues/790"""
+    big = 1e6
+    p1 = np.array((0.1, 0.06), dtype='float')
+    p3 = np.array((big*2.1, big*0.1), dtype='float')
+    p2 = np.array((0.0, big*3.0), dtype='float')
+    p0 = np.array((big*3.0, 0.0), dtype='float')
+
+    mesh = Mesh()
+    ed = MeshEditor()
+    ed.open(mesh, "triangle", 2, 2)
+    ed.init_cells(3)
+    ed.init_vertices(4)
+    ed.add_vertex(0, p0)
+    ed.add_vertex(1, p1)
+    ed.add_vertex(2, p2)
+    ed.add_vertex(3, p3)
+    ed.add_cell(0, np.array( (2, 3, 0), dtype='uint'))
+    ed.add_cell(1, np.array( (0, 1, 3 ), dtype='uint'))
+    ed.add_cell(2, np.array( (1, 2, 3 ), dtype='uint'))
+    ed.close()
+
+    # xdmf = XDMFFile("a.xdmf")
+    # xdmf.write(mesh)
+
+    # print mesh.cells()
+    # print mesh.coordinates()
+
+    bb = mesh.bounding_box_tree()
+
+    # Find a point on line somewhere between p3 and p1
+    j = 4
+    pq = (p3*j + p1*(50-j))/50.0
+    c = bb.compute_entity_collisions(Point(pq[0], pq[1]))
+    # print pq.str(), c
+
+    # Check that the neighbouring points are in the correct cells
+    cell_numbers = [1, 2, 2, 1, 1, 2, 1, 1, 2]
+    step = 1e-6
+    cnt = 0
+    for i in range(-1, 2):
+        for j in range(-1, 2):
+            pt = Point(pq[0], pq[1]) + Point(step*i, step*j)
+            c = bb.compute_entity_collisions(pt)
+            assert c[0] == cell_numbers[cnt]
+            cnt += 1
diff --git a/test/unit/python/geometry/test_intersection.py b/test/unit/python/geometry/test_intersection.py
index 13ab034..e83f027 100755
--- a/test/unit/python/geometry/test_intersection.py
+++ b/test/unit/python/geometry/test_intersection.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for intersection computation"""
 
 # Copyright (C) 2013-2014 Anders Logg
@@ -23,7 +21,7 @@ from __future__ import print_function
 import pytest
 
 from dolfin import intersect
-from dolfin import UnitIntervalMesh, UnitSquareMesh, UnitCubeMesh, BoxMesh, UnitQuadMesh, UnitHexMesh
+from dolfin import (UnitIntervalMesh, UnitSquareMesh, UnitCubeMesh, BoxMesh, CellType)
 from dolfin import Point, FunctionSpace, Expression, interpolate
 from dolfin import MPI, mpi_comm_world
 
@@ -68,7 +66,7 @@ def test_mesh_point_2d_quadrilateral():
     "Test mesh-point intersection in 2D for quadrilateral mesh"
 
     point = Point(0.1, 0.2)
-    mesh = UnitQuadMesh.create(16, 16)
+    mesh = UnitSquareMesh.create(16, 16, CellType.Type_quadrilateral)
 
     intersection = intersect(mesh, point)
 
@@ -80,7 +78,7 @@ def test_mesh_point_3d_hexahedron():
     "Test mesh-point intersection in 3D for hexahedral mesh"
 
     point = Point(0.1, 0.2, 0.3)
-    mesh = UnitHexMesh.create(8, 8, 8)
+    mesh = UnitCubeMesh.create(8, 8, 8, CellType.Type_hexahedron)
 
     intersection = intersect(mesh, point)
 
diff --git a/test/unit/python/geometry/test_intersection_construction.py b/test/unit/python/geometry/test_intersection_construction.py
new file mode 100755
index 0000000..6fd27be
--- /dev/null
+++ b/test/unit/python/geometry/test_intersection_construction.py
@@ -0,0 +1,323 @@
+"""Unit tests for the IntersectionConstruction class"""
+
+# Copyright (C) 2014 Anders Logg and August Johansson
+#
+# This file is part of DOLFIN.
+#
+# DOLFIN is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# DOLFIN 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+
+import pytest
+import numpy as np
+from dolfin import *
+from six.moves import xrange as range
+from dolfin_utils.test import skip_in_parallel, skip_if_not_pybind11
+
+def triangulation_to_mesh_2d(triangulation):
+    editor = MeshEditor()
+    mesh = Mesh()
+    editor.open(mesh, 2, 2)
+    num_cells = len(triangulation) // 6
+    num_vertices = len(triangulation) // 2
+    editor.init_cells(num_cells)
+    editor.init_vertices(num_vertices)
+    for i in range(num_cells):
+        editor.add_cell(i, np.array( (3*i, 3*i + 1, 3*i + 2), dtype='uint') )
+    for i in range(num_vertices):
+        editor.add_vertex(i, np.array( (triangulation[2*i], triangulation[2*i + 1]), dtype='float'))
+    editor.close()
+    return mesh
+
+def triangulation_to_mesh_2d_3d(triangulation):
+    editor = MeshEditor()
+    mesh = Mesh()
+    editor.open(mesh,2,3)
+    num_cells = len(triangulation) // 9
+    num_vertices = len(triangulation) // 3
+    editor.init_cells(num_cells)
+    editor.init_vertices(num_vertices)
+    for i in range(num_cells):
+        editor.add_cell(i, np.array( (3*i, 3*i+1, 3*i+2), dtype='uint'))
+    for i in range(num_vertices):
+        editor.add_vertex(i, np.array( (triangulation[3*i], triangulation[3*i+1], triangulation[3*i+2]), dtype='float') )
+    editor.close()
+    return mesh
+
+def triangulation_to_mesh_3d(triangulation):
+    editor = MeshEditor()
+    mesh = Mesh()
+    editor.open(mesh,3,3)
+    num_cells = len(triangulation) // 12
+    num_vertices = len(triangulation) // 3
+    editor.init_cells(num_cells)
+    editor.init_vertices(num_vertices)
+    for i in range(num_cells):
+        editor.add_cell(i, np.array( (4*i, 4*i+1, 4*i+2, 4*i+3), dtype='uint'))
+    for i in range(num_vertices):
+        editor.add_vertex(i, np.array( (triangulation[3*i], triangulation[3*i+1], triangulation[3*i+2]), dtype='float'))
+    editor.close()
+    return mesh
+
+ at skip_in_parallel
+ at pytest.mark.skipif(True, reason="Missing swig typemap")
+def test_triangulate_intersection_2d():
+
+    # Create two meshes of the unit square
+    mesh_0 = UnitSquareMesh(1, 1)
+    mesh_1 = UnitSquareMesh(1, 1)
+
+    # Translate second mesh randomly
+    #dx = Point(np.random.rand(),np.random.rand())
+    dx = Point(0.278498, 0.546881)
+    mesh_1.translate(dx)
+
+    # Exact volume of intersection
+    exactvolume = (1 - abs(dx[0]))*(1 - abs(dx[1]))
+
+    # Compute triangulation volume
+    volume = 0
+    for c0 in cells(mesh_0):
+        for c1 in cells(mesh_1):
+            intersection = c0.intersection(c1)
+            if len(intersection) >= 3 :
+                triangulation = cpp.geometry.ConvexTriangulation.triangulate(intersection, 2, 2)
+                tmesh = triangulation_to_mesh_2d(triangulation)
+                for t in cells(tmesh):
+                    volume += t.volume()
+
+    errorstring = "translation=" + str(dx[0]) + str(" ") + str(dx[1])
+    assert round(volume - exactvolume, 7) == 0, errorstring
+
+ at skip_in_parallel
+ at pytest.mark.skipif(True, reason="Not implemented in 3D")
+def test_triangulate_intersection_2d_3d():
+
+    # Note: this test will fail if the triangle mesh is aligned
+    # with the tetrahedron mesh
+
+    # Create a unit cube
+    mesh_0 = UnitCubeMesh(1,1,1)
+
+    # Create a 3D surface mesh
+    editor = MeshEditor()
+    mesh_1 = Mesh()
+    editor.open(mesh_1,2,3)
+    editor.init_cells(2)
+    editor.init_vertices(4)
+
+    # Add cells
+    editor.add_cell(0, np.array( (0,1,2), dtype='uint'))
+    editor.add_cell(1, np.array( (1,2,3), dtype='uint'))
+
+    # Add vertices
+    editor.add_vertex(0, np.array( (0, 0, 0.5), dtype='float'))
+    editor.add_vertex(1, np.array( (1, 0, 0.5), dtype='float'))
+    editor.add_vertex(2, np.array( (0, 1, 0.5), dtype='float'))
+    editor.add_vertex(3, np.array( (1, 1, 0.5), dtype='float'))
+    editor.close()
+
+    # Rotate the triangle mesh around y axis
+    angle = 23.46354
+    mesh_1.rotate(angle,1)
+
+    # Exact area
+    exact_volume = 1
+
+    # Compute triangulation
+    volume = 0
+    for c0 in cells(mesh_0):
+        for c1 in cells(mesh_1):
+            intersection = c0.intersection(c1)
+            triangulation = cpp.geometry.ConvexTriangulation.triangulate(intersection, 3, 2)
+            if (triangulation.size>0):
+                tmesh = triangulation_to_mesh_2d_3d(triangulation)
+                for t in cells(tmesh):
+                    volume += t.volume()
+
+    errorstring = "rotation angle = " + str(angle)
+    assert round(volume - exact_volume, 7) == 0, errorstring
+
+ at skip_in_parallel
+ at pytest.mark.skipif(True, reason="Missing swig typemap for call to ConvexTriangulation")
+def test_triangulate_intersection_3d():
+
+    # Create two meshes of the unit cube
+    mesh_0 = UnitCubeMesh(1, 1, 1)
+    mesh_1 = UnitCubeMesh(1, 1, 1)
+
+    # Translate second mesh
+    # dx = Point(np.random.rand(),np.random.rand(),np.random.rand())
+    dx = Point(0.913375, 0.632359, 0.097540)
+
+    mesh_1.translate(dx)
+    exactvolume = (1 - abs(dx[0]))*(1 - abs(dx[1]))*(1 - abs(dx[2]))
+
+    # Compute triangulation
+    volume = 0
+    for c0 in cells(mesh_0):
+        for c1 in cells(mesh_1):
+            intersection = c0.intersection(c1)
+            triangulation = cpp.geometry.ConvexTriangulation.triangulate(intersection, 3, 3)
+            if (triangulation.size>0):
+                tmesh = triangulation_to_mesh_3d(triangulation)
+                for t in cells(tmesh):
+                    volume += t.volume()
+
+    errorstring = "translation="
+    errorstring += str(dx[0])+" "+str(dx[1])+" "+str(dx[2])
+    assert round(volume - exactvolume, 7) == 0, errorstring
+
+ at skip_if_not_pybind11
+def test_triangle_triangle_2d_trivial() :
+    " These two triangles intersect in a common edge"
+    res = cpp.geometry.IntersectionConstruction.intersection_triangle_triangle_2d(Point(0.0, 0.0),
+	                                                                          Point(1.0, 0.0),
+							                          Point(0.5, 1.0),
+							                          Point(0.5, 0.5),
+							                          Point(1.0, 1.5),
+							                          Point(0.0, 1.5))
+    assert len(res) == 4
+
+ at skip_if_not_pybind11
+def test_triangle_triangle_2d() :
+    " These two triangles intersect in a common edge"
+    res = cpp.geometry.IntersectionConstruction.intersection_triangle_triangle_2d(Point(0.4960412972015322, 0.3953317542541379),
+	                                                                          Point(0.5, 0.3997044273055517),
+							                          Point(0.5, 0.4060889538943557),
+							                          Point(0.4960412972015322, 0.3953317542541379),
+							                          Point(0.5, 0.4060889538943557),
+                                                                                  Point(.5, .5))
+    for p in res:
+        print(p[0], p[1])
+
+    assert len(res) == 2
+
+ at skip_in_parallel
+ at skip_if_not_pybind11
+def test_parallel_segments_2d():
+    " These two segments should be parallel and the intersection computed accordingly"
+    p0 = Point(0, 0)
+    p1 = Point(1, 0)
+    q0 = Point(0.4, 0)
+    q1 = Point(1.4, 0)
+    intersection = cpp.geometry.IntersectionConstruction.intersection_segment_segment_2d(p0, p1, q0, q1)
+    assert len(intersection) == 2
+
+ at skip_if_not_pybind11
+def test_equal_segments_2d():
+    " These two segments are equal and the intersection computed accordingly"
+    p0 = Point(DOLFIN_PI / 7., 9. / DOLFIN_PI)
+    p1 = Point(9. / DOLFIN_PI, DOLFIN_PI / 7.)
+    q0 = Point(DOLFIN_PI / 7., 9. / DOLFIN_PI)
+    q1 = Point(9. / DOLFIN_PI, DOLFIN_PI / 7.)
+    intersection = cpp.geometry.IntersectionConstruction.intersection_segment_segment_2d(p0, p1, q0, q1)
+    assert len(intersection) == 2
+
+ at skip_in_parallel
+ at skip_if_not_pybind11
+def test_triangle_segment_2D_1():
+    "The intersection of a specific triangle and a specific segment"
+    p0 = Point(1e-30, 0)
+    p1 = Point(1, 2)
+    p2 = Point(2, 1)
+    q0 = Point(1, 0)
+    q1 = Point(0, 0)
+    intersection = cpp.geometry.IntersectionConstruction.intersection_triangle_segment_2d(p0, p1, p2, q0, q1)
+    assert len(intersection) == 1
+    intersection = cpp.geometry.IntersectionConstruction.intersection_triangle_segment_2d(p0, p1, p2, q1, q0)
+    assert len(intersection) == 1
+
+def compare_with_cgal(p0, p1, q0, q1, cgal):
+    intersection = cpp.geometry.IntersectionConstruction.intersection_segment_segment_2d(p0, p1, q0, q1)
+
+    #for p in intersection:
+    #    print(*p)
+
+    return abs(intersection[0][0] - cgal[0]) < DOLFIN_EPS and \
+           abs(intersection[0][1] - cgal[1]) < DOLFIN_EPS
+
+ at skip_in_parallel
+ at pytest.mark.skipif(True, reason="This is a case where the intersection currently fails")
+def test_segment_segment_1():
+    "Case that fails CGAL comparison. We get a different intersection point but still correct area."
+    p0 = Point(-0.50000000000000710543,-0.50000000000000710543)
+    p1 = Point(0.99999999999999955591,-2)
+    q0 = Point(0.9142135623730932581,-1.9142135623730944793)
+    q1 = Point(-0.29289321881346941367,-0.70710678118654635149)
+
+    # The intersection should according to CGAL be
+    cgal = Point(0.91066799144849319703, -1.9106679914484945293)
+
+    assert compare_with_cgal(p0, p1, q0, q1, cgal)
+
+ at skip_in_parallel
+ at pytest.mark.skipif(True, reason="This is a case where the intersection currently fails")
+def test_segment_segment_2():
+    "Case that fails CGAL comparison. We get a different intersection point but still correct area."
+    p0 = Point(0.70710678118654746172,-0.70710678118654746172)
+    p1 = Point(0.70710678118654612945,0.70710678118654612945)
+    q0 = Point(0.70710678118654612945,0.70710678118654113344)
+    q1 = Point(0.70710678118654657354,0.2928932188134645842)
+    cgal = Point(0.70710678118654612945, 0.7071067811865050512)
+    assert compare_with_cgal(p0, p1, q0, q1, cgal)
+
+
+ at skip_in_parallel
+ at skip_if_not_pybind11
+#@pytest.mark.skipif(True, reason="This test needs to be updated")
+def test_segment_segment_3():
+    "Case that fails CGAL comparison. We get a different intersection point but still correct area."
+    p0 = Point(0.70710678118654746172,-0.70710678118654746172)
+    p1 = Point(0.70710678118654612945,0.70710678118654612945)
+    q0 = Point(0.70710678118654757274,-0.097631072937819973756)
+    q1 = Point(0.70710678118654257673,-0.1601886205085209236)
+    cgal = Point(0.70710678118654679558, -0.10611057050352221132)
+    assert compare_with_cgal(p0, p1, q0, q1, cgal)
+
+
+ at skip_in_parallel
+ at pytest.mark.skipif(True, reason="This is a case where the intersection currently fails")
+def test_segment_segment_4():
+    "Case that fails CGAL comparison. We get a different intersection point but still correct area."
+    p0 = Point(0.70710678118654746172,-0.70710678118654746172)
+    p1 = Point(3.5527136788005009294e-14,3.5527136788005009294e-14)
+    q0 = Point(0.35355339059326984508,-0.35355339059327078877)
+    q1 = Point(0.70710678118655057034,-0.70710678118654701763)
+    cgal = Point(0.67572340116162599166, -0.67572340116162288304)
+    assert compare_with_cgal(p0, p1, q0, q1, cgal)
+
+
+ at skip_in_parallel
+ at skip_if_not_pybind11
+def test_segment_segment_5():
+    "Case that failed CGAL comparison but passed when scaling the numerator in x = p0 + o / d * v"
+    p0 = Point(1.1429047494274684563e-12,0.5)
+    p1 = Point(0.42146018366139809119,0.9214601836602551721)
+    q0 = Point(0.34292036732279607136,0.8429203673205103442)
+    q1 = Point(0.3429203673205103442,0.8429203673205103442)
+    cgal = Point(0.3429203673216533188,0.8429203673205103442)
+    assert compare_with_cgal(p0, p1, q0, q1, cgal)
+
+
+ at skip_in_parallel
+ at skip_if_not_pybind11
+def test_segment_segment_6():
+    "Test that demonstrates, among other things, that we must check the orientation for p0, p1 in intersection_segment_segment_2d"
+    p0 = Point(0.045342566799435518599,0.41358248517265505662);
+    p1 = Point(0.045342566799434436131,0.41358248517265394639);
+    q0 = Point(1.8601965322712701917e-16,0.5);
+    q1 = Point(1.873501354054951662e-16,0.3499999999999999778);
+
+    intersection = cpp.geometry.IntersectionConstruction.intersection_segment_segment_2d(p0, p1, q0, q1)
+
+    assert len(intersection) == 0
diff --git a/test/unit/python/geometry/test_intersection_triangulation.py b/test/unit/python/geometry/test_intersection_triangulation.py
deleted file mode 100755
index 2471cac..0000000
--- a/test/unit/python/geometry/test_intersection_triangulation.py
+++ /dev/null
@@ -1,174 +0,0 @@
-#!/usr/bin/env py.test
-
-"""Unit tests for the IntersectionTriangulation class"""
-
-# Copyright (C) 2014 Anders Logg and August Johansson
-#
-# This file is part of DOLFIN.
-#
-# DOLFIN is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# DOLFIN 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
-
-import pytest
-import numpy
-from dolfin import *
-from six.moves import xrange as range
-from dolfin_utils.test import skip_in_parallel
-
-def triangulation_to_mesh_2d(triangulation):
-    editor = MeshEditor()
-    mesh = Mesh()
-    editor.open(mesh, 'triangle', 2, 2)
-    num_cells = len(triangulation) // 6
-    num_vertices = len(triangulation) // 2
-    editor.init_cells(num_cells)
-    editor.init_vertices(num_vertices)
-    for i in range(num_cells):
-        editor.add_cell(i, numpy.array([3*i, 3*i + 1, 3*i + 2], dtype='uint'))
-    for i in range(num_vertices):
-        editor.add_vertex(i, numpy.array([triangulation[2*i], triangulation[2*i + 1]], dtype='float'))
-    editor.close()
-    return mesh
-
-def triangulation_to_mesh_2d_3d(triangulation):
-    editor = MeshEditor()
-    mesh = Mesh()
-    editor.open(mesh, 'triangle', 2,3)
-    num_cells = len(triangulation) // 9
-    num_vertices = len(triangulation) // 3
-    editor.init_cells(num_cells)
-    editor.init_vertices(num_vertices)
-    for i in range(num_cells):
-        editor.add_cell(i, numpy.array([3*i, 3*i+1, 3*i+2], dtype='uint'))
-    for i in range(num_vertices):
-        editor.add_vertex(i, numpy.array([triangulation[3*i], triangulation[3*i+1], triangulation[3*i+2]], dtype='float'))
-    editor.close()
-    return mesh
-
-def triangulation_to_mesh_3d(triangulation):
-    editor = MeshEditor()
-    mesh = Mesh()
-    editor.open(mesh, 'tetrahedron', 3, 3)
-    num_cells = len(triangulation) // 12
-    num_vertices = len(triangulation) // 3
-    editor.init_cells(num_cells)
-    editor.init_vertices(num_vertices)
-    for i in range(num_cells):
-        editor.add_cell(i, numpy.array([4*i, 4*i+1, 4*i+2, 4*i+3], dtype='uint'))
-    for i in range(num_vertices):
-        editor.add_vertex(i, numpy.array([triangulation[3*i], triangulation[3*i+1], triangulation[3*i+2]], dtype='float'))
-    editor.close()
-    return mesh
-
- at skip_in_parallel
-def test_triangulate_intersection_2d():
-
-    # Create two meshes of the unit square
-    mesh_0 = UnitSquareMesh(1, 1)
-    mesh_1 = UnitSquareMesh(1, 1)
-
-    # Translate second mesh randomly
-    #dx = Point(numpy.random.rand(),numpy.random.rand())
-    dx = Point(0.278498, 0.546881)
-    mesh_1.translate(dx)
-
-    exactvolume = (1 - abs(dx[0]))*(1 - abs(dx[1]))
-
-    # Compute triangulation
-    volume = 0
-    for c0 in cells(mesh_0):
-        for c1 in cells(mesh_1):
-            triangulation = c0.triangulate_intersection(c1)
-            if (len(triangulation) > 0):
-                tmesh = triangulation_to_mesh_2d(triangulation)
-                for t in cells(tmesh):
-                    volume += t.volume()
-
-    errorstring = "translation=" + str(dx[0]) + str(" ") + str(dx[1])
-    assert round(volume - exactvolume, 7) == 0, errorstring
-
- at skip_in_parallel
-def test_triangulate_intersection_2d_3d():
-
-    # Note: this test will fail if the triangle mesh is aligned
-    # with the tetrahedron mesh
-
-    # Create a unit cube
-    mesh_0 = UnitCubeMesh(1,1,1)
-
-    # Create a 3D surface mesh
-    editor = MeshEditor()
-    mesh_1 = Mesh()
-    editor.open(mesh_1, 'triangle', 2, 3)
-    editor.init_cells(2)
-    editor.init_vertices(4)
-    # add cells
-    editor.add_cell(0, numpy.array([0,1,2], dtype='uint'))
-    editor.add_cell(1, numpy.array([1,2,3], dtype='uint'))
-    # add vertices
-    editor.add_vertex(0, numpy.array([0,0,0.5], dtype='float'))
-    editor.add_vertex(1, numpy.array([1,0,0.5], dtype='float'))
-    editor.add_vertex(2, numpy.array([0,1,0.5], dtype='float'))
-    editor.add_vertex(3, numpy.array([1,1,0.5], dtype='float'))
-    editor.close()
-
-    # Rotate the triangle mesh around y axis a random angle in
-    # (0,90) degrees
-    #angle = numpy.random.rand()*90
-    angle = 23.46354
-    mesh_1.rotate(angle,1)
-
-    # Exact area
-    exactvolume = 1
-
-    # Compute triangulation
-    volume = 0
-    for c0 in cells(mesh_0):
-        for c1 in cells(mesh_1):
-            triangulation = c0.triangulate_intersection(c1)
-            if (len(triangulation) > 0):
-                tmesh = triangulation_to_mesh_2d_3d(triangulation)
-                for t in cells(tmesh):
-                    volume += t.volume()
-
-    errorstring = "rotation angle = " + str(angle)
-    assert round(volume - exactvolume, 7) == 0, errorstring
-
-
- at skip_in_parallel
-def test_triangulate_intersection_3d():
-
-    # Create two meshes of the unit cube
-    mesh_0 = UnitCubeMesh(1, 1, 1)
-    mesh_1 = UnitCubeMesh(1, 1, 1)
-
-    # Translate second mesh
-    # dx = Point(numpy.random.rand(),numpy.random.rand(),numpy.random.rand())
-    dx = Point(0.913375, 0.632359, 0.097540)
-
-    mesh_1.translate(dx)
-    exactvolume = (1 - abs(dx[0]))*(1 - abs(dx[1]))*(1 - abs(dx[2]))
-
-    # Compute triangulation
-    volume = 0
-    for c0 in cells(mesh_0):
-        for c1 in cells(mesh_1):
-            triangulation = c0.triangulate_intersection(c1)
-            if (len(triangulation) > 0):
-                tmesh = triangulation_to_mesh_3d(triangulation)
-                for t in cells(tmesh):
-                    volume += t.volume()
-
-    errorstring = "translation="
-    errorstring += str(dx[0])+" "+str(dx[1])+" "+str(dx[2])
-    assert round(volume - exactvolume, 7) == 0, errorstring
diff --git a/test/unit/python/geometry/test_point.py b/test/unit/python/geometry/test_point.py
index bdda9c5..3c43a51 100644
--- a/test/unit/python/geometry/test_point.py
+++ b/test/unit/python/geometry/test_point.py
@@ -22,7 +22,7 @@ import pytest
 import numpy as np
 from dolfin_utils.test import skip_if_pybind11
 
-from dolfin import Point
+from dolfin import *
 
 
 def test_point_getitem():
@@ -69,7 +69,6 @@ def test_point_setitem():
     assert np.all(p[:] == (2, 4, 6))
 
 
- at skip_if_pybind11
 def test_point_array():
     p = Point(1, 2, 3)
     assert np.all(p.array() == (1, 2, 3))
@@ -77,3 +76,11 @@ def test_point_array():
     # Point.array() is a copy, no in-place modification
     p.array()[:] += 1000.0
     assert np.all(p.array() == (1, 2, 3))
+
+
+def test_point_equality():
+    p = Point(1.23, 2, DOLFIN_PI)
+    q = Point(1.23, 2, DOLFIN_PI)
+    r = Point(1.23+DOLFIN_EPS, 2, DOLFIN_PI)
+    assert p == q
+    assert p != r
diff --git a/test/unit/python/graph/test_graph_build.py b/test/unit/python/graph/test_graph_build.py
index 12b124d..d66bf5f 100755
--- a/test/unit/python/graph/test_graph_build.py
+++ b/test/unit/python/graph/test_graph_build.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for graph building"""
 
 # Copyright (C) 2013 Garth N. Wells
diff --git a/test/unit/python/io/test_HDF5.py b/test/unit/python/io/test_HDF5.py
index ca16059..55d4fde 100755
--- a/test/unit/python/io/test_HDF5.py
+++ b/test/unit/python/io/test_HDF5.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the HDF5 io library"""
 
 # Copyright (C) 2012 Garth N. Wells
@@ -194,7 +192,7 @@ def test_save_and_read_function(tempdir):
     hdf5_file = HDF5File(mesh.mpi_comm(), filename, "r")
     hdf5_file.read(F1, "/function")
     result = F0.vector() - F1.vector()
-    assert len(result.array().nonzero()[0]) == 0
+    assert len(result.get_local().nonzero()[0]) == 0
     hdf5_file.close()
 
 @skip_if_not_HDF5
@@ -214,9 +212,9 @@ def test_save_and_read_mesh_2D(tempdir):
     mesh_file.read(mesh1, "/my_mesh", False)
     mesh_file.close()
 
-    assert mesh0.size_global(0) == mesh1.size_global(0)
+    assert mesh0.num_entities_global(0) == mesh1.num_entities_global(0)
     dim = mesh0.topology().dim()
-    assert mesh0.size_global(dim) == mesh1.size_global(dim)
+    assert mesh0.num_entities_global(dim) == mesh1.num_entities_global(dim)
 
 @skip_if_not_HDF5
 @xfail_with_serial_hdf5_in_parallel
@@ -235,9 +233,9 @@ def test_save_and_read_mesh_3D(tempdir):
     mesh_file.read(mesh1, "/my_mesh", False)
     mesh_file.close()
 
-    assert mesh0.size_global(0) == mesh1.size_global(0)
+    assert mesh0.num_entities_global(0) == mesh1.num_entities_global(0)
     dim = mesh0.topology().dim()
-    assert mesh0.size_global(dim) == mesh1.size_global(dim)
+    assert mesh0.num_entities_global(dim) == mesh1.num_entities_global(dim)
 
 @skip_if_not_HDF5
 @xfail_with_serial_hdf5_in_parallel
diff --git a/test/unit/python/io/test_HDF5_attribute.py b/test/unit/python/io/test_HDF5_attribute.py
index 6582d6e..1c6425b 100755
--- a/test/unit/python/io/test_HDF5_attribute.py
+++ b/test/unit/python/io/test_HDF5_attribute.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the Attribute interface of the HDF5 io library"""
 
 # Copyright (C) 2013 Chris Richardson
diff --git a/test/unit/python/io/test_HDF5_series.py b/test/unit/python/io/test_HDF5_series.py
index 4cd619a..5f0260e 100644
--- a/test/unit/python/io/test_HDF5_series.py
+++ b/test/unit/python/io/test_HDF5_series.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the HDF5 io library - timeseries io"""
 
 # Copyright (C) 2014 Chris Richardson
@@ -56,5 +54,5 @@ def test_save_and_read_function_timeseries(tempdir):
         timestamp = hdf5_file.attributes(vec_name)["timestamp"]
         assert timestamp == t
         result = F0.vector() - F1.vector()
-        assert len(result.array().nonzero()[0]) == 0
+        assert len(result.get_local().nonzero()[0]) == 0
     hdf5_file.close()
diff --git a/test/unit/python/io/test_SVG.py b/test/unit/python/io/test_SVG.py
index 58e81b8..6f5580a 100755
--- a/test/unit/python/io/test_SVG.py
+++ b/test/unit/python/io/test_SVG.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for SVG output"""
 
 # Copyright (C) 2012 Anders Logg
diff --git a/test/unit/python/io/test_X3D.py b/test/unit/python/io/test_X3D.py
index 9135e20..f9cd197 100755
--- a/test/unit/python/io/test_X3D.py
+++ b/test/unit/python/io/test_X3D.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 # Copyright (C) 2013 Garth N. Wells
 #
 # This file is part of DOLFIN.
@@ -40,13 +38,13 @@ def test_save_mesh3D(cd_tempdir):
 
 def test_save_cell_meshfunction2D(cd_tempdir):
     mesh = UnitSquareMesh(16, 16)
-    mf = CellFunction("size_t", mesh, 12)
+    mf = MeshFunction("size_t", mesh, mesh.topology().dim(), 12)
     file = File("cell_mf2D.x3d")
     file << mf
 
 def test_save_facet_meshfunction2D(cd_tempdir):
     mesh = UnitSquareMesh(16, 16)
-    mf = FacetFunction("size_t", mesh, 12)
+    mf = MeshFunction("size_t", mesh, mesh.topology().dim()-1, 12)
     file = File("facet_mf2D.x3d")
     #with pytest.raises(RuntimeError):
     #    file << mf
@@ -54,14 +52,14 @@ def test_save_facet_meshfunction2D(cd_tempdir):
 
 def test_save_cell_meshfunctio22D(cd_tempdir):
     mesh = UnitCubeMesh(16, 16, 16)
-    mf = CellFunction("size_t", mesh, 12)
+    mf = MeshFunction("size_t", mesh, mesh.topology().dim(), 12)
     file = File("cell_mf3D.x3d")
     file << mf
 
 
 def test_save_facet_meshfunction3D(cd_tempdir):
     mesh = UnitCubeMesh(16, 16, 16)
-    mf = FacetFunction("size_t", mesh, 12)
+    mf = MeshFunction("size_t", mesh, mesh.topology().dim()-1, 12)
     file = File("facet_mf3D.x3d")
     #with pytest.raises(RuntimeError):
     #    file << mf
diff --git a/test/unit/python/io/test_XDMF.py b/test/unit/python/io/test_XDMF.py
index 13b16e9..01c415e 100755
--- a/test/unit/python/io/test_XDMF.py
+++ b/test/unit/python/io/test_XDMF.py
@@ -18,7 +18,7 @@
 import pytest
 import os
 from dolfin import *
-from dolfin_utils.test import skip_in_parallel, fixture, tempdir
+from dolfin_utils.test import skip_in_parallel, fixture, tempdir, skip_if_not_pybind11
 
 
 # Supported XDMF file encoding
@@ -55,6 +55,19 @@ def invalid_config(encoding):
 def invalid_fe(fe_family, fe_degree):
     return (fe_family == "CG" and fe_degree == 0)
 
+
+ at pytest.fixture
+def worker_id(request):
+    """Return worker ID when using pytest-xdist to run tests in
+    parallell
+
+    """
+    if hasattr(request.config, 'slaveinput'):
+        return request.config.slaveinput['slaveid']
+    else:
+        return 'master'
+
+
 @pytest.mark.parametrize("encoding", encodings)
 def test_save_and_load_1d_mesh(tempdir, encoding):
     if invalid_config(encoding):
@@ -68,9 +81,9 @@ def test_save_and_load_1d_mesh(tempdir, encoding):
     mesh2 = Mesh()
     with XDMFFile(mpi_comm_world(), filename) as file:
         file.read(mesh2)
-    assert mesh.size_global(0) == mesh2.size_global(0)
+    assert mesh.num_entities_global(0) == mesh2.num_entities_global(0)
     dim = mesh.topology().dim()
-    assert mesh.size_global(dim) == mesh2.size_global(dim)
+    assert mesh.num_entities_global(dim) == mesh2.num_entities_global(dim)
 
 
 @pytest.mark.parametrize("encoding", encodings)
@@ -86,9 +99,9 @@ def test_save_and_load_2d_mesh(tempdir, encoding):
     mesh2 = Mesh()
     with XDMFFile(mpi_comm_world(), filename) as file:
         file.read(mesh2)
-    assert mesh.size_global(0) == mesh2.size_global(0)
+    assert mesh.num_entities_global(0) == mesh2.num_entities_global(0)
     dim = mesh.topology().dim()
-    assert mesh.size_global(dim) == mesh2.size_global(dim)
+    assert mesh.num_entities_global(dim) == mesh2.num_entities_global(dim)
 
 
 @pytest.mark.parametrize("encoding", encodings)
@@ -96,7 +109,7 @@ def test_save_and_load_2d_quad_mesh(tempdir, encoding):
     if invalid_config(encoding):
         pytest.skip("XDMF unsupported in current configuration")
     filename = os.path.join(tempdir, "mesh_2D_quad.xdmf")
-    mesh = UnitQuadMesh.create(32, 32)
+    mesh = UnitSquareMesh.create(32, 32, CellType.Type_quadrilateral)
 
     with XDMFFile(mesh.mpi_comm(), filename) as file:
         file.write(mesh, encoding)
@@ -104,9 +117,9 @@ def test_save_and_load_2d_quad_mesh(tempdir, encoding):
     mesh2 = Mesh()
     with XDMFFile(mpi_comm_world(), filename) as file:
         file.read(mesh2)
-    assert mesh.size_global(0) == mesh2.size_global(0)
+    assert mesh.num_entities_global(0) == mesh2.num_entities_global(0)
     dim = mesh.topology().dim()
-    assert mesh.size_global(dim) == mesh2.size_global(dim)
+    assert mesh.num_entities_global(dim) == mesh2.num_entities_global(dim)
 
 
 @pytest.mark.parametrize("encoding", encodings)
@@ -122,9 +135,9 @@ def test_save_and_load_3d_mesh(tempdir, encoding):
     mesh2 = Mesh()
     with XDMFFile(mpi_comm_world(), filename) as file:
         file.read(mesh2)
-    assert mesh.size_global(0) == mesh2.size_global(0)
+    assert mesh.num_entities_global(0) == mesh2.num_entities_global(0)
     dim = mesh.topology().dim()
-    assert mesh.size_global(dim) == mesh2.size_global(dim)
+    assert mesh.num_entities_global(dim) == mesh2.num_entities_global(dim)
 
 
 @pytest.mark.parametrize("encoding", encodings)
@@ -171,7 +184,7 @@ def test_save_and_checkpoint_scalar(tempdir, encoding, fe_degree, fe_family,
         file.read_checkpoint(u_in, "u_out", 0)
 
     result = u_in.vector() - u_out.vector()
-    assert all([near(x, 0.0) for x in result.array()])
+    assert all([near(x, 0.0) for x in result.get_local()])
 
 
 @pytest.mark.parametrize("encoding", encodings)
@@ -208,7 +221,7 @@ def test_save_and_checkpoint_vector(tempdir, encoding, fe_degree, fe_family,
         file.read_checkpoint(u_in, "u_out", 0)
 
     result = u_in.vector() - u_out.vector()
-    assert all([near(x, 0.0) for x in result.array()])
+    assert all([near(x, 0.0) for x in result.get_local()])
 
 
 @pytest.mark.parametrize("encoding", encodings)
@@ -237,7 +250,7 @@ def test_save_and_checkpoint_timeseries(tempdir, encoding):
 
     for i, p in enumerate(times):
         result = u_in[i].vector() - u_out[i].vector()
-        assert all([near(x, 0.0) for x in result.array()])
+        assert all([near(x, 0.0) for x in result.get_local()])
 
     # test reading last
     with XDMFFile(mesh.mpi_comm(), filename) as file:
@@ -245,7 +258,7 @@ def test_save_and_checkpoint_timeseries(tempdir, encoding):
         file.read_checkpoint(u_in_last, "u_out", -1)
 
     result = u_out[-1].vector() - u_in_last.vector()
-    assert all([near(x, 0.0) for x in result.array()])
+    assert all([near(x, 0.0) for x in result.get_local()])
 
 
 @pytest.mark.parametrize("encoding", encodings)
@@ -356,7 +369,7 @@ def test_save_1d_mesh(tempdir, encoding):
         pytest.skip("XDMF unsupported in current configuration")
     filename = os.path.join(tempdir, "mf_1D.xdmf")
     mesh = UnitIntervalMesh(32)
-    mf = CellFunction("size_t", mesh)
+    mf = MeshFunction("size_t", mesh, mesh.topology().dim())
     for cell in cells(mesh):
         mf[cell] = cell.index()
 
@@ -374,7 +387,7 @@ def test_save_2D_cell_function(tempdir, encoding, data_type):
 
     filename = os.path.join(tempdir, "mf_2D_%s.xdmf" % dtype_str)
     mesh = UnitSquareMesh(32, 32)
-    mf = CellFunction(dtype_str, mesh)
+    mf = MeshFunction(dtype_str, mesh, mesh.topology().dim())
     mf.rename("cells", "cells")
     for cell in cells(mesh):
         mf[cell] = dtype(cell.index())
@@ -382,7 +395,7 @@ def test_save_2D_cell_function(tempdir, encoding, data_type):
     with XDMFFile(mesh.mpi_comm(), filename) as file:
         file.write(mf, encoding)
 
-    mf_in = CellFunction(dtype_str, mesh)
+    mf_in = MeshFunction(dtype_str, mesh, mesh.topology().dim())
     with XDMFFile(mesh.mpi_comm(), filename) as xdmf:
         xdmf.read(mf_in, "cells")
 
@@ -401,7 +414,7 @@ def test_save_3D_cell_function(tempdir, encoding, data_type):
     dtype_str, dtype = data_type
 
     mesh = UnitCubeMesh(8, 8, 8)
-    mf = CellFunction(dtype_str, mesh)
+    mf = MeshFunction(dtype_str, mesh, mesh.topology().dim())
     mf.rename("cells", "cells")
     for cell in cells(mesh):
         mf[cell] = dtype(cell.index())
@@ -410,7 +423,7 @@ def test_save_3D_cell_function(tempdir, encoding, data_type):
     with XDMFFile(mesh.mpi_comm(), filename) as file:
         file.write(mf, encoding)
 
-    mf_in = CellFunction(dtype_str, mesh)
+    mf_in = MeshFunction(dtype_str, mesh, mesh.topology().dim())
     with XDMFFile(mesh.mpi_comm(), filename) as xdmf:
         xdmf.read(mf_in, "cells")
 
@@ -428,7 +441,7 @@ def test_save_2D_facet_function(tempdir, encoding, data_type):
     dtype_str, dtype = data_type
 
     mesh = UnitSquareMesh(32, 32)
-    mf = FacetFunction(dtype_str, mesh)
+    mf = MeshFunction(dtype_str, mesh, mesh.topology().dim()-1)
     mf.rename("facets", "facets")
 
     if (MPI.size(mesh.mpi_comm()) == 1):
@@ -442,7 +455,7 @@ def test_save_2D_facet_function(tempdir, encoding, data_type):
     with XDMFFile(mesh.mpi_comm(), filename) as xdmf:
         xdmf.write(mf, encoding)
 
-    mf_in = FacetFunction(dtype_str, mesh)
+    mf_in = MeshFunction(dtype_str, mesh, mesh.topology().dim()-1)
     with XDMFFile(mesh.mpi_comm(), filename) as xdmf:
         xdmf.read(mf_in, "facets")
 
@@ -460,7 +473,7 @@ def test_save_3D_facet_function(tempdir, encoding, data_type):
     dtype_str, dtype = data_type
 
     mesh = UnitCubeMesh(8, 8, 8)
-    mf = FacetFunction(dtype_str, mesh)
+    mf = MeshFunction(dtype_str, mesh, mesh.topology().dim()-1)
     mf.rename("facets", "facets")
 
     if (MPI.size(mesh.mpi_comm()) == 1):
@@ -474,7 +487,7 @@ def test_save_3D_facet_function(tempdir, encoding, data_type):
     with XDMFFile(mesh.mpi_comm(), filename) as file:
         file.write(mf, encoding)
 
-    mf_in = FacetFunction(dtype_str, mesh)
+    mf_in = MeshFunction(dtype_str, mesh, mesh.topology().dim()-1)
     with XDMFFile(mesh.mpi_comm(), filename) as file:
         file.read(mf_in, "facets")
 
@@ -492,7 +505,7 @@ def test_save_3D_edge_function(tempdir, encoding, data_type):
     dtype_str, dtype = data_type
 
     mesh = UnitCubeMesh(8, 8, 8)
-    mf = EdgeFunction(dtype_str, mesh)
+    mf = MeshFunction(dtype_str, mesh, 1)
     mf.rename("edges", "edges")
     for edge in edges(mesh):
         mf[edge] = dtype(edge.index())
@@ -511,7 +524,7 @@ def test_save_2D_vertex_function(tempdir, encoding, data_type):
     dtype_str, dtype = data_type
 
     mesh = UnitSquareMesh(32, 32)
-    mf = VertexFunction(dtype_str, mesh)
+    mf = MeshFunction(dtype_str, mesh, 0)
     mf.rename("vertices", "vertices")
     for vertex in vertices(mesh):
         mf[vertex] = dtype(vertex.global_index())
@@ -520,7 +533,7 @@ def test_save_2D_vertex_function(tempdir, encoding, data_type):
     with XDMFFile(mesh.mpi_comm(), filename) as file:
         file.write(mf, encoding)
 
-    mf_in = VertexFunction(dtype_str, mesh)
+    mf_in = MeshFunction(dtype_str, mesh, 0)
     with XDMFFile(mesh.mpi_comm(), filename) as xdmf:
         xdmf.read(mf_in, "vertices")
 
@@ -539,14 +552,14 @@ def test_save_3D_vertex_function(tempdir, encoding, data_type):
 
     filename = os.path.join(tempdir, "mf_vertex_3D_%s.xdmf" % dtype_str)
     mesh = UnitCubeMesh(8, 8, 8)
-    mf = VertexFunction(dtype_str, mesh)
+    mf = MeshFunction(dtype_str, mesh, 0)
     for vertex in vertices(mesh):
         mf[vertex] = dtype(vertex.index())
 
     with XDMFFile(mesh.mpi_comm(), filename) as file:
         file.write(mf, encoding)
 
-
+ at skip_if_not_pybind11
 @pytest.mark.parametrize("encoding", encodings)
 def test_save_points_2D(tempdir, encoding):
     if invalid_config(encoding):
@@ -567,6 +580,7 @@ def test_save_points_2D(tempdir, encoding):
         file.write(points, vals, encoding)
 
 
+ at skip_if_not_pybind11
 @pytest.mark.parametrize("encoding", encodings)
 def test_save_points_3D(tempdir, encoding):
     if invalid_config(encoding):
@@ -597,7 +611,7 @@ def test_save_mesh_value_collection(tempdir, encoding, data_type):
     mesh = UnitCubeMesh(4, 4, 4)
     tdim = mesh.topology().dim()
 
-    meshfn = CellFunction(dtype_str, mesh, 0)
+    meshfn = MeshFunction(dtype_str, mesh, mesh.topology().dim(), False)
     meshfn.rename("volume_marker", "Volume Markers")
     for c in cells(mesh):
         if c.midpoint().y() > 0.1:
@@ -669,11 +683,11 @@ def test_append_and_load_mesh_functions(tempdir, encoding, data_type):
     for mesh in meshes:
         dim = mesh.topology().dim()
 
-        vf = VertexFunction(dtype_str, mesh)
+        vf = MeshFunction(dtype_str, mesh, 0)
         vf.rename("vertices", "vertices")
-        ff = FacetFunction(dtype_str, mesh)
+        ff = MeshFunction(dtype_str, mesh, mesh.topology().dim()-1)
         ff.rename("facets", "facets")
-        cf = CellFunction(dtype_str, mesh)
+        cf = MeshFunction(dtype_str, mesh, mesh.topology().dim())
         cf.rename("cells", "cells")
 
         if (MPI.size(mesh.mpi_comm()) == 1):
@@ -700,11 +714,11 @@ def test_append_and_load_mesh_functions(tempdir, encoding, data_type):
             xdmf.write(cf, encoding)
 
         with XDMFFile(mesh.mpi_comm(), filename) as xdmf:
-            vf_in = VertexFunction(dtype_str, mesh)
+            vf_in = MeshFunction(dtype_str, mesh, 0)
             xdmf.read(vf_in, "vertices")
-            ff_in = FacetFunction(dtype_str, mesh)
+            ff_in = MeshFunction(dtype_str, mesh, mesh.topology().dim()-1)
             xdmf.read(ff_in, "facets")
-            cf_in = CellFunction(dtype_str, mesh)
+            cf_in = MeshFunction(dtype_str, mesh, mesh.topology().dim())
             xdmf.read(cf_in, "cells")
 
         diff = 0
diff --git a/test/unit/python/io/test_XDMF_cell_output.py b/test/unit/python/io/test_XDMF_cell_output.py
index d76e7e9..1aa0d36 100644
--- a/test/unit/python/io/test_XDMF_cell_output.py
+++ b/test/unit/python/io/test_XDMF_cell_output.py
@@ -41,5 +41,5 @@ def test_xdmf_cell_scalar_ghost(cd_tempdir, ghost_mode):
         vec = Vector()
         hdf.read(vec, "/VisualisationVector/0", False)
     
-    area = MPI.sum(mesh.mpi_comm(), sum(vec.array()))
+    area = MPI.sum(mesh.mpi_comm(), sum(vec.get_local()))
     assert abs(n*n - area) < 1e-9
diff --git a/test/unit/python/io/test_XMLFunction.py b/test/unit/python/io/test_XMLFunction.py
index 55c08de..ab86032 100755
--- a/test/unit/python/io/test_XMLFunction.py
+++ b/test/unit/python/io/test_XMLFunction.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env py.test
 """Unit tests for the XML input/output of Function"""
 
 # Copyright (C) 2014 Matthias Liertzer
@@ -39,4 +38,4 @@ def test_save_and_read_xml_function(cd_tempdir):
     xml_file >> F1
     result = F0.vector() - F1.vector()
 
-    assert len(result.array().nonzero()[0]) == 0
+    assert len(result.get_local().nonzero()[0]) == 0
diff --git a/test/unit/python/io/test_XML_mesh.py b/test/unit/python/io/test_XML_mesh.py
index a36ae90..d94f67b 100755
--- a/test/unit/python/io/test_XML_mesh.py
+++ b/test/unit/python/io/test_XML_mesh.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 "Unit tests for XML input/output of Mesh (class XMLMesh)"
 
 # Copyright (C) 2011 Garth N. Wells
diff --git a/test/unit/python/io/test_XML_mesh_function.py b/test/unit/python/io/test_XML_mesh_function.py
index b86d3af..3c322b7 100755
--- a/test/unit/python/io/test_XML_mesh_function.py
+++ b/test/unit/python/io/test_XML_mesh_function.py
@@ -1,5 +1,3 @@
-#!/us/bin/env py.test
-
 "Unit tests for XML input/output of MeshFunction (class XMLMeshFunction)"
 
 # Copyright (C) 2011-2014 Garth N. Wells
diff --git a/test/unit/python/io/test_XML_mesh_value_collection.py b/test/unit/python/io/test_XML_mesh_value_collection.py
index 2274ed9..2d773f1 100755
--- a/test/unit/python/io/test_XML_mesh_value_collection.py
+++ b/test/unit/python/io/test_XML_mesh_value_collection.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 "Unit tests for XML input/output of MeshValueCollection"
 
 # Copyright (C) 2011 Anders Logg
diff --git a/test/unit/python/io/test_XML_table.py b/test/unit/python/io/test_XML_table.py
index fce1bb1..11800cf 100755
--- a/test/unit/python/io/test_XML_table.py
+++ b/test/unit/python/io/test_XML_table.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the XML io library for Tables"""
 
 # Copyright (C) 2016 Simon Funke and Marie E. Rognes
diff --git a/test/unit/python/io/test_XML_vector.py b/test/unit/python/io/test_XML_vector.py
index 39068e5..6b36eba 100755
--- a/test/unit/python/io/test_XML_vector.py
+++ b/test/unit/python/io/test_XML_vector.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the XML io library for vectors"""
 
 # Copyright (C) 2011-2014 Garth N. Wells
diff --git a/test/unit/python/io/test_vtk.py b/test/unit/python/io/test_vtk.py
index 84f0da9..750a5a2 100755
--- a/test/unit/python/io/test_vtk.py
+++ b/test/unit/python/io/test_vtk.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 # Copyright (C) 2011 Garth N. Wells
 #
 # This file is part of DOLFIN.
@@ -28,10 +26,6 @@ def file_options():
     return ["ascii", "base64", "compressed"]
 
 @fixture
-def mesh_functions():
-    return [CellFunction, FacetFunction, FaceFunction, EdgeFunction, VertexFunction]
-
- at fixture
 def mesh_function_types():
     return ["size_t", "int", "double", "bool"]
 
@@ -43,13 +37,12 @@ def type_conv():
 def tempfile(tempdir, request):
     return os.path.join(tempdir, request.function.__name__)
 
-def test_save_1d_meshfunctions(tempfile, mesh_functions,
+def test_save_1d_meshfunctions(tempfile,
                                 mesh_function_types, file_options, type_conv):
     mesh = UnitIntervalMesh(32)
-    for F in mesh_functions:
-       if F in [FaceFunction, EdgeFunction]: continue
-       for t in mesh_function_types:
-            mf = F(t, mesh, type_conv[t](1))
+    for d in range(mesh.topology().dim()+1):
+        for t in mesh_function_types:
+            mf = MeshFunction(t, mesh, mesh.topology().dim()-d, type_conv[t](1))
             File(tempfile + "mf.pvd") << mf
             f = File(tempfile + "mf.pvd")
             f << (mf, 0.)
@@ -57,12 +50,12 @@ def test_save_1d_meshfunctions(tempfile, mesh_functions,
             for file_option in file_options:
                 File(tempfile + "mf.pvd", file_option) << mf
 
-def test_save_2d_meshfunctions(tempfile, mesh_functions,
+def test_save_2d_meshfunctions(tempfile,
                                 mesh_function_types, file_options, type_conv):
     mesh = UnitSquareMesh(32, 32)
-    for F in mesh_functions:
+    for d in range(mesh.topology().dim()+1):
         for t in mesh_function_types:
-            mf = F(t, mesh, type_conv[t](1))
+            mf = MeshFunction(t, mesh, mesh.topology().dim()-d, type_conv[t](1))
             File(tempfile + "mf.pvd") << mf
             f = File(tempfile + "mf.pvd")
             f << (mf, 0.)
@@ -70,12 +63,12 @@ def test_save_2d_meshfunctions(tempfile, mesh_functions,
             for file_option in file_options:
                 File(tempfile + "mf.pvd", file_option) << mf
 
-def test_save_3d_meshfunctions(tempfile, mesh_functions,
+def test_save_3d_meshfunctions(tempfile,
                                 mesh_function_types, file_options, type_conv):
     mesh = UnitCubeMesh(8, 8, 8)
-    for F in mesh_functions:
+    for d in range(mesh.topology().dim()+1):
         for t in mesh_function_types:
-            mf = F(t, mesh, type_conv[t](1))
+            mf = MeshFunction(t, mesh, mesh.topology().dim()-d, type_conv[t](1))
             File(tempfile + "mf.pvd") << mf
             f = File(tempfile + "mf.pvd")
             f << (mf, 0.)
diff --git a/test/unit/python/jit/test_jit.py b/test/unit/python/jit/test_jit.py
index 6224402..785b2a7 100755
--- a/test/unit/python/jit/test_jit.py
+++ b/test/unit/python/jit/test_jit.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the JIT compiler"""
 
 # Copyright (C) 2011 Anders Logg
@@ -21,6 +19,7 @@
 
 import pytest
 import platform
+import dolfin
 from dolfin import *
 from dolfin_utils.test import (skip_if_not_PETSc, skip_if_not_SLEPc,
                                skip_if_not_MPI, skip_in_serial,
@@ -51,21 +50,62 @@ def test_nasty_jit_caching_bug():
 @skip_if_pybind11
 @skip_if_not_MPI
 def test_mpi_swig():
-    from dolfin import compile_extension_module
-
     create_transfer_matrix_code = r'''
     namespace dolfin
     {
         void find_exterior_points(MPI_Comm mpi_comm) {}
     }'''
-    create_transfer_matrix =  compile_extension_module(code=create_transfer_matrix_code)
+    compile_extension_module(code=create_transfer_matrix_code)
+
+
+ at skip_if_not_pybind11
+def test_mpi_pybind11():
+    """
+    Test MPICommWrapper <-> mpi4py.MPI.Comm conversion for JIT-ed code
+    """
+    cpp_code = """
+    #include <pybind11/pybind11.h>
+    #include <dolfin_wrappers/MPICommWrapper.h>
+    namespace dolfin
+    {
+      dolfin_wrappers::MPICommWrapper
+      test_comm_passing(const dolfin_wrappers::MPICommWrapper comm)
+      {
+        MPI_Comm c = comm.get();
+        return dolfin_wrappers::MPICommWrapper(c);
+      }
+    }
+    PYBIND11_MODULE(SIGNATURE, m)
+    {
+        m.def("test_comm_passing", &dolfin::test_comm_passing);
+    }
+    """
+
+    # Import MPI_COMM_WORLD
+    if dolfin.has_mpi4py():
+        from mpi4py import MPI
+        w1 = MPI.COMM_WORLD
+    else:
+        w1 = dolfin.MPI.comm_world
+
+    # Compile the JIT module
+    return pytest.xfail('Include path for dolfin_wrappers/* not set up to '
+                        'work in the JIT at the moment')
+    mod = dolfin.compile_cpp_code(cpp_code)
+
+    # Pass a comm into C++ and get a new wrapper of the same comm back
+    w2 = mod.test_comm_passing(w1)
+
+    if dolfin.has_mpi4py():
+        assert isinstance(w2, MPI.Comm)
+    else:
+        assert isinstance(w2, dolfin.cpp.MPICommWrapper)
+        assert w1.underlying_comm() == w2.underlying_comm()
 
 
 @skip_if_pybind11
 @skip_if_not_PETSc
 def test_pesc_swig():
-    from dolfin import compile_extension_module
-
     create_matrix_code = r'''
     namespace dolfin
     {
@@ -76,14 +116,12 @@ def test_pesc_swig():
         }
     }
     '''
-    create_matrix =  compile_extension_module(code=create_matrix_code)
+    compile_extension_module(code=create_matrix_code)
 
 
 @skip_if_pybind11
 @skip_if_not_SLEPc
 def test_slepc_swig():
-    from dolfin import compile_extension_module
-
     create_eps_code = r'''
     #include <slepc.h>
     namespace dolfin
@@ -91,55 +129,89 @@ def test_slepc_swig():
         std::shared_ptr<EPS> create_matrix(MPI_Comm comm) {
             EPS eps;
             EPSCreate(comm, &eps);
-	    std::shared_ptr<EPS> ptr = std::make_shared<EPS>(eps);
+            std::shared_ptr<EPS> ptr = std::make_shared<EPS>(eps);
             return ptr;
         }
     }
     '''
-    create_matrix =  compile_extension_module(code=create_eps_code)
+    compile_extension_module(code=create_eps_code)
 
 
- at skip_if_pybind11
 def test_pass_array_int():
     import numpy
-    code = """
-    int test_int_array(const Array<int>& int_arr)
-    {
-        int ret = 0;
-        for (int i = 0; i < int_arr.size(); i++)
+
+    if has_pybind11():
+        code = """
+        #include <Eigen/Core>
+        #include <pybind11/pybind11.h>
+        #include <pybind11/eigen.h>
+        using IntVecIn = Eigen::Ref<const Eigen::VectorXi>;
+        int test_int_array(const IntVecIn arr)
         {
-            ret += int_arr[i];
+            return arr.sum();
         }
-        return ret;
-    }
-    """
-    module = compile_extension_module(code=code,
-                                      source_directory='.',
-                                      sources=[],
-                                      include_dirs=["."])
+        PYBIND11_MODULE(SIGNATURE, m)
+        {
+            m.def("test_int_array", &test_int_array);
+        }
+        """
+        module = compile_cpp_code(code)
+    else:
+        code = """
+        int test_int_array(const Array<int>& int_arr)
+        {
+            int ret = 0;
+            for (int i = 0; i < int_arr.size(); i++)
+            {
+                ret += int_arr[i];
+            }
+            return ret;
+        }
+        """
+        module = compile_extension_module(code=code,
+                                          source_directory='.',
+                                          sources=[],
+                                          include_dirs=["."])
     arr = numpy.array([1, 2, 4, 8], dtype=numpy.intc)
     ans = module.test_int_array(arr)
     assert ans == arr.sum() == 15
 
 
- at skip_if_pybind11
 def test_pass_array_double():
     import numpy
-    code = """
-    double test_double_array(const Array<double>& arr)
-    {
-        double ret = 0;
-        for (int i = 0; i < arr.size(); i++)
+
+    if has_pybind11():
+        code = """
+        #include <Eigen/Core>
+        #include <pybind11/pybind11.h>
+        #include <pybind11/eigen.h>
+        using DoubleVecIn = Eigen::Ref<const Eigen::VectorXd>;
+        int test_double_array(const DoubleVecIn arr)
         {
-            ret += arr[i];
+            return arr.sum();
         }
-        return ret;
-    }
-    """
-    module = compile_extension_module(code=code,
-                                      source_directory='.',
-                                      sources=[],
-                                      include_dirs=["."])
+        PYBIND11_MODULE(SIGNATURE, m)
+        {
+            m.def("test_double_array", &test_double_array);
+        }
+        """
+        module = compile_cpp_code(code)
+    else:
+        code = """
+        double test_double_array(const Array<double>& arr)
+        {
+            double ret = 0;
+            for (int i = 0; i < arr.size(); i++)
+            {
+                ret += arr[i];
+            }
+            return ret;
+        }
+        """
+        module = compile_extension_module(code=code,
+                                          source_directory='.',
+                                          sources=[],
+                                          include_dirs=["."])
     arr = numpy.array([1, 2, 4, 8], dtype=float)
     ans = module.test_double_array(arr)
     assert abs(arr.sum() - 15) < 1e-15
@@ -211,12 +283,12 @@ def test_compile_extension_module_pybind11():
     ext_module = compile_cpp_code(code)
 
     vec = PETScVector(mpi_comm_world(), 10)
-    np_vec = vec.array()
+    np_vec = vec.get_local()
     np_vec[:] = arange(len(np_vec))
     vec.set_local(np_vec)
     ext_module.PETSc_exp(vec)
     np_vec[:] = exp(np_vec)
-    assert (np_vec == vec.array()).all()
+    assert (np_vec == vec.get_local()).all()
 
 
 @skip_if_pybind11
@@ -228,12 +300,14 @@ def test_compile_extension_module_kwargs():
     assert not m2.__file__ == m0.__file__
 
 
+ at skip_if_pybind11
 @skip_if_not_petsc4py
 @skip_in_serial
 def test_mpi_dependent_jiting():
     # FIXME: Not a proper unit test...
-    from dolfin import Expression, UnitSquareMesh, Function, TestFunction, \
-         Form, FunctionSpace, dx, CompiledSubDomain, SubSystemsManager
+    from dolfin import (Expression, UnitSquareMesh, Function,
+                        TestFunction, Form, FunctionSpace, dx, CompiledSubDomain,
+                        SubSystemsManager)
 
     # Init petsc (needed to initalize petsc and slepc collectively on
     # all processes)
diff --git a/test/unit/python/la/test_krylov_solver.py b/test/unit/python/la/test_krylov_solver.py
index e18a1d9..2bd1b3e 100755
--- a/test/unit/python/la/test_krylov_solver.py
+++ b/test/unit/python/la/test_krylov_solver.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the KrylovSolver interface"""
 
 # Copyright (C) 2014 Garth N. Wells
diff --git a/test/unit/python/la/test_la_basic.py b/test/unit/python/la/test_la_basic.py
index acc4297..d4b323c 100755
--- a/test/unit/python/la/test_la_basic.py
+++ b/test/unit/python/la/test_la_basic.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the linear algebra interface"""
 
 # Copyright (C) 2008 Johan Hake
@@ -186,7 +184,7 @@ class TestBasicLaOperations:
         else:
             assert round(A[lind0] - val1 - val2*100, 7) == 0
 
-        A2 = A.array()
+        A2 = A.get_local()
         assert isinstance(A2,ndarray)
         assert A2.shape == (n1 - n0, )
 
@@ -197,7 +195,7 @@ class TestBasicLaOperations:
 
         assert round(MPI.sum(A.mpi_comm(), A2.sum()) - A.sum(), 7) == 0
 
-        B2 = B.array()
+        B2 = B.get_local()
 
         inds = [1,3,6,9,15,20,24,28,32,40,50,60,70,100000]
 
@@ -240,7 +238,7 @@ class TestBasicLaOperations:
         assert (A3==A2).all()
 
         A[:] = A2
-        assert (A.array()==A2).all()
+        assert (A.get_local()==A2).all()
 
         H  = A.copy()
         if not has_pybind11():
@@ -289,7 +287,7 @@ class TestBasicLaOperations:
         with pytest.raises(IndexError):
             wrong_dim([0,2], slice(0,4,1))
 
-        A2 = A.array()
+        A2 = A.get_local()
         A *= B
         A2 *= B2
         I = A*B
@@ -385,13 +383,13 @@ class TestBasicLaOperations:
         if distributed:
             return
 
-        v_numpy = v.array()
+        v_numpy = v.get_local()
         A_numpy = A.array()
 
         u_numpy = dot(A_numpy, v_numpy)
         u_numpy2 = A*v_numpy
 
-        assert absolute(u.array() - u_numpy).sum() < DOLFIN_EPS*len(v)
+        assert absolute(u.get_local() - u_numpy).sum() < DOLFIN_EPS*len(v)
         assert absolute(u_numpy2 - u_numpy).sum() < DOLFIN_EPS*len(v)
 
 
diff --git a/test/unit/python/la/test_linear_operator.py b/test/unit/python/la/test_linear_operator.py
index aa31927..298f607 100755
--- a/test/unit/python/la/test_linear_operator.py
+++ b/test/unit/python/la/test_linear_operator.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 "Unit tests for matrix-free linear solvers (LinearOperator)"
 
 # Copyright (C) 2012 Anders Logg
@@ -80,14 +78,14 @@ def test_linear_operator(backend):
         u = Function(V)
         a_action = action(a, coefficient=u)
         O = MyLinearOperator(a_action, u)
-        O = _as_backend_type(O)
-        solve(O, x, b, "gmres", "none")
+        Ob = _as_backend_type(O)
+        solve(Ob, x, b, "gmres", "none")
         norm_action = norm(x, "l2")
 
         # Check at least that petsc4py interface is available
         if backend == 'PETSc' and has_petsc4py() and _as_backend_type == as_backend_type:
             from petsc4py import PETSc
-            assert isinstance(O.mat(), PETSc.Mat)
+            assert isinstance(Ob.mat(), PETSc.Mat)
 
     # Reset backend
     parameters["linear_algebra_backend"] = prev_backend
diff --git a/test/unit/python/la/test_lu_solver.py b/test/unit/python/la/test_lu_solver.py
index 9bb819f..d14dbdf 100755
--- a/test/unit/python/la/test_lu_solver.py
+++ b/test/unit/python/la/test_lu_solver.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the LUSolver interface"""
 
 # Copyright (C) 2014 Garth N. Wells
@@ -60,6 +58,11 @@ def test_lu_solver(backend):
     solver.solve(x, b)
     assert round(x.norm("l2") - norm, 10) == 0
 
+    solver = LUSolver()
+    x = Vector()
+    solver.solve(A, x, b)
+    assert round(x.norm("l2") - norm, 10) == 0
+
     # Reset backend
     parameters["linear_algebra_backend"] = prev_backend
 
diff --git a/test/unit/python/la/test_matrix.py b/test/unit/python/la/test_matrix.py
index 2b6eab1..0065418 100755
--- a/test/unit/python/la/test_matrix.py
+++ b/test/unit/python/la/test_matrix.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the Matrix interface"""
 
 # Copyright (C) 2011-2014 Garth N. Wells
@@ -267,6 +265,42 @@ class TestMatrixForAnyBackend:
             assert j < cols.size
             assert round(sum(abs(row)) - 1.0, 7) == 0
 
+    @skip_in_parallel
+    def test_ident(self, use_backend, any_backend):
+        self.backend, self.sub_backend = any_backend
+        if self.backend == 'Tpetra':
+            pytest.skip()
+        A, B = self.assemble_matrices(use_backend)
+        N, M = A.size(0), A.size(1)
+
+        # Make sure rows are not identity from before
+        import numpy
+        ROWS = [2, 4]
+        for row in ROWS:
+            block = numpy.array([[42.0]], dtype=float)
+            A.set(block, numpy.array([row], dtype=numpy.intc),
+                  numpy.array([row], dtype=numpy.intc))
+        A.apply("insert")
+
+        def check_row(A, row, idented):
+            cols, vals = A.getrow(row)
+            i = list(cols).index(row)
+            if idented:
+                assert vals[i] == 1
+                vals[i] = 0
+                for c in cols:
+                    if c != row:
+                        assert (vals == 0).all()
+            else:
+                assert vals[i] == 42.0
+
+        for row in ROWS:
+            check_row(A, row, False)
+        A.ident(numpy.array(ROWS, dtype=numpy.intc))
+        A.apply("insert")
+        for row in ROWS:
+            check_row(A, row, True)
+
     def test_setting_getting_diagonal(self, use_backend, any_backend):
         self.backend, self.sub_backend = any_backend
 
@@ -305,6 +339,32 @@ class TestMatrixForAnyBackend:
         w.vector()[:] -= b
         assert round(w.vector().norm("l2"), 14) == 0
 
+    @skip_in_parallel
+    def test_get_set(self, use_backend, any_backend):
+        self.backend, self.sub_backend = any_backend
+        if self.backend == 'Tpetra':
+            pytest.skip()
+        A, B = self.assemble_matrices(use_backend)
+        N, M = A.size(0), A.size(1)
+
+        import numpy
+        rows = numpy.array([1, 2], dtype=numpy.intc)
+        cols = numpy.array([1, 2], dtype=numpy.intc)
+
+        block_in = numpy.ones((2, 2), dtype=float) * 42
+        Anp0 = A.array()
+        assert (Anp0[1:3,1:3] != block_in).any()
+
+        A.set(block_in, rows, cols)
+        A.apply("insert")
+
+        Anp1 = A.array()
+        assert (Anp1[1:3,1:3] == block_in).all()
+
+        block_out = numpy.zeros_like(block_in)
+        A.get(block_out, rows, cols)
+        assert (block_out == block_in).all()
+
     # def test_create_from_sparsity_pattern(self):
 
     # def test_size(self):
diff --git a/test/unit/python/la/test_mg_solver.py b/test/unit/python/la/test_mg_solver.py
index 6ec7880..19be0d3 100755
--- a/test/unit/python/la/test_mg_solver.py
+++ b/test/unit/python/la/test_mg_solver.py
@@ -20,8 +20,11 @@
 
 from dolfin import *
 import pytest
-from dolfin_utils.test import skip_if_not_PETSc, skip_if_not_petsc4py, pushpop_parameters
+from dolfin_utils.test import (skip_if_not_PETSc,
+                               skip_if_not_petsc4py, skip_if_pybind11,
+                               pushpop_parameters)
 
+ at skip_if_pybind11  # See https://bitbucket.org/fenics-project/dolfin/issues/938
 @skip_if_not_petsc4py
 def test_mg_solver_laplace(pushpop_parameters):
 
diff --git a/test/unit/python/la/test_nullspace.py b/test/unit/python/la/test_nullspace.py
index 54fa8e5..e60680a 100755
--- a/test/unit/python/la/test_nullspace.py
+++ b/test/unit/python/la/test_nullspace.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 "Unit tests for nullspace test"
 
 # Copyright (C) 2014 Garth N. Wells
diff --git a/test/unit/python/la/test_petsc4py.py b/test/unit/python/la/test_petsc4py.py
new file mode 100644
index 0000000..5ac5dfd
--- /dev/null
+++ b/test/unit/python/la/test_petsc4py.py
@@ -0,0 +1,97 @@
+"""Unit tests for the pybind11 wrapping of PETSc / petsc4py"""
+
+# Copyright (C) 2017 Tormod Landet
+#
+# This file is part of DOLFIN.
+#
+# DOLFIN is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# DOLFIN 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+
+import gc
+from dolfin import (PETScVector, PETScMatrix, UnitSquareMesh, TrialFunction,
+                    TestFunction, FunctionSpace, Function, assemble, dx,
+                    parameters, as_backend_type)
+from dolfin_utils.test import skip_if_not_petsc4py, pushpop_parameters
+
+
+ at skip_if_not_petsc4py
+def test_petsc4py_vector(pushpop_parameters):
+    "Test PETScVector <-> petsc4py.PETSc.Vec conversions"
+    parameters["linear_algebra_backend"] = "PETSc"
+
+    # Assemble a test matrix  
+    mesh = UnitSquareMesh(4, 4)
+    V = FunctionSpace(mesh, "Lagrange", 1)
+    v = TestFunction(V)
+    a = v*dx
+    b1 = assemble(a)
+
+    # Test conversion dolfin.PETScVector -> petsc4py.PETSc.Vec
+    b1 = as_backend_type(b1)
+    v1 = b1.vec()
+
+    # Copy and scale vector with petsc4py
+    v2 = v1.copy()
+    v2.scale(2.0)
+
+    # Test conversion petsc4py.PETSc.Vec  -> PETScVector
+    b2 = PETScVector(v2)
+
+    assert (b1.get_local()*2.0 == b2.get_local()).all()
+
+
+ at skip_if_not_petsc4py
+def test_petsc4py_matrix(pushpop_parameters):
+    "Test PETScMatrix <-> petsc4py.PETSc.Mat conversions"
+    parameters["linear_algebra_backend"] = "PETSc"
+
+    # Assemble a test matrix    
+    mesh = UnitSquareMesh(4, 4)
+    V = FunctionSpace(mesh, "Lagrange", 1)
+    u, v = TrialFunction(V), TestFunction(V)
+    a = u*v*dx
+    A1 = assemble(a)
+
+    # Test conversion dolfin.PETScMatrix -> petsc4py.PETSc.Mat
+    A1 = as_backend_type(A1)
+    M1 = A1.mat()
+
+    # Copy and scale matrix with petsc4py
+    M2 = M1.copy()
+    M2.scale(2.0)
+
+    # Test conversion petsc4py.PETSc.Mat  -> PETScMatrix
+    A2 = PETScMatrix(M2)
+
+    assert (A1.array()*2.0 == A2.array()).all()
+
+ at skip_if_not_petsc4py
+def test_ref_count(pushpop_parameters):
+    "Test petsc4py reference counting"
+    parameters["linear_algebra_backend"] = "PETSc"
+
+    mesh = UnitSquareMesh(3, 3)
+    V = FunctionSpace(mesh, "P", 1)
+
+    # Check u and x own the vector
+    u = Function(V)
+    x = as_backend_type(u.vector()).vec()
+    assert x.refcount == 2
+
+    # Check decref
+    del u; gc.collect()  # destroy u
+    assert x.refcount == 1
+
+    # Check incref
+    vec = PETScVector(x)
+    assert x.refcount == 2
diff --git a/test/unit/python/la/test_scalar.py b/test/unit/python/la/test_scalar.py
index 3b747de..d6c1a5c 100755
--- a/test/unit/python/la/test_scalar.py
+++ b/test/unit/python/la/test_scalar.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the Scalar interface"""
 
 # Copyright (C) 2011 Garth N. Wells
diff --git a/test/unit/python/la/test_slepc_solver.py b/test/unit/python/la/test_slepc_solver.py
index 628e300..9d531d5 100755
--- a/test/unit/python/la/test_slepc_solver.py
+++ b/test/unit/python/la/test_slepc_solver.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the KrylovSolver interface"""
 
 # Copyright (C) 2016 Nate Sime
@@ -32,6 +30,14 @@ def k(u, v):
 def m(u, v):
     return dot(u, v)*dx
 
+# Wrappers around SLEPcEigenSolver for test_slepc_eigensolver_gen_hermitian
+def SLEPcEigenSolverOperatorsFromInit(K, M):
+    return SLEPcEigenSolver(K, M)
+    
+def SLEPcEigenSolverOperatorsFromSetOperators(K, M):
+    slepc_eigen_solver = SLEPcEigenSolver(K.mpi_comm())
+    slepc_eigen_solver.set_operators(K, M)
+    return slepc_eigen_solver
 
 # Fixtures
 
@@ -82,11 +88,12 @@ def test_set_from_options():
     assert solver.get_options_prefix() == prefix
 
 @skip_if_not_PETsc_or_not_slepc
-def test_slepc_eigensolver_gen_hermitian(K_M):
+ at pytest.mark.parametrize("SLEPcEigenSolverWrapper", (SLEPcEigenSolverOperatorsFromInit, SLEPcEigenSolverOperatorsFromSetOperators))
+def test_slepc_eigensolver_gen_hermitian(K_M, SLEPcEigenSolverWrapper):
     "Test SLEPc eigen solver"
 
     K, M = K_M
-    esolver = SLEPcEigenSolver(K, M)
+    esolver = SLEPcEigenSolverWrapper(K, M)
 
     esolver.parameters["solver"] = "krylov-schur"
     esolver.parameters["spectral_transform"] = 'shift-and-invert'
diff --git a/test/unit/python/la/test_solve.py b/test/unit/python/la/test_solve.py
index b295f0a..9d6a762 100755
--- a/test/unit/python/la/test_solve.py
+++ b/test/unit/python/la/test_solve.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the solve interface"""
 
 # Copyright (C) 2011 Garth N. Wells
diff --git a/test/unit/python/la/test_tensor_layout.py b/test/unit/python/la/test_tensor_layout.py
index e044456..b244e1e 100644
--- a/test/unit/python/la/test_tensor_layout.py
+++ b/test/unit/python/la/test_tensor_layout.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for TensorLayout and SparsityPattern interface"""
 
 # Copyright (C) 2015 Jan Blechta
diff --git a/test/unit/python/la/test_vector.py b/test/unit/python/la/test_vector.py
index 3a59aa5..739d017 100755
--- a/test/unit/python/la/test_vector.py
+++ b/test/unit/python/la/test_vector.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the Vector interface"""
 
 # Copyright (C) 2011-2014 Garth N. Wells
@@ -136,10 +134,7 @@ class TestVectorForAnyBackend:
         from numpy import empty
         n = 301
         v0 = Vector(mpi_comm_world(), n)
-        if has_pybind11():
-            data = v0.array()
-        else:
-            data = v0.get_local()
+        data = v0.get_local()
 
     def test_set_local(self, any_backend):
         from numpy import zeros
@@ -389,27 +384,39 @@ class TestVectorForAnyBackend:
         # Test for ordinary Vector
         v = Vector(mpi_comm_world(), 301)
         v = as_backend_type(v)
-        array = v.array()
+
         if has_pybind11():
-            assert array.flags.owndata == False
+            rw_array = v.array_view()
+            assert rw_array.flags.owndata == False
             with pytest.raises(Exception):
-                array.resize([10])
+                rw_array.resize([10])
+
+            # Check that the array is a writable view
+            rw_array[0] = 42
+            ro_array = v.get_local()
+            assert ro_array[0] == 42
+
+            # Test for as_backend_type Vector
+            v = as_backend_type(v)
+            rw_array2 = v.array_view()
+            assert (rw_array2 == ro_array).all()
+
         else:
+            ro_array = v.get_local()
             data = v.data()
-            assert (data == array).all()
-
+            assert (data == ro_array).all()
 
-            # Test none writeable of a shallow copy of the data
+            # Test that a shallow copy of the data is not writable
             data = v.data(False)
             def write_data(data):
                 data[0] = 1
             with pytest.raises(Exception):
                 write_data(data)
 
-            # Test for as_backend_typeed Vector
+            # Test for as_backend_type Vector
             v = as_backend_type(v)
             data = v.data()
-            assert (data==array).all()
+            assert (data == ro_array).all()
 
 
     # xfail on TypeError
diff --git a/test/unit/python/mesh/test_mesh_data.py b/test/unit/python/log/test_log.py
old mode 100755
new mode 100644
similarity index 68%
copy from test/unit/python/mesh/test_mesh_data.py
copy to test/unit/python/log/test_log.py
index 7145ef4..b071cdc
--- a/test/unit/python/mesh/test_mesh_data.py
+++ b/test/unit/python/log/test_log.py
@@ -1,8 +1,6 @@
-#!/usr/bin/env py.test
+"""Unit tests for the log"""
 
-"Unit tests for the MeshData class"
-
-# Copyright (C) 2011 Anders Logg
+# Copyright (C) 2017 Tormod Landet
 #
 # This file is part of DOLFIN.
 #
@@ -18,16 +16,14 @@
 #
 # You should have received a copy of the GNU Lesser General Public License
 # along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
-#
-# First added:  2011-08-22
-# Last changed: 2011-08-22
-
-import pytest
-from dolfin import *
 
+import dolfin
+from dolfin_utils.test import skip_if_not_pybind11
 
-def test_meshfunction():
-    "Test input/output"
 
-    mesh = UnitCubeMesh(3, 3, 3)
-    f = mesh.data().create_array("foo", 3)
+ at skip_if_not_pybind11
+def test_log_level_comparable():
+    info = dolfin.LogLevel.INFO
+    warning = dolfin.LogLevel.WARNING
+    assert info < warning
+    assert warning < 1000
diff --git a/test/unit/python/math/test_math.py b/test/unit/python/math/test_math.py
index 6e32fa8..f4c3ba3 100755
--- a/test/unit/python/math/test_math.py
+++ b/test/unit/python/math/test_math.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for basic math functions"""
 
 # Copyright (C) 2011-2014 Martin Alnaes
diff --git a/test/unit/python/mesh/test_boundary_mesh.py b/test/unit/python/mesh/test_boundary_mesh.py
old mode 100755
new mode 100644
index f632f5e..b013bf5
--- a/test/unit/python/mesh/test_boundary_mesh.py
+++ b/test/unit/python/mesh/test_boundary_mesh.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 "Unit tests for BoundaryMesh library"
 
 # Copyright (C) 2012 Garth N. Wells
@@ -35,7 +33,7 @@ def test_1D_mesh():
     # Create global boundary mesh
     bmesh1 = BoundaryMesh(mesh, "exterior")
     assert MPI.sum(mesh.mpi_comm(), bmesh1.num_cells()) == 2
-    assert bmesh1.size_global(0) == 2
+    assert bmesh1.num_entities_global(0) == 2
     assert bmesh1.topology().dim() == 0
 
 
@@ -45,7 +43,7 @@ def test_2D_mesh():
     # Create global boundary mesh
     bmesh1 = BoundaryMesh(mesh, "exterior")
     assert MPI.sum(mesh.mpi_comm(), bmesh1.num_cells()) == 4*8
-    assert bmesh1.size_global(1) == 4*8
+    assert bmesh1.num_entities_global(1) == 4*8
     assert bmesh1.topology().dim() == 1
 
 
@@ -55,5 +53,5 @@ def test_3D_mesh():
     # Create global boundary mesh
     bmesh1 = BoundaryMesh(mesh, "exterior")
     assert MPI.sum(mesh.mpi_comm(), bmesh1.num_cells()) == 6*8*8*2
-    assert bmesh1.size_global(2) == 6*8*8*2
+    assert bmesh1.num_entities_global(2) == 6*8*8*2
     assert bmesh1.topology().dim() == 2
diff --git a/test/unit/python/mesh/test_cell.py b/test/unit/python/mesh/test_cell.py
old mode 100755
new mode 100644
index 90ccf9b..8fee151
--- a/test/unit/python/mesh/test_cell.py
+++ b/test/unit/python/mesh/test_cell.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the Cell class"""
 
 # Copyright (C) 2013 Anders Logg
@@ -77,13 +75,13 @@ def test_issue_568():
 
 def test_volume_quadrilateralR2():
 
-    mesh = UnitQuadMesh.create(mpi_comm_self(), 1, 1)
+    mesh = UnitSquareMesh.create(mpi_comm_self(), 1, 1, CellType.Type_quadrilateral)
     cell = Cell(mesh, 0)
 
     assert cell.volume() == 1.0
 
 
- at pytest.mark.parametrize('coordinates', [[[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [1.0, 1.0, 0.0]], 
+ at pytest.mark.parametrize('coordinates', [[[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [1.0, 1.0, 0.0]],
     [[0.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0], [0.0, 1.0, 1.0]]])
 def test_volume_quadrilateralR3(coordinates):
 
diff --git a/test/unit/python/mesh/test_edge.py b/test/unit/python/mesh/test_edge.py
old mode 100755
new mode 100644
index 3831e18..7fe462c
--- a/test/unit/python/mesh/test_edge.py
+++ b/test/unit/python/mesh/test_edge.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the Edge class"""
 
 # Copyright (C) 2011 Garth N. Wells
diff --git a/test/unit/python/mesh/test_face.py b/test/unit/python/mesh/test_face.py
old mode 100755
new mode 100644
index dc72cd7..9375bb6
--- a/test/unit/python/mesh/test_face.py
+++ b/test/unit/python/mesh/test_face.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the Face class"""
 
 # Copyright (C) 2011 Garth N. Wells
diff --git a/test/unit/python/mesh/test_mesh_data.py b/test/unit/python/mesh/test_facet.py
old mode 100755
new mode 100644
similarity index 61%
copy from test/unit/python/mesh/test_mesh_data.py
copy to test/unit/python/mesh/test_facet.py
index 7145ef4..d989886
--- a/test/unit/python/mesh/test_mesh_data.py
+++ b/test/unit/python/mesh/test_facet.py
@@ -1,8 +1,6 @@
-#!/usr/bin/env py.test
+"""Unit tests for the Facet class"""
 
-"Unit tests for the MeshData class"
-
-# Copyright (C) 2011 Anders Logg
+# Copyright (C) 2017 Tormod Landet
 #
 # This file is part of DOLFIN.
 #
@@ -18,16 +16,16 @@
 #
 # You should have received a copy of the GNU Lesser General Public License
 # along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
-#
-# First added:  2011-08-22
-# Last changed: 2011-08-22
-
-import pytest
-from dolfin import *
 
+from dolfin import UnitSquareMesh, facets
 
-def test_meshfunction():
-    "Test input/output"
 
-    mesh = UnitCubeMesh(3, 3, 3)
-    f = mesh.data().create_array("foo", 3)
+def test_normal():
+    "Test that the normal() method is wrapped"
+    mesh = UnitSquareMesh(4, 4)
+    for facet in facets(mesh):
+        n = facet.normal()
+        nx, ny, nz = n.x(), n.y(), n.z()
+        assert isinstance(nx, float)
+        assert isinstance(ny, float)
+        assert isinstance(nz, float)
diff --git a/test/unit/python/mesh/test_ghost_mesh.py b/test/unit/python/mesh/test_ghost_mesh.py
old mode 100755
new mode 100644
index 269ea96..938c104
--- a/test/unit/python/mesh/test_ghost_mesh.py
+++ b/test/unit/python/mesh/test_ghost_mesh.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 "Unit tests for ghosted meshes"
 
 # Copyright (C) 2016 Garth N. Wells
diff --git a/test/unit/python/mesh/test_manifold_point_search.py b/test/unit/python/mesh/test_manifold_point_search.py
old mode 100755
new mode 100644
index 466bddb..b6659bb
--- a/test/unit/python/mesh/test_manifold_point_search.py
+++ b/test/unit/python/mesh/test_manifold_point_search.py
@@ -1,5 +1,4 @@
-#!/usr/bin/env py.test
-import pytest
+
 import numpy
 from dolfin import *
 
@@ -30,8 +29,8 @@ def test_manifold_point_search():
     mesh.init_cell_orientations(Expression(("0.0", "0.0", "1.0"), degree=0))
 
     bb = mesh.bounding_box_tree()
-    p = Point(2.0/3.0, 1.0/3.0, 2.0/3.0)
+    p = Point(0.5, 0.25, 0.75)
     assert bb.compute_first_entity_collision(p) == 0
 
-    p = Point(1.0/3.0, 2.0/3.0, 2.0/3.0)
+    p = Point(0.25, 0.5, 0.75)
     assert bb.compute_first_entity_collision(p) == 1
diff --git a/test/unit/python/mesh/test_mesh.py b/test/unit/python/mesh/test_mesh.py
old mode 100755
new mode 100644
index 708f7cb..eef93cb
--- a/test/unit/python/mesh/test_mesh.py
+++ b/test/unit/python/mesh/test_mesh.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 "Unit tests for the mesh library"
 
 # Copyright (C) 2006 Anders Logg
@@ -26,13 +24,20 @@ import numpy
 import six
 from six.moves import range
 
+import sys
+import os
+
+import FIAT
 from dolfin import *
 from dolfin_utils.test import fixture, set_parameters_fixture
 from dolfin_utils.test import skip_in_parallel, xfail_in_parallel
 from dolfin_utils.test import cd_tempdir
-import FIAT
+from dolfin_utils.test import skip_if_not_pybind11
 
-import os
+
+if has_pybind11():
+    CellType.Type_quadrilateral = CellType.Type.quadrilateral
+    CellType.Type_hexahedron = CellType.Type.hexahedron
 
 
 @fixture
@@ -142,18 +147,17 @@ def test_UFLDomain(interval, square, rectangle, cube, box):
 def test_UnitSquareMesh():
     """Create mesh of unit square."""
     mesh = UnitSquareMesh(5, 7)
-    assert mesh.size_global(0) == 48
-    assert mesh.size_global(2) == 70
+    assert mesh.num_entities_global(0) == 48
+    assert mesh.num_entities_global(2) == 70
 
 
 def test_UnitSquareMeshDistributed():
     """Create mesh of unit square."""
     mesh = UnitSquareMesh(mpi_comm_world(), 5, 7)
-    assert mesh.size_global(0) == 48
-    assert mesh.size_global(2) == 70
-    if has_petsc4py():
+    assert mesh.num_entities_global(0) == 48
+    assert mesh.num_entities_global(2) == 70
+    if has_petsc4py() and not has_pybind11():
         import petsc4py
-        assert isinstance(mpi_comm_world(), petsc4py.PETSc.Comm)
         assert isinstance(mesh.mpi_comm(), petsc4py.PETSc.Comm)
         assert mesh.mpi_comm() == mpi_comm_world()
 
@@ -163,9 +167,8 @@ def test_UnitSquareMeshLocal():
     mesh = UnitSquareMesh(mpi_comm_self(), 5, 7)
     assert mesh.num_vertices() == 48
     assert mesh.num_cells() == 70
-    if has_petsc4py():
+    if has_petsc4py() and not has_pybind11():
         import petsc4py
-        assert isinstance(mpi_comm_self(), petsc4py.PETSc.Comm)
         assert isinstance(mesh.mpi_comm(), petsc4py.PETSc.Comm)
         assert mesh.mpi_comm() == mpi_comm_self()
 
@@ -173,15 +176,15 @@ def test_UnitSquareMeshLocal():
 def test_UnitCubeMesh():
     """Create mesh of unit cube."""
     mesh = UnitCubeMesh(5, 7, 9)
-    assert mesh.size_global(0) == 480
-    assert mesh.size_global(3) == 1890
+    assert mesh.num_entities_global(0) == 480
+    assert mesh.num_entities_global(3) == 1890
 
 
 def test_UnitCubeMeshDistributed():
     """Create mesh of unit cube."""
     mesh = UnitCubeMesh(mpi_comm_world(), 5, 7, 9)
-    assert mesh.size_global(0) == 480
-    assert mesh.size_global(3) == 1890
+    assert mesh.num_entities_global(0) == 480
+    assert mesh.num_entities_global(3) == 1890
 
 
 def test_UnitCubeMeshDistributedLocal():
@@ -192,49 +195,49 @@ def test_UnitCubeMeshDistributedLocal():
 
 
 def test_UnitQuadMesh():
-    mesh = UnitQuadMesh.create(mpi_comm_world(), 5, 7)
-    assert mesh.size_global(0) == 48
-    assert mesh.size_global(2) == 35
+    mesh = UnitSquareMesh.create(5, 7, CellType.Type_quadrilateral)
+    assert mesh.num_entities_global(0) == 48
+    assert mesh.num_entities_global(2) == 35
 
 
 def test_UnitHexMesh():
-    mesh = UnitHexMesh.create(mpi_comm_world(), 5, 7, 9)
-    assert mesh.size_global(0) == 480
-    assert mesh.size_global(3) == 315
+    mesh = UnitCubeMesh.create(5, 7, 9, CellType.Type_hexahedron)
+    assert mesh.num_entities_global(0) == 480
+    assert mesh.num_entities_global(3) == 315
 
 
 def test_RefineUnitIntervalMesh():
     """Refine mesh of unit interval."""
     mesh = UnitIntervalMesh(20)
-    cell_markers = CellFunction("bool", mesh)
+    cell_markers = MeshFunction("bool", mesh, mesh.topology().dim(), False)
     cell_markers[0] = (MPI.rank(mesh.mpi_comm()) == 0)
     mesh2 = refine(mesh, cell_markers)
-    assert mesh2.size_global(0) == 22
-    assert mesh2.size_global(1) == 21
+    assert mesh2.num_entities_global(0) == 22
+    assert mesh2.num_entities_global(1) == 21
 
 
 def test_RefineUnitSquareMesh():
     """Refine mesh of unit square."""
     mesh = UnitSquareMesh(5, 7)
     mesh = refine(mesh)
-    assert mesh.size_global(0) == 165
-    assert mesh.size_global(2) == 280
+    assert mesh.num_entities_global(0) == 165
+    assert mesh.num_entities_global(2) == 280
 
 
 def test_RefineUnitCubeMesh():
     """Refine mesh of unit cube."""
     mesh = UnitCubeMesh(5, 7, 9)
     mesh = refine(mesh)
-    assert mesh.size_global(0) == 3135
-    assert mesh.size_global(3) == 15120
+    assert mesh.num_entities_global(0) == 3135
+    assert mesh.num_entities_global(3) == 15120
 
 
 def test_BoundaryComputation():
     """Compute boundary of mesh."""
     mesh = UnitCubeMesh(2, 2, 2)
     boundary = BoundaryMesh(mesh, "exterior")
-    assert boundary.size_global(0) == 26
-    assert boundary.size_global(2) == 48
+    assert boundary.num_entities_global(0) == 26
+    assert boundary.num_entities_global(2) == 48
 
 
 @xfail_in_parallel
@@ -283,6 +286,14 @@ def test_Read(cd_tempdir):
     # assert all(f.array() == f.array())
 
 
+def test_hash():
+    h1 = UnitSquareMesh(4, 4).hash()
+    h2 = UnitSquareMesh(4, 5).hash()
+    h3 = UnitSquareMesh(4, 4).hash()
+    assert h1 == h3
+    assert h1 != h2
+
+
 @skip_in_parallel
 def test_SubsetIterators(mesh):
     def inside1(x):
@@ -292,7 +303,7 @@ def test_SubsetIterators(mesh):
         return x[0] >= 0.5
     sd1 = AutoSubDomain(inside1)
     sd2 = AutoSubDomain(inside2)
-    cf = CellFunction('size_t', mesh)
+    cf = MeshFunction('size_t', mesh, mesh.topology().dim())
     cf.set_all(0)
     sd1.mark(cf, 1)
     sd2.mark(cf, 2)
@@ -469,8 +480,8 @@ mesh_factories = [
     (SphericalShellMesh.create, (mpi_comm_world(), 1,)),
     (SphericalShellMesh.create, (mpi_comm_world(), 2,)),
     (UnitCubeMesh, (2, 2, 2)),
-    (UnitQuadMesh.create, (4, 4)),
-    (UnitHexMesh.create, (2, 2, 2)),
+    (UnitSquareMesh.create, (4, 4, CellType.Type_quadrilateral)),
+    (UnitCubeMesh.create, (2, 2, 2, CellType.Type_hexahedron)),
     # FIXME: Add mechanism for testing meshes coming from IO
 ]
 
@@ -485,8 +496,8 @@ mesh_factories_broken_shared_entities = [
     xfail_in_parallel((SphericalShellMesh.create, (mpi_comm_world(), 1,))),
     xfail_in_parallel((SphericalShellMesh.create, (mpi_comm_world(), 2,))),
     (UnitCubeMesh, (2, 2, 2)),
-    (UnitQuadMesh.create, (4, 4)),
-    (UnitHexMesh.create, (2, 2, 2)),
+    (UnitSquareMesh.create, (4, 4, CellType.Type_quadrilateral)),
+    (UnitCubeMesh.create, (2, 2, 2, CellType.Type_hexahedron)),
 ]
 
 # FIXME: Fix this xfail
@@ -494,10 +505,10 @@ def xfail_ghosted_quads_hexes(mesh_factory, ghost_mode):
     """Xfail when mesh_factory on quads/hexes uses
     shared_vertex mode. Needs implementing.
     """
-    if mesh_factory in [UnitQuadMesh.create, UnitHexMesh.create]:
+    if mesh_factory in [UnitSquareMesh.create, UnitCubeMesh.create]:
         if ghost_mode == 'shared_vertex':
             pytest.xfail(reason="Missing functionality in '{}' with '' "
-                                "mode".format(mesh_factory, ghost_mode))
+                         "mode".format(mesh_factory, ghost_mode))
 
 
 @pytest.mark.parametrize('mesh_factory', mesh_factories_broken_shared_entities)
@@ -526,16 +537,16 @@ def test_shared_entities(mesh_factory, ghost_mode):
                     assert isinstance(sharing, set)
                     assert (len(sharing) > 0) == e.is_shared()
 
-        n_entities = mesh.size(shared_dim)
-        n_global_entities = mesh.size_global(shared_dim)
+        n_entities = mesh.num_entities(shared_dim)
+        n_global_entities = mesh.num_entities_global(shared_dim)
         shared_entities = mesh.topology().shared_entities(shared_dim)
 
         # Check that sum(local-shared) = global count
         rank = MPI.rank(mesh.mpi_comm())
         ct = sum(1 for val in six.itervalues(shared_entities) if list(val)[0] < rank)
-        size_global = MPI.sum(mesh.mpi_comm(), mesh.size(shared_dim) - ct)
+        num_entities_global = MPI.sum(mesh.mpi_comm(), mesh.num_entities(shared_dim) - ct)
 
-        assert size_global ==  mesh.size_global(shared_dim)
+        assert num_entities_global ==  mesh.num_entities_global(shared_dim)
 
 
 @pytest.mark.parametrize('mesh_factory', mesh_factories)
@@ -599,7 +610,7 @@ def test_mesh_ufc_ordering(mesh_factory, ghost_mode):
 
             # NOTE: DOLFIN UFC noncompliance!
             # DOLFIN has increasing indices only for d-0 incidence
-            # with any d; UFC convention for d-d1 with d>d1 is not
+            # with any d; UFC convention for d-d1 with d>d1>0 is not
             # respected in DOLFIN
             if d1 != 0:
                 continue
@@ -618,3 +629,25 @@ def test_mesh_ufc_ordering(mesh_factory, ghost_mode):
 
                 # Check that d1-subentities of d-entity have increasing indices
                 assert sorted(subentities_indices) == subentities_indices
+
+
+def test_mesh_topology_reference():
+    """Check that Mesh.topology() returns a reference rather
+    than copy"""
+    mesh = UnitSquareMesh(4, 4)
+    assert mesh.topology().id() == mesh.topology().id()
+
+
+# Reference counting does not work like expected with SWIG,
+# SWIG handles the lifetime differently
+ at skip_if_not_pybind11
+def test_mesh_topology_lifetime():
+    """Check that lifetime of Mesh.topology() is bound to
+    underlying mesh object"""
+    mesh = UnitSquareMesh(4, 4)
+
+    rc = sys.getrefcount(mesh)
+    topology = mesh.topology()
+    assert sys.getrefcount(mesh) == rc + 1
+    del topology
+    assert sys.getrefcount(mesh) == rc
diff --git a/test/unit/python/mesh/test_mesh_coloring.py b/test/unit/python/mesh/test_mesh_coloring.py
old mode 100755
new mode 100644
diff --git a/test/unit/python/mesh/test_mesh_data.py b/test/unit/python/mesh/test_mesh_data.py
old mode 100755
new mode 100644
index 7145ef4..7b1f0d4
--- a/test/unit/python/mesh/test_mesh_data.py
+++ b/test/unit/python/mesh/test_mesh_data.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 "Unit tests for the MeshData class"
 
 # Copyright (C) 2011 Anders Logg
diff --git a/test/unit/python/mesh/test_mesh_editor.py b/test/unit/python/mesh/test_mesh_editor.py
old mode 100755
new mode 100644
index ad11b8b..36cc3ba
--- a/test/unit/python/mesh/test_mesh_editor.py
+++ b/test/unit/python/mesh/test_mesh_editor.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 "Unit tests for the MeshEditor class"
 
 # Copyright (C) 2006-2011 Anders Logg
diff --git a/test/unit/python/mesh/test_mesh_function.py b/test/unit/python/mesh/test_mesh_function.py
old mode 100755
new mode 100644
index 58052b7..a562fa8
--- a/test/unit/python/mesh/test_mesh_function.py
+++ b/test/unit/python/mesh/test_mesh_function.py
@@ -24,9 +24,9 @@ from six.moves import xrange as range
 from dolfin_utils.test import fixture, skip_in_parallel, skip_if_pybind11
 
 
- at pytest.fixture(params=range(5))
+ at pytest.fixture(params=range(4))
 def name(request):
-    names = ["Cell", "Vertex", "Edge", "Face", "Facet"]
+    names = [3, 0, 1, 2]
     return names[request.param]
 
 
@@ -43,12 +43,12 @@ def mesh():
 
 @fixture
 def funcs(mesh):
-    names = ["Cell", "Vertex", "Edge", "Face", "Facet"]
+    names = [3, 0, 1, 2]
     tps = ['int', 'size_t', 'bool', 'double']
     funcs = {}
     for tp in tps:
         for name in names:
-            funcs[(tp, name)] = eval("%sFunction('%s', mesh)" % (name, tp))
+            funcs[(tp, name)] = eval("MeshFunction('%s', mesh, %d)" % (tp, name))
     return funcs
 
 
@@ -63,13 +63,13 @@ def f(cube):
 
 
 def test_size(tp, name, funcs, mesh):
-    if name is "Vertex":
+    if name == 0:
         a = len(funcs[(tp, name)])
         b = mesh.num_vertices()
         assert a == b
     else:
         a = len(funcs[(tp, name)])
-        b = getattr(mesh, "num_%ss" % name.lower())()
+        b = mesh.num_entities(name)
         assert a == b
 
 
@@ -146,14 +146,14 @@ def test_Assign(f, cube):
 def test_meshfunction_where_equal():
     mesh = UnitSquareMesh(2, 2)
 
-    cf = CellFunction("size_t", mesh)
+    cf = MeshFunction("size_t", mesh, mesh.topology().dim())
     cf.set_all(1)
     cf[0] = 3
     cf[3] = 3
     assert list(cf.where_equal(3)) == [0, 3]
     assert list(cf.where_equal(1)) == [1, 2, 4, 5, 6, 7]
 
-    ff = FacetFunction("size_t", mesh)
+    ff = MeshFunction("size_t", mesh, mesh.topology().dim()-1)
     ff.set_all(0)
     ff[0] = 1
     ff[2] = 3
@@ -162,7 +162,7 @@ def test_meshfunction_where_equal():
     assert list(ff.where_equal(3)) == [2, 3]
     assert list(ff.where_equal(0)) == [1] + list(range(4, ff.size()))
 
-    vf = VertexFunction("size_t", mesh)
+    vf = MeshFunction("size_t", mesh, 0)
     vf.set_all(3)
     vf[1] = 1
     vf[2] = 1
diff --git a/test/unit/python/mesh/test_mesh_iterator.py b/test/unit/python/mesh/test_mesh_iterator.py
old mode 100755
new mode 100644
index 3d44994..9e1f30e
--- a/test/unit/python/mesh/test_mesh_iterator.py
+++ b/test/unit/python/mesh/test_mesh_iterator.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 "Unit tests for MeshIterator and subclasses"
 
 # Copyright (C) 2006-2011 Anders Logg
diff --git a/test/unit/python/mesh/test_mesh_markers.py b/test/unit/python/mesh/test_mesh_markers.py
old mode 100755
new mode 100644
index 63805ec..0996506
--- a/test/unit/python/mesh/test_mesh_markers.py
+++ b/test/unit/python/mesh/test_mesh_markers.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the class MeshMarkers. These unit test actually test
 a bit more than that, since they also test marking of meshes and the
 interaction between Mesh - MeshDomains - MeshMarkers"""
diff --git a/test/unit/python/mesh/test_mesh_quality.py b/test/unit/python/mesh/test_mesh_quality.py
old mode 100755
new mode 100644
index ae5a28b..9739593
--- a/test/unit/python/mesh/test_mesh_quality.py
+++ b/test/unit/python/mesh/test_mesh_quality.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 "Unit tests for the MeshQuality class"
 
 # Copyright (C) 2013 Garth N. Wells
diff --git a/test/unit/python/mesh/test_mesh_transformation.py b/test/unit/python/mesh/test_mesh_transformation.py
old mode 100755
new mode 100644
index af8a8dd..f13f8e1
--- a/test/unit/python/mesh/test_mesh_transformation.py
+++ b/test/unit/python/mesh/test_mesh_transformation.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 "Unit tests for the mesh library"
 
 # Copyright (C) 2012 Anders Logg
diff --git a/test/unit/python/mesh/test_mesh_value_collection.py b/test/unit/python/mesh/test_mesh_value_collection.py
old mode 100755
new mode 100644
index 187c141..b8c947e
--- a/test/unit/python/mesh/test_mesh_value_collection.py
+++ b/test/unit/python/mesh/test_mesh_value_collection.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for MeshValueCollection"""
 
 # Copyright (C) 2011 Johan Hake
@@ -98,7 +96,7 @@ def test_assign_2D_vertices():
 def test_mesh_function_assign_2D_cells():
     mesh = UnitSquareMesh(3, 3)
     ncells = mesh.num_cells()
-    f = CellFunction("int", mesh)
+    f = MeshFunction("int", mesh, mesh.topology().dim())
     for cell in cells(mesh):
         f[cell] = ncells - cell.index()
 
@@ -116,7 +114,7 @@ def test_mesh_function_assign_2D_cells():
 
     h = MeshValueCollection("int", mesh, 2)
     global_indices = mesh.topology().global_indices(2)
-    ncells_global = mesh.size_global(2)
+    ncells_global = mesh.num_entities_global(2)
     for cell in cells(mesh):
         if global_indices[cell.index()] in [5, 8, 10]:
             continue
@@ -137,7 +135,7 @@ def test_mesh_function_assign_2D_cells():
 def test_mesh_function_assign_2D_facets():
     mesh = UnitSquareMesh(3, 3)
     mesh.init(1)
-    f = FacetFunction("int", mesh, 25)
+    f = MeshFunction("int", mesh, mesh.topology().dim()-1, 25)
     for cell in cells(mesh):
         for i, facet in enumerate(facets(cell)):
             assert 25 == f[facet]
@@ -160,7 +158,7 @@ def test_mesh_function_assign_2D_facets():
 def test_mesh_function_assign_2D_vertices():
     mesh = UnitSquareMesh(3, 3)
     mesh.init(0)
-    f = VertexFunction("int", mesh, 25)
+    f = MeshFunction("int", mesh, 0, 25)
     g = MeshValueCollection("int", mesh, 0)
     g.assign(f)
     assert mesh.num_vertices() == f.size()
diff --git a/test/unit/python/mesh/test_multi_mesh_integration.py b/test/unit/python/mesh/test_multi_mesh_integration.py
deleted file mode 100755
index 6caa0e6..0000000
--- a/test/unit/python/mesh/test_multi_mesh_integration.py
+++ /dev/null
@@ -1,113 +0,0 @@
-#!/usr/bin/env py.test
-
-"""Unit tests for MultiMesh Integration"""
-
-# Copyright (C) 2014 Anders Logg and August Johansson
-#
-# This file is part of DOLFIN.
-#
-# DOLFIN is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# DOLFIN 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
-#
-# First added:  2014-03-04
-# Last changed: 2015-11-30
-
-from __future__ import print_function
-import numpy
-import pytest
-from dolfin import *
-from six.moves import xrange as range
-
-from dolfin_utils.test import skip_in_parallel, skip_if_pybind11
-
-
-def triangulation_to_mesh_2d(triangulation):
-    editor = MeshEditor()
-    mesh = Mesh()
-    editor.open(mesh, 2, 2)
-    num_cells = len(triangulation) / 6
-    num_vertices = len(triangulation) / 2
-    editor.init_cells(num_cells)
-    editor.init_vertices(num_vertices)
-    for i in range(num_cells):
-        editor.add_cell(i, 3*i, 3*i + 1, 3*i + 2)
-    for i in range(num_vertices):
-        editor.add_vertex(i, triangulation[2*i], triangulation[2*i + 1])
-    editor.close()
-    return mesh
-
-
- at skip_in_parallel
- at skip_if_pybind11(reason="Not supported in pybind11")
-def test_integrate():
-    # Create two meshes of the unit square
-    mesh_0 = UnitSquareMesh(10, 10)
-    mesh_1 = UnitSquareMesh(11, 11)
-
-    # Translate
-    pt = Point(0.632350,0.278498)
-    mesh_1.translate(pt)
-    exactarea = 2-(1-pt[0])*(1-pt[1])
-
-    multimesh = MultiMesh()
-    multimesh.add(mesh_0)
-    multimesh.add(mesh_1)
-    multimesh.build()
-
-    for part in range(0, multimesh.num_parts()):
-        #print(part)
-        covered = multimesh.covered_cells(part)
-        uncut = multimesh.uncut_cells(part)
-        cut = multimesh.cut_cells(part)
-        qr = multimesh.quadrature_rule_cut_cells(part)
-        #print("covered")
-        #print(covered)
-        #print("uncut")
-        #print(uncut)
-        #print("cut")
-        #print(cut)
-        #print("quadrature")
-        #print(qr)
-
-    # area = assemble(L_0) + assemble(L_1)
-    # MMA = MultiMeshAssembler()
-    # area = MMA.assemble(L_multi)
-    # area = assemble(L_multi)
-    # assert round(area - exactarea, 7) == 0
-
-
-    # # Translate second mesh randomly
-    # #dx = Point(numpy.random.rand(),numpy.random.rand())
-    # dx = Point(0.278498, 0.546881)
-    # mesh_1.translate(dx)
-
-    # exactvolume = (1 - abs(dx[0]))*(1 - abs(dx[1]))
-
-    # # Compute triangulation volume using the quadrature rules
-    # volume = 0
-    # for c0 in cells(mesh_0):
-    #     for c1 in cells(mesh_1):
-    #         triangulation = c0.triangulate_intersection(c1)
-    #         if (triangulation.size>0):
-    #             # compute_quadrature_rule(triangulation,
-    #             #                         2,2,1)
-    #             compute_quadrature_rule(c0,1)
-
-    #             tmesh = triangulation_to_mesh_2d(triangulation)
-    #             for t in cells(tmesh):
-    #                 volume += t.volume()
-
-
-
-    # errorstring = "translation=" + str(dx[0]) + str(" ") + str(dx[1])
-    # assert round(volume - exactvolume, 7, errorstring)
diff --git a/test/unit/python/mesh/test_periodic_boundary_computation.py b/test/unit/python/mesh/test_periodic_boundary_computation.py
old mode 100755
new mode 100644
index dd9b491..ec516a7
--- a/test/unit/python/mesh/test_periodic_boundary_computation.py
+++ b/test/unit/python/mesh/test_periodic_boundary_computation.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for PeriodicBoundaryComputation"""
 
 # Copyright (C) 2013 Mikael Mortensen
diff --git a/test/unit/python/mesh/test_sub_domain.py b/test/unit/python/mesh/test_sub_domain.py
old mode 100755
new mode 100644
index 947d97c..4432e02
--- a/test/unit/python/mesh/test_sub_domain.py
+++ b/test/unit/python/mesh/test_sub_domain.py
@@ -148,10 +148,10 @@ def test_creation_and_marking():
         mesh.init()
 
         for left, right in subdomain_pairs:
-            for MeshFunc, f_dim in [(VertexFunction, 0),
-                                    (FacetFunction, dim - 1),
-                                    (CellFunction, dim)]:
-                f = MeshFunc("size_t", mesh, 0)
+            for t_dim, f_dim in [(0, 0),
+                                    (mesh.topology().dim()-1, dim - 1),
+                                    (mesh.topology().dim(), dim)]:
+                f = MeshFunction("size_t", mesh, t_dim, 0)
 
                 left.mark(f, 1)
                 right.mark(f, 2)
@@ -174,10 +174,10 @@ def test_creation_and_marking():
                         MPI.sum(mesh.mpi_comm(), float((f.array() == 1).sum())),
                 ])
 
-        for MeshFunc, f_dim in [(VertexFunction, 0),
-                                (FacetFunction, dim-1),
-                                (CellFunction, dim)]:
-            f = MeshFunc("size_t", mesh, 0)
+        for t_dim, f_dim in [(0, 0),
+                                (mesh.topology().dim()-1, dim-1),
+                                (mesh.topology().dim(), dim)]:
+            f = MeshFunction("size_t", mesh, t_dim, 0)
 
             empty.mark(f, 1)
             every.mark(f, 2)
@@ -296,10 +296,10 @@ def test_creation_and_marking_pybind11():
         mesh.init()
 
         for left, right in subdomain_pairs:
-            for MeshFunc, f_dim in [(VertexFunction, 0),
-                                    (FacetFunction, dim - 1),
-                                    (CellFunction, dim)]:
-                f = MeshFunc("size_t", mesh, 0)
+            for t_dim, f_dim in [(0, 0),
+                                    (mesh.topology().dim()-1, dim - 1),
+                                    (mesh.topology().dim(), dim)]:
+                f = MeshFunction("size_t", mesh, t_dim, 0)
 
                 left.mark(f, int(1))
                 right.mark(f, 2)
@@ -322,10 +322,10 @@ def test_creation_and_marking_pybind11():
                         MPI.sum(mesh.mpi_comm(), float((f.array() == 1).sum())),
                 ])
 
-        for MeshFunc, f_dim in [(VertexFunction, 0),
-                                (FacetFunction, dim-1),
-                                (CellFunction, dim)]:
-            f = MeshFunc("size_t", mesh, 0)#
+        for t_dim, f_dim in [(0, 0),
+                                (mesh.topology().dim()-1, dim-1),
+                                (mesh.topology().dim(), dim)]:
+            f = MeshFunction("size_t", mesh, t_dim, 0)#
 
             empty.mark(f, 1)
             every.mark(f, 2)
diff --git a/test/unit/python/mesh/test_sub_mesh.py b/test/unit/python/mesh/test_sub_mesh.py
old mode 100755
new mode 100644
index c0e083e..5f43219
--- a/test/unit/python/mesh/test_sub_mesh.py
+++ b/test/unit/python/mesh/test_sub_mesh.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 "Unit tests for the mesh library"
 
 # Copyright (C) 2006 Anders Logg
@@ -40,7 +38,7 @@ def test_creation(MeshFunc):
     mesh = MeshFunc(*args)
     dim_t = mesh.topology().dim()
     mesh.domains().init(dim_t)
-    domains = CellFunction("size_t", mesh, 0)
+    domains = MeshFunction("size_t", mesh, mesh.topology().dim(), 0)
     for cell in cells(mesh):
         # Mark half the cells
         if cell.index() > mesh.num_cells()/2:
@@ -49,7 +47,7 @@ def test_creation(MeshFunc):
         mesh.domains().set_marker((cell.index(), 1), dim_t)
 
     # Create mesh from stored MeshValueCollection and
-    # external CellFunction
+    # external MeshFunction
     smesh0 = SubMesh(mesh, 1)
     smesh1 = SubMesh(mesh, domains, 1)
     assert smesh0.num_cells() == smesh1.num_cells()
diff --git a/test/unit/python/meshconvert/test_mesh_converter.py b/test/unit/python/meshconvert/test_mesh_converter.py
index ec82581..ef9a1f6 100755
--- a/test/unit/python/meshconvert/test_mesh_converter.py
+++ b/test/unit/python/meshconvert/test_mesh_converter.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """ Tests for the meshconvert module."""
 
 # Copyright (C) 2012
@@ -458,7 +456,7 @@ class TestTriangle(Tester):
         # test no. 2
         from dolfin import MPI, Mesh, MeshFunction, \
                            edges, Edge, faces, Face, \
-                           SubsetIterator, facets, CellFunction, mpi_comm_world
+                           SubsetIterator, facets, mpi_comm_world
 
         fname = os.path.join(os.path.dirname(__file__), "data", "test_Triangle_3")
         dfname = fname+".xml"
@@ -474,9 +472,9 @@ class TestTriangle(Tester):
         self.assertEqual(mesh.num_vertices(), 58)
         self.assertEqual(mesh.num_cells(), 58)
 
-        # Create a size_t CellFunction and assign the values based on the
+        # Create a size_t MeshFunction and assign the values based on the
         # converted Meshfunction
-        cf = CellFunction("size_t", mesh)
+        cf = MeshFunction("size_t", mesh, mesh.topology().dim())
         cf.array()[mfun.array()==10.0] = 0
         cf.array()[mfun.array()==-10.0] = 1
 
diff --git a/test/unit/python/multimesh/test_compression.py b/test/unit/python/multimesh/test_compression.py
new file mode 100644
index 0000000..7a6ded6
--- /dev/null
+++ b/test/unit/python/multimesh/test_compression.py
@@ -0,0 +1,103 @@
+"""Unit tests for quadrature compression"""
+
+# Copyright (C) 2017 August Johansson
+#
+# This file is part of DOLFIN.
+#
+# DOLFIN is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# DOLFIN 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+##
+# First added:  2016-06-28
+# Last changed: 2017-05-28
+
+from __future__ import print_function
+import pytest
+
+from dolfin import *
+from dolfin_utils.test import skip_in_parallel, skip_if_pybind11
+from numpy import random, sort, any
+
+def build_multimesh_2d(compress_volume, compress_interface):
+
+    # Create multimesh
+    multimesh = MultiMesh()
+    multimesh.parameters["compress_volume_quadrature"] = compress_volume
+    multimesh.parameters["compress_interface_quadrature"] = compress_interface
+
+    # Add background mesh
+    N_x = 2
+    mesh = UnitSquareMesh(N_x, N_x)
+    multimesh.add(mesh)
+
+    # Set seed
+    random.seed(1)
+
+    # Add num_parts-1 random sized and rotated rectangular meshes
+    num_parts = 2
+    while (multimesh.num_parts() < num_parts):
+
+        x0, x1 = sort(random.rand(2))
+        y0, y1 = sort(random.rand(2))
+        if abs(x1 - x0) < DOLFIN_EPS:
+            x1 += DOLFIN_EPS
+        if abs(y1 - y0) < DOLFIN_EPS:
+            y1 += DOLFIN_EPS
+
+        N_x_part = int(max(abs(x1-x0)*N_x, 1))
+        N_y_part = int(max(abs(y1-y0)*N_x, 1))
+        mesh = RectangleMesh(Point(x0, y0), Point(x1, y1),
+                             N_x_part, N_y_part)
+
+        # Rotate
+        phi = random.rand()*180
+        mesh.rotate(phi)
+        coords = mesh.coordinates()
+        is_interior = not any(coords < 0) and not any(coords > 1.)
+
+        if is_interior:
+            multimesh.add(mesh)
+
+    multimesh.build()
+    return multimesh
+
+def volume_area(multimesh):
+    volume = multimesh.compute_volume()
+    area = multimesh.compute_area()
+    return volume, area
+
+ at skip_in_parallel
+ at skip_if_pybind11
+def test_compression_2d():
+    # Reference volume and area
+    multimesh = build_multimesh_2d(False, False)
+    volume, area = volume_area(multimesh)
+
+    # Volume compression
+    multimesh_v = build_multimesh_2d(True, False)
+    volume_v, area_v = volume_area(multimesh)
+
+    # Interface compression
+    multimesh_i = build_multimesh_2d(False, True)
+    volume_i, area_i = volume_area(multimesh_i)
+
+    # Tolerances
+    volume_tol = 1e-10
+    area_tol = 1e-10
+
+    # Assert that the compressed volume / area is close
+    assert abs(volume - volume_v) < volume_tol
+    assert abs(area - area_i) < area_tol
+
+    # Assert that the compressed volume / area does not influence the area / volume
+    assert abs(volume - volume_i) < DOLFIN_EPS
+    assert abs(area - area_v) < DOLFIN_EPS
diff --git a/test/unit/python/multimesh/test_interface_area.py b/test/unit/python/multimesh/test_interface_area.py
new file mode 100755
index 0000000..82a171d
--- /dev/null
+++ b/test/unit/python/multimesh/test_interface_area.py
@@ -0,0 +1,139 @@
+"""Unit tests for multimesh volume computation"""
+
+# Copyright (C) 2016 Anders Logg
+#
+# This file is part of DOLFIN.
+#
+# DOLFIN is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# DOLFIN 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+#
+# Modified by August Johansson 2016
+#
+# First added:  2016-11-02
+# Last changed: 2016-11-14
+
+from __future__ import print_function
+import pytest
+
+from dolfin import *
+from dolfin_utils.test import skip_in_parallel, skip_if_pybind11
+
+def compute_area_using_quadrature(multimesh):
+    total_area = 0
+    for part in range(multimesh.num_parts()):
+        part_area = 0
+
+        for cell, cell_rules in multimesh.quadrature_rules_interface(part).items():
+            for qr in cell_rules:
+                weights = qr[1]
+                part_area += sum(weights)
+
+        total_area += part_area
+    return total_area
+
+def create_multimesh_with_meshes_on_diagonal(width, offset, Nx):
+
+    # Mesh width (must be less than 1)
+    assert width < 1
+
+    # Mesh placement (must be less than the width)
+    assert offset < width
+
+    # Background mesh
+    mesh_0 = UnitSquareMesh(Nx, Nx)
+
+    # Create multimesh
+    multimesh = MultiMesh()
+    multimesh.add(mesh_0)
+
+    # Now we have num_parts = 1
+    num_parts = multimesh.num_parts()
+
+    while num_parts*offset + width < 1:
+        a = num_parts*offset
+        b = a + width
+        mesh_top = RectangleMesh(Point(a,a), Point(b,b), Nx, Nx)
+        multimesh.add(mesh_top)
+        num_parts = multimesh.num_parts()
+
+    multimesh.build()
+
+    area = compute_area_using_quadrature(multimesh)
+    exact_area = 0 if multimesh.num_parts() == 1 else 4*width + (multimesh.num_parts()-2)*(2*width + 2*offset)
+    error = abs(area - exact_area)
+    relative_error = error / exact_area
+    tol = max(DOLFIN_EPS_LARGE, multimesh.num_parts()*multimesh.part(0).num_cells()*DOLFIN_EPS)
+
+    print("")
+    print("width = {}, offset = {}, Nx = {}, num_parts = {}".format(width, offset, Nx, multimesh.num_parts()))
+    print("error", error)
+    print("relative error", relative_error)
+    print("tol", tol)
+    return relative_error < tol
+
+ at skip_in_parallel
+ at skip_if_pybind11
+def test_meshes_on_diagonal():
+    "Place meshes on the diagonal inside a background mesh and check the interface area"
+
+    # for Nx in range(1, 50):
+    #     for width_factor in range(1, 100):
+    #         width = 3*width_factor/(100*DOLFIN_PI)
+    #         for offset_factor in range(1, 100):
+    #             offset = offset_factor*DOLFIN_PI / (100*3.2)
+    #             if (offset < width):
+    #                 assert(create_multimesh_with_meshes_on_diagonal(width, offset, Nx))
+
+    width = DOLFIN_PI / 5
+    offset = 0.1111
+    Nx = 1
+    assert(create_multimesh_with_meshes_on_diagonal(width, offset, Nx))
+
+    # width = 1/DOLFIN_PI #0.18888
+    # offset = DOLFIN_PI/100 #1e-10
+    # for Nx in range(1, 50):
+    #     assert(create_multimesh_with_meshes_on_diagonal(width, offset, Nx))
+
+ at skip_in_parallel
+ at skip_if_pybind11
+def test_meshes_with_boundary_edge_overlap_2d():
+    # start with boundary of mesh 1 overlapping edges of mesg 0
+    mesh0 = UnitSquareMesh(4,4)
+    mesh1 = UnitSquareMesh(1,1)
+
+    mesh1_coords = mesh1.coordinates()
+    mesh1_coords *= 0.5
+    mesh1.translate(Point(0.25, 0.25))
+
+    multimesh = MultiMesh()
+    multimesh.add(mesh0)
+    multimesh.add(mesh1)
+    multimesh.build()
+
+    exact_area = 2.0
+
+    area = compute_area_using_quadrature(multimesh)
+    assert abs(area - exact_area) < DOLFIN_EPS_LARGE
+
+    # next translate mesh 1 such that only the horizontal part of the boundary overlaps
+    mesh1.translate(Point(0.1, 0.0))
+    multimesh.build()
+    area = compute_area_using_quadrature(multimesh)
+    assert  abs(area - exact_area) < DOLFIN_EPS_LARGE
+
+    # next translate mesh 1 such that no boundaries overlap with edges 
+    mesh1.translate(Point(0.0, 0.1))
+    multimesh.build()
+    area = compute_area_using_quadrature(multimesh)
+    assert  abs(area - exact_area) < DOLFIN_EPS_LARGE
+
diff --git a/test/unit/python/multimesh/test_multimesh.py b/test/unit/python/multimesh/test_multimesh.py
index 4f08288..7a63c9a 100644
--- a/test/unit/python/multimesh/test_multimesh.py
+++ b/test/unit/python/multimesh/test_multimesh.py
@@ -17,6 +17,10 @@
 #
 # You should have received a copy of the GNU Lesser General Public License
 # along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+#
+#
+# First added:  2016-06-11
+# Last changed: 2017-07-18
 
 import pytest
 from dolfin import *
@@ -25,43 +29,85 @@ import numpy
 
 from dolfin_utils.test import fixture, skip_in_parallel, skip_if_pybind11
 
-
 @fixture
 def multimesh():
-    mesh_0 = RectangleMesh(Point(0,0), Point(0.6, 1), 40, 20)
-    mesh_1 = RectangleMesh(Point(0.5,0),  Point(1,1),25,40)
+    mesh_0 = RectangleMesh(Point(0,0), Point(1, 1), 20, 20)
+    mesh_1 = RectangleMesh(Point(numpy.pi/10,numpy.pi/9),
+                           Point(numpy.pi/8,numpy.pi/7),5,8)
     multimesh = MultiMesh()
     multimesh.add(mesh_0)
     multimesh.add(mesh_1)
     multimesh.build()
     return multimesh
 
-
 @fixture
 def V(multimesh):
     element = FiniteElement("Lagrange", triangle, 1)
     return MultiMeshFunctionSpace(multimesh, element)
 
+ at fixture
+def V_high(multimesh):
+    element = FiniteElement("Lagrange", triangle, 3)
+    return MultiMeshFunctionSpace(multimesh, element)
+
+ at fixture
+def f():
+    return Expression("sin(pi*x[0])*cos(2*pi*x[1])", degree=4)
 
 @fixture
+def f_2():
+    return Expression("x[0]*x[1]",degree=2)
+ at fixture
 def v(V):
     return MultiMeshFunction(V)
 
+ at fixture
+def v_high(V_high):
+    return MultiMeshFunction(V_high)
 
 @skip_if_pybind11
 @skip_in_parallel
 def test_measure_mul(v, multimesh):
     assert isinstance(v*dX, ufl.form.Form)
 
-
 @skip_if_pybind11
 @skip_in_parallel
 def test_assemble_zero(v, multimesh):
     assert numpy.isclose(assemble_multimesh(v*dX), 0)
 
-
 @skip_if_pybind11
 @skip_in_parallel
 def test_assemble_area(v, multimesh):
     v.vector()[:] = 1
     assert numpy.isclose(assemble_multimesh(v*dX), 1)
+
+ at skip_if_pybind11
+ at skip_in_parallel
+def test_assemble_exterior_facet(v, multimesh):
+    v.vector()[:] = 1
+    assert numpy.isclose(assemble_multimesh(v*ds), 4)
+
+ at skip_if_pybind11
+ at skip_in_parallel
+def test_interpolate(v_high, f):
+    v_high.interpolate(f)
+    assert numpy.isclose(assemble_multimesh(v_high*dX), 0)
+
+ at skip_if_pybind11
+ at skip_in_parallel
+def test_project(f, V_high):
+    v = project(f ,V_high)
+    assert numpy.isclose(assemble_multimesh(v*dX), 0)
+
+ at skip_if_pybind11
+ at skip_in_parallel
+def test_errornorm_L2(f_2, v_high):
+    const = Expression("1", degree=1)
+    v_high.interpolate(f_2)
+    assert numpy.isclose(errornorm(const, v_high, norm_type="L2", degree_rise=3), numpy.sqrt(22)/6)
+
+ at skip_if_pybind11
+ at skip_in_parallel
+def test_errornorm_H1(f, f_2, v_high):
+    v_high.interpolate(f_2)
+    assert numpy.isclose(errornorm(f, v_high, norm_type="H1", degree_rise=3), numpy.sqrt(37./36+5*numpy.pi**2/4))
diff --git a/test/unit/python/multimesh/test_multimesh_cell_types.py b/test/unit/python/multimesh/test_multimesh_cell_types.py
new file mode 100644
index 0000000..608e6a1
--- /dev/null
+++ b/test/unit/python/multimesh/test_multimesh_cell_types.py
@@ -0,0 +1,94 @@
+"""Unit tests for MultiMesh cell types"""
+
+# Copyright (C) 2016 Magne Nordaas
+#
+# This file is part of DOLFIN.
+#
+# DOLFIN is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# DOLFIN 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+#
+# First added:  2016-11-28
+# Last changed: 2016-11-28
+
+from dolfin import *
+import pytest
+from dolfin_utils.test import skip_in_parallel, skip_if_pybind11
+
+# test case with interface-edge overlap
+ at pytest.fixture
+def test_case_1(M, N):
+    multimesh = MultiMesh()
+    mesh0 = UnitSquareMesh(M, M)
+    mesh1 = RectangleMesh(Point(0.25, 0.25), Point(0.75, 0.75), N, N)
+    multimesh.add(mesh0)
+    multimesh.add(mesh1)
+    multimesh.build()
+    return multimesh
+
+# test case with squares on the diagonal
+ at pytest.fixture
+def test_case_2(width, offset, Nx):
+
+    # Mesh width (must be less than 1)
+    assert width < 1
+
+    # Mesh placement (must be less than the width)
+    assert offset < width
+
+    # Background mesh
+    mesh_0 = UnitSquareMesh(Nx, Nx)
+
+    # Create multimesh
+    multimesh = MultiMesh()
+    multimesh.add(mesh_0)
+
+    # Now we have num_parts = 1
+    num_parts = multimesh.num_parts()
+
+    while num_parts*offset + width < 1:
+        a = num_parts*offset
+        b = a + width
+        mesh_top = RectangleMesh(Point(a,a), Point(b,b), Nx, Nx)
+        multimesh.add(mesh_top)
+        num_parts = multimesh.num_parts()
+
+    multimesh.build()
+    return multimesh
+
+test_cases = [test_case_1(4,3), 
+              test_case_2(DOLFIN_PI/5, 0.1111, 3)]
+
+ at skip_in_parallel
+ at skip_if_pybind11
+ at pytest.mark.parametrize("multimesh", test_cases)
+def test_cut_cell_has_quadrature(multimesh):
+    # Test that every cut cell has a nontrivial interface quadrature rule
+    for part in range(multimesh.num_parts()):
+        for cell in multimesh.cut_cells(part):
+            assert multimesh.quadrature_rules_interface(part, cell)
+
+ at skip_in_parallel
+ at skip_if_pybind11
+ at pytest.mark.parametrize("multimesh", test_cases)
+def test_multimesh_cell_types(multimesh):
+    # Test that every cell in the multimesh is either cut, uncut, or covered
+    for part in range(multimesh.num_parts()):
+        cells = set(range(multimesh.part(part).num_cells()))
+        cut_cells = set(multimesh.cut_cells(part))
+        uncut_cells = set(multimesh.uncut_cells(part))
+        covered_cells = set(multimesh.covered_cells(part))
+
+        assert cut_cells.union(uncut_cells).union(covered_cells) == cells
+        assert cut_cells.intersection(uncut_cells) == set()
+        assert cut_cells.intersection(covered_cells) == set()
+        assert uncut_cells.intersection(covered_cells) == set()
diff --git a/test/unit/python/multimesh/test_multimesh_coefficients.py b/test/unit/python/multimesh/test_multimesh_coefficients.py
new file mode 100644
index 0000000..3605e74
--- /dev/null
+++ b/test/unit/python/multimesh/test_multimesh_coefficients.py
@@ -0,0 +1,113 @@
+"Unit tests for multimesh coefficients"
+
+# Copyright (C) 2006 Magne Nordaas
+#
+# This file is part of DOLFIN.
+#
+# DOLFIN is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# DOLFIN 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+#
+# Modified by August Johansson 2017
+#
+# First added:  2017-04-02
+# Last changed: 2017-06-20
+
+from __future__ import print_function
+import pytest
+from dolfin import *
+from dolfin_utils.test import fixture, skip_in_parallel, skip_if_pybind11
+
+ at fixture
+def mesh0():
+    return UnitSquareMesh(2,2)
+
+ at fixture
+def mesh1():
+    return RectangleMesh(Point(0.25, 0.25), Point(0.75, 0.75), 2, 2)
+
+ at fixture
+def multimesh(mesh0, mesh1):
+    multimesh = MultiMesh()
+    multimesh.add(mesh0)
+    multimesh.add(mesh1)
+    multimesh.build()
+    return multimesh
+
+ at fixture
+def V(multimesh):
+    return MultiMeshFunctionSpace(multimesh, "P", 1)
+
+ at fixture
+def V0(mesh0):
+    return FunctionSpace(mesh0, "P", 1)
+
+ at fixture
+def V1(mesh1):
+    return FunctionSpace(mesh1, "P", 1)
+
+ at fixture
+def f(V, V0, V1):
+    f = MultiMeshFunction(V)
+    f.assign_part(0, interpolate(Constant(1.0), V0))
+    f.assign_part(1, interpolate(Constant(2.0), V1))
+    return f
+
+ at fixture
+def g():
+    return Constant(0.5)
+
+ at fixture
+def h(V, V0, V1):
+    h = MultiMeshFunction(V)
+    h.assign_part(0, interpolate(Constant(1.0), V0))
+    h.assign_part(1, interpolate(Constant(1.5), V1))
+    return h
+
+ at skip_in_parallel
+ at skip_if_pybind11
+def test_dX_integral(f, g, h):
+    f_dX = assemble_multimesh(f * dX)
+    assert abs(f_dX - 1.25) < DOLFIN_EPS_LARGE
+
+    fgh_dX = assemble_multimesh(f*g*h * dX)
+    assert abs(fgh_dX - 0.75) < DOLFIN_EPS_LARGE
+
+ at skip_in_parallel
+ at skip_if_pybind11
+def test_dI_integral(f, g, h):
+    f_dI0 = assemble_multimesh(f("-") * dI)
+    assert abs(f_dI0 - 4.0) < DOLFIN_EPS_LARGE
+
+    f_dI1 = assemble_multimesh(f("+") * dI)
+    assert abs(f_dI1 - 2.0) < DOLFIN_EPS_LARGE
+
+    fgh_dI0 = assemble_multimesh(f("-")*g("-")*h("-") * dI)
+    assert abs(fgh_dI0 - 3.0) < DOLFIN_EPS_LARGE
+
+    fgh_dI1 = assemble_multimesh(f("+")*g("+")*h("+") * dI)
+    assert abs(fgh_dI1 - 1.0) < DOLFIN_EPS_LARGE
+
+ at skip_in_parallel
+ at skip_if_pybind11
+def test_dO_integral(f, g, h):
+    f_dO0 = assemble_multimesh(f("-") * dO)
+    assert abs(f_dO0 - 0.50) < DOLFIN_EPS_LARGE
+
+    f_dO1 = assemble_multimesh(f("+") * dO)
+    assert abs(f_dO1 - 0.25) < DOLFIN_EPS_LARGE
+
+    fgh_dO0 = assemble_multimesh(f("-")*g("-")*h("-") * dO)
+    assert abs(fgh_dO0 - 0.375) < DOLFIN_EPS_LARGE
+
+    fgh_dO1 = assemble_multimesh(f("+")*g("+")*h("+") * dO)
+    assert abs(fgh_dO1 - 0.125) < DOLFIN_EPS_LARGE
diff --git a/test/unit/python/geometry/test_issues.py b/test/unit/python/multimesh/test_multimesh_initialization.py
similarity index 54%
rename from test/unit/python/geometry/test_issues.py
rename to test/unit/python/multimesh/test_multimesh_initialization.py
index 0413a23..04c741a 100755
--- a/test/unit/python/geometry/test_issues.py
+++ b/test/unit/python/multimesh/test_multimesh_initialization.py
@@ -1,8 +1,6 @@
-#!/usr/bin/env py.test
+"""Unit tests for multimesh volume computation"""
 
-"""Unit tests for intersection computation"""
-
-# Copyright (C) 2013 Anders Logg
+# Copyright (C) 2016 Anders Logg
 #
 # This file is part of DOLFIN.
 #
@@ -19,8 +17,8 @@
 # You should have received a copy of the GNU Lesser General Public License
 # along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
 #
-# First added:  2013-12-09
-# Last changed: 2014-05-30
+# First added:  2016-05-03
+# Last changed: 2016-11-16
 
 from __future__ import print_function
 import pytest
@@ -28,26 +26,15 @@ import pytest
 from dolfin import *
 from dolfin_utils.test import skip_in_parallel
 
+from math import pi, sin, cos
 
 @skip_in_parallel
-def test_issue_97():
-    "Test from Mikael Mortensen (issue #97)"
-
-    N = 2
-    L = 1000
-    mesh = BoxMesh(Point(0, 0, 0), Point(L, L, L), N, N, N)
-    V = FunctionSpace(mesh, 'CG', 1)
-    v = interpolate(Expression('x[0]', degree=1), V)
-    x = Point(0.5*L, 0.5*L, 0.5*L)
-    vx = v(x)
-
-
- at skip_in_parallel
-def test_issue_168():
-    "Test from Torsten Wendav (issue #168)"
-
-    mesh = UnitCubeMesh(14, 14, 14)
-    V = FunctionSpace(mesh, "Lagrange", 1)
-    v = Function(V)
-    x = (0.75, 0.25, 0.125)
-    vx = v(x)
+def test_multimesh_init_1():
+  mm = MultiMesh()
+  mesh0 = UnitSquareMesh(1, 1)
+  mesh1 = RectangleMesh(Point(0,0), Point(2,0.5), 1, 1)
+  mm.add(mesh0)
+  mm.add(mesh1)
+  mm.build(2)
+
+  return 1 == 1
diff --git a/test/unit/python/multimesh/test_multimesh_issues.py b/test/unit/python/multimesh/test_multimesh_issues.py
new file mode 100755
index 0000000..afec097
--- /dev/null
+++ b/test/unit/python/multimesh/test_multimesh_issues.py
@@ -0,0 +1,69 @@
+"""Unit tests for reported multimesh issues"""
+
+# Copyright (C) 2016 Anders Logg
+#
+# This file is part of DOLFIN.
+#
+# DOLFIN is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# DOLFIN 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+#
+# Modified by August Johansson 2016
+#
+# First added:  2016-05-03
+# Last changed: 2017-06-19
+
+from __future__ import print_function
+import pytest
+
+from dolfin import *
+from dolfin_utils.test import skip_in_parallel, skip_if_pybind11
+
+ at skip_in_parallel
+ at skip_if_pybind11
+def test_issue_754():
+    N = 3
+    meshes = [UnitSquareMesh(2*N, 2*N),
+              RectangleMesh(Point(0.1, 0.15), Point(0.6, 0.65), N, N),
+              RectangleMesh(Point(0.4, 0.35), Point(0.9, 0.85), N, N)]
+
+    multimesh = MultiMesh()
+    for mesh in meshes:
+        multimesh.add(mesh)
+    multimesh.build()
+
+    V = MultiMeshFunctionSpace(multimesh, "CG", 1)
+    u, v = TrialFunction(V), TestFunction(V)
+
+    a = inner(u,v) * dX
+    b = a + inner(jump(u),jump(v)) * dI
+    A = assemble_multimesh(a)
+    B = assemble_multimesh(b)
+
+    # create multimesh function w such that
+    #     w(x) =  1  if x is in the last mesh
+    #          =  0  otherwise
+
+    w = MultiMeshFunction(V); x = w.vector()
+    dofs = V.part(V.num_parts()-1).dofmap().dofs() \
+           + sum(V.part(i).dim() for i in range(V.num_parts()-1))
+    w.vector()[dofs] = 1.
+
+    # Compute the area and perimeter of the last mesh
+    a = w.vector().inner(A * w.vector())
+    p = w.vector().inner(B * w.vector()) - a
+
+    # print("Computed area (a) and perimeter (p) of last mesh:")
+    # print("  a = {0:1.4f} (exact value is .25)".format(a))
+    # print("  p = {0:1.4f} (exact value is 2.0)".format(p))
+    assert(abs(a - 0.25) < DOLFIN_EPS_LARGE)
+    assert(abs(p - 2.) < DOLFIN_EPS_LARGE)
diff --git a/test/unit/python/multimesh/test_multimesh_solve.py b/test/unit/python/multimesh/test_multimesh_solve.py
new file mode 100644
index 0000000..3d563ee
--- /dev/null
+++ b/test/unit/python/multimesh/test_multimesh_solve.py
@@ -0,0 +1,125 @@
+"""Unit tests for MultiMesh PDE solvers"""
+
+# Copyright (C) 2017 August Johansson
+#
+# This file is part of DOLFIN.
+#
+# DOLFIN is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# DOLFIN 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+#
+# First added:  2017-07-18
+# Last changed: 2017-07-18
+
+import pytest
+from dolfin import *
+
+from dolfin_utils.test import skip_in_parallel, skip_if_pybind11, fixture
+
+ at fixture
+def exactsolution_2d():
+    return Expression("x[0] + x[1]", degree=1)
+
+ at fixture
+def exactsolution_3d():
+    return Expression("x[0] + x[1] + x[2]", degree=1)
+
+ at fixture
+def solve_multimesh_poisson(mesh_0, mesh_1, exactsolution):
+
+    # Build multimesh
+    multimesh = MultiMesh()
+    multimesh.add(mesh_0)
+    multimesh.add(mesh_1)
+    multimesh.build()
+
+    # FEM setup
+    V = MultiMeshFunctionSpace(multimesh, "Lagrange", 1)
+    u = TrialFunction(V)
+    v = TestFunction(V)
+    n = FacetNormal(multimesh)
+    h = 2.0*Circumradius(multimesh)
+    h = (h('+') + h('-')) / 2
+
+    # Set data
+    f = Constant(0.0)
+
+    # Set parameters
+    alpha = 4.0
+    beta = 4.0
+
+    # Define bilinear form
+    a = dot(grad(u), grad(v))*dX \
+      - dot(avg(grad(u)), jump(v, n))*dI \
+      - dot(avg(grad(v)), jump(u, n))*dI \
+      + alpha/h*jump(u)*jump(v)*dI \
+      + beta*dot(jump(grad(u)), jump(grad(v)))*dO
+
+    # Define linear form
+    L = f*v*dX
+
+    # Assemble linear system
+    A = assemble_multimesh(a)
+    b = assemble_multimesh(L)
+
+    # Apply boundary condition
+    bc = MultiMeshDirichletBC(V, exactsolution, DomainBoundary())
+    bc.apply(A, b)
+
+    # Solve
+    uh = MultiMeshFunction(V)
+    solve(A, uh.vector(), b)
+
+    return uh
+    
+ at pytest.mark.slow
+ at skip_if_pybind11
+ at skip_in_parallel
+def test_multimesh_poisson_2d():
+    # This tests solves a Poisson problem on two meshes in 2D with u =
+    # x+y as exact solution
+
+    # FIXME: This test is quite slow.
+
+    # Define meshes
+    mesh_0 = UnitSquareMesh(2, 2)
+    mesh_1 = RectangleMesh(Point(0.1*DOLFIN_PI, 0.1*DOLFIN_PI),
+                           Point(0.2*DOLFIN_PI, 0.2*DOLFIN_PI),
+                           2, 2)
+
+    # Solve multimesh Poisson
+    uh = solve_multimesh_poisson(mesh_0, mesh_1, exactsolution_2d())
+    
+    # Check error
+    assert errornorm(exactsolution_2d(), uh, 'L2', degree_rise=1) < DOLFIN_EPS_LARGE
+
+ at pytest.mark.slow
+ at skip_if_pybind11
+ at skip_in_parallel
+ at pytest.mark.skipif(True, reason="3D not fully implemented")
+def test_multimesh_poisson_3d():
+    # This tests solves a Poisson problem on two meshes in 3D with u =
+    # x+y+z as exact solution
+
+    # FIXME: This test is quite slow.
+
+    # Define meshes
+    mesh_0 = UnitCubeMesh(2, 2, 2)
+    mesh_1 = BoxMesh(Point(0.1*DOLFIN_PI, 0.1*DOLFIN_PI, 0.1*DOLFIN_PI),
+                     Point(0.2*DOLFIN_PI, 0.2*DOLFIN_PI, 0.2*DOLFIN_PI),
+                     2, 2, 2)
+    
+    # Solve multimesh Poisson
+    uh = solve_multimesh_poisson(mesh_0, mesh_1, exactsolution_3d())
+    
+    # Check error
+    assert errornorm(exactsolution_3d(), uh, 'L2', degree_rise=1) < DOLFIN_EPS_LARGE
diff --git a/test/unit/python/multimesh/test_volume.py b/test/unit/python/multimesh/test_volume.py
new file mode 100755
index 0000000..70d4ed0
--- /dev/null
+++ b/test/unit/python/multimesh/test_volume.py
@@ -0,0 +1,206 @@
+"""Unit tests for multimesh volume computation"""
+
+# Copyright (C) 2016 Anders Logg
+#
+# This file is part of DOLFIN.
+#
+# DOLFIN is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# DOLFIN 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
+#
+# Modified by August Johansson 2016
+# Modified by Simon Funke 2017
+#
+# First added:  2016-05-03
+# Last changed: 2017-05-25
+
+from __future__ import print_function
+import pytest
+
+from dolfin import *
+from dolfin_utils.test import skip_in_parallel, skip_if_pybind11
+
+def compute_volume(multimesh):
+    # Reference volume computation
+    v0 = multimesh.compute_volume()
+
+    # Create function space for DG volume computation
+    V = MultiMeshFunctionSpace(multimesh, "DG", 0)
+
+    # Create and evaluate volume functional
+    v = TestFunction(V)
+    M = v*dX
+    v1 = sum(assemble(M).array())
+
+    # Alternative volume computation
+    dXmm = dx(domain=multimesh) + dC(domain=multimesh)
+    M = Constant(1.0)*dXmm
+    v2 = assemble_multimesh(M)
+
+    # FIXME: We could be able to tighten the tolerance here
+    assert abs(v0 - v1) / v0 < DOLFIN_EPS_LARGE
+    assert abs(v0 - v2) / v0 < DOLFIN_EPS_LARGE
+
+    return v0
+
+ at skip_in_parallel
+ at skip_if_pybind11
+def test_volume_2d():
+    "Integrate volume of union of 2D meshes"
+
+    # Number of meshes on top of background mesh
+    num_meshes = 8
+
+    # Create background mesh so we can easily compute volume
+    mesh_0 = UnitSquareMesh(1, 1)
+    mesh_0.scale(10.0)
+    mesh_0.translate(Point(-5, -5))
+    exact_volume = 100.0
+
+    # Create meshes with centres distributed around the unit circle.
+    # Meshes are scaled by a factor 2 so that they overlap.
+    meshes = []
+    for i in range(num_meshes):
+        mesh = UnitSquareMesh(1, 1)
+        angle = 2.*pi*float(i) / float(num_meshes)
+        print("i, angle", i, angle)
+        mesh.translate(Point(-0.5, -0.5))
+        mesh.scale(2.0)
+        mesh.rotate(180.0*angle / pi)
+        mesh.translate(Point(cos(angle), sin(angle)))
+        meshes.append(mesh)
+
+    # Save meshes to file so we can examine them
+    #File('output/background_mesh.pvd') << mesh_0
+    #vtkfile = File('output/meshes.pvd')
+    #for mesh in meshes:
+    #    vtkfile << mesh
+
+    # Create multimesh
+    multimesh = MultiMesh()
+    for mesh in [mesh_0] + meshes:
+        multimesh.add(mesh)
+    multimesh.build()
+
+    # Compute approximate volume
+    approximative_volume = compute_volume(multimesh)
+
+    print("exact volume ", exact_volume)
+    print("approximative volume ", approximative_volume)
+    print("relative approximate volume error %1.16e" % ((exact_volume - approximative_volume) / exact_volume))
+    assert abs(exact_volume - approximative_volume) / exact_volume < DOLFIN_EPS_LARGE
+
+ at skip_in_parallel
+ at skip_if_pybind11
+def test_volume_2d_4_meshes():
+    "Test with four meshes that previously failed"
+
+    # Create multimesh
+    multimesh = MultiMesh()
+
+    # Mesh size
+    h = 0.25
+    Nx = int(round(1 / h))
+
+    # Background mesh
+    mesh_0 = UnitSquareMesh(Nx, Nx)
+    multimesh.add(mesh_0)
+
+    # Mesh 1
+    x0 = 0.35404867974764142602
+    y0 = 0.16597416632155614913
+    x1 = 0.63997881656511634851
+    y1 = 0.68786139026650294781
+    mesh_1 = RectangleMesh(Point(x0, y0), Point(x1, y1),
+                           max(int(round((x1-x0)/h)), 1), max(int(round((y1-y0)/h)), 1))
+    mesh_1.rotate(39.609407484349517858)
+    multimesh.add(mesh_1)
+
+    # Mesh 2
+    x0 = 0.33033712968711609337
+    y0 = 0.22896817104377231722
+    x1 = 0.82920109332967595339
+    y1 = 0.89337241458397931293
+    mesh_2 = RectangleMesh(Point(x0, y0), Point(x1, y1),
+                           max(int(round((x1-x0)/h)), 1), max(int(round((y1-y0)/h)), 1))
+    mesh_2.rotate(31.532416069662392744)
+    multimesh.add(mesh_2)
+
+    # Mesh 3
+    x0 = 0.28105941241656401397
+    y0 = 0.30745787374091237965
+    x1 = 0.61959648394007071914
+    y1 = 0.78600209801737319637
+    mesh_3 = RectangleMesh(Point(x0, y0), Point(x1, y1),
+                           max(int(round((x1-x0)/h)), 1), max(int(round((y1-y0)/h)), 1))
+    mesh_3.rotate(40.233022128340330426)
+    multimesh.add(mesh_3)
+
+    multimesh.build()
+
+    exact_volume = 1
+    approximate_volume = compute_volume(multimesh)
+
+    print("exact volume ", exact_volume)
+    print("approximative volume ", approximate_volume)
+    print("approximate volume error %1.16e" % (exact_volume - approximate_volume))
+    assert abs(exact_volume - approximate_volume) < DOLFIN_EPS_LARGE
+    
+ at skip_in_parallel
+ at skip_if_pybind11
+def test_volume_2d_six_meshes():
+    "Integrate volume of six 2D meshes"
+
+    # Number of elements
+    Nx = 8
+    h = 1. / Nx
+
+    # Background mesh
+    mesh_0 = UnitSquareMesh(Nx, Nx)
+
+    # 5 meshes plus background mesh
+    num_meshes = 5
+
+    # List of points for generating the meshes on top
+    points = [[ Point(0.747427, 0.186781), Point(0.849659, 0.417130) ],
+              [ Point(0.152716, 0.471681), Point(0.455943, 0.741585) ],
+              [ Point(0.464473, 0.251876), Point(0.585051, 0.533569) ],
+              [ Point(0.230112, 0.511897), Point(0.646974, 0.892193) ],
+              [ Point(0.080362, 0.422675), Point(0.580151, 0.454286) ]]
+
+    angles = [ 88.339755, 94.547259, 144.366564, 172.579922, 95.439692 ]
+
+    # Create multimesh
+    multimesh = MultiMesh()
+    multimesh.add(mesh_0)
+
+    # Add the 5 background meshes
+    for i in range(num_meshes):
+        nx = max(int(round(abs(points[i][0].x()-points[i][1].x()) / h)), 1)
+        ny = max(int(round(abs(points[i][0].y()-points[i][1].y()) / h)), 1)
+        mesh = RectangleMesh(points[i][0], points[i][1], nx, ny)
+        mesh.rotate(angles[i])
+        multimesh.add(mesh)
+    multimesh.build()
+
+    # Save meshes to file
+    #vtkfile = File('output/test_six_meshes.pvd')
+    #for i in range(multimesh.num_parts()):
+    #    vtkfile << multimesh.part(i)
+
+    exact_volume = 1.0
+    approximate_volume = compute_volume(multimesh)
+
+    print("exact volume ", exact_volume)
+    print("approximative volume ", approximate_volume)
+    print("approximate volume error %1.16e" % (exact_volume - approximate_volume))
+    assert abs(exact_volume - approximate_volume) < DOLFIN_EPS_LARGE
diff --git a/test/unit/python/multistage/test_RK_solver.py b/test/unit/python/multistage/test_RK_solver.py
index 3ac1b4e..0a00530 100755
--- a/test/unit/python/multistage/test_RK_solver.py
+++ b/test/unit/python/multistage/test_RK_solver.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the RKSolver interface"""
 
 # Copyright (C) 2013 Johan Hake
@@ -64,7 +62,7 @@ def test_butcher_schemes_scalar():
             solver.step_interval(0., tstop, dt)
             u_errors.append(u_true(0.0, 0.0) - u(0.0, 0.0))
 
-        assert scheme.order()-min(convergence_order(u_errors))<0.1
+        assert scheme.order() - min(convergence_order(u_errors)) < 0.1
 
 
 @pytest.mark.slow
@@ -93,5 +91,5 @@ def test_butcher_schemes_vector():
             u_errors_0.append(u_true(0.0, 0.0)[0] - u(0.0, 0.0)[0])
             u_errors_1.append(u_true(0.0, 0.0)[1] - u(0.0, 0.0)[1])
 
-        assert scheme.order()-min(convergence_order(u_errors_0))<0.1
-        assert scheme.order()-min(convergence_order(u_errors_1))<0.1
+        assert scheme.order() - min(convergence_order(u_errors_0)) < 0.1
+        assert scheme.order() - min(convergence_order(u_errors_1)) < 0.1
diff --git a/test/unit/python/multistage/test_point_integral_solver.py b/test/unit/python/multistage/test_point_integral_solver.py
index 320e0c0..4a84ce1 100755
--- a/test/unit/python/multistage/test_point_integral_solver.py
+++ b/test/unit/python/multistage/test_point_integral_solver.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the RKSolver interface"""
 
 # Copyright (C) 2013 Johan Hake
diff --git a/test/unit/python/nls/test_PETScSNES_solver.py b/test/unit/python/nls/test_PETScSNES_solver.py
index 07e87fa..8f896c0 100755
--- a/test/unit/python/nls/test_PETScSNES_solver.py
+++ b/test/unit/python/nls/test_PETScSNES_solver.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit test for the SNES nonlinear solver"""
 
 # Copyright (C) 2012 Patrick E. Farrell
diff --git a/test/unit/python/nls/test_PETScTAOSolver.py b/test/unit/python/nls/test_PETScTAOSolver.py
index 665bacd..d82035b 100755
--- a/test/unit/python/nls/test_PETScTAOSolver.py
+++ b/test/unit/python/nls/test_PETScTAOSolver.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit test for the PETSc TAO solver"""
 
 # Copyright (C) 2014 Tianyi Li
diff --git a/test/unit/python/nls/test_TAO_linear_bound_solver.py b/test/unit/python/nls/test_TAO_linear_bound_solver.py
index eb516a5..6d7ad20 100755
--- a/test/unit/python/nls/test_TAO_linear_bound_solver.py
+++ b/test/unit/python/nls/test_TAO_linear_bound_solver.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for the TAOLinearBoundSolver interface"""
 
 # Copyright (C) 2013 Corrado Maurini
diff --git a/test/unit/python/parallel-assembly-solve/test_solve_result_against_reference.py b/test/unit/python/parallel-assembly-solve/test_solve_result_against_reference.py
index d8bb460..1663642 100755
--- a/test/unit/python/parallel-assembly-solve/test_solve_result_against_reference.py
+++ b/test/unit/python/parallel-assembly-solve/test_solve_result_against_reference.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env py.test
 """This file solves a simple reaction-diffusion problem and compares
 the norm of the solution vector with a known solution (obtained when
 running in serial). It is used for validating mesh partitioning and
@@ -118,8 +117,8 @@ def test_computed_norms_against_references():
     # Mesh files and degrees to check
     meshes = [(UnitSquareMesh(16, 16), "16x16 unit tri square"),
               (UnitCubeMesh(4, 4, 4),  "4x4x4 unit tet cube"),
-              (UnitQuadMesh.create(16, 16), "16x16 unit quad square"),
-              (UnitHexMesh.create(4, 4, 4), "4x4x4 unit hex cube")]
+              (UnitSquareMesh.create(16, 16, CellType.Type_quadrilateral), "16x16 unit quad square"),
+              (UnitCubeMesh.create(4, 4, 4, CellType.Type_hexahedron), "4x4x4 unit hex cube")]
     degrees = [1, 2, 3, 4]
 
     # For MUMPS, increase estimated require memory increase. Typically
diff --git a/test/unit/python/parameter/test_parameters.py b/test/unit/python/parameter/test_parameters.py
index df8b0d0..c2bc54c 100755
--- a/test/unit/python/parameter/test_parameters.py
+++ b/test/unit/python/parameter/test_parameters.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env py.test
-
 """Unit tests for parameter library"""
 
 # Copyright (C) 2011 Anders Logg
@@ -22,8 +20,8 @@
 from __future__ import print_function
 import pytest
 import os
-from dolfin import *
 
+from dolfin import *
 from dolfin_utils.test import *
 
 @skip_in_parallel
diff --git a/test/unit/python/ufl-jit-assemble-chain/test_assembly_derivatives.py b/test/unit/python/ufl-jit-assemble-chain/test_assembly_derivatives.py
index 873aae3..004c3e3 100755
--- a/test/unit/python/ufl-jit-assemble-chain/test_assembly_derivatives.py
+++ b/test/unit/python/ufl-jit-assemble-chain/test_assembly_derivatives.py
@@ -1,5 +1,3 @@
-#!usr/bin/env py.test
-
 """System integration tests for ufl-derivative-jit-assembly chain."""
 
 # Copyright (C) 2011 Martin S. Alnaes
diff --git a/test/unit/python/ufl-jit-assemble-chain/test_form_operations.py b/test/unit/python/ufl-jit-assemble-chain/test_form_operations.py
index 6dff3db..8a02eb9 100755
--- a/test/unit/python/ufl-jit-assemble-chain/test_form_operations.py
+++ b/test/unit/python/ufl-jit-assemble-chain/test_form_operations.py
@@ -1,5 +1,3 @@
-#!usr/bin/env py.test
-
 """Tests for DOLFIN integration of various form operations"""
 
 # Copyright (C) 2011 Marie E. Rognes

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/fenics/dolfin.git



More information about the debian-science-commits mailing list