diff --git a/CMakeLists.txt b/CMakeLists.txt
index caeef4763474054fec31ada62b9580db7643f6f6..8db375a6c35c3d593ccae68ba3569d967f122237 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -161,7 +161,7 @@ include_directories(src/scheme)
 # Pastis tests
 
 set(CATCH_MODULE_PATH "${PASTIS_SOURCE_DIR}/packages/Catch2")
-set(CATCH_INCLUDE_PATH "${CATCH_MODULE_PATH}/single_include")
+set(CATCH_INCLUDE_PATH "${CATCH_MODULE_PATH}/single_include/catch2")
 
 include("${CATCH_MODULE_PATH}/contrib/ParseAndAddCatchTests.cmake")
 add_subdirectory("${CATCH_MODULE_PATH}")
diff --git a/packages/CLI11/.ci/make_and_test.sh b/packages/CLI11/.ci/make_and_test.sh
index 2ba81aeeffa627ae010c61162012a7af75d7998b..6aec305ed97680457fc4c16e5b41fb96b64a902c 100755
--- a/packages/CLI11/.ci/make_and_test.sh
+++ b/packages/CLI11/.ci/make_and_test.sh
@@ -1,11 +1,14 @@
 #!/usr/bin/env bash
 echo -en "travis_fold:start:script.build\\r"
 echo "Building..."
+STD=$1
+shift
 set -evx
 
+
 mkdir -p build
 cd build
-cmake .. -DCLI11_CXX_STD=$1 -DCLI11_SINGLE_FILE_TESTS=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
+cmake .. -DCLI11_SINGLE_FILE=ON -DCLI11_CXX_STD=$STD -DCLI11_SINGLE_FILE_TESTS=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_COMPILER_LAUNCHER=ccache $@
 cmake --build . -- -j2
 
 set +evx
diff --git a/packages/CLI11/.gitmodules b/packages/CLI11/.gitmodules
index 2b5117d2cbaf0a48723d833530996594d19a37a3..e9ec356f3475d5a3c7f043752ed93061180a8c51 100644
--- a/packages/CLI11/.gitmodules
+++ b/packages/CLI11/.gitmodules
@@ -4,3 +4,6 @@
 [submodule "extern/sanitizers"]
 	path = extern/sanitizers
 	url = ../../arsenm/sanitizers-cmake
+[submodule "extern/json"]
+	path = extern/json
+	url = ../../nlohmann/json.git
diff --git a/packages/CLI11/.gitrepo b/packages/CLI11/.gitrepo
index 0bd709b9b6e8c72c9f26be4e626c526327955c1e..96c408126ab71f57466b1bfba721bdb7f67d4bda 100644
--- a/packages/CLI11/.gitrepo
+++ b/packages/CLI11/.gitrepo
@@ -6,6 +6,6 @@
 [subrepo]
 	remote = git@github.com:CLIUtils/CLI11.git
 	branch = master
-	commit = 6f41cca9189129fd6df8c82bff532693dcfe52c3
-	parent = e7630b332e1d23511b2de021692cf478675a662b
+	commit = da901cca542612a133efcb04e8e78080186991e4
+	parent = 4348958e3bface85aedc9e8a5638f38790834cd5
 	cmdver = 0.3.1
diff --git a/packages/CLI11/.travis.yml b/packages/CLI11/.travis.yml
index 80bdfbfbab0240161469308a5324679ccb2474bd..7e5b645eac588a4c506977be1c9ccfc210193d10 100644
--- a/packages/CLI11/.travis.yml
+++ b/packages/CLI11/.travis.yml
@@ -11,7 +11,6 @@ branches:
   - /^v\d/
 
 cache:
-  ccache: true
   apt: true
   directories:
   - "${TRAVIS_BUILD_DIR}/deps/doxygen"
@@ -49,6 +48,7 @@ matrix:
     - .ci/make_and_test.sh 11
     after_success:
     - export DOXYFILE=$TRAVIS_BUILD_DIR/docs/Doxyfile
+    - export DEPS_DIR="${TRAVIS_BUILD_DIR}/deps"
     - |
       if [ "${TRAVIS_BRANCH}" == "master" ] && [ "${TRAVIS_PULL_REQUEST}" == "false" ]
       then
@@ -56,7 +56,7 @@ matrix:
         .ci/build_docs.sh
       fi
 
-    # GCC 6 and Coverage
+    # GCC 7 and coverage (8 does not support lcov, wait till 9 and new lcov)
   - compiler: gcc
     env:
     - GCC_VER=7
@@ -76,9 +76,9 @@ matrix:
     - ". .ci/build_lcov.sh"
     - ".ci/run_codecov.sh"
     script:
-    - .ci/make_and_test.sh 11
-    - .ci/make_and_test.sh 14
-    - .ci/make_and_test.sh 17
+    - .ci/make_and_test.sh 11 -DCLI11_EXAMPLE_JSON=ON
+    - .ci/make_and_test.sh 14 -DCLI11_EXAMPLE_JSON=ON
+    - .ci/make_and_test.sh 17 -DCLI11_EXAMPLE_JSON=ON
 
     # GCC 4.7 and Conan
   - compiler: gcc
diff --git a/packages/CLI11/CHANGELOG.md b/packages/CLI11/CHANGELOG.md
index d9b05d299e331bbacc5561452d50331d7140f11a..ba405ea012b21239467c9c1d48adf9ca0ee1d55b 100644
--- a/packages/CLI11/CHANGELOG.md
+++ b/packages/CLI11/CHANGELOG.md
@@ -1,30 +1,67 @@
+## Version 1.6.2: Help-all
+
+This version fixes some formatting bugs with help-all. It also adds fixes for several warnings, including an experimental optional error on Clang 7.
+
+* Fixed help-all formatting [#163]
+    * Printing help-all on nested command now fixed (App)
+    * Missing space after help-all restored (Default formatter)
+    * More detail printed on help all (Default formatter)
+    * Help-all subcommands get indented with inner blank lines removed (Default formatter)
+    * `detail::find_and_replace` added to utilities
+* Fixed CMake install as subproject with `CLI11_INSTALL` flag. [#156]
+* Fixed warning about local variable hiding class member with MSVC [#157]
+* Fixed compile error with default settings on Clang 7 and libc++ [#158]
+
+[#156]: https://github.com/CLIUtils/CLI11/issues/156
+[#157]: https://github.com/CLIUtils/CLI11/issues/157
+[#158]: https://github.com/CLIUtils/CLI11/issues/158
+[#163]: https://github.com/CLIUtils/CLI11/pull/163
+
+## Version 1.6.1: Platform fixes
+
+This version provides a few fixes for special cases, such as mixing with `Windows.h` and better defaults
+for systems like Hunter. The one new feature is the ability to produce "branded" single file output for
+providing custom namespaces or custom macro names.
+
+* Added fix and test for including Windows.h [#145]
+* No longer build single file by default if main project, supports systems stuck on Python 2.6 [#149], [#151]
+* Branding support for single file output [#150]
+
+[#145]: https://github.com/CLIUtils/CLI11/pull/145
+[#149]: https://github.com/CLIUtils/CLI11/pull/149
+[#150]: https://github.com/CLIUtils/CLI11/pull/150
+[#151]: https://github.com/CLIUtils/CLI11/pull/151
+
 ## Version 1.6: Formatting help
 
 Added a new formatting system [#109]. You can now set the formatter on Apps. This has also simplified the internals of Apps and Options a bit by separating most formatting code.
 
 * Added `CLI::Formatter` and `formatter` slot for apps, inherited.
-* `FormatterBase` is the minimum required
-* `FormatterLambda` provides for the easy addition of an arbitrary function
-* Added `help_all` support (not added by default)
+* `FormatterBase` is the minimum required.
+* `FormatterLambda` provides for the easy addition of an arbitrary function.
+* Added `help_all` support (not added by default).
 
 Changes to the help system (most normal users will not notice this):
 
-* Renamed `single_name` to `get_name(false, false)` (the default)
-* The old `get_name()` is now `get_name(false, true)`
-* The old `get_pname()` is now `get_name(true, false)`
-* Removed `help_*` functions
-* Protected function `_has_help_positional` removed
-* `format_help` can now be chained
+* Renamed `single_name` to `get_name(false, false)` (the default).
+* The old `get_name()` is now `get_name(false, true)`.
+* The old `get_pname()` is now `get_name(true, false)`.
+* Removed `help_*` functions.
+* Protected function `_has_help_positional` removed.
+* `format_help` can now be chained.
+* Added getters for the missing parts of options (help no longer uses any private parts).
+* Help flags now use new `short_circuit` property to simplify parsing. [#121]
 
 
 New for Config file reading and writing [#121]:
 
-* Overridable, bidirectional Config
-* ConfigINI provided and used by default
-* Renamed ini to config in many places
-* Has `config_formatter()` and `get_config_formatter()`
-* Dropped prefix argument from `config_to_str`
-* Added `ConfigItem`
+* Overridable, bidirectional Config.
+* ConfigINI provided and used by default.
+* Renamed ini to config in many places.
+* Has `config_formatter()` and `get_config_formatter()`.
+* Dropped prefix argument from `config_to_str`.
+* Added `ConfigItem`.
+* Added an example of a custom config format using [nlohmann/json]. [#138]
 
 
 Validators are now much more powerful [#118], all built in validators upgraded to the new form:
@@ -36,20 +73,29 @@ Validators are now much more powerful [#118], all built in validators upgraded t
 
 Other changes:
 
-* Added `->each()` to make adding custom callbacks easier [#126]
-* Added filter argument to `get_subcommands`, `get_options`; use empty filter `{}` to avoid filtering
-* Added `get_groups()` to get groups
-* Added getters for the missing parts of options (help no longer uses any private parts)
-* Better support for manual options with `get_option`, `set_results`, and `empty` [#119]
-* `lname` and `sname` have getters, added `const get_parent` [#120]
-* Using `add_set` will now capture L-values for sets, allowing further modification [#113]
-* Internally, `type_name` is now a lambda function; for sets, this reads the set live [#116] 
-* Dropped duplicate way to run `get_type_name` (`get_typeval`)
+* Fixing `parse(args)`'s `args` setting and ordering after parse. [#141]
+* Replaced `set_custom_option` with `type_name` and `type_size` instead of `set_custom_option`. Methods return `this`. [#136]
+* Dropped `set_` on Option's `type_name`, `default_str`, and `default_val`. [#136]
+* Removed `set_` from App's `failure_message`, `footer`, `callback`, and `name`. [#136]
+* Fixed support `N<-1` for `type_size`. [#140]
+* Added `->each()` to make adding custom callbacks easier. [#126]
+* Allow empty options `add_option("-n",{})` to be edited later with `each` [#142]
+* Added filter argument to `get_subcommands`, `get_options`; use empty filter `{}` to avoid filtering.
+* Added `get_groups()` to get groups.
+* Better support for manual options with `get_option`, `set_results`, and `empty`. [#119]
+* `lname` and `sname` have getters, added `const get_parent`. [#120]
+* Using `add_set` will now capture L-values for sets, allowing further modification. [#113]
+* Dropped duplicate way to run `get_type_name` (`get_typeval`).
+* Removed `requires` in favor of `needs` (deprecated in last version). [#112]
+* Const added to argv. [#126]
+
+Backend and testing changes:
+
+* Internally, `type_name` is now a lambda function; for sets, this reads the set live. [#116] 
+* Cleaner tests without `app.reset()` (and `reset` is now `clear`). [#141]
+* Better CMake policy handling. [#110]
+* Includes are properly sorted. [#120]
 * Testing (only) now uses submodules. [#111]
-* Removed `requires` in favor of `needs` (deprecated in last version) [#112]
-* Better CMake policy handling [#110]
-* Includes are properly sorted [#120]
-* Help flags now use new `short_circuit` property to simplify parsing [#121]
 
 [#109]: https://github.com/CLIUtils/CLI11/pull/109
 [#110]: https://github.com/CLIUtils/CLI11/pull/110
@@ -62,6 +108,13 @@ Other changes:
 [#120]: https://github.com/CLIUtils/CLI11/pull/120
 [#121]: https://github.com/CLIUtils/CLI11/pull/121
 [#126]: https://github.com/CLIUtils/CLI11/pull/126
+[#127]: https://github.com/CLIUtils/CLI11/pull/127
+[#138]: https://github.com/CLIUtils/CLI11/pull/138
+[#140]: https://github.com/CLIUtils/CLI11/pull/140
+[#141]: https://github.com/CLIUtils/CLI11/pull/141
+[#142]: https://github.com/CLIUtils/CLI11/pull/142
+
+[nlohmann/json]: https://github.com/nlohmann/json
 
 ### Version 1.5.4: Optionals
 This version fixes the optional search in the single file version; some macros were not yet defined when it did the search. You can define the `CLI11_*_OPTIONAL` macros to 0 if needed to eliminate the search.
diff --git a/packages/CLI11/CMakeLists.txt b/packages/CLI11/CMakeLists.txt
index 1fe8248365dcab530e9d2fc6ac56a6a837e2599c..79404b8deeac7c5fa999644355d8ecac5b4158de 100644
--- a/packages/CLI11/CMakeLists.txt
+++ b/packages/CLI11/CMakeLists.txt
@@ -1,7 +1,13 @@
-cmake_minimum_required(VERSION 3.4...3.11)
+cmake_minimum_required(VERSION 3.4)
+# Note: this is a header only library. If you have an older CMake than 3.4,
+# just add the CLI11/include directory and that's all you need to do.
 
+# Make sure users don't get warnings on a tested (3.4 to 3.12) version
+# of CMake. For most of the policies, the new version is better (hence the change).
 if(${CMAKE_VERSION} VERSION_LESS 3.12)
-    cmake_policy(VERSION ${CMAKE_VERSION})
+    cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
+else()
+    cmake_policy(VERSION 3.12)
 endif()
 
 set(VERSION_REGEX "#define CLI11_VERSION[ \t]+\"(.+)\"")
@@ -13,10 +19,9 @@ file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/include/CLI/Version.hpp"
 # Pick out just the version
 string(REGEX REPLACE ${VERSION_REGEX} "\\1" VERSION_STRING "${VERSION_STRING}")
 
+# Add the project
 project(CLI11 LANGUAGES CXX VERSION ${VERSION_STRING})
 
-set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
-
 # Only if built as the main project
 if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
     # User settable
@@ -31,7 +36,7 @@ if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
     if(MSVC)
         add_definitions("/W4")
     else()
-        add_definitions(-Wall -Wextra -pedantic -Wno-deprecated-declarations)
+        add_definitions(-Wall -Wextra -pedantic)
     endif()
 
     if(CMAKE_VERSION VERSION_GREATER 3.6)
@@ -74,8 +79,16 @@ target_include_directories(CLI11 INTERFACE
 # Make add_subdirectory work like find_package
 add_library(CLI11::CLI11 ALIAS CLI11)
 
+option(CLI11_INSTALL "Install the CLI11 folder to include during install process" ${CUR_PROJ})
+
 # This folder should be installed
-install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/CLI DESTINATION include)
+if(CLI11_INSTALL)
+    install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/CLI DESTINATION include)
+
+    # Make an export target
+    install(TARGETS CLI11
+            EXPORT CLI11Targets)
+endif()
 
 # Use find_package on the installed package
 # Since we have no custom code, we can directly write this
@@ -90,37 +103,42 @@ write_basic_package_version_file(
     COMPATIBILITY AnyNewerVersion
     )
 
-# Make version available in the install
-install(FILES "${CMAKE_CURRENT_BINARY_DIR}/CLI11ConfigVersion.cmake"
-        DESTINATION lib/cmake/CLI11)
-
-# Make an export target
-install(TARGETS CLI11
-        EXPORT CLI11Targets)
-
-# Install the export target as a file
-install(EXPORT CLI11Targets
-        FILE CLI11Config.cmake
-        NAMESPACE CLI11::
-        DESTINATION lib/cmake/CLI11)
-
-# Use find_package on the installed package
-export(TARGETS CLI11
-       NAMESPACE CLI11::
-       FILE CLI11Targets.cmake)
+# These installs only make sense for a local project
+if(CUR_PROJ)
+    # Make version available in the install
+    install(FILES "${CMAKE_CURRENT_BINARY_DIR}/CLI11ConfigVersion.cmake"
+            DESTINATION lib/cmake/CLI11)
+
+    # Install the export target as a file
+    install(EXPORT CLI11Targets
+            FILE CLI11Config.cmake
+            NAMESPACE CLI11::
+            DESTINATION lib/cmake/CLI11)
+
+    # Use find_package on the installed package
+    export(TARGETS CLI11
+           NAMESPACE CLI11::
+           FILE CLI11Targets.cmake)
+
+    # Register in the user cmake package registry
+    export(PACKAGE CLI11)
+endif()
 
-# Register in the user cmake package registry
-export(PACKAGE CLI11)
+option(CLI11_SINGLE_FILE "Generate a single header file" OFF)
 
+if(CLI11_SINGLE_FILE)
 # Single file test
-find_package(PythonInterp)
-cmake_dependent_option(CLI11_SINGLE_FILE "Generate a single header file" ON "CUR_PROJ;PYTHONINTERP_FOUND" OFF)
+    if(CMAKE_VERSION VERSION_LESS 3.12)
+        find_package(PythonInterp REQUIRED)
+        set(Python_VERSION ${PYTHON_VERSION_STRING})
+        set(Python_EXECUTABLE "${PYTHON_EXECUTABLE}")
+    else()
+        find_package(Python REQUIRED)
+    endif()
 
-if(CLI11_SINGLE_FILE)
-    find_package(PythonInterp REQUIRED)
     file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include")
     add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/include/CLI11.hpp"
-        COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/MakeSingleHeader.py" "${CMAKE_CURRENT_BINARY_DIR}/include/CLI11.hpp"
+        COMMAND "${Python_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/MakeSingleHeader.py" "${CMAKE_CURRENT_BINARY_DIR}/include/CLI11.hpp"
         DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/include/CLI/CLI.hpp" ${CLI11_headers}
         )
     add_custom_target(generate_cli_single_file ALL
diff --git a/packages/CLI11/LICENSE b/packages/CLI11/LICENSE
index d3d8f0122469ff0545f94dee5ac22854975e5131..6b00778361fa1a72bf82271e2a56ba166204b540 100644
--- a/packages/CLI11/LICENSE
+++ b/packages/CLI11/LICENSE
@@ -1,4 +1,4 @@
-CLI11 1.5 Copyright (c) 2017-2018 University of Cincinnati, developed by Henry
+CLI11 1.6 Copyright (c) 2017-2018 University of Cincinnati, developed by Henry
 Schreiner under NSF AWARD 1414736. All rights reserved.
 
 Redistribution and use in source and binary forms of CLI11, with or without
diff --git a/packages/CLI11/README.md b/packages/CLI11/README.md
index 10c50049df5145d25f11b012e160b1a37b2d667a..319769ff0943e40d905356886b2ececac1c7fe12 100644
--- a/packages/CLI11/README.md
+++ b/packages/CLI11/README.md
@@ -1,70 +1,105 @@
-[![Build Status Linux and macOS][travis-badge]][Travis]
-[![Build Status Windows][appveyor-badge]][AppVeyor]
-[![Code Coverage][codecov-badge]][CodeCov]
+# CLI11: Command line parser for C++11
+
+![CLI11 Logo](./docs/CLI11_300.png)
+
+[![Build Status Linux and macOS][travis-badge]][travis]
+[![Build Status Windows][appveyor-badge]][appveyor]
+[![Code Coverage][codecov-badge]][codecov]
 [![Codacy Badge][codacy-badge]][codacy-link]
 [![Join the chat at https://gitter.im/CLI11gitter/Lobby][gitter-badge]][gitter]
 [![License: BSD][license-badge]](./LICENSE)
-[![Latest release][releases-badge]][Github Releases]
-[![DOI][DOI-badge]][DOI-link]
+[![Latest release][releases-badge]][github releases]
+[![DOI][doi-badge]][doi-link]
 [![Conan.io][conan-badge]][conan-link]
-[![Try CLI11 1.5.2 online][wandbox-badge]][wandbox-link]
+[![Try CLI11 1.6 online][wandbox-badge]][wandbox-link]
 
-[Documentation][GitBook] •
+[Documentation][gitbook] •
 [API Reference][api-docs] •
 [What's new](./CHANGELOG.md)
 
-# CLI11: Command line parser for C++11
+CLI11 is a command line parser for C++11 and beyond that provides a rich feature set with a simple and intuitive interface.
+
+## Table of Contents
+
+-   [Background](#background)
+    -   [Introduction](#introduction)
+    -   [Why write another CLI parser?](#why-write-another-cli-parser)
+    -   [Other parsers](#other-parsers)
+    -   [Features not supported by this library](#features-not-supported-by-this-library)
+-   [Install](#install)
+-   [Usage](#usage)
+    -   [Adding options](#adding-options)
+        -   [Option types](#option-types)
+        -   [Option options](#option-options)
+    -   [Subcommands](#subcommands)
+        -   [Subcommand options](#subcommand-options)
+    -   [Configuration file](#configuration-file)
+    -   [Inheriting defaults](#inheriting-defaults)
+    -   [Formatting](#formatting)
+    -   [Subclassing](#subclassing)
+    -   [How it works](#how-it-works)
+    -   [Utilities](#utilities)
+    -   [Other libraries](#other-libraries)
+-   [API](#api)
+-   [Contribute](#contribute)
+-   [License](#license)
+
+## Background
+
+### Introduction
 
 CLI11 provides all the features you expect in a powerful command line parser, with a beautiful, minimal syntax and no dependencies beyond C++11. It is header only, and comes in a single file form for easy inclusion in projects. It is easy to use for small projects, but powerful enough for complex command line projects, and can be customized for frameworks.
-It is tested on [Travis] and [AppVeyor], and is being included in the [GooFit GPU fitting framework][GooFit]. It was inspired by [`plumbum.cli`][Plumbum] for Python. CLI11 has a user friendly introduction in this README, a more in-depth tutorial [GitBook], as well as [API documentation][api-docs] generated by Travis.
-See the [changelog](./CHANGELOG.md) or [GitHub Releases] for details for current and past releases. Also see the [Version 1.0 post] and [Version 1.3 post] for more information.
+It is tested on [Travis][] and [AppVeyor][], and is being included in the [GooFit GPU fitting framework][goofit]. It was inspired by [`plumbum.cli`][plumbum] for Python. CLI11 has a user friendly introduction in this README, a more in-depth tutorial [GitBook][], as well as [API documentation][api-docs] generated by Travis.
+See the [changelog](./CHANGELOG.md) or [GitHub Releases][] for details for current and past releases. Also see the [Version 1.0 post][], [Version 1.3 post][], or [Version 1.6 post][] for more information.
 
-You can be notified when new releases are made by subscribing to https://github.com/CLIUtils/CLI11/releases.atom on an RSS reader, like Feedly.
+You can be notified when new releases are made by subscribing to <https://github.com/CLIUtils/CLI11/releases.atom> on an RSS reader, like Feedly.
 
 ### Why write another CLI parser?
 
 An acceptable CLI parser library should be all of the following:
 
-* Easy to include (i.e., header only, one file if possible, **no external requirements**).
-* Short, simple syntax: This is one of the main reasons to use a CLI parser, it should make variables from the command line nearly as easy to define as any other variables. If most of your program is hidden in CLI parsing, this is a problem for readability.
-* C++11 or better: Should work with GCC 4.7+ (such as GCC 4.8 on CentOS 7), Clang 3.5+, AppleClang 7+, NVCC 7.0+, or MSVC 2015+.
-* Work on Linux, macOS, and Windows.
-* Well tested using [Travis] (Linux and macOS) and [AppVeyor] (Windows). "Well" is defined as having good coverage measured by [CodeCov].
-* Clear help printing.
-* Nice error messages.
-* Standard shell idioms supported naturally, like grouping flags, a positional separator, etc.
-* Easy to execute, with help, parse errors, etc. providing correct exit and details.
-* Easy to extend as part of a framework that provides "applications" to users.
-* Usable subcommand syntax, with support for multiple subcommands, nested subcommands, and optional fallthrough (explained later).
-* Ability to add a configuration file (`ini` format), and produce it as well.
-* Produce real values that can be used directly in code, not something you have pay compute time to look up, for HPC applications.
-* Work with standard types, simple custom types, and extendible to exotic types.
-* Permissively licensed.
+-   Easy to include (i.e., header only, one file if possible, **no external requirements**).
+-   Short, simple syntax: This is one of the main reasons to use a CLI parser, it should make variables from the command line nearly as easy to define as any other variables. If most of your program is hidden in CLI parsing, this is a problem for readability.
+-   C++11 or better: Should work with GCC 4.7+ (such as GCC 4.8 on CentOS 7), Clang 3.5+, AppleClang 7+, NVCC 7.0+, or MSVC 2015+.
+-   Work on Linux, macOS, and Windows.
+-   Well tested using [Travis][] (Linux and macOS) and [AppVeyor][] (Windows). "Well" is defined as having good coverage measured by [CodeCov][].
+-   Clear help printing.
+-   Nice error messages.
+-   Standard shell idioms supported naturally, like grouping flags, a positional separator, etc.
+-   Easy to execute, with help, parse errors, etc. providing correct exit and details.
+-   Easy to extend as part of a framework that provides "applications" to users.
+-   Usable subcommand syntax, with support for multiple subcommands, nested subcommands, and optional fallthrough (explained later).
+-   Ability to add a configuration file (`ini` format), and produce it as well.
+-   Produce real values that can be used directly in code, not something you have pay compute time to look up, for HPC applications.
+-   Work with standard types, simple custom types, and extendible to exotic types.
+-   Permissively licensed.
+
+### Other parsers
 
 <details><summary>The major CLI parsers for C++ include, with my biased opinions: (click to expand)</summary><p>
 
-| Library | My biased opinion |
-|---------|-------------------|
-| [Boost Program Options] | A great library if you already depend on Boost, but its pre-C++11 syntax is really odd and setting up the correct call in the main function is poorly documented (and is nearly a page of code). A simple wrapper for the Boost library was originally developed, but was discarded as CLI11 became more powerful. The idea of capturing a value and setting it originated with Boost PO. [See this comparison.][cli11-po-compare] |
-| [The Lean Mean C++ Option Parser] | One header file is great, but the syntax is atrocious, in my opinion. It was quite impractical to wrap the syntax or to use in a complex project. It seems to handle standard parsing quite well. |
-| [TCLAP] | The not-quite-standard command line parsing causes common shortcuts to fail. It also seems to be poorly supported, with only minimal bugfixes accepted. Header only, but in quite a few files. Has not managed to get enough support to move to GitHub yet. No subcommands. Produces wrapped values. |
-| [Cxxopts] | C++11, single file, and nice CMake support, but requires regex, therefore GCC 4.8 (CentOS 7 default) does not work. Syntax closely based on Boost PO, so not ideal but familiar. |
-| [DocOpt] | Completely different approach to program options in C++11, you write the docs and the interface is generated. Too fragile and specialized. |
+| Library                             | My biased opinion                                                                                                                                                                                                                                                                                                                                                                                                                  |
+| ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| [Boost Program Options][]           | A great library if you already depend on Boost, but its pre-C++11 syntax is really odd and setting up the correct call in the main function is poorly documented (and is nearly a page of code). A simple wrapper for the Boost library was originally developed, but was discarded as CLI11 became more powerful. The idea of capturing a value and setting it originated with Boost PO. [See this comparison.][cli11-po-compare] |
+| [The Lean Mean C++ Option Parser][] | One header file is great, but the syntax is atrocious, in my opinion. It was quite impractical to wrap the syntax or to use in a complex project. It seems to handle standard parsing quite well.                                                                                                                                                                                                                                  |
+| [TCLAP][]                           | The not-quite-standard command line parsing causes common shortcuts to fail. It also seems to be poorly supported, with only minimal bugfixes accepted. Header only, but in quite a few files. Has not managed to get enough support to move to GitHub yet. No subcommands. Produces wrapped values.                                                                                                                               |
+| [Cxxopts][]                         | C++11, single file, and nice CMake support, but requires regex, therefore GCC 4.8 (CentOS 7 default) does not work. Syntax closely based on Boost PO, so not ideal but familiar.                                                                                                                                                                                                                                                   |
+| [DocOpt][]                          | Completely different approach to program options in C++11, you write the docs and the interface is generated. Too fragile and specialized.                                                                                                                                                                                                                                                                                         |
 
 After I wrote this, I also found the following libraries:
 
-| Library | My biased opinion |
-|---------|-------------------|
-| [GFlags] | The Google Commandline Flags library. Uses macros heavily, and is limited in scope, missing things like subcommands. It provides a simple syntax and supports config files/env vars. |
-| [GetOpt] | Very limited C solution with long, convoluted syntax. Does not support much of anything, like help generation. Always available on UNIX, though (but in different flavors). |
-| [ProgramOptions.hxx] | Intresting library, less powerful and no subcommands. Nice callback system. |
-| [Args] | Also interesting, and supports subcommands. I like the optional-like design, but CLI11 is cleaner and provides direct value access, and is less verbose. |
-| [Argument Aggregator] | I'm a big fan of the [fmt] library, and the try-catch statement looks familiar.  :thumbsup: Doesn't seem to support subcommands. |
-| [Clara] | Simple library built for the excellent [Catch] testing framework. Unique syntax, limited scope. |
-| [Argh!] | Very minimalistic C++11 parser, single header. Don't have many features. No help generation?!?! At least it's exception-free.|
-| [CLI]   | Custom language and parser. Huge build-system overkill for very little benefit. Last release in 2009, but still occasionally active. |
+| Library                 | My biased opinion                                                                                                                                                                    |
+| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| [GFlags][]              | The Google Commandline Flags library. Uses macros heavily, and is limited in scope, missing things like subcommands. It provides a simple syntax and supports config files/env vars. |
+| [GetOpt][]              | Very limited C solution with long, convoluted syntax. Does not support much of anything, like help generation. Always available on UNIX, though (but in different flavors).          |
+| [ProgramOptions.hxx][]  | Intresting library, less powerful and no subcommands. Nice callback system.                                                                                                          |
+| [Args][]                | Also interesting, and supports subcommands. I like the optional-like design, but CLI11 is cleaner and provides direct value access, and is less verbose.                             |
+| [Argument Aggregator][] | I'm a big fan of the [fmt][] library, and the try-catch statement looks familiar.  :thumbsup: Doesn't seem to support subcommands.                                                   |
+| [Clara][]               | Simple library built for the excellent [Catch][] testing framework. Unique syntax, limited scope.                                                                                    |
+| [Argh!][]               | Very minimalistic C++11 parser, single header. Don't have many features. No help generation?!?! At least it's exception-free.                                                        |
+| [CLI][]                 | Custom language and parser. Huge build-system overkill for very little benefit. Last release in 2009, but still occasionally active.                                                 |
 
-See [Awesome C++] for a less-biased list of parsers. You can also find other single file libraries at [Single file libs].
+See [Awesome C++][] for a less-biased list of parsers. You can also find other single file libraries at [Single file libs][].
 
 </p></details>
 <br/>
@@ -72,26 +107,25 @@ See [Awesome C++] for a less-biased list of parsers. You can also find other sin
 None of these libraries fulfill all the above requirements, or really even come close. As you probably have already guessed, CLI11 does.
 So, this library was designed to provide a great syntax, good compiler compatibility, and minimal installation fuss.
 
-## Features not supported by this library
+### Features not supported by this library
 
 There are some other possible "features" that are intentionally not supported by this library:
 
-* Non-standard variations on syntax, like `-long` options. This is non-standard and should be avoided, so that is enforced by this library.
-* Completion of partial options, such as Python's `argparse` supplies for incomplete arguments. It's better not to guess. Most third party command line parsers for python actually reimplement command line parsing rather than using argparse because of this perceived design flaw.
-* In C++14, you could have a set of `callback` methods with differing signatures (tested in a branch). Not deemed worth having a C++14 variation on API and removed.
-* Autocomplete: This might eventually be added to both Plumbum and CLI11, but it is not supported yet.
-* Wide strings / unicode: Since this uses the standard library only, it might be hard to properly implement, but I would be open to suggestions in how to do this.
-
+-   Non-standard variations on syntax, like `-long` options. This is non-standard and should be avoided, so that is enforced by this library.
+-   Completion of partial options, such as Python's `argparse` supplies for incomplete arguments. It's better not to guess. Most third party command line parsers for python actually reimplement command line parsing rather than using argparse because of this perceived design flaw.
+-   In C++14, you could have a set of `callback` methods with differing signatures (tested in a branch). Not deemed worth having a C++14 variation on API and removed.
+-   Autocomplete: This might eventually be added to both Plumbum and CLI11, but it is not supported yet.
+-   Wide strings / unicode: Since this uses the standard library only, it might be hard to properly implement, but I would be open to suggestions in how to do this.
 
-## Installing
+## Install
 
 To use, there are two methods:
 
-1. Copy `CLI11.hpp` from the [most recent release][Github Releases] into your include directory, and you are set. This is combined from the source files  for every release. This includes the entire command parser library, but does not include separate utilities (like `Timer`, `AutoTimer`). The utilities are completely self contained and can be copied separately.
-2. Use `CLI/*.hpp` files. You could check out the repository as a submodule, for example. You can use the `CLI11::CLI11` interface target when linking from `add_subdirectory`.
-   You can also configure and optionally install the project, and then use `find_package(CLI11 CONFIG)` to get the `CLI11::CLI11` target. You can also use [Conan.io][conan-link] or [Hunter].
-   (These are just conveniences to allow you to use your favorite method of managing packages; it's just header only so including the correct path and
-   using C++11 is all you really need.)
+1.  Copy `CLI11.hpp` from the [most recent release][github releases] into your include directory, and you are set. This is combined from the source files  for every release. This includes the entire command parser library, but does not include separate utilities (like `Timer`, `AutoTimer`). The utilities are completely self contained and can be copied separately.
+2.  Use `CLI/*.hpp` files. You could check out the repository as a submodule, for example. You can use the `CLI11::CLI11` interface target when linking from `add_subdirectory`.
+    You can also configure and optionally install the project, and then use `find_package(CLI11 CONFIG)` to get the `CLI11::CLI11` target. You can also use [Conan.io][conan-link] or [Hunter][].
+    (These are just conveniences to allow you to use your favorite method of managing packages; it's just header only so including the correct path and
+    using C++11 is all you really need.)
 
 To build the tests, checkout the repository and use CMake:
 
@@ -103,7 +137,9 @@ make
 GTEST_COLOR=1 CTEST_OUTPUT_ON_FAILURE=1 make test
 ```
 
-## Adding options
+## Usage
+
+### Adding options
 
 To set up, add options, and run, your main function will look something like this:
 
@@ -131,10 +167,11 @@ The try/catch block ensures that `-h,--help` or a parse error will exit with the
 </p></details>
 </br>
 
-
 The initialization is just one line, adding options is just two each. The parse macro is just one line (or 5 for the contents of the macro).  After the app runs, the filename will be set to the correct value if it was passed, otherwise it will be set to the default. You can check to see if this was passed on the command line with `app.count("--file")`.
 
-The supported values are:
+#### Option types
+
+While all options internally are the same type, there are several ways to add an option depending on what you need. The supported values are:
 
 ```cpp
 app.add_option(option_name,
@@ -160,55 +197,58 @@ app.add_set(option_name,
 
 app.add_set_ignore_case(... // String only
 
-App* subcom = app.add_subcommand(name, discription);
+App* subcom = app.add_subcommand(name, description);
 ```
 
 An option name must start with a alphabetic character or underscore. For long options, anything but an equals sign or a comma is valid after that. Names are given as a comma separated string, with the dash or dashes. An option or flag can have as many names as you want, and afterward, using `count`, you can use any of the names, with dashes as needed, to count the options. One of the names is allowed to be given without proceeding dash(es); if present the option is a positional option, and that name will be used on help line for its positional form. If you want the default value to print in the help description, pass in `true` for the final parameter for `add_option` or `add_set`. The set options allow your users to pick from a set of predefined options; you can add an existing set if you need to modify the set later, or you can use an initializer list.
 
 On a C++14 compiler, you can pass a callback function directly to `.add_flag`, while in C++11 mode you'll need to use `.add_flag_function` if you want a callback function. The function will be given the number of times the flag was passed. You can throw a relevant `CLI::ParseError` to signal a failure.
 
-On a compiler that supports C++17's `__has_include`, you can also use `std::optional`, `std::experimental::optional`, and `boost::optional` directly in an `add_option` call. If you don't have `__has_include`, you can define `CLI11_BOOST_OPTIONAL 1` before including CLI11 to manually add support (or 0 to remove) for `boost::optional`. See [CLI11 Internals] for information on how this was done and how you can add your own converters.
+On a compiler that supports C++17's `__has_include`, you can also use `std::optional`, `std::experimental::optional`, and `boost::optional` directly in an `add_option` call. If you don't have `__has_include`, you can define `CLI11_BOOST_OPTIONAL 1` before including CLI11 to manually add support (or 0 to remove) for `boost::optional`. See [CLI11 Internals][] for information on how this was done and how you can add your own converters.
 
-### Example
+#### Example
 
-* `"one,-o,--one"`: Valid as long as not a flag, would create an option that can be specified positionally, or with `-o` or `--one`
-* `"this"` Can only be passed positionally
-* `"-a,-b,-c"` No limit to the number of non-positional option names
+-   `"one,-o,--one"`: Valid as long as not a flag, would create an option that can be specified positionally, or with `-o` or `--one`
+-   `"this"` Can only be passed positionally
+-   `"-a,-b,-c"` No limit to the number of non-positional option names
 
+The add commands return a pointer to an internally stored `Option`. If you set the final argument to true, the default value is captured and printed on the command line with the help flag. This option can be used directly to check for the count (`->count()`) after parsing to avoid a string based lookup. 
 
-The add commands return a pointer to an internally stored `Option`. If you set the final argument to true, the default value is captured and printed on the command line with the help flag. This option can be used directly to check for the count (`->count()`) after parsing to avoid a string based lookup. Before parsing, you can set the following options:
+#### Option options
 
-* `->required()`: The program will quit if this option is not present. This is `mandatory` in Plumbum, but required options seems to be a more standard term. For compatibility, `->mandatory()` also works.
-* `->expected(N)`: Take `N` values instead of as many as possible, only for vector args. If negative, require at least `-N`; end with `--` or another recognized option.
-* `->set_custom_option(typename, N)`: Set the name and (optional) intrinsic size of an option. The parser will require multiples of this number if negative.
-* `->needs(opt)`: This option requires another option to also be present, opt is an `Option` pointer.
-* `->excludes(opt)`: This option cannot be given with `opt` present, opt is an `Option` pointer.
-* `->envname(name)`: Gets the value from the environment if present and not passed on the command line.
-* `->group(name)`: The help group to put the option in. No effect for positional options. Defaults to `"Options"`. `""` will not show up in the help print (hidden).
-* `->ignore_case()`: Ignore the case on the command line (also works on subcommands, does not affect arguments).
-* `->multi_option_policy(CLI::MultiOptionPolicy::Throw)`: Set the multi-option policy. Shortcuts available: `->take_last()`, `->take_first()`, and `->join()`. This will only affect options expecting 1 argument or bool flags (which always default to take last).
-* `->check(CLI::ExistingFile)`: Requires that the file exists if given.
-* `->check(CLI::ExistingDirectory)`: Requires that the directory exists.
-* `->check(CLI::ExistingPath)`: Requires that the path (file or directory) exists.
-* `->check(CLI::NonexistentPath)`: Requires that the path does not exist.
-* `->check(CLI::Range(min,max))`: Requires that the option be between min and max (make sure to use floating point if needed). Min defaults to 0.
-* `->transform(std::string(std::string))`: Converts the input string into the output string, in-place in the parsed options.
-* `->each(void(std::string)>`: Run this function on each value received, as it is received.
-* `->configurable(false)`: Disable this option from being in a configuration file.
+Before parsing, you can set the following options:
 
-These options return the `Option` pointer, so you can chain them together, and even skip storing the pointer entirely. Check takes any function that has the signature `void(const std::string&)`; it should throw a `ValidationError` when validation fails. The help message will have the name of the parent option prepended. Since `check` and `transform` use the same underlying mechanism, you can chain as many as you want, and they will be executed in order. If you just want to see the unconverted values, use `.results()` to get the `std::vector<std::string>` of results. Validate can also be a subclass of `CLI::Validator`, in which case it can also set the type name and can be combined with `&` and `|` (all built-in validators are this sort).
+-   `->required()`: The program will quit if this option is not present. This is `mandatory` in Plumbum, but required options seems to be a more standard term. For compatibility, `->mandatory()` also works.
+-   `->expected(N)`: Take `N` values instead of as many as possible, only for vector args. If negative, require at least `-N`; end with `--` or another recognized option.
+-   `->type_name(typename)`: Set the name of an Option's type (`type_name_fn` allows a function instead)
+-   `->type_size(N)`: Set the intrinsic size of an option. The parser will require multiples of this number if negative.
+-   `->needs(opt)`: This option requires another option to also be present, opt is an `Option` pointer.
+-   `->excludes(opt)`: This option cannot be given with `opt` present, opt is an `Option` pointer.
+-   `->envname(name)`: Gets the value from the environment if present and not passed on the command line.
+-   `->group(name)`: The help group to put the option in. No effect for positional options. Defaults to `"Options"`. `""` will not show up in the help print (hidden).
+-   `->ignore_case()`: Ignore the case on the command line (also works on subcommands, does not affect arguments).
+-   `->multi_option_policy(CLI::MultiOptionPolicy::Throw)`: Set the multi-option policy. Shortcuts available: `->take_last()`, `->take_first()`, and `->join()`. This will only affect options expecting 1 argument or bool flags (which always default to take last).
+-   `->check(CLI::ExistingFile)`: Requires that the file exists if given.
+-   `->check(CLI::ExistingDirectory)`: Requires that the directory exists.
+-   `->check(CLI::ExistingPath)`: Requires that the path (file or directory) exists.
+-   `->check(CLI::NonexistentPath)`: Requires that the path does not exist.
+-   `->check(CLI::Range(min,max))`: Requires that the option be between min and max (make sure to use floating point if needed). Min defaults to 0.
+-   `->transform(std::string(std::string))`: Converts the input string into the output string, in-place in the parsed options.
+-   `->each(void(std::string)>`: Run this function on each value received, as it is received.
+-   `->configurable(false)`: Disable this option from being in a configuration file.
 
+These options return the `Option` pointer, so you can chain them together, and even skip storing the pointer entirely. Check takes any function that has the signature `void(const std::string&)`; it should throw a `ValidationError` when validation fails. The help message will have the name of the parent option prepended. Since `check` and `transform` use the same underlying mechanism, you can chain as many as you want, and they will be executed in order. If you just want to see the unconverted values, use `.results()` to get the `std::vector<std::string>` of results. Validate can also be a subclass of `CLI::Validator`, in which case it can also set the type name and can be combined with `&` and `|` (all built-in validators are this sort).
 
 On the command line, options can be given as:
 
-* `-a` (flag)
-* `-abc` (flags can be combined)
-* `-f filename` (option)
-* `-ffilename` (no space required)
-* `-abcf filename` (flags and option can be combined)
-* `--long` (long flag)
-* `--file filename` (space)
-* `--file=filename` (equals)
+-   `-a` (flag)
+-   `-abc` (flags can be combined)
+-   `-f filename` (option)
+-   `-ffilename` (no space required)
+-   `-abcf filename` (flags and option can be combined)
+-   `--long` (long flag)
+-   `--file filename` (space)
+-   `--file=filename` (equals)
 
 Extra positional arguments will cause the program to exit, so at least one positional option with a vector is recommended if you want to allow extraneous arguments.
 If you set `.allow_extras()` on the main `App`, you will not get an error. You can access the missing options using `remaining` (if you have subcommands, `app.remaining(true)` will get all remaining options, subcommands included).
@@ -217,9 +257,7 @@ You can access a vector of pointers to the parsed options in the original order
 If `--` is present in the command line that does not end an unlimited option, then
 everything after that is positional only.
 
-
-
-## Subcommands
+### Subcommands
 
 Subcommands are supported, and can be nested infinitely. To add a subcommand, call the `add_subcommand` method with a name and an optional description. This gives a pointer to an `App` that behaves just like the main app, and can take options or further subcommands. Add `->ignore_case()` to a subcommand to allow any variation of caps to also be accepted. Children inherit the current setting from the parent. You cannot add multiple matching subcommand names at the same level (including ignore
 case).
@@ -231,41 +269,43 @@ subcommand name from matching.
 If an `App` (main or subcommand) has been parsed on the command line, `->parsed` will be true (or convert directly to bool).
 All `App`s have a `get_subcommands()` method, which returns a list of pointers to the subcommands passed on the command line. A `got_subcommand(App_or_name)` method is also provided that will check to see if an `App` pointer or a string name was collected on the command line.
 
-For many cases, however, using an app's callback may be easier. Every app executes a callback function after it parses; just use a lambda function (with capture to get parsed values) to `.set_callback`. If you throw `CLI::Success` or `CLI::RuntimeError(return_value)`, you can
+For many cases, however, using an app's callback may be easier. Every app executes a callback function after it parses; just use a lambda function (with capture to get parsed values) to `.callback`. If you throw `CLI::Success` or `CLI::RuntimeError(return_value)`, you can
 even exit the program through the callback. The main `App` has a callback slot, as well, but it is generally not as useful.
 You are allowed to throw `CLI::Success` in the callbacks.
-Multiple subcommands are allowed, to allow [`Click`][Click] like series of commands (order is preserved).
+Multiple subcommands are allowed, to allow [`Click`][click] like series of commands (order is preserved).
+
+#### Subcommand options
 
 There are several options that are supported on the main app and subcommands. These are:
 
-* `.ignore_case()`: Ignore the case of this subcommand. Inherited by added subcommands, so is usually used on the main `App`.
-* `.fallthrough()`: Allow extra unmatched options and positionals to "fall through" and be matched on a parent command. Subcommands always are allowed to fall through.
-* `.require_subcommand()`: Require 1 or more subcommands.
-* `.require_subcommand(N)`: Require `N` subcommands if `N>0`, or up to `N` if `N<0`. `N=0` resets to the default 0 or more.
-* `.require_subcommand(min, max)`: Explicitly set min and max allowed subcommands. Setting `max` to 0 is unlimited.
-* `.add_subcommand(name, description="")` Add a subcommand, returns a pointer to the internally stored subcommand.
-* `.got_subcommand(App_or_name)`: Check to see if a subcommand was received on the command line.
-* `.get_subcommands(filter)`: The list of subcommands given on the command line.
-* `.get_parent()`: Get the parent App or nullptr if called on master App.
-* `.get_option(name)`: Get an option pointer by option name
-* `.get_options(filter)`: Get the list of all defined option pointers (useful for processing the app for custom output formats).
-* `.parse_order()`: Get the list of option pointers in the order they were parsed (including duplicates).
-* `.formatter(fmt)`: Set a formatter, with signature `std::string(const App*, std::string, AppFormatMode)`. See Formatting for more details.
-* `.get_description()`: Access the description.
-* `.parsed()`: True if this subcommand was given on the command line.
-* `.set_name(name)`: Add or change the name.
-* `.set_callback(void() function)`: Set the callback that runs at the end of parsing. The options have already run at this point.
-* `.allow_extras()`: Do not throw an error if extra arguments are left over.
-* `.prefix_command()`: Like `allow_extras`, but stop immediately on the first unrecognised item. It is ideal for allowing your app or subcommand to be a "prefix" to calling another app.
-* `.set_footer(message)`: Set text to appear at the bottom of the help string.
-* `.set_help_flag(name, message)`: Set the help flag name and message, returns a pointer to the created option.
-* `.set_help_all_flag(name, message)`: Set the help all flag name and message, returns a pointer to the created option. Expands subcommands.
-* `.set_failure_message(func)`: Set the failure message function. Two provided: `CLI::FailureMessage::help` and `CLI::FailureMessage::simple` (the default).
-* `.group(name)`: Set a group name, defaults to `"Subcommands"`. Setting `""` will be hide the subcommand.
+-   `.ignore_case()`: Ignore the case of this subcommand. Inherited by added subcommands, so is usually used on the main `App`.
+-   `.fallthrough()`: Allow extra unmatched options and positionals to "fall through" and be matched on a parent command. Subcommands always are allowed to fall through.
+-   `.require_subcommand()`: Require 1 or more subcommands.
+-   `.require_subcommand(N)`: Require `N` subcommands if `N>0`, or up to `N` if `N<0`. `N=0` resets to the default 0 or more.
+-   `.require_subcommand(min, max)`: Explicitly set min and max allowed subcommands. Setting `max` to 0 is unlimited.
+-   `.add_subcommand(name, description="")` Add a subcommand, returns a pointer to the internally stored subcommand.
+-   `.got_subcommand(App_or_name)`: Check to see if a subcommand was received on the command line.
+-   `.get_subcommands(filter)`: The list of subcommands given on the command line.
+-   `.get_parent()`: Get the parent App or nullptr if called on master App.
+-   `.get_option(name)`: Get an option pointer by option name
+-   `.get_options(filter)`: Get the list of all defined option pointers (useful for processing the app for custom output formats).
+-   `.parse_order()`: Get the list of option pointers in the order they were parsed (including duplicates).
+-   `.formatter(fmt)`: Set a formatter, with signature `std::string(const App*, std::string, AppFormatMode)`. See Formatting for more details.
+-   `.get_description()`: Access the description.
+-   `.parsed()`: True if this subcommand was given on the command line.
+-   `.name(name)`: Add or change the name.
+-   `.callback(void() function)`: Set the callback that runs at the end of parsing. The options have already run at this point.
+-   `.allow_extras()`: Do not throw an error if extra arguments are left over.
+-   `.prefix_command()`: Like `allow_extras`, but stop immediately on the first unrecognised item. It is ideal for allowing your app or subcommand to be a "prefix" to calling another app.
+-   `.footer(message)`: Set text to appear at the bottom of the help string.
+-   `.set_help_flag(name, message)`: Set the help flag name and message, returns a pointer to the created option.
+-   `.set_help_all_flag(name, message)`: Set the help all flag name and message, returns a pointer to the created option. Expands subcommands.
+-   `.failure_message(func)`: Set the failure message function. Two provided: `CLI::FailureMessage::help` and `CLI::FailureMessage::simple` (the default).
+-   `.group(name)`: Set a group name, defaults to `"Subcommands"`. Setting `""` will be hide the subcommand.
 
 > Note: if you have a fixed number of required positional options, that will match before subcommand names. `{}` is an empty filter function.
 
-## Configuration file
+### Configuration file
 
 ```cpp
 app.set_config(option_name="",
@@ -283,17 +323,20 @@ If this is called with no arguments, it will remove the configuration file optio
 value = 1
 str = "A string"
 vector = 1 2 3
+str_vector = "one" "two" "and three"
 
-; Section map to subcommands
+; Sections map to subcommands
 [subcommand]
 in_subcommand = Wow
 sub.subcommand = true
 ```
 
-Spaces before and after the name and argument are ignored. Multiple arguments are separated by spaces. One set of quotes will be removed, preserving spaces (the same way the command line works). Boolean options can be `true`, `on`, `1`, `yes`; or `false`, `off`, `0`, `no` (case insensitive). Sections (and `.` separated names) are treated as subcommands (note: this does not mean that subcommand was passed, it just sets the "defaults". To print a configuration file from the passed
+Spaces before and after the name and argument are ignored. Multiple arguments are separated by spaces. One set of quotes will be removed, preserving spaces (the same way the command line works). Boolean options can be `true`, `on`, `1`, `yes`; or `false`, `off`, `0`, `no` (case insensitive). Sections (and `.` separated names) are treated as subcommands (note: this does not mean that subcommand was passed, it just sets the "defaults". You cannot set positional-only arguments or force subcommands to be present in the command line.
+
+To print a configuration file from the passed
 arguments, use `.config_to_str(default_also=false, prefix="", write_description=false)`, where `default_also` will also show any defaulted arguments, `prefix` will add a prefix, and `write_description` will include option descriptions.
 
-## Inheriting defaults
+### Inheriting defaults
 
 Many of the defaults for subcommands and even options are inherited from their creators. The inherited default values for subcommands are `allow_extras`, `prefix_command`, `ignore_case`, `fallthrough`, `group`, `footer`, and maximum number of required subcommands. The help flag existence, name, and description are inherited, as well.
 
@@ -306,7 +349,7 @@ app.option_defaults()->required();
 
 The default settings for options are inherited to subcommands, as well.
 
-## Formatting
+### Formatting
 
 The job of formatting help printouts is delegated to a formatter callable object on Apps and Options. You are free to replace either formatter by calling `formatter(fmt)` on an `App`, where fmt is any copyable callable with the correct signature. 
 CLI11 comes with a default App formatter functional, `Formatter`. It is customizable; you can set `label(key, value)` to replace the default labels like `REQUIRED`, and `column_width(n)` to set the width of the columns before you add the functional to the app or option. You can also override almost any stage of the formatting process in a subclass of either formatter. If you want to make a new formatter from scratch, you can do
@@ -315,18 +358,17 @@ that too; you just need to implement the correct signature. The first argument i
 The `AppFormatMode` can be `Normal`, `All`, or `Sub`, and it indicates the situation the help was called in. `Sub` is optional, but the default formatter uses it to make sure expanded subcommands are called with
 their own formatter since you can't access anything but the call operator once a formatter has been set.
 
-## Subclassing
+### Subclassing
 
 The App class was designed allow toolkits to subclass it, to provide preset default options (see above) and setup/teardown code. Subcommands remain an unsubclassed `App`, since those are not expected to need setup and teardown. The default `App` only adds a help flag, `-h,--help`, than can removed/replaced using `.set_help_flag(name, help_string)`. You can also set a help-all flag with `.set_help_all_flag(name, help_string)`; this will expand the subcommands (one level only). You can remove options if you have pointers to them using `.remove_option(opt)`. You can add a `pre_callback` override to customize the after parse
 but before run behavior, while
-still giving the user freedom to `set_callback` on the main app.
+still giving the user freedom to `callback` on the main app.
 
 The most important parse function is `parse(std::vector<std::string>)`, which takes a reversed list of arguments (so that `pop_back` processes the args in the correct order). `get_help_ptr` and `get_config_ptr` give you access to the help/config option pointers. The standard `parse` manually sets the name from the first argument, so it should not be in this vector.
 
 Also, in a related note, the `App` you get a pointer to is stored in the parent `App` in a `unique_ptr`s (like `Option`s) and are deleted when the main `App` goes out of scope.
 
-
-## How it works
+### How it works
 
 Every `add_` option you have seen so far depends on one method that takes a lambda function. Each of these methods is just making a different lambda function with capture to populate the option. The function has full access to the vector of strings, so it knows how many times an option was passed or how many arguments it received (flags add empty strings to keep the counts correct). The lambda returns `true` if it could validate the option strings, and
 `false` if it failed.
@@ -335,7 +377,7 @@ Other values can be added as long as they support `operator>>` (and defaults can
 
 If you wanted to extend this to support a completely new type, just use a lambda. An example of a new parser for `complex<double>` that supports all of the features of a standard `add_options` call is in [one of the tests](./tests/NewParseTest.cpp). A simpler example is shown below:
 
-### Example
+#### Example
 
 ```cpp
 app.add_option("--fancy-count", [](std::vector<std::string> val){
@@ -343,7 +385,7 @@ app.add_option("--fancy-count", [](std::vector<std::string> val){
     });
 ```
 
-## Utilities
+### Utilities
 
 There are a few other utilities that are often useful in CLI programming. These are in separate headers, and do not appear in `CLI11.hpp`, but are completely independent and can be used as needed. The `Timer`/`AutoTimer` class allows you to easily time a block of code, with custom print output. 
 
@@ -357,9 +399,9 @@ some_long_running_process();
 This will create a timer with a title (default: `Timer`), and will customize the output using the predefined `Big` output (default: `Simple`). Because it is an `AutoTimer`, it will print out the time elapsed when the timer is destroyed at the end of the block. If you use `Timer` instead, you can use `to_string` or `std::cout << timer << std::endl;` to print the time. The print function can be any function that takes two strings, the title and the time, and returns a formatted
 string for printing.
 
-## Other libraries
+### Other libraries
 
-If you use the excellent [Rang] library to add color to your terminal in a safe, multi-platform way, you can combine it with CLI11 nicely:
+If you use the excellent [Rang][] library to add color to your terminal in a safe, multi-platform way, you can combine it with CLI11 nicely:
 
 ```cpp
 std::atexit([](){std::cout << rang::style::reset;});
@@ -395,79 +437,86 @@ And, in your main function:
      sigaction(SIGINT, &sigIntHandler, nullptr);
 ```
 
-## Contributing
+## API
 
-To contribute, open an [issue][Github Issues] or [pull request][Github Pull Requests] on GitHub, or ask a question on [gitter]. The is also a short note to contributors [here](./CONTRIBUTING.md).
+The API is [documented here][api-docs]. Also see the [CLI11 tutorial GitBook][gitbook].
 
-As of version 1.0, this library is available under a 3-Clause BSD license. See the [LICENSE](./LICENSE) file for details.
+## Contribute
+
+To contribute, open an [issue][github issues] or [pull request][github pull requests] on GitHub, or ask a question on [gitter][]. The is also a short note to contributors [here](./.github/CONTRIBUTING.md).
+This readme roughly follows the [Standard Readme Style][] and includes a mention of almost every feature of the library. More complex features are documented in more detail in the [CLI11 tutorial GitBook][gitbook].
 
 This project was created by [Henry Schreiner](https://github.com/henryiii).
 Significant features and/or improvements to the code were contributed by:
 
-* [Marcus Brinkmann](https://github.com/lambdafu)
-* [Jonas Nilsson](https://github.com/SkyToGround)
-* [Doug Johnston](https://github.com/dvj)
-* [Lucas Czech](https://github.com/lczech)
-* [Mathias Soeken](https://github.com/msoeken)
-* [Nathan Hourt](https://github.com/nathanhourt)
-* [Stéphane Del Pino](https://github.com/delpinux)
-* [Anton](https://github.com/SX91)
-
-CLI11 was developed at the [University of Cincinnati] to support of the [GooFit] library under [NSF Award 1414736]. Version 0.9 was featured in a [DIANA/HEP] meeting at CERN ([see the slides][DIANA slides]). Please give it a try! Feedback is always welcome.
-
-
-[DOI-badge]:             https://zenodo.org/badge/80064252.svg
-[DOI-link]:              https://zenodo.org/badge/latestdoi/80064252
-[travis-badge]:          https://img.shields.io/travis/CLIUtils/CLI11/master.svg?label=Linux/macOS
-[Travis]:                https://travis-ci.org/CLIUtils/CLI11
-[appveyor-badge]:        https://img.shields.io/appveyor/ci/HenrySchreiner/cli11/master.svg?label=Windows
-[AppVeyor]:              https://ci.appveyor.com/project/HenrySchreiner/cli11
-[codecov-badge]:         https://codecov.io/gh/CLIUtils/CLI11/branch/master/graph/badge.svg
-[CodeCov]:               https://codecov.io/gh/CLIUtils/CLI11
-[gitter-badge]:          https://badges.gitter.im/CLI11gitter/Lobby.svg
-[gitter]:                https://gitter.im/CLI11gitter/Lobby
-[license-badge]:         https://img.shields.io/badge/License-BSD-blue.svg
-[conan-badge]:           https://api.bintray.com/packages/cliutils/CLI11/CLI11%3Acliutils/images/download.svg
-[conan-link]:            https://bintray.com/cliutils/CLI11/CLI11%3Acliutils/_latestVersion
-[Github Releases]:       https://github.com/CLIUtils/CLI11/releases
-[Github Issues]:         https://github.com/CLIUtils/CLI11/issues
-[Github Pull Requests]:  https://github.com/CLIUtils/CLI11/pulls
-[GooFit]:                https://GooFit.github.io 
-[Plumbum]:               https://plumbum.readthedocs.io/en/latest/
-[Click]:                 http://click.pocoo.org
-[api-docs]:              https://CLIUtils.github.io/CLI11/index.html
-[Rang]:                  https://github.com/agauniyal/rang
-[Boost Program Options]: http://www.boost.org/doc/libs/1_63_0/doc/html/program_options.html
-[The Lean Mean C++ Option Parser]: http://optionparser.sourceforge.net
-[TCLAP]:                 http://tclap.sourceforge.net
-[Cxxopts]:               https://github.com/jarro2783/cxxopts
-[DocOpt]:                https://github.com/docopt/docopt.cpp
-[ROOT]:                  https://root.cern.ch
-[cltools-cmake]:         https://github.com/CLIUtils/cmake
-[GFlags]:                https://gflags.github.io/gflags
-[GetOpt]:                https://www.gnu.org/software/libc/manual/html_node/Getopt.html
-[DIANA/HEP]:             http://diana-hep.org
-[NSF Award 1414736]:     https://nsf.gov/awardsearch/showAward?AWD_ID=1414736
-[University of Cincinnati]: http://www.uc.edu
-[GitBook]:               https://cliutils.gitlab.io/CLI11Tutorial
-[CLI11 Internals]:       https://cliutils.gitlab.io/CLI11Tutorial/chapters/internals.html
-[ProgramOptions.hxx]:    https://github.com/Fytch/ProgramOptions.hxx
-[Argument Aggregator]:   https://github.com/vietjtnguyen/argagg
-[Args]:                  https://github.com/Taywee/args
-[Argh!]:                 https://github.com/adishavit/argh 
-[fmt]:                   https://github.com/fmtlib/fmt
-[Catch]:                 https://github.com/philsquared/Catch
-[Clara]:                 https://github.com/philsquared/Clara
-[Version 1.0 post]:      https://iscinumpy.gitlab.io/post/announcing-cli11-10/
-[Version 1.3 post]:      https://iscinumpy.gitlab.io/post/announcing-cli11-13/
-[wandbox-badge]:         https://img.shields.io/badge/try-online-blue.svg
-[wandbox-link]:          https://wandbox.org/permlink/Z4uwGhnhD2wm2r7Z
-[releases-badge]:        https://img.shields.io/github/release/CLIUtils/CLI11.svg
-[cli11-po-compare]:      https://iscinumpy.gitlab.io/post/comparing-cli11-and-boostpo/
-[DIANA slides]:          https://indico.cern.ch/event/619465/contributions/2507949/attachments/1448567/2232649/20170424-diana-2.pdf
-[Awesome C++]:           https://github.com/fffaraz/awesome-cpp/blob/master/README.md#cli
-[CLI]:                   https://codesynthesis.com/projects/cli/
-[Single file libs]:      https://github.com/nothings/single_file_libs/blob/master/README.md
-[codacy-badge]:          https://api.codacy.com/project/badge/Grade/ac0df3aead2a4421b02070c3f324a0b9
-[codacy-link]:           https://www.codacy.com/app/henryiii/CLI11?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=CLIUtils/CLI11&amp;utm_campaign=Badge_Grade
-[Hunter]:                https://docs.hunter.sh/en/latest/packages/pkg/CLI11.html
+-   [Anton](https://github.com/SX91)
+-   [Doug Johnston](https://github.com/dvj)
+-   [Jonas Nilsson](https://github.com/SkyToGround)
+-   [Lucas Czech](https://github.com/lczech)
+-   [Marcus Brinkmann](https://github.com/lambdafu)
+-   [Mathias Soeken](https://github.com/msoeken)
+-   [Nathan Hourt](https://github.com/nathanhourt)
+-   [Sean Fisk](https://github.com/seanfisk)
+-   [Stéphane Del Pino](https://github.com/delpinux)
+
+## License
+
+As of version 1.0, this library is available under a 3-Clause BSD license. See the [LICENSE](./LICENSE) file for details.
+
+CLI11 was developed at the [University of Cincinnati][] to support of the [GooFit][] library under [NSF Award 1414736][]. Version 0.9 was featured in a [DIANA/HEP][] meeting at CERN ([see the slides][diana slides]). Please give it a try! Feedback is always welcome.
+
+[doi-badge]: https://zenodo.org/badge/80064252.svg
+[doi-link]: https://zenodo.org/badge/latestdoi/80064252
+[travis-badge]: https://img.shields.io/travis/CLIUtils/CLI11/master.svg?label=Linux/macOS
+[travis]: https://travis-ci.org/CLIUtils/CLI11
+[appveyor-badge]: https://img.shields.io/appveyor/ci/HenrySchreiner/cli11/master.svg?label=Windows
+[appveyor]: https://ci.appveyor.com/project/HenrySchreiner/cli11
+[codecov-badge]: https://codecov.io/gh/CLIUtils/CLI11/branch/master/graph/badge.svg
+[codecov]: https://codecov.io/gh/CLIUtils/CLI11
+[gitter-badge]: https://badges.gitter.im/CLI11gitter/Lobby.svg
+[gitter]: https://gitter.im/CLI11gitter/Lobby
+[license-badge]: https://img.shields.io/badge/License-BSD-blue.svg
+[conan-badge]: https://api.bintray.com/packages/cliutils/CLI11/CLI11%3Acliutils/images/download.svg
+[conan-link]: https://bintray.com/cliutils/CLI11/CLI11%3Acliutils/_latestVersion
+[github releases]: https://github.com/CLIUtils/CLI11/releases
+[github issues]: https://github.com/CLIUtils/CLI11/issues
+[github pull requests]: https://github.com/CLIUtils/CLI11/pulls
+[goofit]: https://GooFit.github.io
+[plumbum]: https://plumbum.readthedocs.io/en/latest/
+[click]: http://click.pocoo.org
+[api-docs]: https://CLIUtils.github.io/CLI11/index.html
+[rang]: https://github.com/agauniyal/rang
+[boost program options]: http://www.boost.org/doc/libs/1_63_0/doc/html/program_options.html
+[the lean mean c++ option parser]: http://optionparser.sourceforge.net
+[tclap]: http://tclap.sourceforge.net
+[cxxopts]: https://github.com/jarro2783/cxxopts
+[docopt]: https://github.com/docopt/docopt.cpp
+[gflags]: https://gflags.github.io/gflags
+[getopt]: https://www.gnu.org/software/libc/manual/html_node/Getopt.html
+[diana/hep]: http://diana-hep.org
+[nsf award 1414736]: https://nsf.gov/awardsearch/showAward?AWD_ID=1414736
+[university of cincinnati]: http://www.uc.edu
+[gitbook]: https://cliutils.gitlab.io/CLI11Tutorial
+[cli11 internals]: https://cliutils.gitlab.io/CLI11Tutorial/chapters/internals.html
+[programoptions.hxx]: https://github.com/Fytch/ProgramOptions.hxx
+[argument aggregator]: https://github.com/vietjtnguyen/argagg
+[args]: https://github.com/Taywee/args
+[argh!]: https://github.com/adishavit/argh
+[fmt]: https://github.com/fmtlib/fmt
+[catch]: https://github.com/philsquared/Catch
+[clara]: https://github.com/philsquared/Clara
+[version 1.0 post]: https://iscinumpy.gitlab.io/post/announcing-cli11-10/
+[version 1.3 post]: https://iscinumpy.gitlab.io/post/announcing-cli11-13/
+[version 1.6 post]: https://iscinumpy.gitlab.io/post/announcing-cli11-16/
+[wandbox-badge]: https://img.shields.io/badge/try-online-blue.svg
+[wandbox-link]: https://wandbox.org/permlink/95DStlyHsquYH3k6
+[releases-badge]: https://img.shields.io/github/release/CLIUtils/CLI11.svg
+[cli11-po-compare]: https://iscinumpy.gitlab.io/post/comparing-cli11-and-boostpo/
+[diana slides]: https://indico.cern.ch/event/619465/contributions/2507949/attachments/1448567/2232649/20170424-diana-2.pdf
+[awesome c++]: https://github.com/fffaraz/awesome-cpp/blob/master/README.md#cli
+[cli]: https://codesynthesis.com/projects/cli/
+[single file libs]: https://github.com/nothings/single_file_libs/blob/master/README.md
+[codacy-badge]: https://api.codacy.com/project/badge/Grade/ac0df3aead2a4421b02070c3f324a0b9
+[codacy-link]: https://www.codacy.com/app/henryiii/CLI11?utm_source=github.com&utm_medium=referral&utm_content=CLIUtils/CLI11&utm_campaign=Badge_Grade
+[hunter]: https://docs.hunter.sh/en/latest/packages/pkg/CLI11.html
+[standard readme style]: https://github.com/RichardLitt/standard-readme
diff --git a/packages/CLI11/docs/CLI11.svg b/packages/CLI11/docs/CLI11.svg
new file mode 100644
index 0000000000000000000000000000000000000000..e12b99b6a0453ca8db132473a26d8014aa315dce
--- /dev/null
+++ b/packages/CLI11/docs/CLI11.svg
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="34.342606mm"
+   height="15.300875mm"
+   viewBox="0 0 34.342606 15.300875"
+   version="1.1"
+   id="svg8"
+   inkscape:version="0.92.2 (unknown)"
+   sodipodi:docname="CLI11.svg"
+   inkscape:export-filename="/data/CLI11_300.png"
+   inkscape:export-xdpi="222.62143"
+   inkscape:export-ydpi="222.62143">
+  <defs
+     id="defs2" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="11.206433"
+     inkscape:cx="93.996945"
+     inkscape:cy="15.843961"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="2560"
+     inkscape:window-height="1347"
+     inkscape:window-x="0"
+     inkscape:window-y="1"
+     inkscape:window-maximized="1"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-53.018986,-23.9019)">
+    <g
+       id="g4602"
+       transform="rotate(-0.28559572,70.190289,31.552338)">
+      <path
+         inkscape:connector-curvature="0"
+         id="path3732"
+         transform="scale(0.26458333)"
+         d="m 233.33789,90.337891 -32.95117,28.619139 31.94726,28.91406 64.9004,0.29688 32.95117,-28.61914 -31.94727,-28.914064 z"
+         style="fill:#008080;stroke-width:0.54128456" />
+      <path
+         inkscape:connector-curvature="0"
+         style="fill:none;stroke:#ffffff;stroke-width:0.3148967;stroke-miterlimit:4;stroke-dasharray:none"
+         d="m 62.120274,24.413292 -8.32335,7.065988 8.069765,7.138804 16.393615,0.0733 8.32335,-7.065988 -8.069768,-7.138806 z"
+         id="path3774" />
+    </g>
+    <g
+       id="g4609"
+       transform="translate(-0.43472687)">
+      <path
+         inkscape:transform-center-y="0.00020894337"
+         inkscape:transform-center-x="0.0229185"
+         inkscape:connector-curvature="0"
+         id="path3730"
+         d="m 60.964519,27.804182 c 0.886395,-0.348655 1.859691,-0.390207 2.74248,-0.111952 0.651274,0.210103 1.042699,0.454066 1.576252,0.972044 l -1.506657,0.592635 c -0.744252,-0.446473 -1.423964,-0.497745 -2.270962,-0.164583 -0.738662,0.290549 -1.26082,0.814436 -1.498695,1.510755 -0.203801,0.580557 -0.182185,1.300104 0.05025,1.891033 0.534609,1.359137 2.079298,2.048044 3.418738,1.521183 0.699266,-0.275052 1.11846,-0.713017 1.465328,-1.565931 l 1.585527,-0.623658 c -0.04824,1.554281 -1.023053,2.892949 -2.510224,3.47792 -2.127345,0.836779 -4.497206,-0.187252 -5.322363,-2.28505 -0.809661,-2.058401 0.211919,-4.404734 2.270322,-5.214396 z"
+         style="fill:#ffffff;stroke-width:0.14321487" />
+      <path
+         inkscape:connector-curvature="0"
+         id="path3728"
+         transform="scale(0.26458333)"
+         d="m 253.49609,104.47266 h 5.48047 v 24.32031 h 9.03906 v 5.24023 h -14.51953 z"
+         style="fill:#ffffff;stroke-width:0.54128456" />
+      <path
+         inkscape:connector-curvature="0"
+         id="path3726"
+         transform="scale(0.26458333)"
+         d="m 271.07422,104.47266 h 5.48047 v 29.56054 h -5.48047 z"
+         style="fill:#ffffff;stroke-width:0.54128456" />
+      <path
+         inkscape:connector-curvature="0"
+         id="path3724"
+         transform="scale(0.26458333)"
+         d="m 294.68555,104.47266 v 29.56054 h -5.32032 v -24.56054 h -3.71875 z"
+         style="fill:#ffffff;stroke-width:0.54128456" />
+      <path
+         inkscape:connector-curvature="0"
+         id="path3705"
+         transform="scale(0.26458333)"
+         d="m 305.76758,104.47266 v 29.56054 h -5.32031 v -24.56054 h -3.71875 z"
+         style="fill:#ffffff;stroke-width:0.54128456" />
+    </g>
+  </g>
+</svg>
diff --git a/packages/CLI11/docs/CLI11_100.png b/packages/CLI11/docs/CLI11_100.png
new file mode 100644
index 0000000000000000000000000000000000000000..d318c48a0df1a7e23025a38cf592d4ce97dbdc97
Binary files /dev/null and b/packages/CLI11/docs/CLI11_100.png differ
diff --git a/packages/CLI11/docs/CLI11_300.png b/packages/CLI11/docs/CLI11_300.png
new file mode 100644
index 0000000000000000000000000000000000000000..3dcb4250604cfe8ffb1e3959eef7780ccd6afad7
Binary files /dev/null and b/packages/CLI11/docs/CLI11_300.png differ
diff --git a/packages/CLI11/docs/Doxyfile b/packages/CLI11/docs/Doxyfile
index 0e2a8c75b89dfee49740639db146ac14a4837996..5363a26e1f607228ee15e48dcf8e7f87a8d4aada 100644
--- a/packages/CLI11/docs/Doxyfile
+++ b/packages/CLI11/docs/Doxyfile
@@ -334,7 +334,7 @@ BUILTIN_STL_SUPPORT    = NO
 # enable parsing support.
 # The default value is: NO.
 
-CPP_CLI11_SUPPORT        = NO
+CPP_CLI_SUPPORT        = NO
 
 # Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
 # http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
diff --git a/packages/CLI11/examples/CMakeLists.txt b/packages/CLI11/examples/CMakeLists.txt
index c4618ca47025a30bddbf4a86007abb1d820b5444..ef17d2c2f8351f1771161281f503ea7d65c0a1c1 100644
--- a/packages/CLI11/examples/CMakeLists.txt
+++ b/packages/CLI11/examples/CMakeLists.txt
@@ -14,6 +14,33 @@ function(add_cli_exe T)
     endif()
 endfunction()
 
+option(CLI11_EXAMPLE_JSON OFF)
+if(CLI11_EXAMPLE_JSON)
+    if(NOT EXISTS "${CLI11_SOURCE_DIR}/extern/json/single_include/nlohmann/json.hpp")
+        message(ERROR "You are missing the json package for CLI11_EXAMPLE_JSON. Please update your submodules (git submodule update --init)")
+    endif()
+    if(CMAKE_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)
+        message(WARNING "The json example requires GCC 4.9+ (requirement on json library)")
+    endif()
+    add_cli_exe(json json.cpp)
+    target_include_directories(json PUBLIC SYSTEM "${CLI11_SOURCE_DIR}/extern/json/single_include")
+
+    add_test(NAME json_config_out COMMAND json --item 2)
+    set_property(TEST json_config_out PROPERTY PASS_REGULAR_EXPRESSION
+        "{"
+        "\"item\": \"2\""
+        "\"simple\": false"
+        "}")
+
+    file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/input.json" [=[{"item":3,"simple":false}]=])
+    add_test(NAME json_config_in COMMAND json --config "${CMAKE_CURRENT_BINARY_DIR}/input.json")
+    set_property(TEST json_config_in PROPERTY PASS_REGULAR_EXPRESSION
+        "{"
+        "\"item\": \"3\""
+        "\"simple\": false"
+        "}")
+endif()
+
 add_cli_exe(simple simple.cpp)
 add_test(NAME simple_basic COMMAND simple)
 add_test(NAME simple_all COMMAND simple -f filename.txt -c 12 --flag --flag -d 1.2)
@@ -36,6 +63,20 @@ set_property(TEST subcommands_all PROPERTY PASS_REGULAR_EXPRESSION
     "Subcommand: start"
     "Subcommand: stop")
 
+add_cli_exe(validators validators.cpp)
+add_test(NAME validators_help COMMAND validators --help)
+set_property(TEST validators_help PROPERTY PASS_REGULAR_EXPRESSION
+    "  -f,--file FILE              File name"
+    "  -v,--value INT in [3 - 6]   Value in range")
+add_test(NAME validators_file COMMAND validators --file nonex.xxx)
+set_property(TEST validators_file PROPERTY PASS_REGULAR_EXPRESSION
+    "--file: File does not exist: nonex.xxx"
+    "Run with --help for more information.")
+add_test(NAME validators_plain COMMAND validators --value 9)
+set_property(TEST validators_plain PROPERTY PASS_REGULAR_EXPRESSION
+    "--value: Value 9 not in range 3 to 6"
+    "Run with --help for more information.")
+
 add_cli_exe(groups groups.cpp)
 add_test(NAME groups_none COMMAND groups)
 set_property(TEST groups_none PROPERTY PASS_REGULAR_EXPRESSION
@@ -85,3 +126,5 @@ set_property(TEST subcom_in_files PROPERTY PASS_REGULAR_EXPRESSION
     "Using foo!")
 
 add_cli_exe(formatter formatter.cpp)
+
+add_cli_exe(nested nested.cpp)
diff --git a/packages/CLI11/examples/enum.cpp b/packages/CLI11/examples/enum.cpp
index 3e841da6a70b46ddff5a64c382fafdefb8b8344f..5d404579ab31b4a89a63c71de8e789272a007f15 100644
--- a/packages/CLI11/examples/enum.cpp
+++ b/packages/CLI11/examples/enum.cpp
@@ -17,7 +17,7 @@ int main(int argc, char **argv) {
 
     Level level;
     app.add_set("-l,--level", level, {Level::High, Level::Medium, Level::Low}, "Level settings")
-        ->set_type_name("enum/Level in {High=0, Medium=1, Low=2}");
+        ->type_name("enum/Level in {High=0, Medium=1, Low=2}");
 
     CLI11_PARSE(app, argc, argv);
 
diff --git a/packages/CLI11/examples/json.cpp b/packages/CLI11/examples/json.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bce5ecdabfa22d5695c583997dda4144a3cb1aaf
--- /dev/null
+++ b/packages/CLI11/examples/json.cpp
@@ -0,0 +1,113 @@
+#include <CLI/CLI.hpp>
+#include <nlohmann/json.hpp>
+
+// This example is only built on GCC 7 on Travis due to mismatch in stdlib
+// for clang (CLI11 is forgiving about mismatches, json.hpp is not)
+
+using nlohmann::json;
+
+class ConfigJSON : public CLI::Config {
+  public:
+    std::string to_config(const CLI::App *app, bool default_also, bool, std::string) const override {
+
+        json j;
+
+        for(const CLI::Option *opt : app->get_options({})) {
+
+            // Only process option with a long-name and configurable
+            if(!opt->get_lnames().empty() && opt->get_configurable()) {
+                std::string name = opt->get_lnames()[0];
+
+                // Non-flags
+                if(opt->get_type_size() != 0) {
+
+                    // If the option was found on command line
+                    if(opt->count() == 1)
+                        j[name] = opt->results().at(0);
+                    else if(opt->count() > 1)
+                        j[name] = opt->results();
+
+                    // If the option has a default and is requested by optional argument
+                    else if(default_also && !opt->get_defaultval().empty())
+                        j[name] = opt->get_defaultval();
+
+                    // Flag, one passed
+                } else if(opt->count() == 1) {
+                    j[name] = true;
+
+                    // Flag, multiple passed
+                } else if(opt->count() > 1) {
+                    j[name] = opt->count();
+
+                    // Flag, not present
+                } else if(opt->count() == 0 && default_also) {
+                    j[name] = false;
+                }
+            }
+        }
+
+        for(const CLI::App *subcom : app->get_subcommands({}))
+            j[subcom->get_name()] = json(to_config(subcom, default_also, false, ""));
+
+        return j.dump(4);
+    }
+
+    std::vector<CLI::ConfigItem> from_config(std::istream &input) const override {
+        json j;
+        input >> j;
+        return _from_config(j);
+    }
+
+    std::vector<CLI::ConfigItem>
+    _from_config(json j, std::string name = "", std::vector<std::string> prefix = {}) const {
+        std::vector<CLI::ConfigItem> results;
+
+        if(j.is_object()) {
+            for(json::iterator item = j.begin(); item != j.end(); ++item) {
+                auto copy_prefix = prefix;
+                if(!name.empty())
+                    copy_prefix.push_back(name);
+                auto sub_results = _from_config(*item, item.key(), copy_prefix);
+                results.insert(results.end(), sub_results.begin(), sub_results.end());
+            }
+        } else if(!name.empty()) {
+            results.emplace_back();
+            CLI::ConfigItem &res = results.back();
+            res.name = name;
+            res.parents = prefix;
+            if(j.is_boolean()) {
+                res.inputs = {j.get<bool>() ? "true" : "false"};
+            } else if(j.is_number()) {
+                std::stringstream ss;
+                ss << j.get<double>();
+                res.inputs = {ss.str()};
+            } else if(j.is_string()) {
+                res.inputs = {j.get<std::string>()};
+            } else if(j.is_array()) {
+                for(std::string ival : j)
+                    res.inputs.push_back(ival);
+            } else {
+                throw CLI::ConversionError("Failed to convert " + name);
+            }
+        } else {
+            throw CLI::ConversionError("You must make all top level values objects in json!");
+        }
+
+        return results;
+    }
+};
+
+int main(int argc, char **argv) {
+    CLI::App app;
+    app.config_formatter(std::make_shared<ConfigJSON>());
+
+    int item;
+
+    app.add_flag("--simple");
+    app.add_option("--item", item);
+    app.set_config("--config");
+
+    CLI11_PARSE(app, argc, argv);
+
+    std::cout << app.config_to_str(true, true) << std::endl;
+}
diff --git a/packages/CLI11/examples/nested.cpp b/packages/CLI11/examples/nested.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1714b8df56bf4018d2d409bec791467faf3f772c
--- /dev/null
+++ b/packages/CLI11/examples/nested.cpp
@@ -0,0 +1,22 @@
+#include <CLI/CLI.hpp>
+#include <string>
+
+int main(int argc, char **argv) {
+
+    CLI::App app("Vision Application");
+    app.set_help_all_flag("--help-all", "Expand all help");
+    app.add_flag("--version", "Get version");
+
+    CLI::App *cameraApp = app.add_subcommand("camera", "Configure the app camera");
+    cameraApp->require_subcommand(0, 1); // 0 (default) or 1 camera
+
+    std::string mvcamera_config_file = "mvcamera_config.json";
+    CLI::App *mvcameraApp = cameraApp->add_subcommand("mvcamera", "MatrixVision Camera Configuration");
+    mvcameraApp->add_option("-c,--config", mvcamera_config_file, "Config filename", true)->check(CLI::ExistingFile);
+
+    std::string mock_camera_path;
+    CLI::App *mockcameraApp = cameraApp->add_subcommand("mock", "Mock Camera Configuration");
+    mockcameraApp->add_option("-p,--path", mock_camera_path, "Path")->required()->check(CLI::ExistingPath);
+
+    CLI11_PARSE(app, argc, argv);
+}
diff --git a/packages/CLI11/examples/subcom_in_files/subcommand_a.cpp b/packages/CLI11/examples/subcom_in_files/subcommand_a.cpp
index e347148fc82e3081cb308c4c2b375c732fa3e17a..affc6e849e3abb0bfb14d80c074b6a2806f3b5df 100644
--- a/packages/CLI11/examples/subcom_in_files/subcommand_a.cpp
+++ b/packages/CLI11/examples/subcom_in_files/subcommand_a.cpp
@@ -18,7 +18,7 @@ void setup_subcommand_a(CLI::App &app) {
     sub->add_flag("--with-foo", opt->with_foo, "Counter");
 
     // Set the run function as callback to be called when this subcommand is issued.
-    sub->set_callback([opt]() { run_subcommand_a(*opt); });
+    sub->callback([opt]() { run_subcommand_a(*opt); });
 }
 
 /// The function that runs our code.
diff --git a/packages/CLI11/examples/validators.cpp b/packages/CLI11/examples/validators.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d431ed223b87eb7cbf082943e8400afe76733a24
--- /dev/null
+++ b/packages/CLI11/examples/validators.cpp
@@ -0,0 +1,17 @@
+#include "CLI/CLI.hpp"
+
+int main(int argc, char **argv) {
+
+    CLI::App app("Validator checker");
+
+    std::string file;
+    app.add_option("-f,--file,file", file, "File name")->check(CLI::ExistingFile);
+
+    int count;
+    app.add_option("-v,--value", count, "Value in range")->check(CLI::Range(3, 6));
+    CLI11_PARSE(app, argc, argv);
+
+    std::cout << "Try printing help or failing the validator" << std::endl;
+
+    return 0;
+}
diff --git a/packages/CLI11/extern/json b/packages/CLI11/extern/json
new file mode 160000
index 0000000000000000000000000000000000000000..d2dd27dc3b8472dbaa7d66f83619b3ebcd9185fe
--- /dev/null
+++ b/packages/CLI11/extern/json
@@ -0,0 +1 @@
+Subproject commit d2dd27dc3b8472dbaa7d66f83619b3ebcd9185fe
diff --git a/packages/CLI11/include/CLI/App.hpp b/packages/CLI11/include/CLI/App.hpp
index c1d30ec48826604741ee8cb1ce820b81f0971265..eebab3bfa0f6809b85b514799150eb6d77bb726f 100644
--- a/packages/CLI11/include/CLI/App.hpp
+++ b/packages/CLI11/include/CLI/App.hpp
@@ -222,13 +222,13 @@ class App {
     /// it is not possible to overload on std::function (fixed in c++14
     /// and backported to c++11 on newer compilers). Use capture by reference
     /// to get a pointer to App if needed.
-    App *set_callback(std::function<void()> callback) {
+    App *callback(std::function<void()> callback) {
         callback_ = callback;
         return this;
     }
 
     /// Set a name for the app (empty will use parser to set the name)
-    App *set_name(std::string name = "") {
+    App *name(std::string name = "") {
         name_ = name;
         return this;
     }
@@ -331,7 +331,7 @@ class App {
         CLI::callback_t fun = [&variable](CLI::results_t res) { return detail::lexical_cast(res[0], variable); };
 
         Option *opt = add_option(name, fun, description, false);
-        opt->set_custom_option(detail::type_name<T>());
+        opt->type_name(detail::type_name<T>());
         return opt;
     }
 
@@ -345,11 +345,11 @@ class App {
         CLI::callback_t fun = [&variable](CLI::results_t res) { return detail::lexical_cast(res[0], variable); };
 
         Option *opt = add_option(name, fun, description, defaulted);
-        opt->set_custom_option(detail::type_name<T>());
+        opt->type_name(detail::type_name<T>());
         if(defaulted) {
             std::stringstream out;
             out << variable;
-            opt->set_default_str(out.str());
+            opt->default_str(out.str());
         }
         return opt;
     }
@@ -371,7 +371,7 @@ class App {
         };
 
         Option *opt = add_option(name, fun, description, false);
-        opt->set_custom_option(detail::type_name<T>(), -1);
+        opt->type_name(detail::type_name<T>())->type_size(-1);
         return opt;
     }
 
@@ -393,9 +393,9 @@ class App {
         };
 
         Option *opt = add_option(name, fun, description, defaulted);
-        opt->set_custom_option(detail::type_name<T>(), -1);
+        opt->type_name(detail::type_name<T>())->type_size(-1);
         if(defaulted)
-            opt->set_default_str("[" + detail::join(variable) + "]");
+            opt->default_str("[" + detail::join(variable) + "]");
         return opt;
     }
 
@@ -440,7 +440,7 @@ class App {
         Option *opt = add_option(name, fun, description, false);
         if(opt->get_positional())
             throw IncorrectConstruction::PositionalFlag(name);
-        opt->set_custom_option("", 0);
+        opt->type_size(0);
         return opt;
     }
 
@@ -460,7 +460,7 @@ class App {
         Option *opt = add_option(name, fun, description, false);
         if(opt->get_positional())
             throw IncorrectConstruction::PositionalFlag(name);
-        opt->set_custom_option("", 0);
+        opt->type_size(0);
         return opt;
     }
 
@@ -480,7 +480,7 @@ class App {
         Option *opt = add_option(name, fun, description, false);
         if(opt->get_positional())
             throw IncorrectConstruction::PositionalFlag(name);
-        opt->set_custom_option("", 0);
+        opt->type_size(0);
         opt->multi_option_policy(CLI::MultiOptionPolicy::TakeLast);
         return opt;
     }
@@ -499,7 +499,7 @@ class App {
         Option *opt = add_option(name, fun, description, false);
         if(opt->get_positional())
             throw IncorrectConstruction::PositionalFlag(name);
-        opt->set_custom_option("", 0);
+        opt->type_size(0);
         return opt;
     }
 
@@ -530,7 +530,7 @@ class App {
         Option *opt = add_option(name, fun, description, false);
         std::string typeval = detail::type_name<T>();
         typeval += " in {" + detail::join(options) + "}";
-        opt->set_custom_option(typeval);
+        opt->type_name(typeval);
         return opt;
     }
 
@@ -550,7 +550,7 @@ class App {
         };
 
         Option *opt = add_option(name, fun, description, false);
-        opt->set_type_name_fn(
+        opt->type_name_fn(
             [&options]() { return std::string(detail::type_name<T>()) + " in {" + detail::join(options) + "}"; });
 
         return opt;
@@ -575,11 +575,11 @@ class App {
         Option *opt = add_option(name, fun, description, defaulted);
         std::string typeval = detail::type_name<T>();
         typeval += " in {" + detail::join(options) + "}";
-        opt->set_custom_option(typeval);
+        opt->type_name(typeval);
         if(defaulted) {
             std::stringstream out;
             out << member;
-            opt->set_default_str(out.str());
+            opt->default_str(out.str());
         }
         return opt;
     }
@@ -601,12 +601,12 @@ class App {
         };
 
         Option *opt = add_option(name, fun, description, defaulted);
-        opt->set_type_name_fn(
+        opt->type_name_fn(
             [&options]() { return std::string(detail::type_name<T>()) + " in {" + detail::join(options) + "}"; });
         if(defaulted) {
             std::stringstream out;
             out << member;
-            opt->set_default_str(out.str());
+            opt->default_str(out.str());
         }
         return opt;
     }
@@ -634,7 +634,7 @@ class App {
         Option *opt = add_option(name, fun, description, false);
         std::string typeval = detail::type_name<std::string>();
         typeval += " in {" + detail::join(options) + "}";
-        opt->set_custom_option(typeval);
+        opt->type_name(typeval);
 
         return opt;
     }
@@ -660,7 +660,7 @@ class App {
         };
 
         Option *opt = add_option(name, fun, description, false);
-        opt->set_type_name_fn([&options]() {
+        opt->type_name_fn([&options]() {
             return std::string(detail::type_name<std::string>()) + " in {" + detail::join(options) + "}";
         });
 
@@ -691,9 +691,9 @@ class App {
         Option *opt = add_option(name, fun, description, defaulted);
         std::string typeval = detail::type_name<std::string>();
         typeval += " in {" + detail::join(options) + "}";
-        opt->set_custom_option(typeval);
+        opt->type_name(typeval);
         if(defaulted) {
-            opt->set_default_str(member);
+            opt->default_str(member);
         }
         return opt;
     }
@@ -720,11 +720,11 @@ class App {
         };
 
         Option *opt = add_option(name, fun, description, defaulted);
-        opt->set_type_name_fn([&options]() {
+        opt->type_name_fn([&options]() {
             return std::string(detail::type_name<std::string>()) + " in {" + detail::join(options) + "}";
         });
         if(defaulted) {
-            opt->set_default_str(member);
+            opt->default_str(member);
         }
         return opt;
     }
@@ -749,11 +749,11 @@ class App {
         };
 
         CLI::Option *opt = add_option(name, fun, description, defaulted);
-        opt->set_custom_option(label, 2);
+        opt->type_name(label)->type_size(2);
         if(defaulted) {
             std::stringstream out;
             out << variable;
-            opt->set_default_str(out.str());
+            opt->default_str(out.str());
         }
         return opt;
     }
@@ -878,6 +878,21 @@ class App {
     ///@}
     /// @name Parsing
     ///@{
+    //
+    /// Reset the parsed data
+    void clear() {
+
+        parsed_ = false;
+        missing_.clear();
+        parsed_subcommands_.clear();
+
+        for(const Option_p &opt : options_) {
+            opt->clear();
+        }
+        for(const App_p &app : subcommands_) {
+            app->clear();
+        }
+    }
 
     /// Parses the command line - throws errors
     /// This must be called after the options are in but before the rest of the program.
@@ -895,13 +910,22 @@ class App {
     /// The real work is done here. Expects a reversed vector.
     /// Changes the vector to the remaining options.
     void parse(std::vector<std::string> &args) {
+        // Clear if parsed
+        if(parsed_)
+            clear();
+
+        // Redundant (set by _parse on commands/subcommands)
+        // but placed here to make sure this is cleared when
+        // running parse after an error is thrown, even by _validate.
+        parsed_ = true;
+
         _validate();
         _parse(args);
         run_callback();
     }
 
     /// Provide a function to print a help message. The function gets access to the App pointer and error.
-    void set_failure_message(std::function<std::string(const App *, const Error &e)> function) {
+    void failure_message(std::function<std::string(const App *, const Error &e)> function) {
         failure_message_ = function;
     }
 
@@ -930,21 +954,6 @@ class App {
         return e.get_exit_code();
     }
 
-    /// Reset the parsed data
-    void reset() {
-
-        parsed_ = false;
-        missing_.clear();
-        parsed_subcommands_.clear();
-
-        for(const Option_p &opt : options_) {
-            opt->clear();
-        }
-        for(const App_p &app : subcommands_) {
-            app->reset();
-        }
-    }
-
     ///@}
     /// @name Post parsing
     ///@{
@@ -1012,7 +1021,7 @@ class App {
     ///@{
 
     /// Set footer.
-    App *set_footer(std::string footer) {
+    App *footer(std::string footer) {
         footer_ = footer;
         return this;
     }
@@ -1034,11 +1043,23 @@ class App {
         // Delegate to subcommand if needed
         auto selected_subcommands = get_subcommands();
         if(!selected_subcommands.empty())
-            return selected_subcommands.at(0)->help(prev);
+            return selected_subcommands.at(0)->help(prev, mode);
         else
             return formatter_->make_help(this, prev, mode);
     }
 
+    /// Provided for backwards compatibility \deprecated
+    CLI11_DEPRECATED("Please use footer instead")
+    App *set_footer(std::string msg) { return footer(msg); }
+
+    /// Provided for backwards compatibility \deprecated
+    CLI11_DEPRECATED("Please use name instead")
+    App *set_name(std::string msg) { return name(msg); }
+
+    /// Provided for backwards compatibility \deprecated
+    CLI11_DEPRECATED("Please use callback instead")
+    App *set_callback(std::function<void()> fn) { return callback(fn); }
+
     ///@}
     /// @name Getters
     ///@{
@@ -1187,7 +1208,7 @@ class App {
 
     /// This returns the number of remaining options, minus the -- seperator
     size_t remaining_size(bool recurse = false) const {
-        size_t count = static_cast<size_t>(std::count_if(
+        auto count = static_cast<size_t>(std::count_if(
             std::begin(missing_), std::end(missing_), [](const std::pair<detail::Classifer, std::string> &val) {
                 return val.first != detail::Classifer::POSITIONAL_MARK;
             }));
@@ -1349,10 +1370,13 @@ class App {
             size_t num_left_over = remaining_size();
             if(num_left_over > 0) {
                 args = remaining(false);
-                std::reverse(std::begin(args), std::end(args));
                 throw ExtrasError(args);
             }
         }
+
+        if(parent_ == nullptr) {
+            args = remaining(false);
+        }
     }
 
     /// Parse one config param, return false if not found in any subcommand, remove if it is
@@ -1608,6 +1632,7 @@ class App {
 
 namespace FailureMessage {
 
+/// Printout a clean, simple message on error (the default in CLI11 1.5+)
 inline std::string simple(const App *app, const Error &e) {
     std::string header = std::string(e.what()) + "\n";
     if(app->get_help_ptr() != nullptr)
@@ -1615,6 +1640,7 @@ inline std::string simple(const App *app, const Error &e) {
     return header;
 }
 
+/// Printout the full help string on error (if this fn is set, the old default for CLI11)
 inline std::string help(const App *app, const Error &e) {
     std::string header = std::string("ERROR: ") + e.get_name() + ": " + e.what() + "\n";
     header += app->help();
diff --git a/packages/CLI11/include/CLI/Config.hpp b/packages/CLI11/include/CLI/Config.hpp
index 33f8619739745acba19dcdee5200621dc4a0e863..4a72a6198e60444d250bcc7f49dc869754962b8b 100644
--- a/packages/CLI11/include/CLI/Config.hpp
+++ b/packages/CLI11/include/CLI/Config.hpp
@@ -29,7 +29,7 @@ ConfigINI::to_config(const App *app, bool default_also, bool write_description,
 
                 // If the option was found on command line
                 if(opt->count() > 0)
-                    value = detail::inijoin(opt->results());
+                    value = detail::ini_join(opt->results());
 
                 // If the option has a default and is requested by optional argument
                 else if(default_also && !opt->get_defaultval().empty())
diff --git a/packages/CLI11/include/CLI/ConfigFwd.hpp b/packages/CLI11/include/CLI/ConfigFwd.hpp
index 5ee2e1cbe6a402944f8c0aa8eebb93353572ff03..53be440368f8f5a0d75f71ca11890db158bc6289 100644
--- a/packages/CLI11/include/CLI/ConfigFwd.hpp
+++ b/packages/CLI11/include/CLI/ConfigFwd.hpp
@@ -16,7 +16,8 @@ class App;
 
 namespace detail {
 
-inline std::string inijoin(std::vector<std::string> args) {
+/// Comma separated join, adds quotes if needed
+inline std::string ini_join(std::vector<std::string> args) {
     std::ostringstream s;
     size_t start = 0;
     for(const auto &arg : args) {
@@ -37,6 +38,7 @@ inline std::string inijoin(std::vector<std::string> args) {
 
 } // namespace detail
 
+/// Holds values to load into Options
 struct ConfigItem {
     /// This is the list of parents
     std::vector<std::string> parents;
@@ -68,27 +70,7 @@ class Config {
     virtual std::vector<ConfigItem> from_config(std::istream &) const = 0;
 
     /// Convert a flag to a bool
-    virtual std::vector<std::string> to_flag(const ConfigItem &) const = 0;
-
-    /// Parse a config file, throw an error (ParseError:ConfigParseError or FileError) on failure
-    std::vector<ConfigItem> from_file(const std::string &name) {
-        std::ifstream input{name};
-        if(!input.good())
-            throw FileError::Missing(name);
-
-        return from_config(input);
-    }
-
-    /// virtual destructor
-    virtual ~Config() = default;
-};
-
-/// This converter works with INI files
-class ConfigINI : public Config {
-  public:
-    std::string to_config(const App *, bool default_also, bool write_description, std::string prefix) const override;
-
-    std::vector<std::string> to_flag(const ConfigItem &item) const override {
+    virtual std::vector<std::string> to_flag(const ConfigItem &item) const {
         if(item.inputs.size() == 1) {
             std::string val = item.inputs.at(0);
             val = detail::to_lower(val);
@@ -110,6 +92,24 @@ class ConfigINI : public Config {
         }
     }
 
+    /// Parse a config file, throw an error (ParseError:ConfigParseError or FileError) on failure
+    std::vector<ConfigItem> from_file(const std::string &name) {
+        std::ifstream input{name};
+        if(!input.good())
+            throw FileError::Missing(name);
+
+        return from_config(input);
+    }
+
+    /// virtual destructor
+    virtual ~Config() = default;
+};
+
+/// This converter works with INI files
+class ConfigINI : public Config {
+  public:
+    std::string to_config(const App *, bool default_also, bool write_description, std::string prefix) const override;
+
     std::vector<ConfigItem> from_config(std::istream &input) const override {
         std::string line;
         std::string section = "default";
@@ -117,7 +117,7 @@ class ConfigINI : public Config {
         std::vector<ConfigItem> output;
 
         while(getline(input, line)) {
-            std::vector<std::string> items;
+            std::vector<std::string> items_buffer;
 
             detail::trim(line);
             size_t len = line.length();
@@ -132,10 +132,10 @@ class ConfigINI : public Config {
                 if(pos != std::string::npos) {
                     out.name = detail::trim_copy(line.substr(0, pos));
                     std::string item = detail::trim_copy(line.substr(pos + 1));
-                    items = detail::split_up(item);
+                    items_buffer = detail::split_up(item);
                 } else {
                     out.name = detail::trim_copy(line);
-                    items = {"ON"};
+                    items_buffer = {"ON"};
                 }
 
                 if(detail::to_lower(section) != "default") {
@@ -149,7 +149,7 @@ class ConfigINI : public Config {
                     out.parents.insert(out.parents.end(), plist.begin(), plist.end());
                 }
 
-                out.inputs.insert(std::end(out.inputs), std::begin(items), std::end(items));
+                out.inputs.insert(std::end(out.inputs), std::begin(items_buffer), std::end(items_buffer));
             }
         }
         return output;
diff --git a/packages/CLI11/include/CLI/Formatter.hpp b/packages/CLI11/include/CLI/Formatter.hpp
index 82e641a3b0bb0464e9faca925f8a9153c37f9985..7f1885ec9b42cd8cf6c5cb03f1543e429d8515b1 100644
--- a/packages/CLI11/include/CLI/Formatter.hpp
+++ b/packages/CLI11/include/CLI/Formatter.hpp
@@ -158,8 +158,7 @@ inline std::string Formatter::make_subcommands(const App *app, AppFormatMode mod
                 out << make_subcommand(new_com);
             } else {
                 out << new_com->help(new_com->get_name(), AppFormatMode::Sub);
-                if(new_com != subcommands_group.back())
-                    out << "\n";
+                out << "\n";
             }
         }
     }
@@ -175,12 +174,19 @@ inline std::string Formatter::make_subcommand(const App *sub) const {
 
 inline std::string Formatter::make_expanded(const App *sub) const {
     std::stringstream out;
-    if(sub->get_description().empty())
-        out << sub->get_name();
-    else
-        out << sub->get_name() << " -> " << sub->get_description();
+    out << sub->get_name() << "\n";
+
+    out << make_description(sub);
+    out << make_positionals(sub);
     out << make_groups(sub, AppFormatMode::Sub);
-    return out.str();
+    out << make_subcommands(sub, AppFormatMode::Sub);
+
+    // Drop blank spaces
+    std::string tmp = detail::find_and_replace(out.str(), "\n\n", "\n");
+    tmp = tmp.substr(0, tmp.size() - 1); // Remove the final '\n'
+
+    // Indent all but the first line (the name)
+    return detail::find_and_replace(tmp, "\n", "\n  ") + "\n";
 }
 
 inline std::string Formatter::make_option_name(const Option *opt, bool is_positional) const {
diff --git a/packages/CLI11/include/CLI/FormatterFwd.hpp b/packages/CLI11/include/CLI/FormatterFwd.hpp
index 92bfe65112f0d6331ffc59326ea24a119f6e6eca..0344256ca8c714b55f7d4b690530fde17277fba0 100644
--- a/packages/CLI11/include/CLI/FormatterFwd.hpp
+++ b/packages/CLI11/include/CLI/FormatterFwd.hpp
@@ -86,9 +86,11 @@ class FormatterBase {
 class FormatterLambda final : public FormatterBase {
     using funct_t = std::function<std::string(const App *, std::string, AppFormatMode)>;
 
+    /// The lambda to hold and run
     funct_t lambda_;
 
   public:
+    /// Create a FormatterLambda with a lambda function
     explicit FormatterLambda(funct_t funct) : lambda_(std::move(funct)) {}
 
     /// This will simply call the lambda function
@@ -97,6 +99,8 @@ class FormatterLambda final : public FormatterBase {
     }
 };
 
+/// This is the default Formatter for CLI11. It pretty prints help output, and is broken into quite a few
+/// overridable methods, to be highly customizable with minimal effort.
 class Formatter : public FormatterBase {
   public:
     Formatter() = default;
diff --git a/packages/CLI11/include/CLI/Macros.hpp b/packages/CLI11/include/CLI/Macros.hpp
index 6defe59ac20ad376cec7458362fa95116d0a1957..f7a266506d9df93cfe93a4fc3b0414fdc2589dad 100644
--- a/packages/CLI11/include/CLI/Macros.hpp
+++ b/packages/CLI11/include/CLI/Macros.hpp
@@ -30,7 +30,7 @@
 #endif
 #endif
 
-#if defined(PYBIND11_CPP14)
+#if defined(CLI11_CPP14)
 #define CLI11_DEPRECATED(reason) [[deprecated(reason)]]
 #elif defined(_MSC_VER)
 #define CLI11_DEPRECATED(reason) __declspec(deprecated(reason))
diff --git a/packages/CLI11/include/CLI/Option.hpp b/packages/CLI11/include/CLI/Option.hpp
index db625576eb8336d9733a5c4a211a4b305711b536..a5f046a22acf1a75aa7e406959dfd4feadedcbab 100644
--- a/packages/CLI11/include/CLI/Option.hpp
+++ b/packages/CLI11/include/CLI/Option.hpp
@@ -30,6 +30,8 @@ using Option_p = std::unique_ptr<Option>;
 
 enum class MultiOptionPolicy { Throw, TakeLast, TakeFirst, Join };
 
+/// This is the CRTP base class for Option and OptionDefaults. It was designed this way
+/// to share parts of the class; an OptionDefaults can copy to an Option.
 template <typename CRTP> class OptionBase {
     friend App;
 
@@ -49,6 +51,7 @@ template <typename CRTP> class OptionBase {
     /// Policy for multiple arguments when `expected_ == 1`  (can be set on bool flags, too)
     MultiOptionPolicy multi_option_policy_{MultiOptionPolicy::Throw};
 
+    /// Copy the contents to another similar class (one based on OptionBase)
     template <typename T> void copy_to(T *other) const {
         other->group(group_);
         other->required(required_);
@@ -123,6 +126,8 @@ template <typename CRTP> class OptionBase {
     }
 };
 
+/// This is a version of OptionBase that only supports setting values,
+/// for defaults. It is stored as the default option in an App.
 class OptionDefaults : public OptionBase<OptionDefaults> {
   public:
     OptionDefaults() = default;
@@ -174,7 +179,7 @@ class Option : public OptionBase<Option> {
     /// A human readable type value, set when App creates this
     ///
     /// This is a lambda function so "types" can be dynamic, such as when a set prints its contents.
-    std::function<std::string()> type_name_;
+    std::function<std::string()> type_name_{[]() { return std::string(); }};
 
     /// True if this option has a default
     bool default_{false};
@@ -226,12 +231,10 @@ class Option : public OptionBase<Option> {
     ///@}
 
     /// Making an option by hand is not defined, it must be made by the App class
-    Option(std::string name,
-           std::string description = "",
-           std::function<bool(results_t)> callback = [](results_t) { return true; },
-           bool default_ = true,
-           App *parent = nullptr)
-        : description_(std::move(description)), default_(default_), parent_(parent), callback_(std::move(callback)) {
+    Option(
+        std::string name, std::string description, std::function<bool(results_t)> callback, bool defaulted, App *parent)
+        : description_(std::move(description)), default_(defaulted), parent_(parent),
+          callback_(callback ? std::move(callback) : [](results_t) { return true; }) {
         std::tie(snames_, lnames_, pname_) = detail::get_names(detail::split_names(name));
     }
 
@@ -285,11 +288,11 @@ class Option : public OptionBase<Option> {
     Option *check(const Validator &validator) {
         validators_.emplace_back(validator.func);
         if(!validator.tname.empty())
-            set_type_name(validator.tname);
+            type_name(validator.tname);
         return this;
     }
 
-    /// Adds a validator
+    /// Adds a validator. Takes a const string& and returns an error message (empty if conversion/check is okay).
     Option *check(std::function<std::string(const std::string &)> validator) {
         validators_.emplace_back(validator);
         return this;
@@ -438,7 +441,7 @@ class Option : public OptionBase<Option> {
     /// The number of times the option expects to be included
     int get_expected() const { return expected_; }
 
-    /// \breif The total number of expected values (including the type)
+    /// \brief The total number of expected values (including the type)
     /// This is positive if exactly this number is expected, and negitive for at least N values
     ///
     /// v = fabs(size_type*expected)
@@ -543,7 +546,8 @@ class Option : public OptionBase<Option> {
 
         // Num items expected or length of vector, always at least 1
         // Only valid for a trimming policy
-        int trim_size = std::min(std::max(std::abs(get_items_expected()), 1), static_cast<int>(results_.size()));
+        int trim_size =
+            std::min<int>(std::max<int>(std::abs(get_items_expected()), 1), static_cast<int>(results_.size()));
 
         // Operation depends on the policy setting
         if(multi_option_policy_ == MultiOptionPolicy::TakeLast) {
@@ -560,12 +564,18 @@ class Option : public OptionBase<Option> {
             local_result = !callback_(partial_result);
 
         } else {
-            // For now, vector of non size 1 types are not supported but possibility included here
-            if((get_items_expected() > 0 && results_.size() != static_cast<size_t>(get_items_expected())) ||
-               (get_items_expected() < 0 && results_.size() < static_cast<size_t>(-get_items_expected())))
-                throw ArgumentMismatch(get_name(), get_items_expected(), results_.size());
-            else
-                local_result = !callback_(results_);
+            // Exact number required
+            if(get_items_expected() > 0) {
+                if(results_.size() != static_cast<size_t>(get_items_expected()))
+                    throw ArgumentMismatch(get_name(), get_items_expected(), results_.size());
+                // Variable length list
+            } else if(get_items_expected() < 0) {
+                // Require that this be a multiple of expected size and at least as many as expected
+                if(results_.size() < static_cast<size_t>(-get_items_expected()) ||
+                   results_.size() % static_cast<size_t>(std::abs(get_type_size())) != 0)
+                    throw ArgumentMismatch(get_name(), get_items_expected(), results_.size());
+            }
+            local_result = !callback_(results_);
         }
 
         if(local_result)
@@ -630,15 +640,17 @@ class Option : public OptionBase<Option> {
     }
 
     /// Puts a result at the end
-    void add_result(std::string s) {
+    Option *add_result(std::string s) {
         results_.push_back(s);
         callback_run_ = false;
+        return this;
     }
 
     /// Set the results vector all at once
-    void set_results(std::vector<std::string> results) {
+    Option *set_results(std::vector<std::string> results) {
         results_ = results;
         callback_run_ = false;
+        return this;
     }
 
     /// Get a copy of the results
@@ -651,36 +663,48 @@ class Option : public OptionBase<Option> {
     /// @name Custom options
     ///@{
 
-    /// Set a custom option, typestring, type_size
-    void set_custom_option(std::string typeval, int type_size = 1) {
-        set_type_name(typeval);
+    /// Set the type function to run when displayed on this option
+    Option *type_name_fn(std::function<std::string()> typefun) {
+        type_name_ = typefun;
+        return this;
+    }
+
+    /// Set a custom option typestring
+    Option *type_name(std::string typeval) {
+        type_name_fn([typeval]() { return typeval; });
+        return this;
+    }
+
+    /// Provided for backward compatibility \deprecated
+    CLI11_DEPRECATED("Please use type_name instead")
+    Option *set_type_name(std::string typeval) { return type_name(typeval); }
+
+    /// Set a custom option size
+    Option *type_size(int type_size) {
         type_size_ = type_size;
         if(type_size_ == 0)
             required_ = false;
         if(type_size < 0)
             expected_ = -1;
+        return this;
     }
 
     /// Set the default value string representation
-    void set_default_str(std::string val) { defaultval_ = val; }
+    Option *default_str(std::string val) {
+        defaultval_ = val;
+        return this;
+    }
 
     /// Set the default value string representation and evaluate
-    void set_default_val(std::string val) {
-        set_default_str(val);
+    Option *default_val(std::string val) {
+        default_str(val);
         auto old_results = results_;
         results_ = {val};
         run_callback();
         results_ = std::move(old_results);
+        return this;
     }
 
-    /// Set the type name displayed on this option
-    void set_type_name(std::string typeval) {
-        set_type_name_fn([typeval]() { return typeval; });
-    }
-
-    /// Set the type function to run when displayed on this option
-    void set_type_name_fn(std::function<std::string()> typefun) { type_name_ = typefun; }
-
     /// Get the typename for this option
     std::string get_type_name() const { return type_name_(); }
 };
diff --git a/packages/CLI11/include/CLI/Optional.hpp b/packages/CLI11/include/CLI/Optional.hpp
index faaee3664c0ceee61d5d78b9bf19fe917e7de8f3..d4b7df28d52df89c45dc8d827911f818861dfea4 100644
--- a/packages/CLI11/include/CLI/Optional.hpp
+++ b/packages/CLI11/include/CLI/Optional.hpp
@@ -10,13 +10,16 @@
 // [CLI11:verbatim]
 #ifdef __has_include
 
+// You can explicitly enable or disable support
+// by defining these to 1 or 0.
 #if defined(CLI11_CPP17) && __has_include(<optional>) && \
      !defined(CLI11_STD_OPTIONAL)
 #define CLI11_STD_OPTIONAL 1
 #endif
 
 #if defined(CLI11_CPP14) && __has_include(<experimental/optional>) && \
-    !defined(CLI11_EXPERIMENTAL_OPTIONAL)
+    !defined(CLI11_EXPERIMENTAL_OPTIONAL) \
+    && (!defined(CLI11_STD_OPTIONAL) || CLI11_STD_OPTIONAL == 0)
 #define CLI11_EXPERIMENTAL_OPTIONAL 1
 #endif
 
diff --git a/packages/CLI11/include/CLI/StringTools.hpp b/packages/CLI11/include/CLI/StringTools.hpp
index 24e01bcd7190ca3393fbc148e964b8e280f3d3dc..1b497837d1c1e21bf3c121af2017c1259e54cf10 100644
--- a/packages/CLI11/include/CLI/StringTools.hpp
+++ b/packages/CLI11/include/CLI/StringTools.hpp
@@ -204,5 +204,18 @@ inline std::string fix_newlines(std::string leader, std::string input) {
     return input;
 }
 
+/// Find and replace a subtring with another substring
+inline std::string find_and_replace(std::string str, std::string from, std::string to) {
+
+    size_t start_pos = 0;
+
+    while((start_pos = str.find(from, start_pos)) != std::string::npos) {
+        str.replace(start_pos, from.length(), to);
+        start_pos += to.length();
+    }
+
+    return str;
+}
+
 } // namespace detail
 } // namespace CLI
diff --git a/packages/CLI11/include/CLI/Timer.hpp b/packages/CLI11/include/CLI/Timer.hpp
index eb6054ccb0868529961d6c0221fb9501d37c82dc..62ec84f0e6d9c3923cda011d2ccec7d3aeb2b7b3 100644
--- a/packages/CLI11/include/CLI/Timer.hpp
+++ b/packages/CLI11/include/CLI/Timer.hpp
@@ -17,6 +17,7 @@
 
 namespace CLI {
 
+/// This is a simple timer with pretty printing. Creating the timer starts counting.
 class Timer {
   protected:
     /// This is a typedef to make clocks easier to use
@@ -82,6 +83,7 @@ class Timer {
     }
 
     // LCOV_EXCL_START
+    /// This prints out a time string from a time
     std::string make_time_str(double time) const {
         auto print_it = [](double x, std::string unit) {
             char buffer[50];
diff --git a/packages/CLI11/include/CLI/TypeTools.hpp b/packages/CLI11/include/CLI/TypeTools.hpp
index 9af8ccaa62d264482599ad14788033dfe17b8ecf..d7c3d306ffad0e810bbfcdc1cbe0b2558a854562 100644
--- a/packages/CLI11/include/CLI/TypeTools.hpp
+++ b/packages/CLI11/include/CLI/TypeTools.hpp
@@ -12,18 +12,24 @@ namespace CLI {
 
 // Type tools
 
-// We could check to see if C++14 is being used, but it does not hurt to redefine this
-// (even Google does this: https://github.com/google/skia/blob/master/include/private/SkTLogic.h)
-// It is not in the std namespace anyway, so no harm done.
+/// A copy of enable_if_t from C++14, compatible with C++11.
+///
+/// We could check to see if C++14 is being used, but it does not hurt to redefine this
+/// (even Google does this: https://github.com/google/skia/blob/master/include/private/SkTLogic.h)
+/// It is not in the std namespace anyway, so no harm done.
 
 template <bool B, class T = void> using enable_if_t = typename std::enable_if<B, T>::type;
 
+/// Check to see if something is a vector (fail check by default)
 template <typename T> struct is_vector { static const bool value = false; };
 
+/// Check to see if something is a vector (true if actually a vector)
 template <class T, class A> struct is_vector<std::vector<T, A>> { static bool const value = true; };
 
+/// Check to see if something is bool (fail check by default)
 template <typename T> struct is_bool { static const bool value = false; };
 
+/// Check to see if something is bool (true if actually a bool)
 template <> struct is_bool<bool> { static bool const value = true; };
 
 namespace detail {
diff --git a/packages/CLI11/include/CLI/Validators.hpp b/packages/CLI11/include/CLI/Validators.hpp
index 6c41967e4d8a0075a86331350df994a0de93480d..91c5d9bc844b490b6194ab051cafb898d952fcaa 100644
--- a/packages/CLI11/include/CLI/Validators.hpp
+++ b/packages/CLI11/include/CLI/Validators.hpp
@@ -30,11 +30,14 @@ namespace CLI {
 struct Validator {
     /// This is the type name, if empty the type name will not be changed
     std::string tname;
-    std::function<std::string(const std::string &filename)> func;
+
+    /// This it the base function that is to be called.
+    /// Returns a string error message if validation fails.
+    std::function<std::string(const std::string &)> func;
 
     /// This is the required operator for a validator - provided to help
-    /// users (CLI11 uses the func directly)
-    std::string operator()(const std::string &filename) const { return func(filename); };
+    /// users (CLI11 uses the member `func` directly)
+    std::string operator()(const std::string &str) const { return func(str); };
 
     /// Combining validators is a new validator
     Validator operator&(const Validator &other) const {
@@ -165,6 +168,10 @@ const detail::NonexistentPathValidator NonexistentPath;
 
 ///  Produce a range (factory). Min and max are inclusive.
 struct Range : public Validator {
+    /// This produces a range with min and max inclusive.
+    ///
+    /// Note that the constructor is templated, but the struct is not, so C++17 is not
+    /// needed to provide nice syntax for Range(a,b).
     template <typename T> Range(T min, T max) {
         std::stringstream out;
         out << detail::type_name<T>() << " in [" << min << " - " << max << "]";
diff --git a/packages/CLI11/include/CLI/Version.hpp b/packages/CLI11/include/CLI/Version.hpp
index 49393847c71d7d0d48580d290faa70ea6d00c003..80eaf2a0d2b674d03e4f222d83d2696657b4bb81 100644
--- a/packages/CLI11/include/CLI/Version.hpp
+++ b/packages/CLI11/include/CLI/Version.hpp
@@ -6,8 +6,8 @@
 // [CLI11:verbatim]
 
 #define CLI11_VERSION_MAJOR 1
-#define CLI11_VERSION_MINOR 5
-#define CLI11_VERSION_PATCH 4
-#define CLI11_VERSION "1.5.4"
+#define CLI11_VERSION_MINOR 6
+#define CLI11_VERSION_PATCH 1
+#define CLI11_VERSION "1.6.1"
 
 // [CLI11:verbatim]
diff --git a/packages/CLI11/scripts/MakeSingleHeader.py b/packages/CLI11/scripts/MakeSingleHeader.py
index bb83e8cdeaa7254ed2aa80b13c5fa8a11fb59a4d..ab16799d2321a30984dd454fe843d59c4c1c8276 100755
--- a/packages/CLI11/scripts/MakeSingleHeader.py
+++ b/packages/CLI11/scripts/MakeSingleHeader.py
@@ -4,11 +4,11 @@ from __future__ import print_function, unicode_literals
 
 import os
 import re
-import argparse
-import operator
+from argparse import ArgumentParser
+from operator import add
 from copy import copy
-from subprocess import check_output, CalledProcessError
 from functools import reduce
+from subprocess import Popen, PIPE
 
 includes_local = re.compile(r"""^#include "(.*)"$""", re.MULTILINE)
 includes_system = re.compile(r"""^#include \<(.*)\>$""", re.MULTILINE)
@@ -44,7 +44,7 @@ class HeaderFile(object):
 
         # add self.verbatim
         if 'CLI11:verbatim' in inner:
-            self.verbatim = ["\n\n// Verbatim copy from {}:".format(inc)]
+            self.verbatim = ["\n\n// Verbatim copy from {0}:".format(inc)]
             self.verbatim += verbatim_all.findall(inner)
             inner = verbatim_all.sub("", inner)
         else:
@@ -52,7 +52,9 @@ class HeaderFile(object):
 
         self.headers = set(includes_system.findall(inner))
 
-        self.body = '\n// From {}:\n\n'.format(inc) + inner[inner.find('namespace'):]
+        self.body = '\n// From {0}:\n\n'.format(inc) + inner[inner.find('namespace'):]
+
+        self.namespace = None
 
     def __add__(self, other):
         out = copy(self)
@@ -69,8 +71,15 @@ class HeaderFile(object):
     def verbatim_str(self):
         return '\n'.join(self.verbatim)
 
+    def insert_namespace(self, namespace):
+        self.namespace = namespace
+
+    def macro_replacement(self, before, after):
+        self.verbatim = [x.replace(before, after) for x in self.verbatim]
+        self.body = self.body.replace(before, after)
+
     def __str__(self):
-        return '''\
+        result = '''\
 #pragma once
 
 // CLI11: Version {self.VERSION}
@@ -87,17 +96,27 @@ class HeaderFile(object):
 // Standard combined includes:
 
 {self.header_str}
-{self.verbatim_str}
-{self.body}
 '''.format(self=self)
 
+        if self.namespace:
+             result += '\nnamespace ' + self.namespace + ' {\n\n'
+        result += '{self.verbatim_str}\n{self.body}\n'.format(self=self)
+        if self.namespace:
+            result += '} // namespace ' + self.namespace + '\n\n'
+
+        return result
 
-def MakeHeader(output, main_header, include_dir = '../include'):
+
+def MakeHeader(output, main_header, include_dir = '../include', namespace=None, macro=None):
     # Set tag if possible to class variable
     try:
-        HeaderFile.TAG = check_output(['git', 'describe', '--tags', '--always'], cwd=str(DIR)).decode("utf-8").strip()
-    except CalledProcessError:
+        proc = Popen(['git', 'describe', '--tags', '--always'], cwd=str(DIR), stdout=PIPE)
+        out, _ = proc.communicate()
+    except OSError:
         pass
+    else:
+        if proc.returncode == 0:
+            HeaderFile.TAG = out.decode("utf-8").strip()
 
     base_dir = os.path.abspath(os.path.join(DIR, include_dir))
     main_header = os.path.join(base_dir, main_header)
@@ -112,20 +131,30 @@ def MakeHeader(output, main_header, include_dir = '../include'):
     include_files = includes_local.findall(header)
 
     headers = [HeaderFile(base_dir, inc) for inc in include_files]
-    single_header = reduce(operator.add, headers)
+    single_header = reduce(add, headers)
+
+    if macro is not None:
+        before = 'CLI11_'
+        print("Converting macros", before, "->", macro)
+        single_header.macro_replacement(before, macro)
+
+    if namespace:
+        print("Adding namespace", namespace)
+        single_header.insert_namespace(namespace)
 
     with open(output, 'w') as f:
         f.write(str(single_header))
 
     print("Created", output)
 
-
 if __name__ == '__main__':
-    parser = argparse.ArgumentParser()
+    parser = ArgumentParser(usage='Convert source to single header include. Can optionally add namespace and search-replace replacements (for macros).')
     parser.add_argument("output", help="Single header file output")
     parser.add_argument("--main", default='CLI/CLI.hpp', help="The main include file that defines the other files")
-    parser.add_argument("--include", default='../include')
+    parser.add_argument("--include", default='../include', help="The include directory")
+    parser.add_argument("--namespace", help="Add an optional namespace")
+    parser.add_argument("--macro", help="Replaces CLI11_ with NEW_PREFIX_")
     args = parser.parse_args()
 
-    MakeHeader(args.output, args.main, args.include)
+    MakeHeader(args.output, args.main, args.include, args.namespace, args.macro)
 
diff --git a/packages/CLI11/tests/AppTest.cpp b/packages/CLI11/tests/AppTest.cpp
index 76537e14ea23858e47bd2f6813b88738dfdcb085..1c6a969f7f05d6c33bdd944fc3796257bb8b3d5f 100644
--- a/packages/CLI11/tests/AppTest.cpp
+++ b/packages/CLI11/tests/AppTest.cpp
@@ -152,13 +152,10 @@ TEST_F(TApp, BoolAndIntFlags) {
     EXPECT_EQ(1, iflag);
     EXPECT_EQ((unsigned int)1, uflag);
 
-    app.reset();
-
     args = {"-b", "-b"};
-    EXPECT_NO_THROW(run());
+    ASSERT_NO_THROW(run());
     EXPECT_TRUE(bflag);
 
-    app.reset();
     bflag = false;
 
     args = {"-iiiuu"};
@@ -173,11 +170,9 @@ TEST_F(TApp, BoolOnlyFlag) {
     app.add_flag("-b", bflag)->multi_option_policy(CLI::MultiOptionPolicy::Throw);
 
     args = {"-b"};
-    EXPECT_NO_THROW(run());
+    ASSERT_NO_THROW(run());
     EXPECT_TRUE(bflag);
 
-    app.reset();
-
     args = {"-b", "-b"};
     EXPECT_THROW(run(), CLI::ConversionError);
 }
@@ -332,8 +327,6 @@ TEST_F(TApp, MissingValueNonRequiredOpt) {
     args = {"-c"};
     EXPECT_THROW(run(), CLI::ArgumentMismatch);
 
-    app.reset();
-
     args = {"--count"};
     EXPECT_THROW(run(), CLI::ArgumentMismatch);
 }
@@ -347,8 +340,6 @@ TEST_F(TApp, MissingValueMoreThan) {
     args = {"-v", "2"};
     EXPECT_THROW(run(), CLI::ArgumentMismatch);
 
-    app.reset();
-
     args = {"--vals", "4"};
     EXPECT_THROW(run(), CLI::ArgumentMismatch);
 }
@@ -363,8 +354,6 @@ TEST_F(TApp, NoMissingValueMoreThan) {
     run();
     EXPECT_EQ(vals1, std::vector<int>({2, 3, 4}));
 
-    app.reset();
-
     args = {"--vals", "2", "3", "4"};
     run();
     EXPECT_EQ(vals2, std::vector<int>({2, 3, 4}));
@@ -419,7 +408,6 @@ TEST_F(TApp, RequiredOptsDouble) {
 
     EXPECT_THROW(run(), CLI::ArgumentMismatch);
 
-    app.reset();
     args = {"--str", "one", "two"};
 
     run();
@@ -436,8 +424,6 @@ TEST_F(TApp, RequiredOptsDoubleShort) {
 
     EXPECT_THROW(run(), CLI::ArgumentMismatch);
 
-    app.reset();
-
     args = {"-s", "one", "-s", "one", "-s", "one"};
 
     EXPECT_THROW(run(), CLI::ArgumentMismatch);
@@ -451,19 +437,13 @@ TEST_F(TApp, RequiredOptsDoubleNeg) {
 
     EXPECT_THROW(run(), CLI::ArgumentMismatch);
 
-    app.reset();
-
     args = {"-s", "one", "two", "-s", "three"};
 
-    EXPECT_NO_THROW(run());
-
+    ASSERT_NO_THROW(run());
     EXPECT_EQ(strs, std::vector<std::string>({"one", "two", "three"}));
 
-    app.reset();
     args = {"-s", "one", "two"};
-
-    EXPECT_NO_THROW(run());
-
+    ASSERT_NO_THROW(run());
     EXPECT_EQ(strs, std::vector<std::string>({"one", "two"}));
 }
 
@@ -483,7 +463,6 @@ TEST_F(TApp, PositionalNoSpace) {
     EXPECT_EQ(options.size(), (size_t)1);
     EXPECT_EQ(options.at(0), "Test");
 
-    app.reset();
     args = {"-OTest", "param1", "param2"};
     run();
 
@@ -505,7 +484,6 @@ TEST_F(TApp, PositionalNoSpaceLong) {
     EXPECT_EQ(options.size(), (size_t)1);
     EXPECT_EQ(options.at(0), "Test");
 
-    app.reset();
     args = {"--option=Test", "param1", "param2"};
     run();
 
@@ -521,24 +499,20 @@ TEST_F(TApp, RequiredOptsUnlimited) {
     args = {"--str"};
     EXPECT_THROW(run(), CLI::ArgumentMismatch);
 
-    app.reset();
     args = {"--str", "one", "--str", "two"};
     run();
     EXPECT_EQ(strs, std::vector<std::string>({"one", "two"}));
 
-    app.reset();
     args = {"--str", "one", "two"};
     run();
     EXPECT_EQ(strs, std::vector<std::string>({"one", "two"}));
 
     // It's better to feed a hungry option than to feed allow_extras
-    app.reset();
     app.allow_extras();
     run();
     EXPECT_EQ(strs, std::vector<std::string>({"one", "two"}));
     EXPECT_EQ(app.remaining(), std::vector<std::string>({}));
 
-    app.reset();
     app.allow_extras(false);
     std::vector<std::string> remain;
     app.add_option("positional", remain);
@@ -546,14 +520,12 @@ TEST_F(TApp, RequiredOptsUnlimited) {
     EXPECT_EQ(strs, std::vector<std::string>({"one", "two"}));
     EXPECT_EQ(remain, std::vector<std::string>());
 
-    app.reset();
     args = {"--str", "one", "--", "two"};
 
     run();
     EXPECT_EQ(strs, std::vector<std::string>({"one"}));
     EXPECT_EQ(remain, std::vector<std::string>({"two"}));
 
-    app.reset();
     args = {"one", "--str", "two"};
 
     run();
@@ -569,24 +541,20 @@ TEST_F(TApp, RequiredOptsUnlimitedShort) {
     args = {"-s"};
     EXPECT_THROW(run(), CLI::ArgumentMismatch);
 
-    app.reset();
     args = {"-s", "one", "-s", "two"};
     run();
     EXPECT_EQ(strs, std::vector<std::string>({"one", "two"}));
 
-    app.reset();
     args = {"-s", "one", "two"};
     run();
     EXPECT_EQ(strs, std::vector<std::string>({"one", "two"}));
 
     // It's better to feed a hungry option than to feed allow_extras
-    app.reset();
     app.allow_extras();
     run();
     EXPECT_EQ(strs, std::vector<std::string>({"one", "two"}));
     EXPECT_EQ(app.remaining(), std::vector<std::string>({}));
 
-    app.reset();
     app.allow_extras(false);
     std::vector<std::string> remain;
     app.add_option("positional", remain);
@@ -594,14 +562,12 @@ TEST_F(TApp, RequiredOptsUnlimitedShort) {
     EXPECT_EQ(strs, std::vector<std::string>({"one", "two"}));
     EXPECT_EQ(remain, std::vector<std::string>());
 
-    app.reset();
     args = {"-s", "one", "--", "two"};
 
     run();
     EXPECT_EQ(strs, std::vector<std::string>({"one"}));
     EXPECT_EQ(remain, std::vector<std::string>({"two"}));
 
-    app.reset();
     args = {"one", "-s", "two"};
 
     run();
@@ -635,7 +601,6 @@ TEST_F(TApp, RequireOptPriority) {
     EXPECT_EQ(strs, std::vector<std::string>({"one"}));
     EXPECT_EQ(remain, std::vector<std::string>({"two", "three"}));
 
-    app.reset();
     args = {"two", "three", "--str", "one", "four"};
     run();
 
@@ -656,7 +621,6 @@ TEST_F(TApp, RequireOptPriorityShort) {
     EXPECT_EQ(strs, std::vector<std::string>({"one"}));
     EXPECT_EQ(remain, std::vector<std::string>({"two", "three"}));
 
-    app.reset();
     args = {"two", "three", "-s", "one", "four"};
     run();
 
@@ -690,16 +654,12 @@ TEST_F(TApp, RequiredFlags) {
 
     EXPECT_THROW(run(), CLI::RequiredError);
 
-    app.reset();
-
     args = {"-a"};
     EXPECT_THROW(run(), CLI::RequiredError);
 
-    app.reset();
     args = {"-b"};
     EXPECT_THROW(run(), CLI::RequiredError);
 
-    app.reset();
     args = {"-a", "-b"};
     run();
 }
@@ -715,12 +675,10 @@ TEST_F(TApp, CallbackFlags) {
     run();
     EXPECT_EQ(value, (size_t)0);
 
-    app.reset();
     args = {"-v"};
     run();
     EXPECT_EQ(value, (size_t)1);
 
-    app.reset();
     args = {"-vv"};
     run();
     EXPECT_EQ(value, (size_t)2);
@@ -740,12 +698,10 @@ TEST_F(TApp, CallbackFlagsAuto) {
     run();
     EXPECT_EQ(value, (size_t)0);
 
-    app.reset();
     args = {"-v"};
     run();
     EXPECT_EQ(value, (size_t)1);
 
-    app.reset();
     args = {"-vv"};
     run();
     EXPECT_EQ(value, (size_t)2);
@@ -782,8 +738,6 @@ TEST_F(TApp, ForcedPositional) {
     EXPECT_TRUE(one->count());
     EXPECT_EQ(answers1, posit);
 
-    app.reset();
-
     args = {"--", "--one", "two", "three"};
     std::vector<std::string> answers2 = {"--one", "two", "three"};
     run();
@@ -818,8 +772,6 @@ TEST_F(TApp, BigPositional) {
     run();
     EXPECT_EQ(args, vec);
 
-    app.reset();
-
     args = {"one", "two"};
     run();
 
@@ -840,7 +792,7 @@ TEST_F(TApp, Reset) {
     EXPECT_EQ((size_t)1, app.count("-d"));
     EXPECT_DOUBLE_EQ(1.2, doub);
 
-    app.reset();
+    app.clear();
 
     EXPECT_EQ((size_t)0, app.count("--simple"));
     EXPECT_EQ((size_t)0, app.count("-d"));
@@ -866,7 +818,7 @@ TEST_F(TApp, RemoveOption) {
 
 TEST_F(TApp, FileNotExists) {
     std::string myfile{"TestNonFileNotUsed.txt"};
-    EXPECT_NO_THROW(CLI::NonexistentPath(myfile));
+    ASSERT_NO_THROW(CLI::NonexistentPath(myfile));
 
     std::string filename;
     app.add_option("--file", filename)->check(CLI::NonexistentPath);
@@ -875,8 +827,6 @@ TEST_F(TApp, FileNotExists) {
     run();
     EXPECT_EQ(myfile, filename);
 
-    app.reset();
-
     bool ok = static_cast<bool>(std::ofstream(myfile.c_str()).put('a')); // create file
     EXPECT_TRUE(ok);
     EXPECT_THROW(run(), CLI::ValidationError);
@@ -895,8 +845,6 @@ TEST_F(TApp, FileExists) {
 
     EXPECT_THROW(run(), CLI::ValidationError);
 
-    app.reset();
-
     bool ok = static_cast<bool>(std::ofstream(myfile.c_str()).put('a')); // create file
     EXPECT_TRUE(ok);
     run();
@@ -916,8 +864,6 @@ TEST_F(TApp, InSet) {
     run();
     EXPECT_EQ("two", choice);
 
-    app.reset();
-
     args = {"--quick", "four"};
     EXPECT_THROW(run(), CLI::ConversionError);
 }
@@ -929,15 +875,12 @@ TEST_F(TApp, InSetWithDefault) {
 
     run();
     EXPECT_EQ("one", choice);
-    app.reset();
 
     args = {"--quick", "two"};
 
     run();
     EXPECT_EQ("two", choice);
 
-    app.reset();
-
     args = {"--quick", "four"};
     EXPECT_THROW(run(), CLI::ConversionError);
 }
@@ -949,15 +892,12 @@ TEST_F(TApp, InCaselessSetWithDefault) {
 
     run();
     EXPECT_EQ("one", choice);
-    app.reset();
 
     args = {"--quick", "tWo"};
 
     run();
     EXPECT_EQ("two", choice);
 
-    app.reset();
-
     args = {"--quick", "four"};
     EXPECT_THROW(run(), CLI::ConversionError);
 }
@@ -972,8 +912,6 @@ TEST_F(TApp, InIntSet) {
     run();
     EXPECT_EQ(2, choice);
 
-    app.reset();
-
     args = {"--quick", "4"};
     EXPECT_THROW(run(), CLI::ConversionError);
 }
@@ -986,8 +924,6 @@ TEST_F(TApp, FailSet) {
     args = {"--quick", "3", "--quick=2"};
     EXPECT_THROW(run(), CLI::ArgumentMismatch);
 
-    app.reset();
-
     args = {"--quick=hello"};
     EXPECT_THROW(run(), CLI::ConversionError);
 }
@@ -1002,7 +938,6 @@ TEST_F(TApp, FailLValueSet) {
     args = {"--quick=hello"};
     EXPECT_THROW(run(), CLI::ConversionError);
 
-    app.reset();
     args = {"--slow=hello"};
     EXPECT_THROW(run(), CLI::ConversionError);
 }
@@ -1016,21 +951,17 @@ TEST_F(TApp, InSetIgnoreCase) {
     run();
     EXPECT_EQ("one", choice);
 
-    app.reset();
     args = {"--quick", "two"};
     run();
     EXPECT_EQ("Two", choice); // Keeps caps from set
 
-    app.reset();
     args = {"--quick", "ThrEE"};
     run();
     EXPECT_EQ("THREE", choice); // Keeps caps from set
 
-    app.reset();
     args = {"--quick", "four"};
     EXPECT_THROW(run(), CLI::ConversionError);
 
-    app.reset();
     args = {"--quick=one", "--quick=two"};
     EXPECT_THROW(run(), CLI::ArgumentMismatch);
 }
@@ -1073,7 +1004,6 @@ TEST_F(TApp, VectorUnlimString) {
     EXPECT_EQ((size_t)3, app.count("--string"));
     EXPECT_EQ(answer, strvec);
 
-    app.reset();
     args = {"-s", "mystring", "mystring2", "mystring3"};
     run();
     EXPECT_EQ((size_t)3, app.count("--string"));
@@ -1092,11 +1022,9 @@ TEST_F(TApp, VectorFancyOpts) {
     EXPECT_EQ((size_t)3, app.count("--string"));
     EXPECT_EQ(answer, strvec);
 
-    app.reset();
     args = {"one", "two"};
     EXPECT_THROW(run(), CLI::RequiredError);
 
-    app.reset();
     EXPECT_THROW(run(), CLI::ParseError);
 }
 
@@ -1122,15 +1050,12 @@ TEST_F(TApp, NeedsFlags) {
 
     run();
 
-    app.reset();
     args = {"-s"};
     run();
 
-    app.reset();
     args = {"-s", "--both"};
     run();
 
-    app.reset();
     args = {"--both"};
     EXPECT_THROW(run(), CLI::RequiresError);
 }
@@ -1141,19 +1066,15 @@ TEST_F(TApp, ExcludesFlags) {
 
     run();
 
-    app.reset();
     args = {"-s"};
     run();
 
-    app.reset();
     args = {"--nostr"};
     run();
 
-    app.reset();
     args = {"--nostr", "-s"};
     EXPECT_THROW(run(), CLI::ExcludesError);
 
-    app.reset();
     args = {"--string", "--nostr"};
     EXPECT_THROW(run(), CLI::ExcludesError);
 }
@@ -1166,19 +1087,15 @@ TEST_F(TApp, ExcludesMixedFlags) {
 
     run();
 
-    app.reset();
     args = {"--no"};
     run();
 
-    app.reset();
     args = {"--opt2"};
     run();
 
-    app.reset();
     args = {"--no", "--opt1"};
     EXPECT_THROW(run(), CLI::ExcludesError);
 
-    app.reset();
     args = {"--no", "--opt2"};
     EXPECT_THROW(run(), CLI::ExcludesError);
 }
@@ -1191,27 +1108,21 @@ TEST_F(TApp, NeedsMultiFlags) {
 
     run();
 
-    app.reset();
     args = {"--opt1"};
     run();
 
-    app.reset();
     args = {"--opt2"};
     run();
 
-    app.reset();
     args = {"--optall"};
     EXPECT_THROW(run(), CLI::RequiresError);
 
-    app.reset();
     args = {"--optall", "--opt1"};
     EXPECT_THROW(run(), CLI::RequiresError);
 
-    app.reset();
     args = {"--optall", "--opt2", "--opt1"};
     EXPECT_THROW(run(), CLI::RequiresError);
 
-    app.reset();
     args = {"--optall", "--opt1", "--opt2", "--opt3"};
     run();
 }
@@ -1224,27 +1135,21 @@ TEST_F(TApp, NeedsMixedFlags) {
 
     run();
 
-    app.reset();
     args = {"--opt1"};
     run();
 
-    app.reset();
     args = {"--opt2"};
     run();
 
-    app.reset();
     args = {"--optall"};
     EXPECT_THROW(run(), CLI::RequiresError);
 
-    app.reset();
     args = {"--optall", "--opt1"};
     EXPECT_THROW(run(), CLI::RequiresError);
 
-    app.reset();
     args = {"--optall", "--opt2", "--opt1"};
     EXPECT_THROW(run(), CLI::RequiresError);
 
-    app.reset();
     args = {"--optall", "--opt1", "--opt2", "--opt3"};
     run();
 }
@@ -1256,31 +1161,24 @@ TEST_F(TApp, NeedsChainedFlags) {
 
     run();
 
-    app.reset();
     args = {"--opt1"};
     run();
 
-    app.reset();
     args = {"--opt2"};
     EXPECT_THROW(run(), CLI::RequiresError);
 
-    app.reset();
     args = {"--opt3"};
     EXPECT_THROW(run(), CLI::RequiresError);
 
-    app.reset();
     args = {"--opt3", "--opt2"};
     EXPECT_THROW(run(), CLI::RequiresError);
 
-    app.reset();
     args = {"--opt3", "--opt1"};
     EXPECT_THROW(run(), CLI::RequiresError);
 
-    app.reset();
     args = {"--opt2", "--opt1"};
     run();
 
-    app.reset();
     args = {"--opt1", "--opt2", "--opt3"};
     run();
 }
@@ -1297,11 +1195,9 @@ TEST_F(TApp, Env) {
     EXPECT_EQ(2, val);
     EXPECT_EQ((size_t)1, vopt->count());
 
-    app.reset();
     vopt->required();
     run();
 
-    app.reset();
     unset_env("CLI11_TEST_ENV_TMP");
     EXPECT_THROW(run(), CLI::RequiredError);
 }
@@ -1313,19 +1209,15 @@ TEST_F(TApp, RangeInt) {
     args = {"--one=1"};
     EXPECT_THROW(run(), CLI::ValidationError);
 
-    app.reset();
     args = {"--one=7"};
     EXPECT_THROW(run(), CLI::ValidationError);
 
-    app.reset();
     args = {"--one=3"};
     run();
 
-    app.reset();
     args = {"--one=5"};
     run();
 
-    app.reset();
     args = {"--one=6"};
     run();
 }
@@ -1339,19 +1231,15 @@ TEST_F(TApp, RangeDouble) {
     args = {"--one=1"};
     EXPECT_THROW(run(), CLI::ValidationError);
 
-    app.reset();
     args = {"--one=7"};
     EXPECT_THROW(run(), CLI::ValidationError);
 
-    app.reset();
     args = {"--one=3"};
     run();
 
-    app.reset();
     args = {"--one=5"};
     run();
 
-    app.reset();
     args = {"--one=6"};
     run();
 }
@@ -1367,7 +1255,7 @@ TEST_F(TApp, AllowExtras) {
 
     args = {"-x", "-f"};
 
-    EXPECT_NO_THROW(run());
+    ASSERT_NO_THROW(run());
     EXPECT_TRUE(val);
     EXPECT_EQ(app.remaining(), std::vector<std::string>({"-x"}));
 }
@@ -1377,9 +1265,8 @@ TEST_F(TApp, AllowExtrasOrder) {
     app.allow_extras();
 
     args = {"-x", "-f"};
-    EXPECT_NO_THROW(run());
+    ASSERT_NO_THROW(run());
     EXPECT_EQ(app.remaining(), std::vector<std::string>({"-x", "-f"}));
-    app.reset();
 
     std::vector<std::string> left_over = app.remaining();
     app.parse(left_over);
@@ -1462,15 +1349,12 @@ TEST_F(TApp, ThrowingTransform) {
     auto m = app.add_option("-m,--mess", val);
     m->transform([](std::string) -> std::string { throw CLI::ValidationError("My Message"); });
 
-    EXPECT_NO_THROW(run());
-    app.reset();
+    ASSERT_NO_THROW(run());
 
     args = {"-mone"};
 
     ASSERT_THROW(run(), CLI::ValidationError);
 
-    app.reset();
-
     try {
         run();
     } catch(const CLI::ValidationError &e) {
@@ -1504,7 +1388,7 @@ TEST_F(TApp, CustomDoubleOption) {
         custom_opt = {stol(vals.at(0)), stod(vals.at(1))};
         return true;
     });
-    opt->set_custom_option("INT FLOAT", 2);
+    opt->type_name("INT FLOAT")->type_size(2);
 
     args = {"12", "1.5"};
 
@@ -1533,17 +1417,14 @@ TEST_F(TApp, AddRemoveSetItems) {
     items.erase("TYPE1");
     items.erase("TYPE2");
 
-    app.reset();
     args = {"--type1", "TYPE6", "--type2", "TYPE7"};
     run();
     EXPECT_EQ(type1, "TYPE6");
     EXPECT_EQ(type2, "TYPE7");
 
-    app.reset();
     args = {"--type1", "TYPE1"};
     EXPECT_THROW(run(), CLI::ConversionError);
 
-    app.reset();
     args = {"--type2", "TYPE2"};
     EXPECT_THROW(run(), CLI::ConversionError);
 }
@@ -1567,17 +1448,47 @@ TEST_F(TApp, AddRemoveSetItemsNoCase) {
     items.erase("TYPE1");
     items.erase("TYPE2");
 
-    app.reset();
     args = {"--type1", "TyPE6", "--type2", "tYPE7"};
     run();
     EXPECT_EQ(type1, "TYPE6");
     EXPECT_EQ(type2, "TYPE7");
 
-    app.reset();
     args = {"--type1", "TYPe1"};
     EXPECT_THROW(run(), CLI::ConversionError);
 
-    app.reset();
     args = {"--type2", "TYpE2"};
     EXPECT_THROW(run(), CLI::ConversionError);
 }
+
+// #128
+TEST_F(TApp, RepeatingMultiArgumentOptions) {
+    std::vector<std::string> entries;
+    app.add_option("--entry", entries, "set a key and value")->type_name("KEY VALUE")->type_size(-2);
+
+    args = {"--entry", "key1", "value1", "--entry", "key2", "value2"};
+    ASSERT_NO_THROW(run());
+    EXPECT_EQ(entries, std::vector<std::string>({"key1", "value1", "key2", "value2"}));
+
+    args.pop_back();
+    ASSERT_THROW(run(), CLI::ArgumentMismatch);
+}
+
+// #122
+TEST_F(TApp, EmptyOptionEach) {
+    std::string q;
+    app.add_option("--each", {})->each([&q](std::string s) { q = s; });
+
+    args = {"--each", "that"};
+    run();
+
+    EXPECT_EQ(q, "that");
+}
+
+// #122
+TEST_F(TApp, EmptyOptionFail) {
+    std::string q;
+    app.add_option("--each", {});
+
+    args = {"--each", "that"};
+    run();
+}
diff --git a/packages/CLI11/tests/CMakeLists.txt b/packages/CLI11/tests/CMakeLists.txt
index 81d9c118746b6872bf7919a0ac685b4767c53842..848f1bae12134777925aae5742414ab125f76b89 100644
--- a/packages/CLI11/tests/CMakeLists.txt
+++ b/packages/CLI11/tests/CMakeLists.txt
@@ -3,10 +3,12 @@ if(NOT EXISTS "${CLI11_SOURCE_DIR}/extern/googletest/CMakeLists.txt")
     git submodule update --init")
 endif()
 
+list(APPEND CMAKE_MODULE_PATH "${CLI11_SOURCE_DIR}/cmake")
+
 # If submodule is available, add sanitizers
 # Set SANITIZE_ADDRESS, SANITIZE_MEMORY, SANITIZE_THREAD or SANITIZE_UNDEFINED
 if(EXISTS "${CLI11_SOURCE_DIR}/extern/sanitizers/cmake/FindSanitizers.cmake")
-    set(CMAKE_MODULE_PATH "${CLI11_SOURCE_DIR}/extern/sanitizers/cmake" ${CMAKE_MODULE_PATH})
+    list(APPEND CMAKE_MODULE_PATH "${CLI11_SOURCE_DIR}/extern/sanitizers/cmake")
     find_package(Sanitizers)
     if(SANITIZE_ADDRESS)
         message(STATUS "You might want to use \"${ASan_WRAPPER}\" to run your program")
@@ -30,8 +32,13 @@ set(CLI11_TESTS
     FormatterTest
     NewParseTest
     OptionalTest
+    DeprecatedTest
     )
 
+if(WIN32)
+    list(APPEND CLI11_TESTS WindowsTest)
+endif()
+
 set(CLI11_MULTIONLY_TESTS
     TimerTest
     )
@@ -66,6 +73,13 @@ foreach(T ${CLI11_MULTIONLY_TESTS})
 
 endforeach()
 
+# Add -Wno-deprecated-declarations to DeprecatedTest
+if(NOT MSVC)
+    target_compile_options(DeprecatedTest PRIVATE -Wno-deprecated-declarations)
+    if(TARGET DeprecatedTest_Single)
+        target_compile_options(DeprecatedTest_Single PRIVATE -Wno-deprecated-declarations)
+    endif()
+endif()
 
 # Link test (build error if inlines missing)
 add_library(link_test_1 link_test_1.cpp)
diff --git a/packages/CLI11/tests/CreationTest.cpp b/packages/CLI11/tests/CreationTest.cpp
index 72c00bd3c8ccec192f67139222915b70593f9dcc..e7c75f836a472373de4ddffad87e26ddc89c4d4e 100644
--- a/packages/CLI11/tests/CreationTest.cpp
+++ b/packages/CLI11/tests/CreationTest.cpp
@@ -362,7 +362,7 @@ TEST_F(TApp, SubcommandDefaults) {
     app.prefix_command();
     app.ignore_case();
     app.fallthrough();
-    app.set_footer("footy");
+    app.footer("footy");
     app.group("Stuff");
     app.require_subcommand(2, 3);
 
diff --git a/packages/CLI11/tests/DeprecatedTest.cpp b/packages/CLI11/tests/DeprecatedTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ba574365de0d38182bbb520a1c05627aa2d71a20
--- /dev/null
+++ b/packages/CLI11/tests/DeprecatedTest.cpp
@@ -0,0 +1,43 @@
+#ifdef CLI11_SINGLE_FILE
+#include "CLI11.hpp"
+#else
+#include "CLI/CLI.hpp"
+#endif
+
+#include "gtest/gtest.h"
+
+TEST(Deprecated, SetFooter) {
+    CLI::App app{"My prog"};
+
+    app.set_footer("My Footer");
+    EXPECT_EQ("My Footer", app.get_footer());
+}
+
+TEST(Deprecated, SetName) {
+    CLI::App app{"My prog"};
+
+    app.set_name("My Name");
+    EXPECT_EQ("My Name", app.get_name());
+}
+
+TEST(Deprecated, SetCallback) {
+    CLI::App app{"My prog"};
+
+    bool val;
+    app.set_callback([&val]() { val = true; });
+
+    std::vector<std::string> something;
+    app.parse(something);
+
+    EXPECT_TRUE(val);
+}
+
+TEST(Deprecated, SetTypeName) {
+    CLI::App app{"My prog"};
+
+    std::string val;
+    auto opt = app.add_option("--val", val);
+    opt->set_type_name("THAT");
+
+    EXPECT_EQ(opt->get_type_name(), "THAT");
+}
diff --git a/packages/CLI11/tests/HelpTest.cpp b/packages/CLI11/tests/HelpTest.cpp
index 17bee24c783d0d98ffa1cb128b0b70477c50355e..8825b08e04365de55e36228d633c4deeb0424d62 100644
--- a/packages/CLI11/tests/HelpTest.cpp
+++ b/packages/CLI11/tests/HelpTest.cpp
@@ -24,7 +24,7 @@ TEST(THelp, Basic) {
 
 TEST(THelp, Footer) {
     CLI::App app{"My prog"};
-    app.set_footer("Report bugs to bugs@example.com");
+    app.footer("Report bugs to bugs@example.com");
 
     std::string help = app.help();
 
@@ -128,7 +128,7 @@ TEST(THelp, VectorOpts) {
 
 TEST(THelp, MultiPosOpts) {
     CLI::App app{"My prog"};
-    app.set_name("program");
+    app.name("program");
     std::vector<int> x, y;
     app.add_option("quick", x, "Disc")->expected(2);
     app.add_option("vals", y, "Other");
@@ -222,8 +222,8 @@ TEST(THelp, ManualSetters) {
     int x = 1;
 
     CLI::Option *op1 = app.add_option("--op", x);
-    op1->set_default_str("12");
-    op1->set_type_name("BIGGLES");
+    op1->default_str("12");
+    op1->type_name("BIGGLES");
     EXPECT_EQ(x, 1);
 
     std::string help = app.help();
@@ -231,7 +231,7 @@ TEST(THelp, ManualSetters) {
     EXPECT_THAT(help, HasSubstr("=12"));
     EXPECT_THAT(help, HasSubstr("BIGGLES"));
 
-    op1->set_default_val("14");
+    op1->default_val("14");
     EXPECT_EQ(x, 14);
     help = app.help();
     EXPECT_THAT(help, HasSubstr("=14"));
@@ -327,13 +327,11 @@ TEST(THelp, OnlyOneAllHelp) {
     std::vector<std::string> input{"--help-all"};
     EXPECT_THROW(app.parse(input), CLI::ExtrasError);
 
-    app.reset();
     std::vector<std::string> input2{"--yelp"};
     EXPECT_THROW(app.parse(input2), CLI::CallForAllHelp);
 
     // Remove the flag
     app.set_help_all_flag();
-    app.reset();
     std::vector<std::string> input3{"--yelp"};
     EXPECT_THROW(app.parse(input3), CLI::ExtrasError);
 }
@@ -513,10 +511,11 @@ TEST_F(CapturedHelp, CallForAllHelpOutput) {
               "  --help-all                  Help all\n"
               "\n"
               "Subcommands:\n"
-              "one -> One description\n"
+              "one\n"
+              "  One description\n\n"
               "two\n"
-              "Options:\n"
-              "  --three                     \n");
+              "  Options:\n"
+              "    --three                     \n\n");
 }
 TEST_F(CapturedHelp, NewFormattedHelp) {
     app.formatter_fn([](const CLI::App *, std::string, CLI::AppFormatMode) { return "New Help"; });
@@ -535,7 +534,7 @@ TEST_F(CapturedHelp, NormalError) {
 }
 
 TEST_F(CapturedHelp, RepacedError) {
-    app.set_failure_message(CLI::FailureMessage::help);
+    app.failure_message(CLI::FailureMessage::help);
 
     EXPECT_EQ(run(CLI::ExtrasError({"Thing"})), static_cast<int>(CLI::ExitCodes::ExtrasError));
     EXPECT_EQ(out.str(), "");
@@ -556,11 +555,19 @@ TEST(THelp, CustomDoubleOption) {
         custom_opt = {stol(vals.at(0)), stod(vals.at(1))};
         return true;
     });
-    opt->set_custom_option("INT FLOAT", 2);
+    opt->type_name("INT FLOAT")->type_size(2);
 
     EXPECT_THAT(app.help(), Not(HasSubstr("x 2")));
 }
 
+TEST(THelp, CheckEmptyTypeName) {
+    CLI::App app;
+
+    auto opt = app.add_flag("-f,--flag");
+    std::string name = opt->get_type_name();
+    EXPECT_TRUE(name.empty());
+}
+
 TEST(THelp, AccessDescription) {
     CLI::App app{"My description goes here"};
 
diff --git a/packages/CLI11/tests/IniTest.cpp b/packages/CLI11/tests/IniTest.cpp
index 92c4e35e58bbaf4d1122d95054bb9f251eaea91f..24d24ba48a15ec64b77daeccc09298ee0a1718e9 100644
--- a/packages/CLI11/tests/IniTest.cpp
+++ b/packages/CLI11/tests/IniTest.cpp
@@ -7,6 +7,13 @@
 using ::testing::HasSubstr;
 using ::testing::Not;
 
+TEST(StringBased, IniJoin) {
+    std::vector<std::string> items = {"one", "two", "three four"};
+    std::string result = "one two \"three four\"";
+
+    EXPECT_EQ(CLI::detail::ini_join(items), result);
+}
+
 TEST(StringBased, First) {
     std::stringstream ofile;
 
@@ -186,7 +193,6 @@ TEST_F(TApp, IniNotRequired) {
     EXPECT_EQ(99, two);
     EXPECT_EQ(3, three);
 
-    app.reset();
     one = two = three = 0;
     args = {"--one=1", "--two=2"};
 
@@ -231,7 +237,7 @@ TEST_F(TApp, IniGetRemainingOption) {
 
     int two = 0;
     app.add_option("--two", two);
-    EXPECT_NO_THROW(run());
+    ASSERT_NO_THROW(run());
     std::vector<std::string> ExpectedRemaining = {ExtraOption};
     EXPECT_EQ(app.remaining(), ExpectedRemaining);
 }
@@ -249,7 +255,7 @@ TEST_F(TApp, IniGetNoRemaining) {
 
     int two = 0;
     app.add_option("--two", two);
-    EXPECT_NO_THROW(run());
+    ASSERT_NO_THROW(run());
     EXPECT_EQ(app.remaining().size(), (size_t)0);
 }
 
@@ -284,7 +290,6 @@ TEST_F(TApp, IniNotRequiredNotDefault) {
     EXPECT_EQ(99, two);
     EXPECT_EQ(3, three);
 
-    app.reset();
     args = {"--config", tmpini2};
     run();
 
@@ -353,18 +358,15 @@ TEST_F(TApp, IniRequired) {
 
     run();
 
-    app.reset();
     one = two = three = 0;
     args = {"--one=1", "--two=2"};
 
     run();
 
-    app.reset();
     args = {};
 
     EXPECT_THROW(run(), CLI::RequiredError);
 
-    app.reset();
     args = {"--two=2"};
 
     EXPECT_THROW(run(), CLI::RequiredError);
@@ -451,7 +453,7 @@ TEST_F(TApp, IniConfigurable) {
         out << "val=1" << std::endl;
     }
 
-    EXPECT_NO_THROW(run());
+    ASSERT_NO_THROW(run());
     EXPECT_TRUE(value);
 }
 
@@ -531,7 +533,7 @@ TEST_F(TApp, IniFlagNumbers) {
         out << "flag=3" << std::endl;
     }
 
-    EXPECT_NO_THROW(run());
+    ASSERT_NO_THROW(run());
     EXPECT_TRUE(boo);
 }
 
diff --git a/packages/CLI11/tests/NewParseTest.cpp b/packages/CLI11/tests/NewParseTest.cpp
index a465618f46b525f5851997d57fa460567b8b57cc..68c6adfd77a3ac4e73574dd25c107d751027f089 100644
--- a/packages/CLI11/tests/NewParseTest.cpp
+++ b/packages/CLI11/tests/NewParseTest.cpp
@@ -17,11 +17,11 @@ add_option(CLI::App &app, std::string name, cx &variable, std::string descriptio
     };
 
     CLI::Option *opt = app.add_option(name, fun, description, defaulted);
-    opt->set_custom_option("COMPLEX", 2);
+    opt->type_name("COMPLEX")->type_size(2);
     if(defaulted) {
         std::stringstream out;
         out << variable;
-        opt->set_default_str(out.str());
+        opt->default_str(out.str());
     }
     return opt;
 }
diff --git a/packages/CLI11/tests/OptionalTest.cpp b/packages/CLI11/tests/OptionalTest.cpp
index 6c519e1f261a1254418e0a2f7e5f0f3216671267..5d68c72434b91c7f89eba4b772c65f8e17928e5b 100644
--- a/packages/CLI11/tests/OptionalTest.cpp
+++ b/packages/CLI11/tests/OptionalTest.cpp
@@ -11,13 +11,11 @@ TEST_F(TApp, StdOptionalTest) {
     run();
     EXPECT_FALSE(opt);
 
-    app.reset();
     args = {"-c", "1"};
     run();
     EXPECT_TRUE(opt);
     EXPECT_EQ(*opt, 1);
 
-    app.reset();
     args = {"--count", "3"};
     run();
     EXPECT_TRUE(opt);
@@ -33,13 +31,11 @@ TEST_F(TApp, ExperimentalOptionalTest) {
     run();
     EXPECT_FALSE(opt);
 
-    app.reset();
     args = {"-c", "1"};
     run();
     EXPECT_TRUE(opt);
     EXPECT_EQ(*opt, 1);
 
-    app.reset();
     args = {"--count", "3"};
     run();
     EXPECT_TRUE(opt);
@@ -55,13 +51,11 @@ TEST_F(TApp, BoostOptionalTest) {
     run();
     EXPECT_FALSE(opt);
 
-    app.reset();
     args = {"-c", "1"};
     run();
     EXPECT_TRUE(opt);
     EXPECT_EQ(*opt, 1);
 
-    app.reset();
     args = {"--count", "3"};
     run();
     EXPECT_TRUE(opt);
diff --git a/packages/CLI11/tests/SubcommandTest.cpp b/packages/CLI11/tests/SubcommandTest.cpp
index 1a8174d942ae75cd5a9cbbf05e609c1c8610f337..bc5d8ca0095c0c311ce586107d1f2b90eef2fd7f 100644
--- a/packages/CLI11/tests/SubcommandTest.cpp
+++ b/packages/CLI11/tests/SubcommandTest.cpp
@@ -21,12 +21,12 @@ TEST_F(TApp, BasicSubcommands) {
     run();
     EXPECT_EQ((size_t)0, app.get_subcommands().size());
 
-    app.reset();
     args = {"sub1"};
     run();
     EXPECT_EQ(sub1, app.get_subcommands().at(0));
+    EXPECT_EQ((size_t)1, app.get_subcommands().size());
 
-    app.reset();
+    app.clear();
     EXPECT_EQ((size_t)0, app.get_subcommands().size());
 
     args = {"sub2"};
@@ -34,11 +34,9 @@ TEST_F(TApp, BasicSubcommands) {
     EXPECT_EQ((size_t)1, app.get_subcommands().size());
     EXPECT_EQ(sub2, app.get_subcommands().at(0));
 
-    app.reset();
     args = {"SUb2"};
     EXPECT_THROW(run(), CLI::ExtrasError);
 
-    app.reset();
     args = {"SUb2"};
     try {
         run();
@@ -46,7 +44,6 @@ TEST_F(TApp, BasicSubcommands) {
         EXPECT_THAT(e.what(), HasSubstr("SUb2"));
     }
 
-    app.reset();
     args = {"sub1", "extra"};
     try {
         run();
@@ -72,22 +69,18 @@ TEST_F(TApp, MultiSubFallthrough) {
     EXPECT_TRUE(app.got_subcommand(sub2));
     EXPECT_TRUE(*sub2);
 
-    app.reset();
     app.require_subcommand();
 
     run();
 
-    app.reset();
     app.require_subcommand(2);
 
     run();
 
-    app.reset();
     app.require_subcommand(1);
 
     EXPECT_THROW(run(), CLI::ExtrasError);
 
-    app.reset();
     args = {"sub1"};
     run();
 
@@ -109,24 +102,21 @@ TEST_F(TApp, RequiredAndSubcoms) { // #23
     auto bar = app.add_subcommand("bar");
 
     args = {"bar", "foo"};
-    EXPECT_NO_THROW(run());
+    ASSERT_NO_THROW(run());
     EXPECT_TRUE(*foo);
     EXPECT_FALSE(*bar);
     EXPECT_EQ(baz, "bar");
 
-    app.reset();
     args = {"foo"};
-    EXPECT_NO_THROW(run());
+    ASSERT_NO_THROW(run());
     EXPECT_FALSE(*foo);
     EXPECT_EQ(baz, "foo");
 
-    app.reset();
     args = {"foo", "foo"};
-    EXPECT_NO_THROW(run());
+    ASSERT_NO_THROW(run());
     EXPECT_TRUE(*foo);
     EXPECT_EQ(baz, "foo");
 
-    app.reset();
     args = {"foo", "other"};
     EXPECT_THROW(run(), CLI::ExtrasError);
 }
@@ -144,7 +134,6 @@ TEST_F(TApp, RequiredAndSubcomFallthrough) {
     EXPECT_TRUE(bar);
     EXPECT_EQ(baz, "other");
 
-    app.reset();
     args = {"bar", "other2"};
     EXPECT_THROW(run(), CLI::ExtrasError);
 }
@@ -164,7 +153,6 @@ TEST_F(TApp, FooFooProblem) {
     EXPECT_EQ(baz_str, "");
     EXPECT_EQ(other_str, "foo");
 
-    app.reset();
     baz_str = "";
     other_str = "";
     baz->required();
@@ -178,10 +166,10 @@ TEST_F(TApp, FooFooProblem) {
 
 TEST_F(TApp, Callbacks) {
     auto sub1 = app.add_subcommand("sub1");
-    sub1->set_callback([]() { throw CLI::Success(); });
+    sub1->callback([]() { throw CLI::Success(); });
     auto sub2 = app.add_subcommand("sub2");
     bool val = false;
-    sub2->set_callback([&val]() { val = true; });
+    sub2->callback([&val]() { val = true; });
 
     args = {"sub2"};
     EXPECT_FALSE(val);
@@ -191,14 +179,13 @@ TEST_F(TApp, Callbacks) {
 
 TEST_F(TApp, RuntimeErrorInCallback) {
     auto sub1 = app.add_subcommand("sub1");
-    sub1->set_callback([]() { throw CLI::RuntimeError(); });
+    sub1->callback([]() { throw CLI::RuntimeError(); });
     auto sub2 = app.add_subcommand("sub2");
-    sub2->set_callback([]() { throw CLI::RuntimeError(2); });
+    sub2->callback([]() { throw CLI::RuntimeError(2); });
 
     args = {"sub1"};
     EXPECT_THROW(run(), CLI::RuntimeError);
 
-    app.reset();
     args = {"sub1"};
     try {
         run();
@@ -206,11 +193,9 @@ TEST_F(TApp, RuntimeErrorInCallback) {
         EXPECT_EQ(1, e.get_exit_code());
     }
 
-    app.reset();
     args = {"sub2"};
     EXPECT_THROW(run(), CLI::RuntimeError);
 
-    app.reset();
     args = {"sub2"};
     try {
         run();
@@ -309,14 +294,13 @@ TEST_F(TApp, CallbackOrdering) {
     app.add_option("--val", val);
 
     auto sub = app.add_subcommand("sub");
-    sub->set_callback([&val, &sub_val]() { sub_val = val; });
+    sub->callback([&val, &sub_val]() { sub_val = val; });
 
     args = {"sub", "--val=2"};
     run();
     EXPECT_EQ(2, val);
     EXPECT_EQ(2, sub_val);
 
-    app.reset();
     args = {"--val=2", "sub"};
     run();
     EXPECT_EQ(2, val);
@@ -331,10 +315,7 @@ TEST_F(TApp, RequiredSubCom) {
 
     EXPECT_THROW(run(), CLI::RequiredError);
 
-    app.reset();
-
     args = {"sub1"};
-
     run();
 }
 
@@ -347,22 +328,16 @@ TEST_F(TApp, SubComExtras) {
     EXPECT_EQ(app.remaining(), std::vector<std::string>({"extra"}));
     EXPECT_EQ(sub->remaining(), std::vector<std::string>());
 
-    app.reset();
-
     args = {"extra1", "extra2", "sub"};
     run();
     EXPECT_EQ(app.remaining(), std::vector<std::string>({"extra1", "extra2"}));
     EXPECT_EQ(sub->remaining(), std::vector<std::string>());
 
-    app.reset();
-
     args = {"sub", "extra1", "extra2"};
     run();
     EXPECT_EQ(app.remaining(), std::vector<std::string>());
     EXPECT_EQ(sub->remaining(), std::vector<std::string>({"extra1", "extra2"}));
 
-    app.reset();
-
     args = {"extra1", "extra2", "sub", "extra3", "extra4"};
     run();
     EXPECT_EQ(app.remaining(), std::vector<std::string>({"extra1", "extra2"}));
@@ -378,11 +353,9 @@ TEST_F(TApp, Required1SubCom) {
 
     EXPECT_THROW(run(), CLI::RequiredError);
 
-    app.reset();
     args = {"sub1"};
     run();
 
-    app.reset();
     args = {"sub1", "sub2"};
     EXPECT_THROW(run(), CLI::ExtrasError);
 }
@@ -523,15 +496,12 @@ TEST_F(SubcommandProgram, CaseCheck) {
     args = {"Start"};
     EXPECT_THROW(run(), CLI::ExtrasError);
 
-    app.reset();
     args = {"start"};
     run();
 
-    app.reset();
     start->ignore_case();
     run();
 
-    app.reset();
     args = {"Start"};
     run();
 }
@@ -546,12 +516,12 @@ TEST_F(TApp, SubcomInheritCaseCheck) {
     EXPECT_EQ((size_t)2, app.get_subcommands({}).size());
     EXPECT_EQ((size_t)1, app.get_subcommands([](const CLI::App *s) { return s->get_name() == "sub1"; }).size());
 
-    app.reset();
     args = {"SuB1"};
     run();
     EXPECT_EQ(sub1, app.get_subcommands().at(0));
+    EXPECT_EQ((size_t)1, app.get_subcommands().size());
 
-    app.reset();
+    app.clear();
     EXPECT_EQ((size_t)0, app.get_subcommands().size());
 
     args = {"sUb2"};
@@ -573,12 +543,10 @@ TEST_F(SubcommandProgram, HelpOrder) {
 
 TEST_F(SubcommandProgram, Callbacks) {
 
-    start->set_callback([]() { throw CLI::Success(); });
+    start->callback([]() { throw CLI::Success(); });
 
     run();
 
-    app.reset();
-
     args = {"start"};
 
     EXPECT_THROW(run(), CLI::Success);
@@ -606,15 +574,12 @@ TEST_F(SubcommandProgram, ExtrasErrors) {
 
     args = {"one", "two", "start", "three", "four"};
     EXPECT_THROW(run(), CLI::ExtrasError);
-    app.reset();
 
     args = {"start", "three", "four"};
     EXPECT_THROW(run(), CLI::ExtrasError);
-    app.reset();
 
     args = {"one", "two"};
     EXPECT_THROW(run(), CLI::ExtrasError);
-    app.reset();
 }
 
 TEST_F(SubcommandProgram, OrderedExtras) {
@@ -622,7 +587,6 @@ TEST_F(SubcommandProgram, OrderedExtras) {
     app.allow_extras();
     args = {"one", "two", "start", "three", "four"};
     EXPECT_THROW(run(), CLI::ExtrasError);
-    app.reset();
 
     start->allow_extras();
 
@@ -632,7 +596,6 @@ TEST_F(SubcommandProgram, OrderedExtras) {
     EXPECT_EQ(start->remaining(), std::vector<std::string>({"three", "four"}));
     EXPECT_EQ(app.remaining(true), std::vector<std::string>({"one", "two", "three", "four"}));
 
-    app.reset();
     args = {"one", "two", "start", "three", "--", "four"};
 
     run();
@@ -656,7 +619,6 @@ TEST_F(SubcommandProgram, MixedOrderExtras) {
     EXPECT_EQ(stop->remaining(), std::vector<std::string>({"five", "six"}));
     EXPECT_EQ(app.remaining(true), std::vector<std::string>({"one", "two", "three", "four", "five", "six"}));
 
-    app.reset();
     args = {"one", "two", "stop", "three", "four", "start", "five", "six"};
     run();
 
@@ -668,14 +630,13 @@ TEST_F(SubcommandProgram, MixedOrderExtras) {
 
 TEST_F(SubcommandProgram, CallbackOrder) {
     std::vector<int> callback_order;
-    start->set_callback([&callback_order]() { callback_order.push_back(1); });
-    stop->set_callback([&callback_order]() { callback_order.push_back(2); });
+    start->callback([&callback_order]() { callback_order.push_back(1); });
+    stop->callback([&callback_order]() { callback_order.push_back(2); });
 
     args = {"start", "stop"};
     run();
     EXPECT_EQ(callback_order, std::vector<int>({1, 2}));
 
-    app.reset();
     callback_order.clear();
 
     args = {"stop", "start"};
@@ -728,7 +689,6 @@ TEST_F(ManySubcommands, Required1Fuzzy) {
     run();
     EXPECT_EQ(sub1->remaining(), vs_t({"sub2", "sub3"}));
 
-    app.reset();
     app.require_subcommand(-1);
 
     run();
@@ -742,7 +702,6 @@ TEST_F(ManySubcommands, Required2Fuzzy) {
     EXPECT_EQ(sub2->remaining(), vs_t({"sub3"}));
     EXPECT_EQ(app.remaining(true), vs_t({"sub3"}));
 
-    app.reset();
     app.require_subcommand(-2);
 
     run();
@@ -753,13 +712,11 @@ TEST_F(ManySubcommands, Unlimited) {
     run();
     EXPECT_EQ(app.remaining(true), vs_t());
 
-    app.reset();
     app.require_subcommand();
 
     run();
     EXPECT_EQ(app.remaining(true), vs_t());
 
-    app.reset();
     app.require_subcommand(2, 0); // 2 or more
 
     run();
diff --git a/packages/CLI11/tests/WindowsTest.cpp b/packages/CLI11/tests/WindowsTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bae812668b43689b6bc62aa0d9100356e70d786a
--- /dev/null
+++ b/packages/CLI11/tests/WindowsTest.cpp
@@ -0,0 +1,13 @@
+#include "app_helper.hpp"
+#include <Windows.h>
+
+// This test verifies that CLI11 still works if
+// Windows.h is included. #145
+
+TEST_F(TApp, WindowsTestSimple) {
+    app.add_flag("-c,--count");
+    args = {"-c"};
+    run();
+    EXPECT_EQ((size_t)1, app.count("-c"));
+    EXPECT_EQ((size_t)1, app.count("--count"));
+}
diff --git a/packages/CLI11/tests/link_test_2.cpp b/packages/CLI11/tests/link_test_2.cpp
index a198b6ed71d95c77621c474c34f16068c4ea268e..85c5a74fc6620da7410bd05d414365e8718d60d4 100644
--- a/packages/CLI11/tests/link_test_2.cpp
+++ b/packages/CLI11/tests/link_test_2.cpp
@@ -4,7 +4,7 @@
 
 int do_nothing();
 
-// Verifies there are no ungarded inlines
+// Verifies there are no unguarded inlines
 TEST(Link, DoNothing) {
     int a = do_nothing();
     EXPECT_EQ(7, a);
diff --git a/packages/Catch2/.gitattributes b/packages/Catch2/.gitattributes
index b5a2cdccdf1cddc69c893dc636f95a91ce4059b0..23f98fffa38cb97875db0ba787e9574fa51fc884 100644
--- a/packages/Catch2/.gitattributes
+++ b/packages/Catch2/.gitattributes
@@ -17,6 +17,6 @@
 
 # Keep the single include header with LFs to make sure it is uploaded,
 # hashed etc with LF
-single_include/*.hpp eol=lf
+single_include/**/*.hpp eol=lf
 # Also keep the LICENCE file with LFs for the same reason
 LICENCE.txt eol=lf
diff --git a/packages/Catch2/.gitrepo b/packages/Catch2/.gitrepo
index f0489ed62b2408124ccd6dc479c66fa99de2417b..5c9fe5b98047e2bd6495c7a894c42e09244a586b 100644
--- a/packages/Catch2/.gitrepo
+++ b/packages/Catch2/.gitrepo
@@ -6,6 +6,6 @@
 [subrepo]
 	remote = git@github.com:catchorg/Catch2.git
 	branch = master
-	commit = 1dce91d78eb6764a474badee7559650502f1d2fc
-	parent = 5515dc5466f2c351639c28fdc16cce10cb067e12
+	commit = 9e1bdca4667295fcb16265eae00efa8423f07007
+	parent = cd9b656f2a2e7fe914557e186f30b2123bcb98b4
 	cmdver = 0.3.1
diff --git a/packages/Catch2/.travis.yml b/packages/Catch2/.travis.yml
index b20456039324191c5de3fdd19c9376bc3a19b5b0..1d38d8602c7ccc509ee8ce1cd997664247f46dd1 100644
--- a/packages/Catch2/.travis.yml
+++ b/packages/Catch2/.travis.yml
@@ -219,7 +219,7 @@ matrix:
         apt:
           sources: *all_sources
           packages: ['lcov', 'g++-7']
-      env: COMPILER='g++-7' CPP14=1 EXAMPLES=1 COVERAGE=1
+      env: COMPILER='g++-7' CPP14=1 EXAMPLES=1 COVERAGE=1 EXTRAS=1
 
     - os: linux
       compiler: clang
@@ -229,7 +229,7 @@ matrix:
           sources:
             - ubuntu-toolchain-r-test
             - llvm-toolchain-trusty
-      env: COMPILER='clang++-3.8' EXAMPLES=1 COVERAGE=1
+      env: COMPILER='clang++-3.8' EXAMPLES=1 COVERAGE=1 EXTRAS=1
 
     - os: linux
       compiler: gcc
@@ -237,19 +237,46 @@ matrix:
         apt:
           sources: *all_sources
           packages: ['valgrind', 'lcov', 'g++-7']
-      env: COMPILER='g++-7' CPP14=1 VALGRIND=1      
-      
+      env: COMPILER='g++-7' CPP14=1 VALGRIND=1
+
     - os: osx
       osx_image: xcode9.1
       compiler: clang
-      env: COMPILER='clang++' CPP14=1 EXAMPLES=1 COVERAGE=1
+      env: COMPILER='clang++' CPP14=1 EXAMPLES=1 COVERAGE=1 EXTRAS=1
+
+    # 7/ C++17 builds
+    - os: linux
+      compiler: gcc
+      addons: *gcc7
+      env: COMPILER='g++-7' CPP17=1
+
+    - os: linux
+      compiler: gcc
+      addons: *gcc7
+      env: COMPILER='g++-7' EXAMPLES=1 COVERAGE=1 EXTRAS=1 CPP17=1
+
+    - os: linux
+      compiler: clang
+      addons:
+          apt:
+              sources: *all_sources
+              packages: ['clang-6.0', 'libstdc++-8-dev']
+      env: COMPILER='clang++-6.0' CPP17=1
+
+    - os: linux
+      compiler: clang
+      addons:
+          apt:
+              sources: *all_sources
+              packages: ['clang-6.0', 'libstdc++-8-dev']
+      env: COMPILER='clang++-6.0' CPP17=1 EXAMPLES=1 COVERAGE=1 EXTRAS=1
 
 install:
   - DEPS_DIR="${TRAVIS_BUILD_DIR}/deps"
   - mkdir -p ${DEPS_DIR} && cd ${DEPS_DIR}
   - |
     if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
-      CMAKE_URL="http://www.cmake.org/files/v3.3/cmake-3.3.2-Linux-x86_64.tar.gz"
+      CMAKE_URL="http://cmake.org/files/v3.8/cmake-3.8.2-Linux-x86_64.tar.gz"
       mkdir cmake && travis_retry wget --no-check-certificate --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake
       export PATH=${DEPS_DIR}/cmake/bin:${PATH}
     elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
@@ -263,7 +290,7 @@ before_script:
   - python scripts/generateSingleHeader.py
 
     # Use Debug builds for running Valgrind and building examples
-  - cmake -H. -BBuild-Debug -DCMAKE_BUILD_TYPE=Debug -Wdev -DUSE_CPP14=${CPP14} -DCATCH_USE_VALGRIND=${VALGRIND} -DCATCH_BUILD_EXAMPLES=${EXAMPLES} -DCATCH_ENABLE_COVERAGE=${COVERAGE}
+  - cmake -H. -BBuild-Debug -DCMAKE_BUILD_TYPE=Debug -Wdev -DUSE_CPP14=${CPP14} -DUSE_CPP17=${CPP17} -DCATCH_USE_VALGRIND=${VALGRIND} -DCATCH_BUILD_EXAMPLES=${EXAMPLES} -DCATCH_ENABLE_COVERAGE=${COVERAGE} -DCATCH_BUILD_EXTRA_TESTS=${EXTRAS}
     # Don't bother with release build for coverage build
   - cmake -H. -BBuild-Release -DCMAKE_BUILD_TYPE=Release -Wdev -DUSE_CPP14=${CPP14}
 
diff --git a/packages/Catch2/CMake/Catch2Config.cmake.in b/packages/Catch2/CMake/Catch2Config.cmake.in
new file mode 100644
index 0000000000000000000000000000000000000000..c485219cdb77406be4b972d0f596e335ad9fdf37
--- /dev/null
+++ b/packages/Catch2/CMake/Catch2Config.cmake.in
@@ -0,0 +1,10 @@
+@PACKAGE_INIT@
+
+
+# Avoid repeatedly including the targets
+if(NOT TARGET Catch2::Catch2)
+    # Provide path for scripts
+    list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
+
+    include(${CMAKE_CURRENT_LIST_DIR}/Catch2Targets.cmake)
+endif()
diff --git a/packages/Catch2/CMake/MiscFunctions.cmake b/packages/Catch2/CMake/MiscFunctions.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..262f7cd8292afcef9f6612c337d2a931ede37c98
--- /dev/null
+++ b/packages/Catch2/CMake/MiscFunctions.cmake
@@ -0,0 +1,26 @@
+#checks that the given hard-coded list contains all headers + sources in the given folder
+function(CheckFileList LIST_VAR FOLDER)
+  set(MESSAGE " should be added to the variable ${LIST_VAR}")
+  set(MESSAGE "${MESSAGE} in ${CMAKE_CURRENT_LIST_FILE}\n")
+  file(GLOB GLOBBED_LIST "${FOLDER}/*.cpp"
+                         "${FOLDER}/*.hpp"
+                         "${FOLDER}/*.h")
+  list(REMOVE_ITEM GLOBBED_LIST ${${LIST_VAR}})
+  foreach(EXTRA_ITEM ${GLOBBED_LIST})
+    string(REPLACE "${CATCH_DIR}/" "" RELATIVE_FILE_NAME "${EXTRA_ITEM}")
+    message(AUTHOR_WARNING "The file \"${RELATIVE_FILE_NAME}\"${MESSAGE}")
+  endforeach()
+endfunction()
+
+function(CheckFileListRec LIST_VAR FOLDER)
+  set(MESSAGE " should be added to the variable ${LIST_VAR}")
+  set(MESSAGE "${MESSAGE} in ${CMAKE_CURRENT_LIST_FILE}\n")
+  file(GLOB_RECURSE GLOBBED_LIST "${FOLDER}/*.cpp"
+                                 "${FOLDER}/*.hpp"
+                                 "${FOLDER}/*.h")
+  list(REMOVE_ITEM GLOBBED_LIST ${${LIST_VAR}})
+  foreach(EXTRA_ITEM ${GLOBBED_LIST})
+    string(REPLACE "${CATCH_DIR}/" "" RELATIVE_FILE_NAME "${EXTRA_ITEM}")
+    message(AUTHOR_WARNING "The file \"${RELATIVE_FILE_NAME}\"${MESSAGE}")
+  endforeach()
+endfunction()
diff --git a/packages/Catch2/CMake/catch2.pc.in b/packages/Catch2/CMake/catch2.pc.in
new file mode 100644
index 0000000000000000000000000000000000000000..3ac9fbd1a6ecbc6cd3ddafd83072acd027be8986
--- /dev/null
+++ b/packages/Catch2/CMake/catch2.pc.in
@@ -0,0 +1,7 @@
+includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
+
+Name: Catch2
+Description: A modern, C++-native, header-only, test framework for C++11
+URL: https://github.com/catchorg/Catch2
+Version: @Catch2_VERSION@
+Cflags: -I${includedir}
diff --git a/packages/Catch2/CMakeLists.txt b/packages/Catch2/CMakeLists.txt
index 9fdb50866c35cbb2a5f83ae8f878d298dceb03b3..09793f7b3c2a304868fdb0cc4e8fcd48ef961b61 100644
--- a/packages/Catch2/CMakeLists.txt
+++ b/packages/Catch2/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.1)
+cmake_minimum_required(VERSION 3.5)
 
 # detect if Catch is being bundled,
 # disable testsuite in that case
@@ -6,14 +6,24 @@ if(NOT DEFINED PROJECT_NAME)
   set(NOT_SUBPROJECT ON)
 endif()
 
-project(Catch2 LANGUAGES CXX VERSION 2.2.3)
+project(Catch2 LANGUAGES CXX VERSION 2.4.1)
+
+# Provide path for scripts
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
 
 include(GNUInstallDirs)
+include(CMakePackageConfigHelpers)
+include(CTest)
 
 option(CATCH_USE_VALGRIND "Perform SelfTests with Valgrind" OFF)
+option(CATCH_BUILD_TESTING "Build SelfTest project" ON)
 option(CATCH_BUILD_EXAMPLES "Build documentation examples" OFF)
+option(CATCH_BUILD_EXTRA_TESTS "Build extra tests" OFF)
 option(CATCH_ENABLE_COVERAGE "Generate coverage for codecov.io" OFF)
 option(CATCH_ENABLE_WERROR "Enable all warnings as errors" ON)
+option(CATCH_INSTALL_DOCS "Install documentation alongside library" ON)
+option(CATCH_INSTALL_HELPERS "Install contrib alongside library" ON)
+
 
 set_property(GLOBAL PROPERTY USE_FOLDERS ON)
 
@@ -27,433 +37,172 @@ if(USE_WMAIN)
     set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ENTRY:wmainCRTStartup")
 endif()
 
-#checks that the given hard-coded list contains all headers + sources in the given folder
-function(CheckFileList LIST_VAR FOLDER)
-  set(MESSAGE " should be added to the variable ${LIST_VAR}")
-  set(MESSAGE "${MESSAGE} in ${CMAKE_CURRENT_LIST_FILE}\n")
-  file(GLOB GLOBBED_LIST "${FOLDER}/*.cpp"
-                         "${FOLDER}/*.hpp"
-                         "${FOLDER}/*.h")
-  list(REMOVE_ITEM GLOBBED_LIST ${${LIST_VAR}})
-  foreach(EXTRA_ITEM ${GLOBBED_LIST})
-    string(REPLACE "${CATCH_DIR}/" "" RELATIVE_FILE_NAME "${EXTRA_ITEM}")
-    message(AUTHOR_WARNING "The file \"${RELATIVE_FILE_NAME}\"${MESSAGE}")
-  endforeach()
-endfunction()
-
-function(CheckFileListRec LIST_VAR FOLDER)
-  set(MESSAGE " should be added to the variable ${LIST_VAR}")
-  set(MESSAGE "${MESSAGE} in ${CMAKE_CURRENT_LIST_FILE}\n")
-  file(GLOB_RECURSE GLOBBED_LIST "${FOLDER}/*.cpp"
-                                 "${FOLDER}/*.hpp"
-                                 "${FOLDER}/*.h")
-  list(REMOVE_ITEM GLOBBED_LIST ${${LIST_VAR}})
-  foreach(EXTRA_ITEM ${GLOBBED_LIST})
-    string(REPLACE "${CATCH_DIR}/" "" RELATIVE_FILE_NAME "${EXTRA_ITEM}")
-    message(AUTHOR_WARNING "The file \"${RELATIVE_FILE_NAME}\"${MESSAGE}")
-  endforeach()
-endfunction()
-
-# define the sources of the self test
-# Please keep these ordered alphabetically
-set(TEST_SOURCES
-        ${SELF_TEST_DIR}/TestMain.cpp
-        ${SELF_TEST_DIR}/IntrospectiveTests/CmdLine.tests.cpp
-        ${SELF_TEST_DIR}/IntrospectiveTests/PartTracker.tests.cpp
-        ${SELF_TEST_DIR}/IntrospectiveTests/TagAlias.tests.cpp
-        ${SELF_TEST_DIR}/IntrospectiveTests/String.tests.cpp
-        ${SELF_TEST_DIR}/IntrospectiveTests/Xml.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/Approx.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/BDD.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/Benchmark.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/Class.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/Compilation.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/Condition.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/Decomposition.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/EnumToString.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/Exception.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/Message.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/Misc.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/ToStringChrono.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/ToStringGeneral.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/ToStringPair.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/ToStringTuple.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/ToStringVector.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/ToStringWhich.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/Tricky.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/VariadicMacros.tests.cpp
-        ${SELF_TEST_DIR}/UsageTests/Matchers.tests.cpp
-        )
-CheckFileList(TEST_SOURCES ${SELF_TEST_DIR})
-
-# A set of impl files that just #include a single header
-# Please keep these ordered alphabetically
-set(SURROGATE_SOURCES
-        ${SELF_TEST_DIR}/SurrogateCpps/catch_console_colour.cpp
-        ${SELF_TEST_DIR}/SurrogateCpps/catch_debugger.cpp
-        ${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_reporter.cpp
-        ${SELF_TEST_DIR}/SurrogateCpps/catch_option.cpp
-        ${SELF_TEST_DIR}/SurrogateCpps/catch_stream.cpp
-        ${SELF_TEST_DIR}/SurrogateCpps/catch_test_case_tracker.cpp
-        ${SELF_TEST_DIR}/SurrogateCpps/catch_test_spec.cpp
-        ${SELF_TEST_DIR}/SurrogateCpps/catch_xmlwriter.cpp
-        )
-CheckFileList(SURROGATE_SOURCES ${SELF_TEST_DIR}/SurrogateCpps)
-
-
-# Please keep these ordered alphabetically
-set(TOP_LEVEL_HEADERS
-        ${HEADER_DIR}/catch.hpp
-        ${HEADER_DIR}/catch_with_main.hpp
-        )
-CheckFileList(TOP_LEVEL_HEADERS ${HEADER_DIR})
-
-# Please keep these ordered alphabetically
-set(EXTERNAL_HEADERS
-        ${HEADER_DIR}/external/clara.hpp
-        )
-CheckFileList(EXTERNAL_HEADERS ${HEADER_DIR}/external)
-
-
-# Please keep these ordered alphabetically
-set(INTERNAL_HEADERS
-        ${HEADER_DIR}/internal/catch_approx.h
-        ${HEADER_DIR}/internal/catch_assertionhandler.h
-        ${HEADER_DIR}/internal/catch_assertioninfo.h
-        ${HEADER_DIR}/internal/catch_assertionresult.h
-        ${HEADER_DIR}/internal/catch_capture.hpp
-        ${HEADER_DIR}/internal/catch_capture_matchers.h
-        ${HEADER_DIR}/internal/catch_clara.h
-        ${HEADER_DIR}/internal/catch_commandline.h
-        ${HEADER_DIR}/internal/catch_common.h
-        ${HEADER_DIR}/internal/catch_compiler_capabilities.h
-        ${HEADER_DIR}/internal/catch_config.hpp
-        ${HEADER_DIR}/internal/catch_console_colour.h
-        ${HEADER_DIR}/internal/catch_context.h
-        ${HEADER_DIR}/internal/catch_debug_console.h
-        ${HEADER_DIR}/internal/catch_debugger.h
-        ${HEADER_DIR}/internal/catch_decomposer.h
-        ${HEADER_DIR}/internal/catch_default_main.hpp
-        ${HEADER_DIR}/internal/catch_enforce.h
-        ${HEADER_DIR}/internal/catch_errno_guard.h
-        ${HEADER_DIR}/internal/catch_exception_translator_registry.h
-        ${HEADER_DIR}/internal/catch_external_interfaces.h
-        ${HEADER_DIR}/internal/catch_fatal_condition.h
-        ${HEADER_DIR}/internal/catch_impl.hpp
-        ${HEADER_DIR}/internal/catch_interfaces_capture.h
-        ${HEADER_DIR}/internal/catch_interfaces_config.h
-        ${HEADER_DIR}/internal/catch_interfaces_exception.h
-        ${HEADER_DIR}/internal/catch_interfaces_registry_hub.h
-        ${HEADER_DIR}/internal/catch_interfaces_reporter.h
-        ${HEADER_DIR}/internal/catch_interfaces_runner.h
-        ${HEADER_DIR}/internal/catch_interfaces_tag_alias_registry.h
-        ${HEADER_DIR}/internal/catch_interfaces_testcase.h
-        ${HEADER_DIR}/internal/catch_leak_detector.h
-        ${HEADER_DIR}/internal/catch_list.h
-        ${HEADER_DIR}/internal/catch_matchers.h
-        ${HEADER_DIR}/internal/catch_matchers_floating.h
-        ${HEADER_DIR}/internal/catch_matchers_generic.hpp
-        ${HEADER_DIR}/internal/catch_matchers_string.h
-        ${HEADER_DIR}/internal/catch_matchers_vector.h
-        ${HEADER_DIR}/internal/catch_message.h
-        ${HEADER_DIR}/internal/catch_objc.hpp
-        ${HEADER_DIR}/internal/catch_objc_arc.hpp
-        ${HEADER_DIR}/internal/catch_option.hpp
-        ${HEADER_DIR}/internal/catch_output_redirect.h
-        ${HEADER_DIR}/internal/catch_platform.h
-        ${HEADER_DIR}/internal/catch_random_number_generator.h
-        ${HEADER_DIR}/internal/catch_reenable_warnings.h
-        ${HEADER_DIR}/internal/catch_reporter_registrars.hpp
-        ${HEADER_DIR}/internal/catch_reporter_registry.h
-        ${HEADER_DIR}/internal/catch_result_type.h
-        ${HEADER_DIR}/internal/catch_run_context.h
-        ${HEADER_DIR}/internal/catch_benchmark.h
-        ${HEADER_DIR}/internal/catch_section.h
-        ${HEADER_DIR}/internal/catch_section_info.h
-        ${HEADER_DIR}/internal/catch_session.h
-        ${HEADER_DIR}/internal/catch_startup_exception_registry.h
-        ${HEADER_DIR}/internal/catch_stream.h
-        ${HEADER_DIR}/internal/catch_stringref.h
-        ${HEADER_DIR}/internal/catch_string_manip.h
-        ${HEADER_DIR}/internal/catch_suppress_warnings.h
-        ${HEADER_DIR}/internal/catch_tag_alias.h
-        ${HEADER_DIR}/internal/catch_tag_alias_autoregistrar.h
-        ${HEADER_DIR}/internal/catch_tag_alias_registry.h
-        ${HEADER_DIR}/internal/catch_test_case_info.h
-        ${HEADER_DIR}/internal/catch_test_case_registry_impl.h
-        ${HEADER_DIR}/internal/catch_test_case_tracker.h
-        ${HEADER_DIR}/internal/catch_test_registry.h
-        ${HEADER_DIR}/internal/catch_test_spec.h
-        ${HEADER_DIR}/internal/catch_test_spec_parser.h
-        ${HEADER_DIR}/internal/catch_text.h
-        ${HEADER_DIR}/internal/catch_timer.h
-        ${HEADER_DIR}/internal/catch_to_string.hpp
-        ${HEADER_DIR}/internal/catch_tostring.h
-        ${HEADER_DIR}/internal/catch_totals.h
-        ${HEADER_DIR}/internal/catch_uncaught_exceptions.h
-        ${HEADER_DIR}/internal/catch_user_interfaces.h
-        ${HEADER_DIR}/internal/catch_version.h
-        ${HEADER_DIR}/internal/catch_wildcard_pattern.h
-        ${HEADER_DIR}/internal/catch_windows_h_proxy.h
-        ${HEADER_DIR}/internal/catch_xmlwriter.h
-        )
-set(IMPL_SOURCES
-        ${HEADER_DIR}/internal/catch_approx.cpp
-        ${HEADER_DIR}/internal/catch_assertionhandler.cpp
-        ${HEADER_DIR}/internal/catch_assertionresult.cpp
-        ${HEADER_DIR}/internal/catch_benchmark.cpp
-        ${HEADER_DIR}/internal/catch_capture_matchers.cpp
-        ${HEADER_DIR}/internal/catch_commandline.cpp
-        ${HEADER_DIR}/internal/catch_common.cpp
-        ${HEADER_DIR}/internal/catch_config.cpp
-        ${HEADER_DIR}/internal/catch_console_colour.cpp
-        ${HEADER_DIR}/internal/catch_context.cpp
-        ${HEADER_DIR}/internal/catch_debug_console.cpp
-        ${HEADER_DIR}/internal/catch_debugger.cpp
-        ${HEADER_DIR}/internal/catch_decomposer.cpp
-        ${HEADER_DIR}/internal/catch_errno_guard.cpp
-        ${HEADER_DIR}/internal/catch_exception_translator_registry.cpp
-        ${HEADER_DIR}/internal/catch_fatal_condition.cpp
-        ${HEADER_DIR}/internal/catch_interfaces_capture.cpp
-        ${HEADER_DIR}/internal/catch_interfaces_config.cpp
-        ${HEADER_DIR}/internal/catch_interfaces_exception.cpp
-        ${HEADER_DIR}/internal/catch_interfaces_registry_hub.cpp
-        ${HEADER_DIR}/internal/catch_interfaces_runner.cpp
-        ${HEADER_DIR}/internal/catch_interfaces_testcase.cpp
-        ${HEADER_DIR}/internal/catch_list.cpp
-        ${HEADER_DIR}/internal/catch_leak_detector.cpp
-        ${HEADER_DIR}/internal/catch_matchers.cpp
-        ${HEADER_DIR}/internal/catch_matchers_floating.cpp
-        ${HEADER_DIR}/internal/catch_matchers_generic.cpp
-        ${HEADER_DIR}/internal/catch_matchers_string.cpp
-        ${HEADER_DIR}/internal/catch_message.cpp
-        ${HEADER_DIR}/internal/catch_output_redirect.cpp
-        ${HEADER_DIR}/internal/catch_registry_hub.cpp
-        ${HEADER_DIR}/internal/catch_interfaces_reporter.cpp
-        ${HEADER_DIR}/internal/catch_random_number_generator.cpp
-        ${HEADER_DIR}/internal/catch_reporter_registry.cpp
-        ${HEADER_DIR}/internal/catch_result_type.cpp
-        ${HEADER_DIR}/internal/catch_run_context.cpp
-        ${HEADER_DIR}/internal/catch_section.cpp
-        ${HEADER_DIR}/internal/catch_section_info.cpp
-        ${HEADER_DIR}/internal/catch_session.cpp
-        ${HEADER_DIR}/internal/catch_startup_exception_registry.cpp
-        ${HEADER_DIR}/internal/catch_stream.cpp
-        ${HEADER_DIR}/internal/catch_stringref.cpp
-        ${HEADER_DIR}/internal/catch_string_manip.cpp
-        ${HEADER_DIR}/internal/catch_tag_alias.cpp
-        ${HEADER_DIR}/internal/catch_tag_alias_autoregistrar.cpp
-        ${HEADER_DIR}/internal/catch_tag_alias_registry.cpp
-        ${HEADER_DIR}/internal/catch_test_case_info.cpp
-        ${HEADER_DIR}/internal/catch_test_case_registry_impl.cpp
-        ${HEADER_DIR}/internal/catch_test_case_tracker.cpp
-        ${HEADER_DIR}/internal/catch_test_registry.cpp
-        ${HEADER_DIR}/internal/catch_test_spec.cpp
-        ${HEADER_DIR}/internal/catch_test_spec_parser.cpp
-        ${HEADER_DIR}/internal/catch_timer.cpp
-        ${HEADER_DIR}/internal/catch_tostring.cpp
-        ${HEADER_DIR}/internal/catch_totals.cpp
-        ${HEADER_DIR}/internal/catch_uncaught_exceptions.cpp
-        ${HEADER_DIR}/internal/catch_version.cpp
-        ${HEADER_DIR}/internal/catch_wildcard_pattern.cpp
-        ${HEADER_DIR}/internal/catch_xmlwriter.cpp
-        )
-set(INTERNAL_FILES ${IMPL_SOURCES} ${INTERNAL_HEADERS})
-CheckFileList(INTERNAL_FILES ${HEADER_DIR}/internal)
-
-# Please keep these ordered alphabetically
-set(REPORTER_HEADERS
-        ${HEADER_DIR}/reporters/catch_reporter_automake.hpp
-        ${HEADER_DIR}/reporters/catch_reporter_bases.hpp
-        ${HEADER_DIR}/reporters/catch_reporter_compact.h
-        ${HEADER_DIR}/reporters/catch_reporter_console.h
-        ${HEADER_DIR}/reporters/catch_reporter_junit.h
-        ${HEADER_DIR}/reporters/catch_reporter_listening.h
-        ${HEADER_DIR}/reporters/catch_reporter_tap.hpp
-        ${HEADER_DIR}/reporters/catch_reporter_teamcity.hpp
-        ${HEADER_DIR}/reporters/catch_reporter_xml.h
-        )
-set(REPORTER_SOURCES
-        ${HEADER_DIR}/reporters/catch_reporter_bases.cpp
-        ${HEADER_DIR}/reporters/catch_reporter_compact.cpp
-        ${HEADER_DIR}/reporters/catch_reporter_console.cpp
-        ${HEADER_DIR}/reporters/catch_reporter_junit.cpp
-        ${HEADER_DIR}/reporters/catch_reporter_listening.cpp
-        ${HEADER_DIR}/reporters/catch_reporter_xml.cpp
-        )
-set(REPORTER_FILES ${REPORTER_HEADERS} ${REPORTER_SOURCES})
-CheckFileList(REPORTER_FILES ${HEADER_DIR}/reporters)
-
-# Specify the headers, too, so CLion recognises them as project files
-set(HEADERS
-        ${TOP_LEVEL_HEADERS}
-        ${EXTERNAL_HEADERS}
-        ${INTERNAL_HEADERS}
-        ${REPORTER_HEADERS}
-        )
-
-# Provide some groupings for IDEs
-SOURCE_GROUP("Tests" FILES ${TEST_SOURCES})
-SOURCE_GROUP("Surrogates" FILES ${SURROGATE_SOURCES})
-
-
-# Projects consuming Catch via ExternalProject_Add might want to use install step
-# without building all of our selftests.
-
-if(DEFINED NO_SELFTEST)
-    message(DEPRECATION "*** CMake option NO_SELFTEST is deprecated; use BUILD_TESTING instead")
-    if (NO_SELFTEST)
-        set(BUILD_TESTING OFF CACHE BOOL "Disable Catch2 internal testsuite" FORCE)
-    else()
-        set(BUILD_TESTING ON CACHE BOOL "Disable Catch2 internal testsuite" FORCE)
+if (BUILD_TESTING AND CATCH_BUILD_TESTING AND NOT_SUBPROJECT)
+    find_package(PythonInterp)
+    if (NOT PYTHONINTERP_FOUND)
+        message(FATAL_ERROR "Python not found, but required for tests")
     endif()
+    add_subdirectory(projects)
 endif()
 
-include(CTest)
-
-if (BUILD_TESTING AND NOT_SUBPROJECT)
-    add_executable(SelfTest ${TEST_SOURCES} ${IMPL_SOURCES} ${REPORTER_SOURCES} ${SURROGATE_SOURCES} ${HEADERS})
-    target_include_directories(SelfTest PRIVATE ${HEADER_DIR})
-
-    if(USE_CPP14)
-        message(STATUS "Enabling C++14")
-        set_property(TARGET SelfTest PROPERTY CXX_STANDARD 14)
-    else()
-        message(STATUS "Enabling C++11")
-        set_property(TARGET SelfTest PROPERTY CXX_STANDARD 11)
-    endif()
-
-    set_property(TARGET SelfTest PROPERTY CXX_STANDARD_REQUIRED ON)
-    set_property(TARGET SelfTest PROPERTY CXX_EXTENSIONS OFF)
+if(CATCH_BUILD_EXAMPLES)
+    add_subdirectory(examples)
+endif()
 
-    if (CATCH_ENABLE_COVERAGE)
-        set(ENABLE_COVERAGE ON CACHE BOOL "Enable coverage build." FORCE)
-        list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
-        find_package(codecov)
-        add_coverage(SelfTest)
-        list(APPEND LCOV_REMOVE_PATTERNS "'/usr/*'")
-        coverage_evaluate()
-    endif()
+if(CATCH_BUILD_EXTRA_TESTS)
+    add_subdirectory(projects/ExtraTests)
+endif()
 
-    # Add per compiler options
-    if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" )
-        target_compile_options( SelfTest PRIVATE -Wall -Wextra -Wunreachable-code -Wpedantic)
-        if (CATCH_ENABLE_WERROR)
-            target_compile_options( SelfTest PRIVATE -Werror)
-        endif()
-    endif()
-    # Clang specific options go here
-    if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
-        target_compile_options( SelfTest PRIVATE -Wweak-vtables -Wexit-time-destructors -Wglobal-constructors -Wmissing-noreturn )
-    endif()
-    if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
-		STRING(REGEX REPLACE "/W[0-9]" "/W4" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) # override default warning level
-        target_compile_options( SelfTest PRIVATE /w44265 /w44061 /w44062 )
-        if (CATCH_ENABLE_WERROR)
-            target_compile_options( SelfTest PRIVATE /WX)
-        endif()
-        # Force MSVC to consider everything as encoded in utf-8
-        target_compile_options( SelfTest PRIVATE /utf-8 )
-    endif()
+# add catch as a 'linkable' target
+add_library(Catch2 INTERFACE)
+
+
+
+# depend on some obvious c++11 features so the dependency is transitively added dependents
+target_compile_features(Catch2
+  INTERFACE
+    cxx_alignas
+    cxx_alignof
+    cxx_attributes
+    cxx_auto_type
+    cxx_constexpr
+    cxx_defaulted_functions
+    cxx_deleted_functions
+    cxx_final
+    cxx_lambdas
+    cxx_noexcept
+    cxx_override
+    cxx_range_for
+    cxx_rvalue_references
+    cxx_static_assert
+    cxx_strong_enums
+    cxx_trailing_return_types
+    cxx_unicode_literals
+    cxx_user_literals
+    cxx_variadic_macros
+)
+
+target_include_directories(Catch2
+  INTERFACE
+    $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/single_include>
+    $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
+)
 
+# provide a namespaced alias for clients to 'link' against if catch is included as a sub-project
+add_library(Catch2::Catch2 ALIAS Catch2)
+
+# Only perform the installation steps when Catch is not being used as
+# a subproject via `add_subdirectory`, or the destinations will break,
+# see https://github.com/catchorg/Catch2/issues/1373
+if (NOT_SUBPROJECT)
+    set(CATCH_CMAKE_CONFIG_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Catch2")
+
+    configure_package_config_file(
+        ${CMAKE_CURRENT_LIST_DIR}/CMake/Catch2Config.cmake.in
+        ${CMAKE_CURRENT_BINARY_DIR}/Catch2Config.cmake
+        INSTALL_DESTINATION
+          ${CATCH_CMAKE_CONFIG_DESTINATION}
+    )
 
-    # configure unit tests via CTest
-    include(CTest)
-    add_test(NAME RunTests COMMAND $<TARGET_FILE:SelfTest>)
 
-    add_test(NAME ListTests COMMAND $<TARGET_FILE:SelfTest> --list-tests --verbosity high)
-    set_tests_properties(ListTests PROPERTIES 
-        PASS_REGULAR_EXPRESSION "[0-9]+ test cases"
-        FAIL_REGULAR_EXPRESSION "Hidden Test"
+    # create and install an export set for catch target as Catch2::Catch
+    install(
+      TARGETS
+        Catch2
+      EXPORT
+        Catch2Targets
+      DESTINATION
+        ${CMAKE_INSTALL_LIBDIR}
     )
 
-    add_test(NAME ListTags COMMAND $<TARGET_FILE:SelfTest> --list-tags)
-    set_tests_properties(ListTags PROPERTIES 
-        PASS_REGULAR_EXPRESSION "[0-9]+ tags" 
-        FAIL_REGULAR_EXPRESSION "[.]")
 
-    add_test(NAME ListReporters COMMAND $<TARGET_FILE:SelfTest> --list-reporters)
-    set_tests_properties(ListReporters PROPERTIES PASS_REGULAR_EXPRESSION "Available reporters:")
-
-    add_test(NAME ListTestNamesOnly COMMAND $<TARGET_FILE:SelfTest> --list-test-names-only)
-    set_tests_properties(ListTestNamesOnly PROPERTIES 
-        PASS_REGULAR_EXPRESSION "Regex string matcher"
-        FAIL_REGULAR_EXPRESSION "Hidden Test")
+    install(
+      EXPORT
+        Catch2Targets
+      NAMESPACE
+        Catch2::
+      DESTINATION
+        ${CATCH_CMAKE_CONFIG_DESTINATION}
+    )
 
-    add_test(NAME NoAssertions COMMAND $<TARGET_FILE:SelfTest> -w NoAssertions)
-    set_tests_properties(NoAssertions PROPERTIES PASS_REGULAR_EXPRESSION "No assertions in test case")
+    # By default, FooConfigVersion is tied to architecture that it was
+    # generated on. Because Catch2 is header-only, it is arch-independent
+    # and thus Catch2ConfigVersion should not be tied to the architecture
+    # it was generated on.
+    #
+    # CMake does not provide a direct customization point for this in
+    # `write_basic_package_version_file`, but it can be accomplished
+    # indirectly by temporarily undefining `CMAKE_SIZEOF_VOID_P`.
+    set(CATCH2_CMAKE_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P})
+    unset(CMAKE_SIZEOF_VOID_P)
+    write_basic_package_version_file(
+      "${CMAKE_CURRENT_BINARY_DIR}/Catch2ConfigVersion.cmake"
+      COMPATIBILITY
+        SameMajorVersion
+    )
+    set(CMAKE_SIZEOF_VOID_P ${CATCH2_CMAKE_SIZEOF_VOID_P})
 
-    add_test(NAME NoTest COMMAND $<TARGET_FILE:SelfTest> -w NoTests "___nonexistent_test___")
-    set_tests_properties(NoTest PROPERTIES PASS_REGULAR_EXPRESSION "No test cases matched")
+    install(
+      DIRECTORY
+        "single_include/"
+      DESTINATION
+        "${CMAKE_INSTALL_INCLUDEDIR}"
+    )
 
-    # AppVeyor has a Python 2.7 in path, but doesn't have .py files as autorunnable
-    add_test(NAME ApprovalTests COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/scripts/approvalTests.py $<TARGET_FILE:SelfTest>)
-    set_tests_properties(ApprovalTests PROPERTIES FAIL_REGULAR_EXPRESSION "Results differed")
+    install(
+      FILES
+        "${CMAKE_CURRENT_BINARY_DIR}/Catch2Config.cmake"
+        "${CMAKE_CURRENT_BINARY_DIR}/Catch2ConfigVersion.cmake"
+      DESTINATION
+        ${CATCH_CMAKE_CONFIG_DESTINATION}
+    )
 
-    if (CATCH_USE_VALGRIND)
-        add_test(NAME ValgrindRunTests COMMAND valgrind --leak-check=full --error-exitcode=1 $<TARGET_FILE:SelfTest>)
-        add_test(NAME ValgrindListTests COMMAND valgrind --leak-check=full --error-exitcode=1 $<TARGET_FILE:SelfTest> --list-tests --verbosity high)
-        set_tests_properties(ValgrindListTests PROPERTIES PASS_REGULAR_EXPRESSION "definitely lost: 0 bytes in 0 blocks")
-        add_test(NAME ValgrindListTags COMMAND valgrind --leak-check=full --error-exitcode=1 $<TARGET_FILE:SelfTest> --list-tags)
-        set_tests_properties(ValgrindListTags PROPERTIES PASS_REGULAR_EXPRESSION "definitely lost: 0 bytes in 0 blocks")
+    # Install documentation
+    if(CATCH_INSTALL_DOCS)
+      install(
+        DIRECTORY
+          docs/
+        DESTINATION
+          "${CMAKE_INSTALL_DOCDIR}"
+      )
     endif()
 
-endif() # !NO_SELFTEST
-
-
-if(CATCH_BUILD_EXAMPLES)
-    add_subdirectory(examples)
-endif()
-
-install(DIRECTORY "single_include/" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/catch")
-
-install(DIRECTORY docs/ DESTINATION "${CMAKE_INSTALL_DOCDIR}")
+    if(CATCH_INSTALL_HELPERS)
+    # Install CMake scripts
+    install(
+      FILES
+        "contrib/ParseAndAddCatchTests.cmake"
+        "contrib/Catch.cmake"
+        "contrib/CatchAddTests.cmake"
+      DESTINATION
+        ${CATCH_CMAKE_CONFIG_DESTINATION}
+    )
 
-## Provide some pkg-config integration
-# Don't bother on Windows
-if(NOT WIN32 OR NOT CMAKE_HOST_SYSTEM_NAME MATCHES Windows)
+    # Install debugger helpers
+    install(
+      FILES
+        "contrib/gdbinit"
+        "contrib/lldbinit"
+      DESTINATION
+        ${CMAKE_INSTALL_DATAROOTDIR}/Catch2
+    )
+    endif()
 
+    ## Provide some pkg-config integration
     set(PKGCONFIG_INSTALL_DIR
         "${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig"
-        CACHE PATH "Path where catch.pc is installed"
+        CACHE PATH "Path where catch2.pc is installed"
+    )
+    configure_file(
+      ${CMAKE_CURRENT_SOURCE_DIR}/CMake/catch2.pc.in
+      ${CMAKE_CURRENT_BINARY_DIR}/catch2.pc
+      @ONLY
+    )
+    install(
+      FILES
+        "${CMAKE_CURRENT_BINARY_DIR}/catch2.pc"
+      DESTINATION
+        ${PKGCONFIG_INSTALL_DIR}
     )
 
-    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/catch.pc.in ${CMAKE_CURRENT_BINARY_DIR}/catch.pc @ONLY)
-    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/catch.pc DESTINATION ${PKGCONFIG_INSTALL_DIR})
-
-endif()
-
-# add catch as a 'linkable' target
-add_library(Catch INTERFACE)
-
-# depend on some obvious c++11 features so the dependency is transitively added dependants
-target_compile_features(Catch INTERFACE cxx_auto_type cxx_constexpr cxx_noexcept)
-
-target_include_directories(Catch
-	INTERFACE
-		$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/single_include>
-		$<INSTALL_INTERFACE:include/catch>
-		$<INSTALL_INTERFACE:include>)
-
-# provide a namespaced alias for clients to 'link' against if catch is included as a sub-project
-add_library(Catch2::Catch ALIAS Catch)
-
-set(CATCH_CMAKE_CONFIG_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Catch2")
-
-# create and install an export set for catch target as Catch2::Catch
-install(TARGETS Catch EXPORT Catch2Config DESTINATION ${CMAKE_INSTALL_LIBDIR})
-
-install(EXPORT Catch2Config
-	NAMESPACE Catch2::
-	DESTINATION ${CATCH_CMAKE_CONFIG_DESTINATION})
-
-# install Catch2ConfigVersion.cmake file to handle versions in find_package
-include(CMakePackageConfigHelpers)
-
-write_basic_package_version_file(
-	"${CMAKE_CURRENT_BINARY_DIR}/Catch2ConfigVersion.cmake"
-	COMPATIBILITY SameMajorVersion)
-
-install(FILES
-	"${CMAKE_CURRENT_BINARY_DIR}/Catch2ConfigVersion.cmake"
-	DESTINATION ${CATCH_CMAKE_CONFIG_DESTINATION})
+endif(NOT_SUBPROJECT)
diff --git a/packages/Catch2/README.md b/packages/Catch2/README.md
index 7defcd5567594ea24f21c65812ac3268ee2b44f6..73162bbf498736c05f891e28df04248fa6c25d30 100644
--- a/packages/Catch2/README.md
+++ b/packages/Catch2/README.md
@@ -5,9 +5,11 @@
 [![Build Status](https://travis-ci.org/catchorg/Catch2.svg?branch=master)](https://travis-ci.org/catchorg/Catch2)
 [![Build status](https://ci.appveyor.com/api/projects/status/github/catchorg/Catch2?svg=true)](https://ci.appveyor.com/project/catchorg/catch2)
 [![codecov](https://codecov.io/gh/catchorg/Catch2/branch/master/graph/badge.svg)](https://codecov.io/gh/catchorg/Catch2)
-[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/u7qF77qgv9YqOr55)
+[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/E0msqwbW7U4PVbHn)
+[![Join the chat in Discord: https://discord.gg/4CWS9zD](https://img.shields.io/badge/Discord-Chat!-brightgreen.svg)](https://discord.gg/4CWS9zD)
 
-<a href="https://github.com/catchorg/Catch2/releases/download/v2.2.3/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
+
+<a href="https://github.com/catchorg/Catch2/releases/download/v2.4.1/catch.hpp">The latest version of the single header can be downloaded directly using this link</a>
 
 ## Catch2 is released!
 
@@ -32,5 +34,5 @@ This documentation comprises these three parts:
 
 ## More
 * Issues and bugs can be raised on the [Issue tracker on GitHub](https://github.com/catchorg/Catch2/issues)
-* For discussion or questions please use [the dedicated Google Groups forum](https://groups.google.com/forum/?fromgroups#!forum/catch-forum)
+* For discussion or questions please use [the dedicated Google Groups forum](https://groups.google.com/forum/?fromgroups#!forum/catch-forum) or our [Discord](https://discord.gg/4CWS9zD)
 * See [who else is using Catch2](docs/opensource-users.md#top)
diff --git a/packages/Catch2/appveyor.yml b/packages/Catch2/appveyor.yml
index 0e97589b570613cdc2d29cca5798d855af273cce..53f5b395c470e421934c90444c2e8fa1658605d8 100644
--- a/packages/Catch2/appveyor.yml
+++ b/packages/Catch2/appveyor.yml
@@ -33,8 +33,6 @@ environment:
 
 
 matrix:
-    allow_failures:
-        - os: Visual Studio 2017
     exclude:
         - os: Visual Studio 2015
           additional_flags: "/permissive- /std:c++latest"
diff --git a/packages/Catch2/catch.pc.in b/packages/Catch2/catch.pc.in
deleted file mode 100644
index c2496d29f41b347bfcf2317746b584798395ae8f..0000000000000000000000000000000000000000
--- a/packages/Catch2/catch.pc.in
+++ /dev/null
@@ -1,6 +0,0 @@
-includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
-
-Name: Catch
-Description: Testing library for C++
-Version: @Catch2_VERSION@
-Cflags: -I${includedir} -I${includedir}/catch
diff --git a/packages/Catch2/conanfile.py b/packages/Catch2/conanfile.py
index 716ca420ecb8f088ba82b509888bc6ef78f0a819..19b2c65e68bfb5f2d8378cb7108c2c494d599510 100644
--- a/packages/Catch2/conanfile.py
+++ b/packages/Catch2/conanfile.py
@@ -1,19 +1,31 @@
 #!/usr/bin/env python
-from conans import ConanFile
+from conans import ConanFile, CMake
 
 
 class CatchConan(ConanFile):
     name = "Catch"
-    version = "2.2.3"
+    version = "2.4.1"
     description = "A modern, C++-native, header-only, framework for unit-tests, TDD and BDD"
     author = "philsquared"
     generators = "cmake"
-    exports_sources = "single_include/*"
-    url = "https://github.com/philsquared/Catch"
+    # Only needed until conan 1.5 is released
+    settings = "compiler", "arch"
+    exports_sources = "single_include/*", "CMakeLists.txt", "CMake/catch2.pc.in", "LICENSE.txt"
+    url = "https://github.com/catchorg/Catch2"
     license = "Boost Software License - Version 1.0. http://www.boost.org/LICENSE_1_0.txt"
 
+    def build(self):
+        pass
+
     def package(self):
-        self.copy(pattern="catch.hpp", src="single_include", dst="include")
+        cmake = CMake(self)
+        cmake.definitions["BUILD_TESTING"] = "OFF"
+        cmake.definitions["CATCH_INSTALL_DOCS"] = "OFF"
+        cmake.definitions["CATCH_INSTALL_HELPERS"] = "ON"
+        cmake.configure()
+        cmake.install()
+
+        self.copy(pattern="LICENSE.txt", dst="licenses")
 
     def package_id(self):
-            self.info.header_only()
+        self.info.header_only()
diff --git a/packages/Catch2/contrib/ParseAndAddCatchTests.cmake b/packages/Catch2/contrib/ParseAndAddCatchTests.cmake
index cb2846d0a36afb8fd31d736e258c0162484b5b28..85c06a0dd93c5e80dea87564948d405b40ab0e33 100644
--- a/packages/Catch2/contrib/ParseAndAddCatchTests.cmake
+++ b/packages/Catch2/contrib/ParseAndAddCatchTests.cmake
@@ -143,6 +143,9 @@ function(ParseFile SourceFile TestTarget)
             endif()
             string(REPLACE "]" ";" Tags "${Tags}")
             string(REPLACE "[" "" Tags "${Tags}")
+        else()
+          # unset tags variable from previous loop
+          unset(Tags)
         endif()
 
         list(APPEND Labels ${Tags})
diff --git a/packages/Catch2/docs/Readme.md b/packages/Catch2/docs/Readme.md
index be7d1cd1244c697a340417cc74a542da662c7ecd..9087551816921b362ac463e5afb1418851ba489a 100644
--- a/packages/Catch2/docs/Readme.md
+++ b/packages/Catch2/docs/Readme.md
@@ -12,6 +12,7 @@ Writing tests:
 * [Test fixtures](test-fixtures.md#top)
 * [Reporters](reporters.md#top)
 * [Event Listeners](event-listeners.md#top)
+* [Data Generators](generators.md#top)
 
 Fine tuning:
 * [Supplying your own main()](own-main.md#top)
@@ -20,7 +21,10 @@ Fine tuning:
 
 Running:
 * [Command line](command-line.md#top)
-* [CI and Build system integration](build-systems.md#top)
+
+Odds and ends:
+* [CMake integration](cmake-integration.md#top)
+* [CI and other miscellaneous pieces](ci-and-misc.md#top)
 
 FAQ:
 * [Why are my tests slow to compile?](slow-compiles.md#top)
diff --git a/packages/Catch2/docs/assertions.md b/packages/Catch2/docs/assertions.md
index 90c0856cb3ea63aad9af63f4909b29de23af0070..900fd52c03d2a8a620a459d88653c84ac0c59bf7 100644
--- a/packages/Catch2/docs/assertions.md
+++ b/packages/Catch2/docs/assertions.md
@@ -55,33 +55,45 @@ This expression is too complex because of the `||` operator. If you want to chec
 
 When comparing floating point numbers - especially if at least one of them has been computed - great care must be taken to allow for rounding errors and inexact representations.
 
-Catch provides a way to perform tolerant comparisons of floating point values through use of a wrapper class called ```Approx```. ```Approx``` can be used on either side of a comparison expression. It overloads the comparisons operators to take a tolerance into account. Here's a simple example:
+Catch provides a way to perform tolerant comparisons of floating point values through use of a wrapper class called `Approx`. `Approx` can be used on either side of a comparison expression. It overloads the comparisons operators to take a tolerance into account. Here's a simple example:
 
-```
+```cpp
 REQUIRE( performComputation() == Approx( 2.1 ) );
 ```
 
-This way `Approx` is constructed with reasonable defaults, covering most simple cases of rounding errors. If these are insufficient, each `Approx` instance has 3 tuning knobs, that can be used to customize it for your computation.
+Catch also provides a UDL for `Approx`; `_a`. It resides in
+the `Catch::literals` namespace and can be used like so:
+```cpp
+using namespace Catch::literals;
+REQUIRE( performComputation() == 2.1_a );
+```
+
+`Approx` is constructed with defaults that should cover most simple cases.
+For the more complex cases, `Approx` provides 3 customization points:
 
-* __epsilon__ - epsilon serves to set the percentage by which a result can be erroneous, before it is rejected. By default set to `std::numeric_limits<float>::epsilon()*100`.
-* __margin__ - margin serves to set the the absolute value by which a result can be erroneous before it is rejected. By default set to `0.0`.
-* __scale__ - scale serves to adjust the epsilon's multiplicator. By default set to `0.0`.
+* __epsilon__ - epsilon serves to set the coefficient by which a result
+can differ from `Approx`'s value before it is rejected.
+_By default set to `std::numeric_limits<float>::epsilon()*100`._
+* __margin__ - margin serves to set the the absolute value by which
+a result can differ from `Approx`'s value before it is rejected.
+_By default set to `0.0`._
+* __scale__ - scale is used to change the magnitude of `Approx` for relative check.
+_By default set to `0.0`._
 
 #### epsilon example
 ```cpp
 Approx target = Approx(100).epsilon(0.01);
 100.0 == target; // Obviously true
 200.0 == target; // Obviously still false
-100.5 == target; // True, because we set target to allow up to 1% error
+100.5 == target; // True, because we set target to allow up to 1% difference
 ```
 
 #### margin example
-_Margin check is used only if the relative (epsilon and scale based) check fails._
 ```cpp
 Approx target = Approx(100).margin(5);
 100.0 == target; // Obviously true
 200.0 == target; // Obviously still false
-104.0 == target; // True, because we set target to allow absolute error up to 5
+104.0 == target; // True, because we set target to allow absolute difference of at most 5
 ```
 
 #### scale
diff --git a/packages/Catch2/docs/build-systems.md b/packages/Catch2/docs/ci-and-misc.md
similarity index 59%
rename from packages/Catch2/docs/build-systems.md
rename to packages/Catch2/docs/ci-and-misc.md
index 2873bc62ae40aaaa52ee4f484b0e057582e7802a..8c330872565517e4b21f2ad78a3fd096e6b1ae13 100644
--- a/packages/Catch2/docs/build-systems.md
+++ b/packages/Catch2/docs/ci-and-misc.md
@@ -1,6 +1,13 @@
 <a id="top"></a>
-# CI and build system integration
+# CI and other odd pieces
 
+**Contents**<br>
+[Continuous Integration systems](#continuous-integration-systems)<br>
+[Other reporters](#other-reporters)<br>
+[Low-level tools](#low-level-tools)<br>
+[CMake](#cmake)<br>
+
+This page talks about how Catch integrates with Continuous Integration 
 Build Systems may refer to low-level tools, like CMake, or larger systems that run on servers, like Jenkins or TeamCity. This page will talk about both.
 
 ## Continuous Integration systems
@@ -71,104 +78,30 @@ Catch offers prototypal support for being included in precompiled headers, but b
   * include "catch.hpp" again
 
 
-### CMake
-
-In general we recommend "vendoring" Catch's single-include releases inside your own repository. If you do this, the following example shows a minimal CMake project:
-```CMake
-cmake_minimum_required(VERSION 3.0)
-
-project(cmake_test)
-
-# 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)
-add_executable(tests ${TEST_SOURCES})
-target_link_libraries(tests Catch)
-```
-Note that it assumes that the path to the Catch's header is `catch/catch.hpp` from the `CMakeLists.txt` file.
-
-
-You can also use the following CMake snippet to automatically fetch the entire Catch repository from github and configure it as an external project:
-```CMake
-cmake_minimum_required(VERSION 2.8.8)
-project(catch_builder CXX)
-include(ExternalProject)
-find_package(Git REQUIRED)
-
-ExternalProject_Add(
-    catch
-    PREFIX ${CMAKE_BINARY_DIR}/catch
-    GIT_REPOSITORY https://github.com/philsquared/Catch.git
-    TIMEOUT 10
-    UPDATE_COMMAND ${GIT_EXECUTABLE} pull
-    CONFIGURE_COMMAND ""
-    BUILD_COMMAND ""
-    INSTALL_COMMAND ""
-    LOG_DOWNLOAD ON
-   )
-
-# Expose required variable (CATCH_INCLUDE_DIR) to parent scope
-ExternalProject_Get_Property(catch source_dir)
-set(CATCH_INCLUDE_DIR ${source_dir}/single_include CACHE INTERNAL "Path to include folder for Catch")
-```
-
-If you put it in, e.g., `${PROJECT_SRC_DIR}/${EXT_PROJECTS_DIR}/catch/`, you can use it in your project by adding the following to your root CMake file:
+### CodeCoverage module (GCOV, LCOV...)
 
-```CMake
-# Includes Catch in the project:
-add_subdirectory(${EXT_PROJECTS_DIR}/catch)
-include_directories(${CATCH_INCLUDE_DIR} ${COMMON_INCLUDES})
-enable_testing(true)  # Enables unit-testing.
-```
+If you are using GCOV tool to get testing coverage of your code, and are not sure how to integrate it with CMake and Catch, there should be an external example over at https://github.com/fkromer/catch_cmake_coverage
 
-The advantage of this approach is that you can always automatically update Catch to the latest release. The disadvantage is that it means bringing in lot more than you need.
 
+### pkg-config
 
-### Automatic test registration
-We provide 2 CMake scripts that can automatically register Catch-based
-tests with CTest,
-  * `contrib/ParseAndAddCatchTests.cmake`
-  * `contrib/CatchAddTests.cmake`
+Catch2 provides a rudimentary pkg-config integration, by registering itself
+under the name `catch2`. This means that after Catch2 is installed, you
+can use `pkg-config` to get its include path: `pkg-config --cflags catch2`.
 
-The first is based on parsing the test implementation files, and attempts
-to register all `TEST_CASE`s using their tags as labels. This means that
-these:
+### gdb and lldb scripts
 
-```cpp
-TEST_CASE("Test1", "[unit]") {
-    int a = 1;
-    int b = 2;
-    REQUIRE(a == b);
-}
-
-TEST_CASE("Test2") {
-    int a = 1;
-    int b = 2;
-    REQUIRE(a == b);
-}
-
-TEST_CASE("Test3", "[a][b][c]") {
-    int a = 1;
-    int b = 2;
-    REQUIRE(a == b);
-}
-```
-would be registered as 3 tests, `Test1`, `Test2` and `Test3`,
-and 4 CTest labels would be created, `a`, `b`, `c` and `unit`.
+Catch2's `contrib` folder also contains two simple debugger scripts,
+`gdbinit` for `gdb` and `lldbinit` for `lldb`. If loaded into their
+respective debugger, these will tell it to step over Catch2's internals
+when stepping through code.
 
 
-The second is based on parsing the output of a Catch binary given
-`--list-test-names-only`. This means that it deals with inactive
-(e.g. commented-out) tests better, but requires CMake 3.10 for full
-functionality.
+## CMake
 
-### CodeCoverage module (GCOV, LCOV...)
+[As it has been getting kinda long, the documentation of Catch2's
+integration with CMake has been moved to its own page.](cmake-integration.md#top)
 
-If you are using GCOV tool to get testing coverage of your code, and are not sure how to integrate it with CMake and Catch, there should be an external example over at https://github.com/fkromer/catch_cmake_coverage
 
 ---
 
diff --git a/packages/Catch2/docs/cmake-integration.md b/packages/Catch2/docs/cmake-integration.md
new file mode 100644
index 0000000000000000000000000000000000000000..a075c040f2ba7561b97cec8808f93c6e48acc11a
--- /dev/null
+++ b/packages/Catch2/docs/cmake-integration.md
@@ -0,0 +1,216 @@
+<a id="top"></a>
+# CMake integration
+
+**Contents**<br>
+[CMake target](#cmake-target)<br>
+[Automatic test registration](#automatic-test-registration)<br>
+[CMake project options](#cmake-project-options)<br>
+[Installing Catch2 from git repository](#installing-catch2-from-git-repository)<br>
+
+Because we use CMake to build Catch2, we also provide a couple of
+integration points for our users.
+
+1) Catch2 exports a (namespaced) CMake target
+2) Catch2's repository contains CMake scripts for automatic registration
+of `TEST_CASE`s in CTest
+
+## CMake target
+
+Catch2's CMake build exports an interface target `Catch2::Catch2`. Linking
+against it will add the proper include path and all necessary capabilities
+to the resulting binary.
+
+This means that if Catch2 has been installed on the system, it should be
+enough to do:
+```cmake
+find_package(Catch2 REQUIRED)
+target_link_libraries(tests Catch2::Catch2)
+```
+
+
+This target is also provided when Catch2 is used as a subdirectory.
+Assuming that Catch2 has been cloned to `lib/Catch2`:
+```cmake
+add_subdirectory(lib/Catch2)
+target_link_libraries(tests Catch2::Catch2)
+```
+
+## Automatic test registration
+
+Catch2's repository also contains two CMake scripts that help users
+with automatically registering their `TEST_CASE`s with CTest. They
+can be found in the `contrib` folder, and are
+
+1) `Catch.cmake` (and its dependency `CatchAddTests.cmake`)
+2) `ParseAndAddCatchTests.cmake`
+
+If Catch2 has been installed in system, both of these can be used after
+doing `find_package(Catch2 REQUIRED)`. Otherwise you need to add them
+to your CMake module path.
+
+### `Catch.cmake` and `AddCatchTests.cmake`
+
+`Catch.cmake` provides function `catch_discover_tests` to get tests from
+a target. This function works by running the resulting executable with
+`--list-test-names-only` flag, and then parsing the output to find all
+existing tests.
+
+#### Usage
+```cmake
+cmake_minimum_required(VERSION 3.5)
+
+project(baz LANGUAGES CXX VERSION 0.0.1)
+
+find_package(Catch2 REQUIRED)
+add_executable(foo test.cpp)
+target_link_libraries(foo Catch2::Catch2)
+
+include(CTest)
+include(Catch)
+catch_discover_tests(foo)
+```
+
+
+#### Customization
+`catch_discover_tests` can be given several extra argumets:
+```cmake
+catch_discover_tests(target
+                     [TEST_SPEC arg1...]
+                     [EXTRA_ARGS arg1...]
+                     [WORKING_DIRECTORY dir]
+                     [TEST_PREFIX prefix]
+                     [TEST_SUFFIX suffix]
+                     [PROPERTIES name1 value1...]
+                     [TEST_LIST var]
+)
+```
+
+* `TEST_SPEC arg1...`
+
+Specifies test cases, wildcarded test cases, tags and tag expressions to
+pass to the Catch executable alongside the `--list-test-names-only` flag.
+
+
+* `EXTRA_ARGS arg1...`
+
+Any extra arguments to pass on the command line to each test case.
+
+
+* `WORKING_DIRECTORY dir`
+
+Specifies the directory in which to run the discovered test cases.  If this
+option is not provided, the current binary directory is used.
+
+
+* `TEST_PREFIX prefix`
+
+Specifies a _prefix_ to be added to the name of each discovered test case.
+This can be useful when the same test executable is being used in multiple
+calls to `catch_discover_tests()`, with different `TEST_SPEC` or `EXTRA_ARGS`.
+
+
+* `TEST_SUFFIX suffix`
+
+Same as `TEST_PREFIX`, except it specific the _suffix_ for the test names.
+Both `TEST_PREFIX` and `TEST_SUFFIX` can be specified at the same time.
+
+
+* `PROPERTIES name1 value1...`
+
+Specifies additional properties to be set on all tests discovered by this
+invocation of `catch_discover_tests`.
+
+
+* `TEST_LIST var`
+
+Make the list of tests available in the variable `var`, rather than the
+default `<target>_TESTS`.  This can be useful when the same test
+executable is being used in multiple calls to `catch_discover_tests()`.
+Note that this variable is only available in CTest.
+
+
+### `ParseAndAddCatchTests.cmake`
+
+`ParseAndAddCatchTests` works by parsing all implementation files
+associated with the provided target, and registering them via CTest's
+`add_test`. This approach has some limitations, such as the fact that
+commented-out tests will be registered anyway.
+
+
+#### Usage
+
+```cmake
+cmake_minimum_required(VERSION 3.5)
+
+project(baz LANGUAGES CXX VERSION 0.0.1)
+
+find_package(Catch2 REQUIRED)
+add_executable(foo test.cpp)
+target_link_libraries(foo Catch2::Catch2)
+
+include(CTest)
+include(ParseAndAddCatchTests)
+ParseAndAddCatchTests(foo)
+```
+
+
+#### Customization
+
+`ParseAndAddCatchTests` provides some customization points:
+* `PARSE_CATCH_TESTS_VERBOSE` -- When `ON`, the script prints debug
+messages. Defaults to `OFF`.
+* `PARSE_CATCH_TESTS_NO_HIDDEN_TESTS` -- When `ON`, hidden tests (tests
+tagged with any of `[!hide]`, `[.]` or `[.foo]`) will not be registered.
+Defaults to `OFF`.
+* `PARSE_CATCH_TESTS_ADD_FIXTURE_IN_TEST_NAME` -- When `ON`, adds fixture
+class name to the test name in CTest. Defaults to `ON`.
+* `PARSE_CATCH_TESTS_ADD_TARGET_IN_TEST_NAME` -- When `ON`, adds target
+name to the test name in CTest. Defaults to `ON`.
+* `PARSE_CATCH_TESTS_ADD_TO_CONFIGURE_DEPENDS` -- When `ON`, adds test
+file to `CMAKE_CONFIGURE_DEPENDS`. This means that the CMake configuration
+step will be re-ran when the test files change, letting new tests be
+automatically discovered. Defaults to `OFF`.
+
+
+## CMake project options
+
+Catch2's CMake project also provides some options for other projects
+that consume it. These are
+
+* `CATCH_BUILD_TESTING` -- When `ON`, Catch2's SelfTest project will be
+built. Defaults to `ON`. Note that Catch2 also obeys `BUILD_TESTING` CMake
+variable, so _both_ of them need to be `ON` for the SelfTest to be built,
+and either of them can be set to `OFF` to disable building SelfTest.
+* `CATCH_BUILD_EXAMPLES` -- When `ON`, Catch2's usage examples will be
+built. Defaults to `OFF`.
+* `CATCH_INSTALL_DOCS` -- When `ON`, Catch2's documentation will be
+included in the installation. Defaults to `ON`.
+* `CATCH_INSTALL_HELPERS` -- When `ON`, Catch2's contrib folder will be
+included in the installation. Defaults to `ON`.
+* `BUILD_TESTING` -- When `ON` and the project is not used as a subproject,
+Catch2's test binary will be built. Defaults to `ON`.
+
+
+## Installing Catch2 from git repository
+
+If you cannot install Catch2 from a package manager (e.g. Ubuntu 16.04
+provides catch only in version 1.2.0) you might want to install it from
+the repository instead. Assuming you have enough rights, you can just
+install it to the default location, like so:
+```
+$ git clone https://github.com/catchorg/Catch2.git
+$ cd Catch2
+$ cmake -Bbuild -H. -DBUILD_TESTING=OFF
+$ sudo cmake --build build/ --target install
+```
+
+If you do not have superuser rights, you will also need to specify
+[CMAKE_INSTALL_PREFIX](https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX.html)
+when configuring the build, and then modify your calls to
+[find_package](https://cmake.org/cmake/help/latest/command/find_package.html)
+accordingly.
+
+
+---
+
+[Home](Readme.md#top)
diff --git a/packages/Catch2/docs/command-line.md b/packages/Catch2/docs/command-line.md
index 9a095a04d480ed4d18ef4239464335cb12092975..fc63fe87b7801f90a473cc9829f888d23cb57583 100644
--- a/packages/Catch2/docs/command-line.md
+++ b/packages/Catch2/docs/command-line.md
@@ -24,7 +24,7 @@
 [Usage](#usage)<br>
 [Specify the section to run](#specify-the-section-to-run)<br>
 [Filenames as tags](#filenames-as-tags)<br>
-[Override output colouring](#use-colour)<br>
+[Override output colouring](#override-output-colouring)<br>
 
 Catch works quite nicely without any command line options at all - but for those times when you want greater control the following options are available.
 Click one of the followings links to take you straight to that option - or scroll on to browse the available options.
@@ -124,7 +124,9 @@ The JUnit reporter is an xml format that follows the structure of the JUnit XML
 ## Breaking into the debugger
 <pre>-b, --break</pre>
 
-In some IDEs (currently XCode and Visual Studio) it is possible for Catch to break into the debugger on a test failure. This can be very helpful during debug sessions - especially when there is more than one path through a particular test.
+Under most debuggers Catch2 is capable of automatically breaking on a test
+failure. This allows the user to see the current state of the test during
+failure.
 
 <a id="showing-results-for-successful-tests"></a>
 ## Showing results for successful tests
diff --git a/packages/Catch2/docs/configuration.md b/packages/Catch2/docs/configuration.md
index 81bf292aa7b998075c7ccef9178155c0244cb6f2..db1ebc728382143736660e60ec18a39f7d37b4e8 100644
--- a/packages/Catch2/docs/configuration.md
+++ b/packages/Catch2/docs/configuration.md
@@ -3,15 +3,19 @@
 
 **Contents**<br>
 [main()/ implementation](#main-implementation)<br>
+[Reporter / Listener interfaces](#reporter--listener-interfaces)<br>
 [Prefixing Catch macros](#prefixing-catch-macros)<br>
 [Terminal colour](#terminal-colour)<br>
 [Console width](#console-width)<br>
 [stdout](#stdout)<br>
 [Fallback stringifier](#fallback-stringifier)<br>
 [Default reporter](#default-reporter)<br>
+[C++11 toggles](#c11-toggles)<br>
+[C++17 toggles](#c17-toggles)<br>
 [Other toggles](#other-toggles)<br>
 [Windows header clutter](#windows-header-clutter)<br>
 [Enabling stringification](#enabling-stringification)<br>
+[Disabling exceptions](#disabling-exceptions)<br>
 
 Catch is designed to "just work" as much as possible. For most people the only configuration needed is telling Catch which source file should host all the implementation code (```CATCH_CONFIG_MAIN```).
 
@@ -19,12 +23,12 @@ Nonetheless there are still some occasions where finer control is needed. For th
 
 ## main()/ implementation
 
-	CATCH_CONFIG_MAIN	// Designates this as implementation file and defines main()
-	CATCH_CONFIG_RUNNER	// Designates this as implementation file
+    CATCH_CONFIG_MAIN      // Designates this as implementation file and defines main()
+    CATCH_CONFIG_RUNNER    // Designates this as implementation file
 
 Although Catch is header only it still, internally, maintains a distinction between interface headers and headers that contain implementation. Only one source file in your test project should compile the implementation headers and this is controlled through the use of one of these macros - one of these identifiers should be defined before including Catch in *exactly one implementation file in your project*.
 
-# Reporter / Listener interfaces
+## Reporter / Listener interfaces
 
     CATCH_CONFIG_EXTERNAL_INTERFACES  // Brings in necessary headers for Reporter/Listener implementation
 
@@ -34,16 +38,16 @@ Implied by both `CATCH_CONFIG_MAIN` and `CATCH_CONFIG_RUNNER`.
 
 ## Prefixing Catch macros
 
-	CATCH_CONFIG_PREFIX_ALL
+    CATCH_CONFIG_PREFIX_ALL
 
 To keep test code clean and uncluttered Catch uses short macro names (e.g. ```TEST_CASE``` and ```REQUIRE```). Occasionally these may conflict with identifiers from platform headers or the system under test. In this case the above identifier can be defined. This will cause all the Catch user macros to be prefixed with ```CATCH_``` (e.g. ```CATCH_TEST_CASE``` and ```CATCH_REQUIRE```).
 
 
 ## Terminal colour
 
-	CATCH_CONFIG_COLOUR_NONE	// completely disables all text colouring
-	CATCH_CONFIG_COLOUR_WINDOWS	// forces the Win32 console API to be used
-	CATCH_CONFIG_COLOUR_ANSI	// forces ANSI colour codes to be used
+    CATCH_CONFIG_COLOUR_NONE      // completely disables all text colouring
+    CATCH_CONFIG_COLOUR_WINDOWS   // forces the Win32 console API to be used
+    CATCH_CONFIG_COLOUR_ANSI      // forces ANSI colour codes to be used
 
 Yes, I am English, so I will continue to spell "colour" with a 'u'.
 
@@ -57,22 +61,27 @@ Typically you should place the ```#define``` before #including "catch.hpp" in yo
 
 ## Console width
 
-	CATCH_CONFIG_CONSOLE_WIDTH = x // where x is a number
+    CATCH_CONFIG_CONSOLE_WIDTH = x // where x is a number
 
 Catch formats output intended for the console to fit within a fixed number of characters. This is especially important as indentation is used extensively and uncontrolled line wraps break this.
 By default a console width of 80 is assumed but this can be controlled by defining the above identifier to be a different value.
 
 ## stdout
 
-	CATCH_CONFIG_NOSTDOUT
+    CATCH_CONFIG_NOSTDOUT
 
-Catch does not use ```std::cout```, ```std::cerr``` and ```std::clog``` directly but gets them from ```Catch::cout()```, ```Catch::cerr()``` and ```Catch::clog``` respectively. If the above identifier is defined these functions are left unimplemented and you must implement them yourself. Their signatures are:
+To support platforms that do not provide `std::cout`, `std::cerr` and
+`std::clog`, Catch does not usem the directly, but rather calls
+`Catch::cout`, `Catch::cerr` and `Catch::clog`. You can replace their
+implementation by defining `CATCH_CONFIG_NOSTDOUT` and implementing
+them yourself, their signatures are:
 
     std::ostream& cout();
     std::ostream& cerr();
     std::ostream& clog();
 
-This can be useful on certain platforms that do not provide the standard iostreams, such as certain embedded systems.
+[You can see an example of replacing these functions here.](
+../examples/231-Cfg-OutputStreams.cpp)
 
 
 ## Fallback stringifier
@@ -118,6 +127,8 @@ Catch's selection, by defining either `CATCH_CONFIG_CPP11_TO_STRING` or
 ## C++17 toggles
 
     CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS  // Use std::uncaught_exceptions instead of std::uncaught_exception
+    CATCH_CONFIG_CPP17_STRING_VIEW          // Provide StringMaker specialization for std::string_view
+    CATCH_CONFIG_CPP17_VARIANT              // Override C++17 detection for CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
 
 Catch contains basic compiler/standard detection and attempts to use
 some C++17 features whenever appropriate. This automatic detection
@@ -153,11 +164,14 @@ these toggles can be disabled by using `_NO_` form of the toggle,
 e.g. `CATCH_CONFIG_NO_WINDOWS_SEH`.
 
 ### `CATCH_CONFIG_FAST_COMPILE`
-Defining this flag speeds up compilation of test files by ~20%, by making 2 changes:
-* The `-b` (`--break`) flag no longer makes Catch break into debugger in the same stack frame as the failed test, but rather in a stack frame *below*.
-* Non-exception family of macros ({`REQUIRE`,`CHECK`}{`_`,`_FALSE`, `_THAT`}, no longer use local try-catch block. This disables exception translation, but should not lead to false negatives.
+This compile-time flag speeds up compilation of assertion macros by ~20%,
+by disabling the generation of assertion-local try-catch blocks for
+non-exception family of assertion macros ({`REQUIRE`,`CHECK`}{``,`_FALSE`, `_THAT`}).
+This disables translation of exceptions thrown under these assertions, but
+should not lead to false negatives.
 
-`CATCH_CONFIG_FAST_COMPILE` has to be either defined, or not defined, in all translation units that are linked into single test binary, or the behaviour of setting `-b` flag and throwing unexpected exceptions will be unpredictable.
+`CATCH_CONFIG_FAST_COMPILE` has to be either defined, or not defined,
+in all translation units that are linked into single test binary.
 
 ### `CATCH_CONFIG_DISABLE_MATCHERS`
 When `CATCH_CONFIG_DISABLE_MATCHERS` is defined, all mentions of Catch's Matchers are ifdef-ed away from the translation unit. Doing so will speed up compilation of that TU.
@@ -189,9 +203,44 @@ By default, Catch does not stringify some types from the standard library. This
     CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER    // Provide StringMaker specialization for std::pair
     CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER   // Provide StringMaker specialization for std::tuple
     CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER  // Provide StringMaker specialization for std::chrono::duration, std::chrono::timepoint
+    CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER // Provide StringMaker specialization for std::variant, std::monostate (on C++17)
     CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS    // Defines all of the above
 
 
+## Disabling exceptions
+
+By default, Catch2 uses exceptions to signal errors and to abort tests
+when an assertion from the `REQUIRE` family of assertions fails. We also
+provide an experimental support for disabling exceptions. Catch2 should
+automatically detect when it is compiled with exceptions disabled, but
+it can be forced to compile without exceptions by defining
+
+    CATCH_CONFIG_DISABLE_EXCEPTIONS
+
+Note that when using Catch2 without exceptions, there are 2 major
+limitations:
+
+1) If there is an error that would normally be signalled by an exception,
+the exception's message will instead be written to `Catch::cerr` and
+`std::terminate` will be called.
+2) If an assertion from the `REQUIRE` family of macros fails,
+`std::terminate` will be called after the active reporter returns.
+
+
+There is also a customization point for the exact behaviour of what
+happens instead of exception being thrown. To use it, define
+
+    CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER
+
+and provide a definition for this function:
+
+```cpp
+namespace Catch {
+    [[noreturn]]
+    void throw_exception(std::exception const&);
+}
+```
+
 ---
 
 [Home](Readme.md#top)
diff --git a/packages/Catch2/docs/generators.md b/packages/Catch2/docs/generators.md
new file mode 100644
index 0000000000000000000000000000000000000000..40b42004e39c82c26e5b04c838b8cd58a837dd64
--- /dev/null
+++ b/packages/Catch2/docs/generators.md
@@ -0,0 +1,50 @@
+<a id="top"></a>
+# Data Generators
+
+_Generators are currently considered an experimental feature and their
+API can change between versions freely._
+
+Data generators (also known as _data driven/parametrized test cases_)
+let you reuse the same set of assertions across different input values.
+In Catch2, this means that they respect the ordering and nesting
+of the `TEST_CASE` and `SECTION` macros.
+
+How does combining generators and test cases work might be better
+explained by an example:
+
+```cpp
+TEST_CASE("Generators") {
+    auto i = GENERATE( range(1, 11) );
+
+    SECTION( "Some section" ) {
+        auto j = GENERATE( range( 11, 21 ) );
+        REQUIRE(i < j);
+    }
+}
+```
+
+the assertion will be checked 100 times, because there are 10 possible
+values for `i` (1, 2, ..., 10) and for each of them, there are 10 possible
+values for `j` (11, 12, ..., 20).
+
+You can also combine multiple generators by concatenation:
+```cpp
+static int square(int x) { return x * x; }
+TEST_CASE("Generators 2") {
+    auto i = GENERATE(0, 1, -1, range(-20, -10), range(10, 20));
+    CAPTURE(i);
+    REQUIRE(square(i) >= 0);
+}
+```
+
+This will call `square` with arguments `0`, `1`, `-1`, `-20`, ..., `-11`,
+`10`, ..., `19`.
+
+----------
+
+Because of the experimental nature of the current Generator implementation,
+we won't list all of the first-party generators in Catch2. Instead you
+should look at our current usage tests in
+[projects/SelfTest/UsageTests/Generators.tests.cpp](/projects/SelfTest/UsageTests/Generators.tests.cpp).
+For implementing your own generators, you can look at their implementation in
+[include/internal/catch_generators.hpp](/include/internal/catch_generators.hpp).
diff --git a/packages/Catch2/docs/limitations.md b/packages/Catch2/docs/limitations.md
index 9acade0e1cd08974f35ca955a1d2422b9f74c3dd..b95cd87f2c4511cc62ecc506ae28a65a5ba5cea9 100644
--- a/packages/Catch2/docs/limitations.md
+++ b/packages/Catch2/docs/limitations.md
@@ -1,12 +1,19 @@
 <a id="top"></a>
 # Known limitations
 
-Catch has some known limitations, that we are not planning to change. Some of these are caused by our desire to support C++98 compilers, some of these are caused by our desire to keep Catch crossplatform, some exist because their priority is seen as low compared to the development effort they would need and some other yet are compiler/runtime bugs.
+Over time, some limitations of Catch2 emerged. Some of these are due
+to implementation details that cannot be easily changed, some of these
+are due to lack of development resources on our part, and some of these
+are due to plain old 3rd party bugs.
+
 
 ## Implementation limits
 ### Sections nested in loops
 
-If you are using `SECTION`s inside loops, you have to create them with different name per loop's iteration. The recommended way to do so is to incorporate the loop's counter into section's name, like so
+If you are using `SECTION`s inside loops, you have to create them with
+different name per loop's iteration. The recommended way to do so is to
+incorporate the loop's counter into section's name, like so:
+
 ```cpp
 TEST_CASE( "Looped section" ) {
     for (char i = '0'; i < '5'; ++i) {
@@ -17,11 +24,34 @@ TEST_CASE( "Looped section" ) {
 }
 ```
 
+or with a `DYNAMIC_SECTION` macro (that was made for exactly this purpose):
+
+```cpp
+TEST_CASE( "Looped section" ) {
+    for (char i = '0'; i < '5'; ++i) {
+        DYNAMIC_SECTION( "Looped section " << i) {
+            SUCCEED( "Everything is OK" );
+        }
+    }
+}
+```
+
+### Tests might be run again if last section fails
+
+If the last section in a test fails, it might be run again. This is because
+Catch2 discovers `SECTION`s dynamically, as they are about to run, and
+if the last section in test case is aborted during execution (e.g. via
+the `REQUIRE` family of macros), Catch2 does not know that there are no
+more sections in that test case and must run the test case again.
+
+
 ## Features
 This section outlines some missing features, what is their status and their possible workarounds.
 
 ### Thread safe assertions
-Because threading support in standard C++98 is limited (well, non-existent), assertion macros in Catch are not thread safe. This does not mean that you cannot use threads inside Catch's test, but that only single thread can interact with Catch's assertions and other macros.
+Catch2's assertion macros are not thread safe. This does not mean that
+you cannot use threads inside Catch's test, but that only single thread
+can interact with Catch's assertions and other macros.
 
 This means that this is ok
 ```cpp
@@ -49,8 +79,8 @@ because only one thread passes the `REQUIRE` macro and this is not
     REQUIRE(cnt == 16);
 ```
 
-
-_This limitation is highly unlikely to be lifted before Catch 2 is released._
+Because C++11 provides the necessary tools to do this, we are planning
+to remove this limitation in the future.
 
 ### Process isolation in a test
 Catch does not support running tests in isolated (forked) processes. While this might in the future, the fact that Windows does not support forking and only allows full-on process creation and the desire to keep code as similar as possible across platforms, mean that this is likely to take significant development time, that is not currently available.
@@ -135,3 +165,14 @@ If you are seeing a problem like this, i.e. a weird test paths that trigger only
 This is a bug in `libstdc++-4.8`, where all matching methods from `<regex>` return false. Since `Matches` uses `<regex>` internally, if the underlying implementation does not work, it doesn't work either.
 
 Workaround: Use newer version of `libstdc++`.
+
+
+### libstdc++, `_GLIBCXX_DEBUG` macro and random ordering of tests
+
+Running a Catch2 binary compiled against libstdc++ with `_GLIBCXX_DEBUG`
+macro defined with `--order rand` will cause a debug check to trigger and
+abort the run due to self-assignment.
+[This is a known bug inside libstdc++](https://stackoverflow.com/questions/22915325/avoiding-self-assignment-in-stdshuffle/23691322)
+
+Workaround: Don't use `--order rand` when compiling against debug-enabled
+libstdc++.
diff --git a/packages/Catch2/docs/list-of-examples.md b/packages/Catch2/docs/list-of-examples.md
index 81f5a903f067dbc5a18e24bcef39ff7d43a02388..5b538da032338aaa544c6be18ac00a2c214203f8 100644
--- a/packages/Catch2/docs/list-of-examples.md
+++ b/packages/Catch2/docs/list-of-examples.md
@@ -3,14 +3,17 @@
 
 ## Already available
 
+- Catch main: [Catch-provided main](../examples/000-CatchMain.cpp)
 - Test Case: [Single-file](../examples/010-TestCase.cpp)
-- Test Case: [Multiple-file 1](../examples/020-TestCase-1.cpp), [2](../examples/020-TestCase-1.cpp)
+- Test Case: [Multiple-file 1](../examples/020-TestCase-1.cpp), [2](../examples/020-TestCase-2.cpp)
 - Assertion: [REQUIRE, CHECK](../examples/030-Asn-Require-Check.cpp)
 - Fixture: [Sections](../examples/100-Fix-Section.cpp)
 - Fixture: [Class-based fixtures](../examples/110-Fix-ClassFixture.cpp)
 - BDD: [SCENARIO, GIVEN, WHEN, THEN](../examples/120-Bdd-ScenarioGivenWhenThen.cpp)
+- Report: [Catch-provided main](../examples/200-Rpt-CatchMain.cpp)
+- Report: [TeamCity reporter](../examples/207-Rpt-TeamCityReporter.cpp)
 - Listener: [Listeners](../examples/210-Evt-EventListeners.cpp)
-
+- Configuration: [Provide your own output streams](../examples/231-Cfg-OutputStreams.cpp)
 
 ## Planned
 
@@ -27,7 +30,10 @@
 - Logging: [FAIL, FAIL_CHECK - Issue message and force failure/continue](../examples/170-Log-Fail.cpp)
 - Logging: [SUCCEED - Issue message and continue](../examples/180-Log-Succeed.cpp)
 - Report: [User-defined type](../examples/190-Rpt-ReportUserDefinedType.cpp)
-- Report: [Reporter](../examples/200-Rpt-UserDefinedReporter.cpp)
+- Report: [User-defined reporter](../examples/202-Rpt-UserDefinedReporter.cpp)
+- Report: [Automake reporter](../examples/205-Rpt-AutomakeReporter.cpp)
+- Report: [TAP reporter](../examples/206-Rpt-TapReporter.cpp)
+- Report: [Multiple reporter](../examples/208-Rpt-MultipleReporters.cpp)
 - Configuration: [Provide your own main()](../examples/220-Cfg-OwnMain.cpp)
 - Configuration: [Compile-time configuration](../examples/230-Cfg-CompileTimeConfiguration.cpp)
 - Configuration: [Run-time configuration](../examples/240-Cfg-RunTimeConfiguration.cpp)
diff --git a/packages/Catch2/docs/logging.md b/packages/Catch2/docs/logging.md
index 7ae54aab592ae004bd45c8b505d5334019f7d374..39ae5c7ac32dd8e8640b3a56880bab6c088b2b8b 100644
--- a/packages/Catch2/docs/logging.md
+++ b/packages/Catch2/docs/logging.md
@@ -72,12 +72,6 @@ This would log something like:
 
 <pre>"theAnswer := 42"</pre>
 
-## Deprecated macros
-
-**SCOPED_INFO and SCOPED_CAPTURE**
-
-These macros are now deprecated and are just aliases for INFO and CAPTURE (which were not previously scoped).
-
 ---
 
 [Home](Readme.md#top)
diff --git a/packages/Catch2/docs/opensource-users.md b/packages/Catch2/docs/opensource-users.md
index 86ab82fe4c968130bad49ba3facd0846e974ed63..25e5a437b0538be030ab0d4c83360ae2da330f2a 100644
--- a/packages/Catch2/docs/opensource-users.md
+++ b/packages/Catch2/docs/opensource-users.md
@@ -36,7 +36,7 @@ The next-generation core storage and query engine for Couchbase Lite
 A High-performance Cluster Computing Engine
 
 ### [forest](https://github.com/xorz57/forest)
-Forest is an open-source, template library of tree data structures written in C++11.
+Template Library of Tree Data Structures
 
 ### [Fuxedo](https://github.com/fuxedo/fuxedo)
 Open source Oracle Tuxedo-like XATMI middleware for C and C++.
@@ -71,6 +71,9 @@ A C++ client library for Consul. Consul is a distributed tool for discovering an
 ### [Reactive-Extensions/ RxCpp](https://github.com/Reactive-Extensions/RxCpp)
 A library of algorithms for values-distributed-in-time
 
+### [thor](https://github.com/xorz57/thor)
+Wrapper Library for CUDA
+
 ### [TextFlowCpp](https://github.com/philsquared/textflowcpp)
 A small, single-header-only, library for wrapping and composing columns of text
 
diff --git a/packages/Catch2/docs/own-main.md b/packages/Catch2/docs/own-main.md
index c74f9f14e913f68208ee72fca725809e18bed493..6a9b1aadc7ab31ff3923adbf3ef3daf14d05bdb7 100644
--- a/packages/Catch2/docs/own-main.md
+++ b/packages/Catch2/docs/own-main.md
@@ -1,6 +1,12 @@
 <a id="top"></a>
 # Supplying main() yourself
 
+**Contents**<br>
+[Let Catch take full control of args and config](#let-catch-take-full-control-of-args-and-config)<br>
+[Amending the config](#amending-the-config)<br>
+[Adding your own command line options](#adding-your-own-command-line-options)<br>
+[Version detection](#version-detection)<br>
+
 The easiest way to use Catch is to let it supply ```main()``` for you and handle configuring itself from the command line.
 
 This is achieved by writing ```#define CATCH_CONFIG_MAIN``` before the ```#include "catch.hpp"``` in *exactly one* source file.
@@ -45,7 +51,7 @@ int main( int argc, char* argv[] )
     
   int returnCode = session.applyCommandLine( argc, argv );
   if( returnCode != 0 ) // Indicates a command line error
-  	  return returnCode;
+        return returnCode;
  
   // writing to session.configData() or session.Config() here 
   // overrides command line args
@@ -94,7 +100,7 @@ int main( int argc, char* argv[] )
   // Let Catch (using Clara) parse the command line
   int returnCode = session.applyCommandLine( argc, argv );
   if( returnCode != 0 ) // Indicates a command line error
-  	return returnCode;
+      return returnCode;
 
   // if set on the command line then 'height' is now set at this point
   if( height > 0 )
diff --git a/packages/Catch2/docs/release-notes.md b/packages/Catch2/docs/release-notes.md
index 6ebe4d03d0d85138a720383676b6373c9fc6c22c..f31f0e8760762908299d78e4bbab0318adf4b686 100644
--- a/packages/Catch2/docs/release-notes.md
+++ b/packages/Catch2/docs/release-notes.md
@@ -1,11 +1,103 @@
 <a id="top"></a>
 
-# 2.2.3
+# Release notes
+**Contents**<br>
+[2.4.1](#241)<br>
+[2.4.0](#240)<br>
+[2.3.0](#230)<br>
+[2.2.3](#223)<br>
+[2.2.2](#222)<br>
+[2.2.1](#221)<br>
+[2.2.0](#220)<br>
+[2.1.2](#212)<br>
+[2.1.1](#211)<br>
+[2.1.0](#210)<br>
+[2.0.1](#201)<br>
+[Older versions](#older-versions)<br>
+[Even Older versions](#even-older-versions)<br>
+
+
+## 2.4.1
+
+### Improvements
+* Added a StringMaker for `std::(w)string_view` (#1375, #1376)
+* Added a StringMaker for `std::variant` (#1380)
+  * This one is disabled by default to avoid increased compile-time drag
+* Added detection for cygwin environment without `std::to_string` (#1396, #1397)
+
+### Fixes
+* `UnorderedEqualsMatcher` will no longer accept erroneously accept
+vectors that share suffix, but are not permutation of the desired vector
+* Abort after (`-x N`) can no longer be overshot by nested `REQUIRES` and
+subsequently ignored (#1391, #1392)
+
+
+## 2.4.0
+
+**This release brings two new experimental features, generator support
+and a `-fno-exceptions` support. Being experimental means that they
+will not be subject to the usual stability guarantees provided by semver.**
+
+### Improvements
+* Various small runtime performance improvements
+* `CAPTURE` macro is now variadic
+* Added `AND_GIVEN` macro (#1360)
+* Added experimental support for data generators
+  * See [their documentation](generators.md) for details
+* Added support for compiling and running Catch without exceptions
+  * Doing so limits the functionality somewhat
+  * Look [into the documentation](configuration.md#disablingexceptions) for details
+
+### Fixes
+* Suppressed `-Wnon-virtual-dtor` warnings in Matchers (#1357)
+* Suppressed `-Wunreachable-code` warnings in floating point matchers (#1350)
+
+### CMake
+* It is now possible to override which Python is used to run Catch's tests (#1365)
+* Catch now provides infrastructure for adding tests that check compile-time configuration
+* Catch no longer tries to install itself when used as a subproject (#1373)
+* Catch2ConfigVersion.cmake is now generated as arch-independent (#1368)
+  * This means that installing Catch from 32-bit machine and copying it to 64-bit one works
+  * This fixes conan installation of Catch
+
+
+## 2.3.0
+
+**This release changes the include paths provided by our CMake and
+pkg-config integration. The proper include path for the single-header
+when using one of the above is now `<catch2/catch.hpp>`. This change
+also necessitated changes to paths inside the repository, so that the
+single-header version is now at `single_include/catch2/catch.hpp`, rather
+than `single_include/catch.hpp`.**
+
+
+
+### Fixes
+* Fixed Objective-C++ build
+* `-Wunused-variable` suppression no longer leaks from Catch's header under Clang
+* Implementation of the experimental new output capture can now be disabled (#1335)
+  * This allows building Catch2 on platforms that do not provide things like `dup` or `tmpfile`.
+* The JUnit and XML reporters will no longer skip over successful tests when running without `-s`  (#1264, #1267, #1310)
+  * See improvements for more details
+
+### Improvements
+* pkg-config and CMake integration has been rewritten
+  * If you use them, the new include path is `#include <catch2/catch.hpp>`
+  * CMake installation now also installs scripts from `contrib/`
+  * For details see the [new documentation](cmake-integration.md#top)
+* Reporters now have a new customization point, `ReporterPreferences::shouldReportAllAssertions`
+  * When this is set to `false` and the tests are run without `-s`, passing assertions are not sent to the reporter.
+  * Defaults to `false`.
+* Added `DYNAMIC_SECTION`, a section variant that constructs its name using stream
+  * This means that you can do `DYNAMIC_SECTION("For X := " << x)`.
+
+
+## 2.2.3
 
 **To fix some of the bugs, some behavior had to change in potentially breaking manner.**
 **This means that even though this is a patch release, it might not be a drop-in replacement.**
 
-## Fixes
+### Fixes
 * Listeners are now called before reporter
   * This was always documented to be the case, now it actually works that way
 * Catch's commandline will no longer accept multiple reporters
@@ -24,23 +116,23 @@
   * **This has potential to be a breaking change**
 * Fixed compilation error when a type has an `operator<<` with templated lhs (#1285, #1306)
 
-## Improvements
+### Improvements
 * Added a new, experimental, output capture (#1243)
   * This capture can also redirect output written via C apis, e.g. `printf`
   * To opt-in, define `CATCH_CONFIG_EXPERIMENTAL_REDIRECT` in the implementation file
 * Added a new fallback stringifier for classes derived from `std::exception`
   * Both `StringMaker` specialization and `operator<<` overload are given priority
 
-## Miscellaneous
+### Miscellaneous
 * `contrib/` now contains dbg scripts that skip over Catch's internals (#904, #1283)
   * `gdbinit` for gdb `lldbinit` for lldb
 * `CatchAddTests.cmake` no longer strips whitespace from tests (#1265, #1281)
 * Online documentation now describes `--use-colour` option (#1263)
 
 
-# 2.2.2
+## 2.2.2
 
-## Fixes
+### Fixes
 * Fixed bug in `WithinAbs::match()` failing spuriously (#1228)
 * Fixed clang-tidy diagnostic about virtual call in destructor (#1226)
 * Reduced the number of GCC warnings suppression leaking out of the header (#1090, #1091)
@@ -49,7 +141,7 @@
   * On platforms where `std::chrono::high_resolution_clock`'s resolution is low, the calibration would appear stuck
 * Fixed compilation error when stringifying static arrays of `unsigned char`s (#1238)
 
-## Improvements
+### Improvements
 * XML encoder now hex-encodes invalid UTF-8 sequences (#1207)
   * This affects xml and junit reporters
   * Some invalid UTF-8 parts are left as is, e.g. surrogate pairs. This is because certain extensions of UTF-8 allow them, such as WTF-8.
@@ -58,29 +150,29 @@
 * Added `PredicateMatcher`, a matcher that takes an arbitrary predicate function (#1236)
   * See [documentation for details](https://github.com/catchorg/Catch2/blob/master/docs/matchers.md)
 
-## Others
+### Others
 * Modified CMake-installed pkg-config to allow `#include <catch.hpp>`(#1239)
   * The plans to standardize on `#include <catch2/catch.hpp>` are still in effect
 
 
-# 2.2.1
+## 2.2.1
 
-## Fixes
+### Fixes
 * Fixed compilation error when compiling Catch2 with `std=c++17` against libc++ (#1214)
   * Clara (Catch2's CLI parsing library) used `std::optional` without including it explicitly
 * Fixed Catch2 return code always being 0 (#1215)
   * In the words of STL, "We feel superbad about letting this in"
 
 
-# 2.2.0
+## 2.2.0
 
-## Fixes
+### Fixes
 * Hidden tests are not listed by default when listing tests (#1175)
   * This makes `catch_discover_tests` CMake script work better
 * Fixed regression that meant `<windows.h>` could potentially not be included properly (#1197)
 * Fixed installing `Catch2ConfigVersion.cmake` when Catch2 is a subproject.
 
-## Improvements
+### Improvements
 * Added an option to warn (+ exit with error) when no tests were ran (#1158)
   * Use as `-w NoTests`
 * Added provisional support for Emscripten (#1114)
@@ -92,38 +184,38 @@
 * Added support for DJGPP DOS crosscompiler (#1206)
 
 
-# 2.1.2
+## 2.1.2
 
-## Fixes
+### Fixes
 * Fixed compilation error with `-fno-rtti` (#1165)
 * Fixed NoAssertion warnings
 * `operator<<` is used before range-based stringification (#1172)
 * Fixed `-Wpedantic` warnings (extra semicolons and binary literals) (#1173)
 
 
-## Improvements
+### Improvements
 * Added `CATCH_VERSION_{MAJOR,MINOR,PATCH}` macros (#1131)
 * Added `BrightYellow` colour for use in reporters (#979)
   * It is also used by ConsoleReporter for reconstructed expressions
 
-## Other changes
+### Other changes
 * Catch is now exported as a CMake package and linkable target (#1170)
 
-# 2.1.1
+## 2.1.1
 
-## Improvements
+### Improvements
 * Static arrays are now properly stringified like ranges across MSVC/GCC/Clang
 * Embedded newer version of Clara -- v1.1.1
   * This should fix some warnings dragged in from Clara
 * MSVC's CLR exceptions are supported
 
 
-## Fixes
+### Fixes
 * Fixed compilation when comparison operators do not return bool (#1147)
 * Fixed CLR exceptions blowing up the executable during translation (#1138)
 
 
-## Other changes
+### Other changes
 * Many CMake changes
   * `NO_SELFTEST` option is deprecated, use `BUILD_TESTING` instead.
   * Catch specific CMake options were prefixed with `CATCH_` for namespacing purposes
@@ -131,9 +223,9 @@
 
 
 
-# 2.1.0
+## 2.1.0
 
-## Improvements
+### Improvements
 * Various performance improvements
   * On top of the performance regression fixes
 * Experimental support for PCH was added (#1061)
@@ -143,7 +235,7 @@
   * Bugs in g++ 4.x and 5.x mean that some of them have to be left in
 
 
-## Fixes
+### Fixes
 * Fixed performance regression from Catch classic
   * One of the performance improvement patches for Catch classic was not applied to Catch2
 * Fixed platform detection for iOS (#1084)
@@ -156,7 +248,7 @@
 * Fixed `std::uncaught_exception` deprecation warning (#1124)
 
 
-## New features
+### New features
 * New Matchers
   * Regex matcher for strings, `Matches`.
   * Set-equal matcher for vectors, `UnorderedEquals`
@@ -165,15 +257,15 @@
   * Containers are objects that respond to ADL `begin(T)` and `end(T)`.
 
 
-## Other changes
+### Other changes
 * Reporters will now be versioned in the `single_include` folder to ensure their compatibility with the last released version
 
 
 
 
-# 2.0.1
+## 2.0.1
 
-## Breaking changes
+### Breaking changes
 * Removed C++98 support
 * Removed legacy reporter support
 * Removed legacy generator support
@@ -203,7 +295,7 @@
   * `INFINITY == Approx(INFINITY)` returns true
 
 
-## Improvements
+### Improvements
 * Reporters and Listeners can be defined in files different from the main file
   * The file has to define `CATCH_CONFIG_EXTERNAL_INTERFACES` before including catch.hpp.
 * Errors that happen during set up before main are now caught and properly reported once main is entered
@@ -237,7 +329,7 @@
 * Add `pkg-config` support to CMake install command
 
 
-## Fixes
+### Fixes
 * Don't use console colour if running in XCode
 * Explicit constructor in reporter base class
 * Swept out `-Wweak-vtables`, `-Wexit-time-destructors`, `-Wglobal-constructors` warnings
@@ -249,7 +341,7 @@
 * Suppressed C4061 warning under MSVC
 
 
-## Internal changes
+### Internal changes
 * The development version now uses .cpp files instead of header files containing implementation.
   * This makes partial rebuilds much faster during development
 * The expression decomposition layer has been rewritten
@@ -257,13 +349,33 @@
 * New library (TextFlow) is used for formatting text to output
 
 
-# Older versions
+## Older versions
 
-## 1.11.x
+### 1.12.x
 
-### 1.11.0
+#### 1.12.2
+##### Fixes
+* Fixed missing <cassert> include
 
-#### Fixes
+#### 1.12.1
+
+##### Fixes
+* Fixed deprecation warning in `ScopedMessage::~ScopedMessage`
+* All uses of `min` or `max` identifiers are now wrapped in parentheses
+  * This avoids problems when Windows headers define `min` and `max` macros
+
+#### 1.12.0
+
+##### Fixes
+* Fixed compilation for strict C++98 mode (ie not gnu++98) and older compilers (#1103)
+* `INFO` messages are included in the `xml` reporter output even without `-s` specified.
+
+
+### 1.11.x
+
+#### 1.11.0
+
+##### Fixes
 * The original expression in `REQUIRE_FALSE( expr )` is now reporter properly as `!( expr )` (#1051)
   * Previously the parentheses were missing and `x != y` would be expanded as `!x != x`
 * `Approx::Margin` is now inclusive (#952)
@@ -271,7 +383,7 @@
   * This means that `REQUIRE( 0.25f == Approx( 0.0f ).margin( 0.25f ) )` passes, instead of fails
 * `RandomNumberGenerator::result_type` is now unsigned (#1050)
 
-#### Improvements
+##### Improvements
 * `__JETBRAINS_IDE__` macro handling is now CLion version specific (#1017)
   * When CLion 2017.3 or newer is detected, `__COUNTER__` is used instead of
 * TeamCity reporter now explicitly flushes output stream after each report (#1057)
@@ -279,35 +391,35 @@
 * `ParseAndAddCatchTests` now can add test files as dependency to CMake configuration
   * This means you do not have to manually rerun CMake configuration step to detect new tests
 
-## 1.10.x
+### 1.10.x
 
-### 1.10.0
+#### 1.10.0
 
-#### Fixes
+##### Fixes
 * Evaluation layer has been rewritten (backported from Catch 2)
   * The new layer is much simpler and fixes some issues (#981)
 * Implemented workaround for VS 2017 raw string literal stringification bug (#995)
 * Fixed interaction between `[!shouldfail]` and `[!mayfail]` tags and sections
   * Previously sections with failing assertions would be marked as failed, not failed-but-ok
 
-#### Improvements
+##### Improvements
 * Added [libidentify](https://github.com/janwilmans/LibIdentify) support
 * Added "wait-for-keypress" option
 
-## 1.9.x
+### 1.9.x
 
-### 1.9.6
+#### 1.9.6
 
-#### Improvements
+##### Improvements
 * Catch's runtime overhead has been significantly decreased (#937, #939)
 * Added `--list-extra-info` cli option (#934).
   * It lists all tests together with extra information, ie filename, line number and description.
 
 
 
-### 1.9.5
+#### 1.9.5
 
-#### Fixes
+##### Fixes
 * Truthy expressions are now reconstructed properly, not as booleans (#914)
 * Various warnings are no longer erroneously suppressed in test files (files that include `catch.hpp`, but do not define `CATCH_CONFIG_MAIN` or `CATCH_CONFIG_RUNNER`) (#871)
 * Catch no longer fails to link when main is compiled as C++, but linked against Objective-C (#855)
@@ -315,35 +427,35 @@
   * Previously any GCC with minor version less than 3 would be incorrectly classified as not supporting `__COUNTER__`.
 * Suppressed C4996 warning caused by upcoming updated to MSVC 2017, marking `std::uncaught_exception` as deprecated. (#927)
 
-#### Improvements
+##### Improvements
 * CMake integration script now incorporates debug messages and registers tests in an improved way (#911)
 * Various documentation improvements
 
 
 
-### 1.9.4
+#### 1.9.4
 
-#### Fixes
+##### Fixes
 * `CATCH_FAIL` macro no longer causes compilation error without variadic macro support
 * `INFO` messages are no longer cleared after being reported once
 
-#### Improvements and minor changes
+##### Improvements and minor changes
 * Catch now uses `wmain` when compiled under Windows and `UNICODE` is defined.
   * Note that Catch still officially supports only ASCII
 
-### 1.9.3
+#### 1.9.3
 
-#### Fixes
+##### Fixes
 * Completed the fix for (lack of) uint64_t in earlier Visual Studios
 
-### 1.9.2
+#### 1.9.2
 
-#### Improvements and minor changes
+##### Improvements and minor changes
 * All of `Approx`'s member functions now accept strong typedefs in C++11 mode (#888)
   * Previously `Approx::scale`, `Approx::epsilon`, `Approx::margin` and `Approx::operator()` didn't.
 
 
-#### Fixes
+##### Fixes
 * POSIX signals are now disabled by default under QNX (#889)
   * QNX does not support current enough (2001) POSIX specification
 * JUnit no longer counts exceptions as failures if given test case is marked as ok to fail.
@@ -351,22 +463,22 @@
 * Catch no longer attempts to define `uint64_t` on windows (#862)
   * This was causing trouble when compiled under Cygwin
 
-#### Other
+##### Other
 * Catch is now compiled under MSVC 2017 using `std:c++latest` (C++17 mode) in CI
 * We now provide cmake script that autoregisters Catch tests into ctest.
   * See `contrib` folder.
 
 
-### 1.9.1
+#### 1.9.1
 
-#### Fixes
+##### Fixes
 * Unexpected exceptions are no longer ignored by default (#885, #887)
 
 
-### 1.9.0
+#### 1.9.0
 
 
-#### Improvements and minor changes
+##### Improvements and minor changes
 * Catch no longer attempts to ensure the exception type passed by user in `REQUIRE_THROWS_AS` is a constant reference.
   * It was causing trouble when `REQUIRE_THROWS_AS` was used inside templated functions
   * This actually reverts changes made in v1.7.2
@@ -380,7 +492,7 @@
 * When Catch is compiled using C++11, `Approx` is now constructible with anything that can be explicitly converted to `double`.
 * Captured messages are now printed on unexpected exceptions
 
-#### Fixes:
+##### Fixes:
 * Clang's `-Wexit-time-destructors` should be suppressed for Catch's internals
 * GCC's `-Wparentheses` is now suppressed for all TU's that include `catch.hpp`.
   * This is functionally a revert of changes made in 1.8.0, where we tried using `_Pragma` based suppression. This should have kept the suppression local to Catch's assertions, but bugs in GCC's handling of `_Pragma`s in C++ mode meant that it did not always work.
@@ -389,18 +501,18 @@
   * [Details can be found in documentation](configuration.md#catch_config_cpp11_stream_insertable_check)
 
 
-#### Other notes:
+##### Other notes:
 * We have added VS 2017 to our CI
 * Work on Catch 2 should start soon
 
 
 
-## 1.8.x
+### 1.8.x
 
-### 1.8.2
+#### 1.8.2
 
 
-#### Improvements and minor changes
+##### Improvements and minor changes
 * TAP reporter now behaves as if `-s` was always set
   * This should be more consistent with the protocol desired behaviour.
 * Compact reporter now obeys `-d yes` argument (#780)
@@ -414,7 +526,7 @@
   * Listeners provide a way to hook into events generated by running your tests, including start and end of run, every test case, every section and every assertion.
 
 
-#### Fixes:
+##### Fixes:
 * Catch no longer attempts to reconstruct expression that led to a fatal error  (#810)
   * This fixes possible signal/SEH loop when processing expressions, where the signal was triggered by expression decomposition.
 * Fixed (C4265) missing virtual destructor warning in Matchers (#844)
@@ -431,21 +543,21 @@
 * Regression in Objective-C bindings (Matchers) fixed (#854)
 
 
-#### Other notes:
+##### Other notes:
 * We have added VS 2013 and 2015 to our CI
 * Catch Classic (1.x.x) now contains its own, forked, version of Clara (the argument parser).
 
 
 
-### 1.8.1
+#### 1.8.1
 
-#### Fixes
+##### Fixes
 
 Cygwin issue with `gettimeofday` - `#define` was not early enough
 
-### 1.8.0
+#### 1.8.0
 
-#### New features/ minor changes
+##### New features/ minor changes
 
 * Matchers have new, simpler (and documented) interface.
   * Catch provides string and vector matchers.
@@ -465,7 +577,7 @@ Cygwin issue with `gettimeofday` - `#define` was not early enough
 * `Approx` now supports an optional margin of absolute error
   * It has also received [new documentation](assertions.md#top).
 
-#### Fixes
+##### Fixes
 * Silenced C4312 ("conversion from int to 'ClassName *") warnings in the evaluate layer.
 * Fixed C4512 ("assignment operator could not be generated") warnings under VS2013.
 * Cygwin compatibility fixes
@@ -476,15 +588,15 @@ Cygwin issue with `gettimeofday` - `#define` was not early enough
   * Otherwise it is supressed for the whole TU
 * Fixed test spec parser issue (with escapes in multiple names)
 
-#### Other
+##### Other
 * Various documentation fixes and improvements
 
 
-## 1.7.x
+### 1.7.x
 
-### 1.7.2
+#### 1.7.2
 
-#### Fixes and minor improvements
+##### Fixes and minor improvements
 Xml:
 
 (technically the first two are breaking changes but are also fixes and arguably break few if any people)
@@ -503,9 +615,9 @@ Other:
 * Silenced a few more warnings in different circumstances
 * Travis improvements
 
-### 1.7.1
+#### 1.7.1
 
-#### Fixes:
+##### Fixes:
 * Fixed inconsistency in defining `NOMINMAX` and `WIN32_LEAN_AND_MEAN` inside `catch.hpp`.
 * Fixed SEH-related compilation error under older MinGW compilers, by making Windows SEH handling opt-in for compilers other than MSVC.
   * For specifics, look into the [documentation](configuration.md#top).
@@ -515,9 +627,9 @@ Other:
 * Fixed possible infinite recursion in Windows SEH.
 * Fixed possible compilation error caused by Catch's operator overloads being ambiguous in regards to user-defined templated operators.
 
-### 1.7.0
+#### 1.7.0
 
-#### Features/ Changes:
+##### Features/ Changes:
 * Catch now runs significantly faster for passing tests
   * Microbenchmark focused on Catch's overhead went from ~3.4s to ~0.7s.
   * Real world test using [JSON for Modern C++](https://github.com/nlohmann/json)'s test suite went from ~6m 25s to ~4m 14s.
@@ -531,30 +643,30 @@ Other:
 * Certain characters (space, tab, etc) are now pretty printed.
   * This means that a `char c = ' '; REQUIRE(c == '\t');` would be printed as `' ' == '\t'`, instead of ` == 9`.
 
-#### Fixes:
+##### Fixes:
 * Text formatting no longer attempts to access out-of-bounds characters under certain conditions.
 * THROW family of assertions no longer trigger `-Wunused-value` on expressions containing explicit cast.
 * Breaking into debugger under OS X works again and no longer required `DEBUG` to be defined.
 * Compilation no longer breaks under certain compiler if a lambda is used inside assertion macro.
 
-#### Other:
+##### Other:
 * Catch's CMakeLists now defines install command.
 * Catch's CMakeLists now generates projects with warnings enabled.
 
 
-## 1.6.x
+### 1.6.x
 
-### 1.6.1
+#### 1.6.1
 
-#### Features/ Changes:
+##### Features/ Changes:
 * Catch now supports breaking into debugger on Linux
 
-#### Fixes:
+##### Fixes:
 * Generators no longer leak memory (generators are still unsupported in general)
 * JUnit reporter now reports UTC timestamps, instead of "tbd"
 * `CHECK_THAT` macro is now properly defined as `CATCH_CHECK_THAT` when using `CATCH_` prefixed macros
 
-#### Other:
+##### Other:
 * Types with overloaded `&&` operator are no longer evaluated twice when used in an assertion macro.
 * The use of `__COUNTER__` is supressed when Catch is parsed by CLion
   * This change is not active when compiling a binary
@@ -564,28 +676,28 @@ Other:
   * This can be disabled if needed, see [documentation](configuration.md#top) for details.
 
 
-### 1.6.0
+#### 1.6.0
 
-#### Cmake/ projects:
+##### Cmake/ projects:
 * Moved CMakeLists.txt to root, made it friendlier for CLion and generating XCode and VS projects, and removed the manually maintained XCode and VS projects.
 
-#### Features/ Changes:
+##### Features/ Changes:
 * Approx now supports `>=` and `<=`
 * Can now use `\` to escape chars in test names on command line
 * Standardize C++11 feature toggles
 
-#### Fixes:
+##### Fixes:
 * Blue shell colour
 * Missing argument to `CATCH_CHECK_THROWS`
 * Don't encode extended ASCII in XML
 * use `std::shuffle` on more compilers (fixes deprecation warning/error)
 * Use `__COUNTER__` more consistently (where available)
 
-#### Other:
+##### Other:
 * Tweaks and changes to scripts - particularly for Approval test - to make them more portable
 
 
-# Even Older versions
+## Even Older versions
 Release notes were not maintained prior to v1.6.0, but you should be able to work them out from the Git history
 
 ---
diff --git a/packages/Catch2/docs/reporters.md b/packages/Catch2/docs/reporters.md
index 78e78ee925f37998695e2e1dde0226e435d09d31..32b3419b5a5ae795fec67da9b5fd04a311577d07 100644
--- a/packages/Catch2/docs/reporters.md
+++ b/packages/Catch2/docs/reporters.md
@@ -25,8 +25,8 @@ Because of the way the junit format is structured the run must complete before a
 There are a few additional reporters, for specific build systems, in the Catch repository (in `include\reporters`) which you can `#include` in your project if you would like to make use of them.
 Do this in one source file - the same one you have `CATCH_CONFIG_MAIN` or `CATCH_CONFIG_RUNNER`.
 
-* `teamcity` writes the native, streaming, format that [TeamCity](https://www.jetbrains.com/teamcity/) understands.
-Use this when building as part of a TeamCity build to see results as they happen.
+* `teamcity` writes the native, streaming, format that [TeamCity](https://www.jetbrains.com/teamcity/) understands. 
+Use this when building as part of a TeamCity build to see results as they happen ([code example](../examples/207-Rpt-TeamCityReporter.cpp)).
 * `tap` writes in the TAP ([Test Anything Protocol](https://en.wikipedia.org/wiki/Test_Anything_Protocol)) format.
 * `automake` writes in a format that correspond to [automake  .trs](https://www.gnu.org/software/automake/manual/html_node/Log-files-generation-and-test-results-recording.html) files
 
diff --git a/packages/Catch2/docs/test-cases-and-sections.md b/packages/Catch2/docs/test-cases-and-sections.md
index 68944f51cf34fd6fe55ccbf4df1c6677fd891f1a..621d226ee9801b437f2a77154ba0d9bc58ebeee8 100644
--- a/packages/Catch2/docs/test-cases-and-sections.md
+++ b/packages/Catch2/docs/test-cases-and-sections.md
@@ -20,10 +20,10 @@ Tags allow an arbitrary number of additional strings to be associated with a tes
 
 As an example - given the following test cases:
 
-	TEST_CASE( "A", "[widget]" ) { /* ... */ }
-	TEST_CASE( "B", "[widget]" ) { /* ... */ }
-	TEST_CASE( "C", "[gadget]" ) { /* ... */ }
-	TEST_CASE( "D", "[widget][gadget]" ) { /* ... */ }
+    TEST_CASE( "A", "[widget]" ) { /* ... */ }
+    TEST_CASE( "B", "[widget]" ) { /* ... */ }
+    TEST_CASE( "C", "[gadget]" ) { /* ... */ }
+    TEST_CASE( "D", "[widget][gadget]" ) { /* ... */ }
 
 The tag expression, ```"[widget]"``` selects A, B & D. ```"[gadget]"``` selects C & D. ```"[widget][gadget]"``` selects just D and ```"[widget],[gadget]"``` selects all four test cases.
 
@@ -37,7 +37,7 @@ All tag names beginning with non-alphanumeric characters are reserved by Catch.
 
 * `[!hide]` or `[.]` - causes test cases to be skipped from the default list (i.e. when no test cases have been explicitly selected through tag expressions or name wildcards). The hide tag is often combined with another, user, tag (for example `[.][integration]` - so all integration tests are excluded from the default run but can be run by passing `[integration]` on the command line). As a short-cut you can combine these by simply prefixing your user tag with a `.` - e.g. `[.integration]`. Because the hide tag has evolved to have several forms, all forms are added as tags if you use one of them.
 
-* `[!throws]`	- lets Catch know that this test is likely to throw an exception even if successful. This causes the test to be excluded when running with `-e` or `--nothrow`.
+* `[!throws]` - lets Catch know that this test is likely to throw an exception even if successful. This causes the test to be excluded when running with `-e` or `--nothrow`.
 
 * `[!mayfail]` - doesn't fail the test if any given assertion fails (but still reports it). This can be useful to flag a work-in-progress, or a known issue that you don't want to immediately fix but still want to track in your tests.
 
@@ -55,11 +55,11 @@ All tag names beginning with non-alphanumeric characters are reserved by Catch.
 
 Between tag expressions and wildcarded test names (as well as combinations of the two) quite complex patterns can be constructed to direct which test cases are run. If a complex pattern is used often it is convenient to be able to create an alias for the expression. This can be done, in code, using the following form:
 
-	CATCH_REGISTER_TAG_ALIAS( <alias string>, <tag expression> )
+    CATCH_REGISTER_TAG_ALIAS( <alias string>, <tag expression> )
 
 Aliases must begin with the `@` character. An example of a tag alias is:
 
-	CATCH_REGISTER_TAG_ALIAS( "[@nhf]", "[failing]~[.]" )
+    CATCH_REGISTER_TAG_ALIAS( "[@nhf]", "[failing]~[.]" )
 
 Now when `[@nhf]` is used on the command line this matches all tests that are tagged `[failing]`, but which are not also hidden.
 
diff --git a/packages/Catch2/docs/tostring.md b/packages/Catch2/docs/tostring.md
index 568c1c2758209573cdb56303455361f9fa82f4bc..be79f6e9455c33f49051b44bef9afe1531126ece 100644
--- a/packages/Catch2/docs/tostring.md
+++ b/packages/Catch2/docs/tostring.md
@@ -1,6 +1,12 @@
 <a id="top"></a>
 # String conversions
 
+**Contents**<br>
+[operator << overload for std::ostream](#operator--overload-for-stdostream)<br>
+[Catch::StringMaker specialisation](#catchstringmaker-specialisation)<br>
+[Catch::is_range specialisation](#catchis_range-specialisation)<br>
+[Exceptions](#exceptions)<br>
+
 Catch needs to be able to convert types you use in assertions and logging expressions into strings (for logging and reporting purposes).
 Most built-in or std types are supported out of the box but there are two ways that you can tell Catch how to convert your own types (or other, third-party types) into strings.
 
@@ -10,8 +16,8 @@ This is the standard way of providing string conversions in C++ - and the chance
 
 ```
 std::ostream& operator << ( std::ostream& os, T const& value ) {
-	os << convertMyTypeToString( value );
-	return os;
+    os << convertMyTypeToString( value );
+    return os;
 }
 ```
 
@@ -19,21 +25,21 @@ std::ostream& operator << ( std::ostream& os, T const& value ) {
 
 You should put this function in the same namespace as your type and have it declared before including Catch's header.
 
-## Catch::StringMaker<T> specialisation
+## Catch::StringMaker specialisation
 If you don't want to provide an ```operator <<``` overload, or you want to convert your type differently for testing purposes, you can provide a specialization for `Catch::StringMaker<T>`:
 
 ```
 namespace Catch {
-	template<>
+    template<>
     struct StringMaker<T> {
-    	static std::string convert( T const& value ) {
-        	return convertMyTypeToString( value );
+        static std::string convert( T const& value ) {
+            return convertMyTypeToString( value );
         }
     };
 }
 ```
 
-## Catch::is_range<T> specialisation
+## Catch::is_range specialisation
 As a fallback, Catch attempts to detect if the type can be iterated
 (`begin(T)` and `end(T)` are valid) and if it can be, it is stringified
 as a range. For certain types this can lead to infinite recursion, so
@@ -56,7 +62,7 @@ By default all exceptions deriving from `std::exception` will be translated to s
 
 ```
 CATCH_TRANSLATE_EXCEPTION( MyType& ex ) {
-	return ex.message();
+    return ex.message();
 }
 ```
 
diff --git a/packages/Catch2/docs/tutorial.md b/packages/Catch2/docs/tutorial.md
index d55355c64b816b64ae66408130376bad1684bf32..387a250a1432fad5bf784db4b239f1e808634316 100644
--- a/packages/Catch2/docs/tutorial.md
+++ b/packages/Catch2/docs/tutorial.md
@@ -12,7 +12,10 @@
 
 ## Getting Catch2
 
-The simplest way to get Catch2 is to download the latest [single header version](https://raw.githubusercontent.com/CatchOrg/Catch2/master/single_include/catch.hpp). The single header is generated by merging a set of individual headers but it is still just normal source code in a header file.
+The simplest way to get Catch2 is to download the latest [single header version](https://raw.githubusercontent.com/catchorg/Catch2/master/single_include/catch2/catch.hpp). The single header is generated by merging a set of individual headers but it is still just normal source code in a header file.
+
+Alternative ways of getting Catch2 include using your system package
+manager, or installing it using [its CMake package](cmake-integration.md#installing-catch2-from-git-repository).
 
 The full source for Catch2, including test projects, documentation, and other things, is hosted on GitHub. [http://catch-lib.net](http://catch-lib.net) will redirect you there.
 
@@ -23,6 +26,9 @@ Catch2 is header only. All you need to do is drop the file somewhere reachable f
 
 The rest of this tutorial will assume that the Catch2 single-include header (or the include folder) is available unqualified - but you may need to prefix it with a folder name if necessary.
 
+_If you have installed Catch2 from system package manager, or CMake
+package, you need to include the header as `#include <catch2/catch.hpp>`_
+
 ## Writing tests
 
 Let's start with a really simple example ([code](../examples/010-TestCase.cpp)). Say you have written a function to calculate factorials and now you want to test it (let's leave aside TDD for now). 
diff --git a/packages/Catch2/examples/000-CatchMain.cpp b/packages/Catch2/examples/000-CatchMain.cpp
index c8bf91e454700cf32be395ee22c4a24f3e96ca2d..2894d425add19df071033e1f0224709f003f299f 100644
--- a/packages/Catch2/examples/000-CatchMain.cpp
+++ b/packages/Catch2/examples/000-CatchMain.cpp
@@ -6,7 +6,7 @@
 // Let Catch provide main():
 #define CATCH_CONFIG_MAIN
 
-#include "catch.hpp"
+#include <catch2/catch.hpp>
 
 // That's it
 
diff --git a/packages/Catch2/examples/010-TestCase.cpp b/packages/Catch2/examples/010-TestCase.cpp
index 16a212a3ea798ee015c4c6336ba315b4c8391c36..c00b8a8f3967f372550af4b3473a5285709a5cee 100644
--- a/packages/Catch2/examples/010-TestCase.cpp
+++ b/packages/Catch2/examples/010-TestCase.cpp
@@ -3,7 +3,7 @@
 // Let Catch provide main():
 #define CATCH_CONFIG_MAIN
 
-#include "catch.hpp"
+#include <catch2/catch.hpp>
 
 int Factorial( int number ) {
    return number <= 1 ? number : Factorial( number - 1 ) * number;  // fail
diff --git a/packages/Catch2/examples/020-TestCase-1.cpp b/packages/Catch2/examples/020-TestCase-1.cpp
index 0d10276c2d4932fe2a4aa6104320f6aa916d3a36..ab0249e4ddb47a0c32ada176c97a0844b37adf83 100644
--- a/packages/Catch2/examples/020-TestCase-1.cpp
+++ b/packages/Catch2/examples/020-TestCase-1.cpp
@@ -6,7 +6,7 @@
 // Let Catch provide main():
 #define CATCH_CONFIG_MAIN
 
-#include "catch.hpp"
+#include <catch2/catch.hpp>
 
 TEST_CASE( "1: All test cases reside in other .cpp files (empty)", "[multi-file:1]" ) {
 }
diff --git a/packages/Catch2/examples/020-TestCase-2.cpp b/packages/Catch2/examples/020-TestCase-2.cpp
index 2cca362120d43473936e3d7696ac9bcee33e1ec8..08b313e0cfa2fe9862ac861c5d25951a69135478 100644
--- a/packages/Catch2/examples/020-TestCase-2.cpp
+++ b/packages/Catch2/examples/020-TestCase-2.cpp
@@ -2,7 +2,7 @@
 
 // main() provided by Catch in file 020-TestCase-1.cpp.
 
-#include "catch.hpp"
+#include <catch2/catch.hpp>
 
 int Factorial( int number ) {
    return number <= 1 ? number : Factorial( number - 1 ) * number;  // fail
diff --git a/packages/Catch2/examples/030-Asn-Require-Check.cpp b/packages/Catch2/examples/030-Asn-Require-Check.cpp
index 35f2ff790571deab19bb201b735dbc71d507fe9b..f814a1b3ca4561f5e056b9c16c1426a0f95dc56e 100644
--- a/packages/Catch2/examples/030-Asn-Require-Check.cpp
+++ b/packages/Catch2/examples/030-Asn-Require-Check.cpp
@@ -10,7 +10,7 @@
 
 // main() provided in 000-CatchMain.cpp
 
-#include "catch.hpp"
+#include <catch2/catch.hpp>
 
 std::string one() {
     return "1";
diff --git a/packages/Catch2/examples/100-Fix-Section.cpp b/packages/Catch2/examples/100-Fix-Section.cpp
index 8cb94bffd9416e3bb86b3718e778135b966c5031..d0b9f2da5b73a693d9415e9ef0dada7f4db6f7e8 100644
--- a/packages/Catch2/examples/100-Fix-Section.cpp
+++ b/packages/Catch2/examples/100-Fix-Section.cpp
@@ -6,7 +6,7 @@
 
 // main() provided in 000-CatchMain.cpp
 
-#include "catch.hpp"
+#include <catch2/catch.hpp>
 
 TEST_CASE( "vectors can be sized and resized", "[vector]" ) {
 
diff --git a/packages/Catch2/examples/110-Fix-ClassFixture.cpp b/packages/Catch2/examples/110-Fix-ClassFixture.cpp
index 06c2cf329ceae9121d04262cfaaefb022d30f653..e42fd17585d530255df88ba5d5a5add27523f141 100644
--- a/packages/Catch2/examples/110-Fix-ClassFixture.cpp
+++ b/packages/Catch2/examples/110-Fix-ClassFixture.cpp
@@ -6,7 +6,7 @@
 
 // main() provided in 000-CatchMain.cpp
 
-#include "catch.hpp"
+#include <catch2/catch.hpp>
 
 class DBConnection
 {
diff --git a/packages/Catch2/examples/120-Bdd-ScenarioGivenWhenThen.cpp b/packages/Catch2/examples/120-Bdd-ScenarioGivenWhenThen.cpp
index c45f1f260e25af5eb67bb7d8bc757612cf4c4470..d1b9ce558a0f40f0707549cd0c04324adaaba1f7 100644
--- a/packages/Catch2/examples/120-Bdd-ScenarioGivenWhenThen.cpp
+++ b/packages/Catch2/examples/120-Bdd-ScenarioGivenWhenThen.cpp
@@ -2,7 +2,7 @@
 
 // main() provided in 000-CatchMain.cpp
 
-#include "catch.hpp"
+#include <catch2/catch.hpp>
 
 SCENARIO( "vectors can be sized and resized", "[vector]" ) {
 
diff --git a/packages/Catch2/examples/200-Rpt-CatchMain.cpp b/packages/Catch2/examples/200-Rpt-CatchMain.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b84c804dd5eb2af471ed12cbb3e8978a27f674a1
--- /dev/null
+++ b/packages/Catch2/examples/200-Rpt-CatchMain.cpp
@@ -0,0 +1,27 @@
+// 200-Rpt-CatchMain.cpp
+
+// In a Catch project with multiple files, dedicate one file to compile the
+// source code of Catch itself and reuse the resulting object file for linking.
+
+// Let Catch provide main():
+#define CATCH_CONFIG_MAIN
+
+#include <catch2/catch.hpp>
+
+#ifdef   CATCH_EXAMPLE_RPT_1
+#include CATCH_EXAMPLE_RPT_1
+#endif
+
+#ifdef   CATCH_EXAMPLE_RPT_2
+#include CATCH_EXAMPLE_RPT_2
+#endif
+
+#ifdef   CATCH_EXAMPLE_RPT_3
+#include CATCH_EXAMPLE_RPT_3
+#endif
+
+// That's it
+
+// Compile implementation of Catch for use with files that do contain tests:
+// - g++ -std=c++11 -Wall -I$(CATCH_ROOT) -DCATCH_EXAMPLE_RPT_1=\"include/reporters/catch_reporter_teamcity.hpp\" -o 200-Rpt-CatchMainTeamCity.o -c 200-Rpt-CatchMain.cpp
+// cl -EHsc -I%CATCH_ROOT% -DCATCH_EXAMPLE_RPT_1=\"include/reporters/catch_reporter_teamcity.hpp\" -Fo200-Rpt-CatchMainTeamCity.obj -c 200-Rpt-CatchMain.cpp
diff --git a/packages/Catch2/examples/207-Rpt-TeamCityReporter.cpp b/packages/Catch2/examples/207-Rpt-TeamCityReporter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d28460f400d76e7d206904c857b7f5318d30ed9e
--- /dev/null
+++ b/packages/Catch2/examples/207-Rpt-TeamCityReporter.cpp
@@ -0,0 +1,171 @@
+// 207-Rpt-TeamCityReporter.cpp
+
+// Catch has built-in and external reporters:
+// Built-in:
+// - compact
+// - console
+// - junit
+// - xml
+// External:
+// - automake
+// - tap
+// - teamcity (this example)
+
+// main() and reporter code provided in 200-Rpt-CatchMain.cpp
+
+#include <catch2/catch.hpp>
+
+#ifdef _MSC_VER
+# pragma warning (disable : 4702) // Disable warning: unreachable code
+#endif
+
+TEST_CASE( "TeamCity passes unconditionally succeeding assertion", "[teamcity]" ) {
+
+    SUCCEED();
+}
+
+TEST_CASE( "TeamCity reports unconditionally failing assertion", "[teamcity]" ) {
+
+    FAIL();
+}
+
+TEST_CASE( "TeamCity reports failing check", "[teamcity]" ) {
+
+    REQUIRE( 3 == 7 );
+}
+
+TEST_CASE( "TeamCity reports failing check-false", "[teamcity]" ) {
+
+    REQUIRE_FALSE( 3 == 3 );
+}
+
+TEST_CASE( "TeamCity reports failing check-that", "[teamcity]" ) {
+
+    using namespace Catch;
+
+    REQUIRE_THAT( "hello", Contains( "world" ) );
+}
+
+TEST_CASE( "TeamCity reports unexpected exception", "[teamcity]" ) {
+
+    REQUIRE( (throw std::runtime_error("surprise!"), true) );
+}
+
+TEST_CASE( "TeamCity reports undesired exception", "[teamcity]" ) {
+
+    REQUIRE_NOTHROW( (throw std::runtime_error("surprise!"), true) );
+}
+
+TEST_CASE( "TeamCity reports missing expected exception", "[teamcity]" ) {
+
+    REQUIRE_THROWS( true );
+}
+
+TEST_CASE( "TeamCity reports missing specific expected exception", "[teamcity]" ) {
+
+    REQUIRE_THROWS_AS( throw std::bad_alloc(), std::runtime_error );
+}
+
+TEST_CASE( "TeamCity reports unexpected message in expected exception", "[teamcity]" ) {
+
+    using namespace Catch;
+
+    CHECK_THROWS_WITH( throw std::runtime_error("hello"), "world" );
+    CHECK_THROWS_WITH( throw std::runtime_error("hello"), Contains("world") );
+}
+
+struct MyException: public std::runtime_error
+{
+    MyException( char const * text )
+    : std::runtime_error( text ) {}
+    
+    ~MyException() override;
+};
+
+// prevent -Wweak-vtables:
+MyException::~MyException() = default;
+
+struct MyExceptionMatcher : Catch::MatcherBase< std::runtime_error >
+{
+    std::string m_text;
+
+    MyExceptionMatcher( char const * text )
+    : m_text( text )
+    {}
+
+    ~MyExceptionMatcher() override;
+    
+    bool match( std::runtime_error const & arg ) const override
+    { 
+        return m_text == arg.what() ; 
+    }
+    
+    std::string describe() const override 
+    { 
+        return "it's me";
+    }
+};
+
+// prevent -Wweak-vtables:
+MyExceptionMatcher::~MyExceptionMatcher() = default;
+
+TEST_CASE( "TeamCity failing check-throws-matches", "[teamcity]" ) {
+
+    CHECK_THROWS_MATCHES( throw MyException("hello"), MyException, MyExceptionMatcher("world") );
+}
+
+// [!throws] - lets Catch know that this test is likely to throw an exception even if successful. 
+// This causes the test to be excluded when running with -e or --nothrow.
+
+// No special effects for the reporter.
+
+TEST_CASE( "TeamCity throwing exception with tag [!throws]", "[teamcity][!throws]" ) {
+
+    REQUIRE_THROWS( throw std::runtime_error("unsurprisingly") );
+}
+
+// [!mayfail] - doesn't fail the test if any given assertion fails (but still reports it). This can be useful to flag a work-in-progress, or a known issue that you don't want to immediately fix but still want to track in your tests.
+
+TEST_CASE( "TeamCity failing assertion with tag [!mayfail]", "[teamcity][!mayfail] " ) {
+
+    REQUIRE( 3 == 7 );  // doesn't fail test case this time, reports: testIgnored
+    REQUIRE( 3 == 3 );
+}
+
+// [!shouldfail] - like [!mayfail] but fails the test if it passes. 
+// This can be useful if you want to be notified of accidental, or third-party, fixes.
+
+TEST_CASE( "TeamCity succeeding assertion with tag [!shouldfail]", "[teamcity][!shouldfail]" ) {
+
+    SUCCEED( "Marked [!shouldfail]" );
+}
+
+// Compile & run:
+// - g++ -std=c++11 -Wall -I$(CATCH_ROOT) -DCATCH_EXAMPLE_RPT_1=\"include/reporters/catch_reporter_teamcity.hpp\" -o 200-Rpt-CatchMainTeamCity.o -c 200-Rpt-CatchMain.cpp
+// - g++ -std=c++11 -Wall -I$(CATCH_ROOT) -o 207-Rpt-TeamCityReporter 207-Rpt-TeamCityReporter.cpp 200-Rpt-CatchMainTeamCity.o && 207-Rpt-TeamCityReporter --list-reporters
+//
+// - cl -EHsc -I%CATCH_ROOT% -DCATCH_EXAMPLE_RPT_1=\"include/reporters/catch_reporter_teamcity.hpp\" -Fo200-Rpt-CatchMainTeamCity.obj -c 200-Rpt-CatchMain.cpp
+// - cl -EHsc -I%CATCH_ROOT% 207-Rpt-TeamCityReporter.cpp 200-Rpt-CatchMainTeamCity.o && 207-Rpt-TeamCityReporter --list-reporters
+
+// Compilation output (--list-reporters):
+// Available reporters:
+//   compact:   Reports test results on a single line, suitable for IDEs
+//   console:   Reports test results as plain lines of text
+//   junit:     Reports test results in an XML format that looks like Ant's
+//                junitreport target
+//   teamcity:  Reports test results as TeamCity service messages
+//   xml:       Reports test results as an XML document
+
+// Expected output (abbreviated and broken into shorter lines):
+//
+// prompt> 207-Rpt-TeamCityReporter.exe --reporter teamcity
+// ##teamcity[testSuiteStarted name='207-Rpt-TeamCityReporter.exe']
+// ##teamcity[testStarted name='TeamCity passes unconditionally succeeding assertion']
+// ##teamcity[testFinished name='TeamCity passes unconditionally succeeding assertion' duration='1']
+// ##teamcity[testStarted name='TeamCity reports unconditionally failing assertion']
+// ##teamcity[testFailed name='TeamCity reports unconditionally failing assertion' /
+// message='.../examples/207-Rpt-TeamCityReporter.cpp:23|n/
+// ...............................................................................|n|n/
+// .../examples/207-Rpt-TeamCityReporter.cpp:25|nexplicit failure']
+// ##teamcity[testFinished name='TeamCity reports unconditionally failing assertion' duration='3']
+// ...
diff --git a/packages/Catch2/examples/210-Evt-EventListeners.cpp b/packages/Catch2/examples/210-Evt-EventListeners.cpp
index 8ba360f5fdf6d1de25bd0a221a2e448211de25bc..7df93d715b8a6986c579f419ce0ff2e65f4e2e7b 100644
--- a/packages/Catch2/examples/210-Evt-EventListeners.cpp
+++ b/packages/Catch2/examples/210-Evt-EventListeners.cpp
@@ -10,7 +10,7 @@
 // Let Catch provide the required interfaces:
 #define CATCH_CONFIG_EXTERNAL_INTERFACES
 
-#include "catch.hpp"
+#include <catch2/catch.hpp>
 #include <iostream>
 
 // -----------------------------------------------------------------------
@@ -187,8 +187,7 @@ void print( std::ostream& os, int const level, std::string const& title, Catch::
 
 void print( std::ostream& os, int const level, std::string const& title, Catch::SectionInfo const& info ) {
     os << ws(level  ) << title << ":\n"
-       << ws(level+1) << "- name: "         << info.name << "\n"
-       << ws(level+1) << "- description: '" << info.description << "'\n";
+       << ws(level+1) << "- name: "         << info.name << "\n";
     print( os, level+1 , "- lineInfo", info.lineInfo );
 }
 
diff --git a/packages/Catch2/examples/231-Cfg-OutputStreams.cpp b/packages/Catch2/examples/231-Cfg-OutputStreams.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..efa9997193f2abe1c065e6a2aa3f4b012206e6b3
--- /dev/null
+++ b/packages/Catch2/examples/231-Cfg-OutputStreams.cpp
@@ -0,0 +1,49 @@
+// 231-Cfg-OutputStreams.cpp
+// Show how to replace the streams with a simple custom made streambuf.
+
+// Note that this reimplementation _does not_ follow `std::cerr`
+// semantic, because it buffers the output. For most uses however,
+// there is no important difference between having `std::cerr` buffered
+// or unbuffered.
+
+#define CATCH_CONFIG_NOSTDOUT
+#define CATCH_CONFIG_MAIN
+#include <catch2/catch.hpp>
+
+class out_buff : public std::stringbuf {
+    std::FILE* m_stream;
+public:
+    out_buff(std::FILE* stream) :m_stream(stream) {}
+    ~out_buff() { pubsync(); }
+    int sync() {
+        int ret = 0;
+        for (unsigned char c : str()) {
+            if (putc(c, m_stream) == EOF) {
+                ret = -1;
+                break;
+            }
+        }
+        // Reset the buffer to avoid printing it multiple times
+        str("");
+        return ret;
+    }
+};
+
+namespace Catch {
+    std::ostream& cout() {
+        static std::ostream ret(new out_buff(stdout));
+        return ret;
+    }
+    std::ostream& clog() {
+        static std::ostream ret(new out_buff(stderr));
+        return ret;
+    }
+    std::ostream& cerr() {
+        return clog();
+    }
+}
+
+
+TEST_CASE("This binary uses putc to write out output", "[compilation-only]") {
+    SUCCEED("Nothing to test.");
+}
diff --git a/packages/Catch2/examples/CMakeLists.txt b/packages/Catch2/examples/CMakeLists.txt
index 7270e933eee3cf2f78c46b492c94ee7c5a151ad8..2551e77c07e29012920785a39972677a5372c219 100644
--- a/packages/Catch2/examples/CMakeLists.txt
+++ b/packages/Catch2/examples/CMakeLists.txt
@@ -8,15 +8,19 @@ cmake_minimum_required( VERSION 3.0 )
 
 project( CatchExamples CXX )
 
+message( STATUS "Examples included" )
+
 # define folders used:
 
 set( EXAMPLES_DIR ${CATCH_DIR}/examples )
 set( HEADER_DIR   ${CATCH_DIR}/single_include )
+set( REPORTER_HEADER_DIR ${CATCH_DIR}/include/reporters )
 
 # single-file sources:
 
 set( SOURCES_SINGLE_FILE
     010-TestCase.cpp
+    231-Cfg-OutputStreams.cpp
 )
 
 # multiple-file modules:
@@ -42,6 +46,26 @@ set( SOURCES_IDIOMATIC_TESTS
     210-Evt-EventListeners.cpp
 )
 
+# main-s for reporter-specific test sources:
+
+set( SOURCES_REPORTERS_MAIN
+    200-Rpt-CatchMain.cpp
+)
+
+string( REPLACE ".cpp" "" BASENAMES_REPORTERS_MAIN 200-Rpt-CatchMain.cpp )
+
+set( NAMES_REPORTERS TeamCity )
+
+foreach( reporter ${NAMES_REPORTERS} )
+    list( APPEND SOURCES_SPECIFIC_REPORTERS_MAIN ${BASENAMES_REPORTERS_MAIN}${reporter}.cpp )
+endforeach()
+
+# sources to combine with 200-Rpt-CatchMain{Reporter}.cpp:
+
+set( SOURCES_REPORTERS_TESTS
+    207-Rpt-TeamCityReporter.cpp
+)
+
 # check if all sources are listed, warn if not:
 
 set( SOURCES_ALL
@@ -49,6 +73,8 @@ set( SOURCES_ALL
     ${SOURCES_SINGLE_FILE}
     ${SOURCES_IDIOMATIC_MAIN}
     ${SOURCES_IDIOMATIC_TESTS}
+    ${SOURCES_REPORTERS_MAIN}
+    ${SOURCES_REPORTERS_TESTS}
 )
 
 foreach( name ${SOURCES_ALL} )
@@ -61,29 +87,55 @@ CheckFileList( SOURCES_ALL_PATH ${EXAMPLES_DIR} )
 
 string( REPLACE ".cpp" "" BASENAMES_SINGLE_FILE     "${SOURCES_SINGLE_FILE}" )
 string( REPLACE ".cpp" "" BASENAMES_IDIOMATIC_TESTS "${SOURCES_IDIOMATIC_TESTS}" )
+string( REPLACE ".cpp" "" BASENAMES_REPORTERS_TESTS "${SOURCES_REPORTERS_TESTS}" )
+string( REPLACE ".cpp" "" BASENAMES_REPORTERS_MAIN  "${SOURCES_REPORTERS_MAIN}" )
 
 set( TARGETS_SINGLE_FILE     ${BASENAMES_SINGLE_FILE} )
 set( TARGETS_IDIOMATIC_TESTS ${BASENAMES_IDIOMATIC_TESTS} )
-set( TARGETS_ALL             ${TARGETS_SINGLE_FILE} ${TARGETS_IDIOMATIC_TESTS} 020-TestCase CatchMain )
+set( TARGETS_REPORTERS_TESTS ${BASENAMES_REPORTERS_TESTS} )
+set( TARGETS_REPORTERS_MAIN  ${BASENAMES_REPORTERS_MAIN} )
+
+set( TARGETS_ALL
+    ${TARGETS_SINGLE_FILE}
+    020-TestCase
+    ${TARGETS_IDIOMATIC_TESTS} CatchMain
+    ${TARGETS_REPORTERS_TESTS} CatchMainTeamCity
+)
 
 # define program targets:
 
-add_library( CatchMain OBJECT ${EXAMPLES_DIR}/${SOURCES_IDIOMATIC_MAIN} ${HEADER_DIR}/catch.hpp )
+add_library( CatchMain         OBJECT ${EXAMPLES_DIR}/${SOURCES_IDIOMATIC_MAIN} ${HEADER_DIR}/catch2/catch.hpp )
+#add_library( CatchMainAutomake OBJECT ${EXAMPLES_DIR}/200-Rpt-CatchMain.cpp ${HEADER_DIR}/catch2/catch.hpp )
+#add_library( CatchMainTap      OBJECT ${EXAMPLES_DIR}/200-Rpt-CatchMain.cpp ${HEADER_DIR}/catch2/catch.hpp )
+add_library( CatchMainTeamCity OBJECT ${EXAMPLES_DIR}/200-Rpt-CatchMain.cpp ${HEADER_DIR}/catch2/catch.hpp )
 
-add_executable( 020-TestCase ${EXAMPLES_DIR}/020-TestCase-1.cpp ${EXAMPLES_DIR}/020-TestCase-2.cpp ${HEADER_DIR}/catch.hpp )
+#target_compile_definitions( CatchMainAutomake PRIVATE CATCH_EXAMPLE_RPT_1=\"include/reporters/catch_reporter_automake.hpp\" )
+#target_compile_definitions( CatchMainTap      PRIVATE CATCH_EXAMPLE_RPT_1=\"include/reporters/catch_reporter_tap.hpp\" )
+target_compile_definitions( CatchMainTeamCity PRIVATE CATCH_EXAMPLE_RPT_1=\"include/reporters/catch_reporter_teamcity.hpp\" )
 
 foreach( name ${TARGETS_SINGLE_FILE} )
-    add_executable( ${name} ${EXAMPLES_DIR}/${name}.cpp ${HEADER_DIR}/catch.hpp )
+    add_executable( ${name} ${EXAMPLES_DIR}/${name}.cpp ${HEADER_DIR}/catch2/catch.hpp )
 endforeach()
 
 foreach( name ${TARGETS_IDIOMATIC_TESTS} )
-    add_executable( ${name} ${EXAMPLES_DIR}/${name}.cpp $<TARGET_OBJECTS:CatchMain> ${HEADER_DIR}/catch.hpp )
+    add_executable( ${name} ${EXAMPLES_DIR}/${name}.cpp $<TARGET_OBJECTS:CatchMain> ${HEADER_DIR}/catch2/catch.hpp )
 endforeach()
 
+add_executable( 020-TestCase ${EXAMPLES_DIR}/020-TestCase-1.cpp ${EXAMPLES_DIR}/020-TestCase-2.cpp ${HEADER_DIR}/catch2/catch.hpp )
+
+#add_executable( 207-Rpt-AutomakeReporter ${EXAMPLES_DIR}/207-Rpt-AutomakeReporter.cpp $<TARGET_OBJECTS:CatchMainAutomake> ${HEADER_DIR}/catch2/catch.hpp )
+#add_executable( 207-Rpt-TapReporter      ${EXAMPLES_DIR}/207-Rpt-TapReporter.cpp      $<TARGET_OBJECTS:CatchMainTap>      ${HEADER_DIR}/catch2/catch.hpp )
+add_executable( 207-Rpt-TeamCityReporter ${EXAMPLES_DIR}/207-Rpt-TeamCityReporter.cpp $<TARGET_OBJECTS:CatchMainTeamCity> ${HEADER_DIR}/catch2/catch.hpp )
+
+#foreach( name ${TARGETS_REPORTERS_TESTS} )
+#    add_executable( ${name} ${EXAMPLES_DIR}/${name}.cpp $<TARGET_OBJECTS:CatchMain> ${HEADER_DIR}/catch2/catch.hpp )
+#endforeach()
+
 foreach( name ${TARGETS_ALL} )
-    target_include_directories( ${name} PRIVATE ${HEADER_DIR} )
+    target_include_directories( ${name} PRIVATE ${HEADER_DIR} ${CATCH_DIR} )
 
     set_property(TARGET ${name} PROPERTY CXX_STANDARD 11)
+    set_property(TARGET ${name} PROPERTY CXX_EXTENSIONS OFF)
 
     # Add desired warnings
     if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" )
@@ -98,3 +150,4 @@ foreach( name ${TARGETS_ALL} )
         target_compile_options( ${name}  PRIVATE /W4 /w44265 /WX )
     endif()
 endforeach()
+
diff --git a/packages/Catch2/include/catch.hpp b/packages/Catch2/include/catch.hpp
index 0c92ed3af153a90a51f9def57dcfa45c13b38617..f8b380c4e4053062fa1b94ab6254699b25aed918 100644
--- a/packages/Catch2/include/catch.hpp
+++ b/packages/Catch2/include/catch.hpp
@@ -10,8 +10,8 @@
 #define TWOBLUECUBES_CATCH_HPP_INCLUDED
 
 #define CATCH_VERSION_MAJOR 2
-#define CATCH_VERSION_MINOR 2
-#define CATCH_VERSION_PATCH 3
+#define CATCH_VERSION_MINOR 4
+#define CATCH_VERSION_PATCH 1
 
 #ifdef __clang__
 #    pragma clang system_header
@@ -33,7 +33,9 @@
 #  if defined(CATCH_CONFIG_DISABLE_MATCHERS)
 #    undef CATCH_CONFIG_DISABLE_MATCHERS
 #  endif
-#  define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
+#  if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
+#    define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
+#  endif
 #endif
 
 #if !defined(CATCH_CONFIG_IMPL_ONLY)
@@ -60,6 +62,7 @@
 #ifndef CATCH_CONFIG_DISABLE_MATCHERS
 #include "internal/catch_capture_matchers.h"
 #endif
+#include "internal/catch_generators.hpp"
 
 // These files are included here so the single_include script doesn't put them
 // in the conditionally compiled sections
@@ -128,13 +131,14 @@
 
 #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_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg) )
+#define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE",__VA_ARGS__ )
 
 #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_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_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__ )
@@ -144,11 +148,12 @@
 // "BDD-style" convenience wrappers
 #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
-#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 )
+#define CATCH_GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( "    Given: " << desc )
+#define CATCH_AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
+#define CATCH_WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     When: " << desc )
+#define CATCH_AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
+#define CATCH_THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     Then: " << desc )
+#define CATCH_AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( "      And: " << desc )
 
 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
 #else
@@ -187,13 +192,14 @@
 
 #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
 #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
-#define CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg) )
+#define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ )
 
 #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 DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_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__ )
@@ -207,15 +213,17 @@
 #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
 
-#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 )
+#define GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( "    Given: " << desc )
+#define AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
+#define WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     When: " << desc )
+#define AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
+#define THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     Then: " << desc )
+#define AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( "      And: " << desc )
 
 using Catch::Detail::Approx;
 
-#else
+#else // CATCH_CONFIG_DISABLE
+
 //////
 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
 #ifdef CATCH_CONFIG_PREFIX_ALL
@@ -260,6 +268,7 @@ using Catch::Detail::Approx;
 #define CATCH_METHOD_AS_TEST_CASE( method, ... )
 #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
 #define CATCH_SECTION( ... )
+#define CATCH_DYNAMIC_SECTION( ... )
 #define CATCH_FAIL( ... ) (void)(0)
 #define CATCH_FAIL_CHECK( ... ) (void)(0)
 #define CATCH_SUCCEED( ... ) (void)(0)
@@ -270,6 +279,7 @@ using Catch::Detail::Approx;
 #define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
 #define CATCH_GIVEN( desc )
+#define CATCH_AND_GIVEN( desc )
 #define CATCH_WHEN( desc )
 #define CATCH_AND_WHEN( desc )
 #define CATCH_THEN( desc )
@@ -319,6 +329,7 @@ using Catch::Detail::Approx;
 #define METHOD_AS_TEST_CASE( method, ... )
 #define REGISTER_TEST_CASE( Function, ... ) (void)(0)
 #define SECTION( ... )
+#define DYNAMIC_SECTION( ... )
 #define FAIL( ... ) (void)(0)
 #define FAIL_CHECK( ... ) (void)(0)
 #define SUCCEED( ... ) (void)(0)
@@ -333,6 +344,7 @@ using Catch::Detail::Approx;
 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
 
 #define GIVEN( desc )
+#define AND_GIVEN( desc )
 #define WHEN( desc )
 #define AND_WHEN( desc )
 #define THEN( desc )
diff --git a/packages/Catch2/include/internal/catch_approx.cpp b/packages/Catch2/include/internal/catch_approx.cpp
index 20f7b1652be061a1b45ed7d259dec72437a3faa6..a7d7111ca43f4fb24840adebf8611b689ea1a110 100644
--- a/packages/Catch2/include/internal/catch_approx.cpp
+++ b/packages/Catch2/include/internal/catch_approx.cpp
@@ -7,6 +7,7 @@
  */
 
 #include "catch_approx.h"
+#include "catch_enforce.h"
 
 #include <cmath>
 #include <limits>
@@ -35,6 +36,13 @@ namespace Detail {
         return Approx( 0 );
     }
 
+    Approx Approx::operator-() const {
+        auto temp(*this);
+        temp.m_value = -temp.m_value;
+        return temp;
+    }
+
+
     std::string Approx::toString() const {
         ReusableStringStream rss;
         rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
@@ -47,8 +55,31 @@ namespace Detail {
         return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
     }
 
+    void Approx::setMargin(double margin) {
+        CATCH_ENFORCE(margin >= 0,
+            "Invalid Approx::margin: " << margin << '.'
+            << " Approx::Margin has to be non-negative.");
+        m_margin = margin;
+    }
+
+    void Approx::setEpsilon(double epsilon) {
+        CATCH_ENFORCE(epsilon >= 0 && epsilon <= 1.0,
+            "Invalid Approx::epsilon: " << epsilon << '.'
+            << " Approx::epsilon has to be in [0, 1]");
+        m_epsilon = epsilon;
+    }
+
 } // end namespace Detail
 
+namespace literals {
+    Detail::Approx operator "" _a(long double val) {
+        return Detail::Approx(val);
+    }
+    Detail::Approx operator "" _a(unsigned long long val) {
+        return Detail::Approx(val);
+    }
+} // end namespace literals
+
 std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
     return value.toString();
 }
diff --git a/packages/Catch2/include/internal/catch_approx.h b/packages/Catch2/include/internal/catch_approx.h
index 27068872ec7afe4d32b22edc08f636cb42f98ebc..4522e5ad70d1b57c8a5bb0bc874f0680b27bcf9a 100644
--- a/packages/Catch2/include/internal/catch_approx.h
+++ b/packages/Catch2/include/internal/catch_approx.h
@@ -11,7 +11,6 @@
 #include "catch_tostring.h"
 
 #include <type_traits>
-#include <stdexcept>
 
 namespace Catch {
 namespace Detail {
@@ -19,18 +18,26 @@ namespace Detail {
     class Approx {
     private:
         bool equalityComparisonImpl(double other) const;
+        // Validates the new margin (margin >= 0)
+        // out-of-line to avoid including stdexcept in the header
+        void setMargin(double margin);
+        // Validates the new epsilon (0 < epsilon < 1)
+        // out-of-line to avoid including stdexcept in the header
+        void setEpsilon(double epsilon);
 
     public:
         explicit Approx ( double value );
 
         static Approx custom();
 
+        Approx operator-() const;
+
         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
         Approx operator()( T const& value ) {
             Approx approx( static_cast<double>(value) );
-            approx.epsilon( m_epsilon );
-            approx.margin( m_margin );
-            approx.scale( m_scale );
+            approx.m_epsilon = m_epsilon;
+            approx.m_margin = m_margin;
+            approx.m_scale = m_scale;
             return approx;
         }
 
@@ -83,27 +90,14 @@ namespace Detail {
         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
         Approx& epsilon( T const& newEpsilon ) {
             double epsilonAsDouble = static_cast<double>(newEpsilon);
-            if( epsilonAsDouble < 0 || epsilonAsDouble > 1.0 ) {
-                throw std::domain_error
-                    (   "Invalid Approx::epsilon: " +
-                        Catch::Detail::stringify( epsilonAsDouble ) +
-                        ", Approx::epsilon has to be between 0 and 1" );
-            }
-            m_epsilon = epsilonAsDouble;
+            setEpsilon(epsilonAsDouble);
             return *this;
         }
 
         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
         Approx& margin( T const& newMargin ) {
             double marginAsDouble = static_cast<double>(newMargin);
-            if( marginAsDouble < 0 ) {
-                throw std::domain_error
-                    (   "Invalid Approx::margin: " +
-                         Catch::Detail::stringify( marginAsDouble ) +
-                         ", Approx::Margin has to be non-negative." );
-
-            }
-            m_margin = marginAsDouble;
+            setMargin(marginAsDouble);
             return *this;
         }
 
@@ -121,7 +115,12 @@ namespace Detail {
         double m_scale;
         double m_value;
     };
-}
+} // end namespace Detail
+
+namespace literals {
+    Detail::Approx operator "" _a(long double val);
+    Detail::Approx operator "" _a(unsigned long long val);
+} // end namespace literals
 
 template<>
 struct StringMaker<Catch::Detail::Approx> {
diff --git a/packages/Catch2/include/internal/catch_assertionhandler.cpp b/packages/Catch2/include/internal/catch_assertionhandler.cpp
index 28768077ab50eabb4a8d78beba651893a44e0188..77c3f1d4748db6aa4ad3c388f0c4203639923674 100644
--- a/packages/Catch2/include/internal/catch_assertionhandler.cpp
+++ b/packages/Catch2/include/internal/catch_assertionhandler.cpp
@@ -52,7 +52,7 @@ namespace Catch {
     }
 
     AssertionHandler::AssertionHandler
-        (   StringRef macroName,
+        (   StringRef const& macroName,
             SourceLineInfo const& lineInfo,
             StringRef capturedExpression,
             ResultDisposition::Flags resultDisposition )
@@ -81,8 +81,13 @@ namespace Catch {
             // (To go back to the test and change execution, jump over the throw, next)
             CATCH_BREAK_INTO_DEBUGGER();
         }
-        if( m_reaction.shouldThrow )
+        if (m_reaction.shouldThrow) {
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
             throw Catch::TestFailureException();
+#else
+            CATCH_ERROR( "Test failure requires aborting test!" );
+#endif
+        }
     }
     void AssertionHandler::setCompleted() {
         m_completed = true;
@@ -109,7 +114,7 @@ namespace Catch {
 
     // This is the overload that takes a string and infers the Equals matcher from it
     // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
-    void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef matcherString  ) {
+    void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString  ) {
         handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString );
     }
 
diff --git a/packages/Catch2/include/internal/catch_assertionhandler.h b/packages/Catch2/include/internal/catch_assertionhandler.h
index cadc78f34dcf3e2dc4bf32834d44049f1eb3ad11..3089e662c4901c21c2ad72b9d01276488f654c9e 100644
--- a/packages/Catch2/include/internal/catch_assertionhandler.h
+++ b/packages/Catch2/include/internal/catch_assertionhandler.h
@@ -49,7 +49,7 @@ namespace Catch {
 
     public:
         AssertionHandler
-            (   StringRef macroName,
+            (   StringRef const& macroName,
                 SourceLineInfo const& lineInfo,
                 StringRef capturedExpression,
                 ResultDisposition::Flags resultDisposition );
@@ -81,7 +81,7 @@ namespace Catch {
         auto allowThrows() const -> bool;
     };
 
-    void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef matcherString );
+    void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString );
 
 } // namespace Catch
 
diff --git a/packages/Catch2/include/internal/catch_capture.hpp b/packages/Catch2/include/internal/catch_capture.hpp
index e4600f7c6aaec0d890c9e2b1b4569da23160d92c..a9c2e0d72b8905805dd99b890aa3edd112df7b82 100644
--- a/packages/Catch2/include/internal/catch_capture.hpp
+++ b/packages/Catch2/include/internal/catch_capture.hpp
@@ -9,8 +9,9 @@
 #define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
 
 #include "catch_assertionhandler.h"
-#include "catch_message.h"
 #include "catch_interfaces_capture.h"
+#include "catch_message.h"
+#include "catch_stringref.h"
 
 #if !defined(CATCH_CONFIG_DISABLE)
 
@@ -20,7 +21,7 @@
   #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
 #endif
 
-#if defined(CATCH_CONFIG_FAST_COMPILE)
+#if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
 
 ///////////////////////////////////////////////////////////////////////////////
 // Another way to speed-up compilation is to omit local try-catch for REQUIRE*
@@ -40,7 +41,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
         INTERNAL_CATCH_TRY { \
             CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
             catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
@@ -63,7 +64,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
         try { \
             static_cast<void>(__VA_ARGS__); \
             catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
@@ -77,7 +78,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
         if( catchAssertionHandler.allowThrows() ) \
             try { \
                 static_cast<void>(__VA_ARGS__); \
@@ -94,7 +95,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
         if( catchAssertionHandler.allowThrows() ) \
             try { \
                 static_cast<void>(expr); \
@@ -115,27 +116,32 @@
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \
         catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
     } while( false )
 
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \
+    auto varName = Catch::Capturer( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \
+    varName.captureValues( 0, __VA_ARGS__ )
+
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_INFO( macroName, log ) \
-    Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
+    Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
 
 ///////////////////////////////////////////////////////////////////////////////
 // Although this is matcher-based, it can be used with just a string
 #define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
         if( catchAssertionHandler.allowThrows() ) \
             try { \
                 static_cast<void>(__VA_ARGS__); \
                 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
             } \
             catch( ... ) { \
-                Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher ); \
+                Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \
             } \
         else \
             catchAssertionHandler.handleThrowingCallSkipped(); \
diff --git a/packages/Catch2/include/internal/catch_capture_matchers.cpp b/packages/Catch2/include/internal/catch_capture_matchers.cpp
index a67cc797a7ab8b649bf80c62d923deac48d241c8..6f320449a2475fffa240639c4f582e16eb64b12e 100644
--- a/packages/Catch2/include/internal/catch_capture_matchers.cpp
+++ b/packages/Catch2/include/internal/catch_capture_matchers.cpp
@@ -15,7 +15,7 @@ namespace Catch {
     // This is the general overload that takes a any string matcher
     // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
     // the Equals matcher (so the header does not mention matchers)
-    void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString  ) {
+    void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString  ) {
         std::string exceptionMessage = Catch::translateActiveException();
         MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString );
         handler.handleExpr( expr );
diff --git a/packages/Catch2/include/internal/catch_capture_matchers.h b/packages/Catch2/include/internal/catch_capture_matchers.h
index 9026aebf67a3c6e90f0bdf16fa37568ae3a49681..0ced01d5785209496d7c2cdc95406d665aac5243 100644
--- a/packages/Catch2/include/internal/catch_capture_matchers.h
+++ b/packages/Catch2/include/internal/catch_capture_matchers.h
@@ -14,6 +14,7 @@
 #include "catch_matchers_generic.hpp"
 #include "catch_matchers_string.h"
 #include "catch_matchers_vector.h"
+#include "catch_stringref.h"
 
 namespace Catch {
 
@@ -23,7 +24,7 @@ namespace Catch {
         MatcherT m_matcher;
         StringRef m_matcherString;
     public:
-        MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef matcherString )
+        MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString )
         :   ITransientExpression{ true, matcher.match( arg ) },
             m_arg( arg ),
             m_matcher( matcher ),
@@ -42,10 +43,10 @@ namespace Catch {
 
     using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
 
-    void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString  );
+    void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString  );
 
     template<typename ArgT, typename MatcherT>
-    auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef matcherString  ) -> MatchExpr<ArgT, MatcherT> {
+    auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString  ) -> MatchExpr<ArgT, MatcherT> {
         return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );
     }
 
@@ -55,9 +56,9 @@ namespace Catch {
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
         INTERNAL_CATCH_TRY { \
-            catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher ) ); \
+            catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \
         } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
     } while( false )
@@ -66,14 +67,14 @@ namespace Catch {
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
         if( catchAssertionHandler.allowThrows() ) \
             try { \
                 static_cast<void>(__VA_ARGS__ ); \
                 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
             } \
             catch( exceptionType const& ex ) { \
-                catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher ) ); \
+                catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \
             } \
             catch( ... ) { \
                 catchAssertionHandler.handleUnexpectedInflightException(); \
diff --git a/packages/Catch2/include/internal/catch_common.cpp b/packages/Catch2/include/internal/catch_common.cpp
index c271146d7e46da33e8689e588b9a40f7a2586b88..b2fca4c4c330577952027458885a94b19f858b9b 100644
--- a/packages/Catch2/include/internal/catch_common.cpp
+++ b/packages/Catch2/include/internal/catch_common.cpp
@@ -22,7 +22,9 @@ namespace Catch {
         return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
     }
     bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept {
-        return line < other.line || ( line == other.line && (std::strcmp(file, other.file) < 0));
+        // We can assume that the same file will usually have the same pointer.
+        // Thus, if the pointers are the same, there is no point in calling the strcmp
+        return line < other.line || ( line == other.line && file != other.file && (std::strcmp(file, other.file) < 0));
     }
 
     std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
diff --git a/packages/Catch2/include/internal/catch_compiler_capabilities.h b/packages/Catch2/include/internal/catch_compiler_capabilities.h
index 37f625b2827c43b040dcd39802e5d1686a56626d..aa3e599e30a1b9a5c5615f152184667ee547f26c 100644
--- a/packages/Catch2/include/internal/catch_compiler_capabilities.h
+++ b/packages/Catch2/include/internal/catch_compiler_capabilities.h
@@ -14,6 +14,7 @@
 // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
 // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
 // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
+// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?
 // ****************
 // Note to maintainers: if new toggles are added please document them
 // in configuration.md, too
@@ -28,11 +29,11 @@
 
 #ifdef __cplusplus
 
-#  if __cplusplus >= 201402L
+#  if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
 #    define CATCH_CPP14_OR_GREATER
 #  endif
 
-#  if __cplusplus >= 201703L
+#  if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
 #    define CATCH_CPP17_OR_GREATER
 #  endif
 
@@ -57,6 +58,12 @@
 #       define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
             _Pragma( "clang diagnostic pop" )
 
+#       define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
+            _Pragma( "clang diagnostic push" ) \
+            _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
+#       define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS \
+            _Pragma( "clang diagnostic pop" )
+
 #endif // __clang__
 
 
@@ -89,6 +96,12 @@
 #    define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
 #endif
 
+////////////////////////////////////////////////////////////////////////////////
+// PS4
+#if defined(__ORBIS__)
+#    define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
+#endif
+
 ////////////////////////////////////////////////////////////////////////////////
 // Cygwin
 #ifdef __CYGWIN__
@@ -96,7 +109,14 @@
 // 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
+// some versions of cygwin (most) do not support std::to_string. Use the libstd check. 
+// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813
+# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
+	       && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
+
+#	define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
 
+# endif
 #endif // __CYGWIN__
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -119,7 +139,12 @@
 #endif // _MSC_VER
 
 ////////////////////////////////////////////////////////////////////////////////
+// Check if we are compiled with -fno-exceptions or equivalent
+#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
+#  define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
+#endif
 
+////////////////////////////////////////////////////////////////////////////////
 // DJGPP
 #ifdef __DJGPP__
 #  define CATCH_INTERNAL_CONFIG_NO_WCHAR
@@ -136,6 +161,33 @@
     #define CATCH_INTERNAL_CONFIG_COUNTER
 #endif
 
+////////////////////////////////////////////////////////////////////////////////
+// Check if string_view is available and usable
+// The check is split apart to work around v140 (VS2015) preprocessor issue...
+#if defined(__has_include)
+#if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
+#    define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
+#endif
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// Check if variant is available and usable
+#if defined(__has_include)
+#  if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
+#    if defined(__clang__) && (__clang_major__ < 8)
+       // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
+       // fix should be in clang 8, workaround in libstdc++ 8.2
+#      include <ciso646>
+#      if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
+#        define CATCH_CONFIG_NO_CPP17_VARIANT
+#     else
+#        define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
+#      endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
+#    endif // defined(__clang__) && (__clang_major__ < 8)
+#  endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
+#endif // __has_include
+
+
 #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
 #   define CATCH_CONFIG_COUNTER
 #endif
@@ -159,6 +211,25 @@
 #  define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
 #endif
 
+#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
+#  define CATCH_CONFIG_CPP17_STRING_VIEW
+#endif
+
+#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)
+#  define CATCH_CONFIG_CPP17_VARIANT
+#endif
+
+#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
+#  define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
+#endif
+
+#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE)
+#  define CATCH_CONFIG_NEW_CAPTURE
+#endif
+
+#if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+#  define CATCH_CONFIG_DISABLE_EXCEPTIONS
+#endif
 
 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
 #   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
@@ -168,6 +239,20 @@
 #   define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
 #   define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
 #endif
+#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
+#   define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
+#   define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
+#endif
+
+#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+#define CATCH_TRY if ((true))
+#define CATCH_CATCH_ALL if ((false))
+#define CATCH_CATCH_ANON(type) if ((false))
+#else
+#define CATCH_TRY try
+#define CATCH_CATCH_ALL catch (...)
+#define CATCH_CATCH_ANON(type) catch (type)
+#endif
 
 
 #endif // TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_enforce.cpp b/packages/Catch2/include/internal/catch_enforce.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f4db1c150b8e7c944422ca4236564709352bb523
--- /dev/null
+++ b/packages/Catch2/include/internal/catch_enforce.cpp
@@ -0,0 +1,19 @@
+/*
+ *  Created by Martin on 03/09/2018.
+ *
+ *  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)
+ */
+
+#include "catch_enforce.h"
+
+namespace Catch {
+#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER)
+    [[noreturn]]
+    void throw_exception(std::exception const& e) {
+        Catch::cerr() << "Catch will terminate because it needed to throw an exception.\n"
+                      << "The message was: " << e.what() << '\n';
+        std::terminate();
+    }
+#endif
+} // namespace Catch;
diff --git a/packages/Catch2/include/internal/catch_enforce.h b/packages/Catch2/include/internal/catch_enforce.h
index 513dcf1c633f163bc7f6c4bc4221133fdf466d04..0069402302d910a4b4397f1bef76d5698af8b156 100644
--- a/packages/Catch2/include/internal/catch_enforce.h
+++ b/packages/Catch2/include/internal/catch_enforce.h
@@ -8,17 +8,35 @@
 #define TWOBLUECUBES_CATCH_ENFORCE_H_INCLUDED
 
 #include "catch_common.h"
+#include "catch_compiler_capabilities.h"
 #include "catch_stream.h"
 
+
 #include <stdexcept>
 
+namespace Catch {
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+    template <typename Ex>
+    [[noreturn]]
+    void throw_exception(Ex const& e) {
+        throw e;
+    }
+#else // ^^ Exceptions are enabled //  Exceptions are disabled vv
+    [[noreturn]]
+    void throw_exception(std::exception const& e);
+#endif
+} // namespace Catch;
+
 #define CATCH_PREPARE_EXCEPTION( type, msg ) \
     type( ( Catch::ReusableStringStream() << msg ).str() )
 #define CATCH_INTERNAL_ERROR( msg ) \
-    throw CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg);
+    Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg))
 #define CATCH_ERROR( msg ) \
-    throw CATCH_PREPARE_EXCEPTION( std::domain_error, msg )
+    Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::domain_error, msg ))
+#define CATCH_RUNTIME_ERROR( msg ) \
+    Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::runtime_error, msg ))
 #define CATCH_ENFORCE( condition, msg ) \
     do{ if( !(condition) ) CATCH_ERROR( msg ); } while(false)
 
+
 #endif // TWOBLUECUBES_CATCH_ENFORCE_H_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_exception_translator_registry.cpp b/packages/Catch2/include/internal/catch_exception_translator_registry.cpp
index 78b9c57334a48db02685d100e59dfb76c867e74f..b836cd9cba0051edb32e8188f02b7dc05af4eff1 100644
--- a/packages/Catch2/include/internal/catch_exception_translator_registry.cpp
+++ b/packages/Catch2/include/internal/catch_exception_translator_registry.cpp
@@ -6,8 +6,10 @@
  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  */
 
-#include "catch_assertionhandler.h"
 #include "catch_exception_translator_registry.h"
+#include "catch_assertionhandler.h"
+#include "catch_compiler_capabilities.h"
+#include "catch_enforce.h"
 
 #ifdef __OBJC__
 #import "Foundation/Foundation.h"
@@ -22,6 +24,7 @@ namespace Catch {
         m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) );
     }
 
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
     std::string ExceptionTranslatorRegistry::translateActiveException() const {
         try {
 #ifdef __OBJC__
@@ -64,6 +67,13 @@ namespace Catch {
         }
     }
 
+#else // ^^ Exceptions are enabled // Exceptions are disabled vv
+    std::string ExceptionTranslatorRegistry::translateActiveException() const {
+        CATCH_INTERNAL_ERROR("Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
+    }
+#endif
+
+
     std::string ExceptionTranslatorRegistry::tryTranslators() const {
         if( m_translators.empty() )
             std::rethrow_exception(std::current_exception());
diff --git a/packages/Catch2/include/internal/catch_generators.cpp b/packages/Catch2/include/internal/catch_generators.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..786da73675aa0664e2300cc4f37a4822b5fadd76
--- /dev/null
+++ b/packages/Catch2/include/internal/catch_generators.cpp
@@ -0,0 +1,50 @@
+/*
+ *  Created by Phil Nash on 15/6/2018.
+ *
+ *  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)
+ */
+
+#include "catch_generators.hpp"
+#include "catch_random_number_generator.h"
+#include "catch_interfaces_capture.h"
+
+#include <limits>
+#include <set>
+
+namespace Catch {
+
+IGeneratorTracker::~IGeneratorTracker() {}
+
+namespace Generators {
+
+    GeneratorBase::~GeneratorBase() {}
+
+    std::vector<size_t> randomiseIndices( size_t selectionSize, size_t sourceSize ) {
+
+        assert( selectionSize <= sourceSize );
+        std::vector<size_t> indices;
+        indices.reserve( selectionSize );
+        std::uniform_int_distribution<size_t> uid( 0, sourceSize-1 );
+
+        std::set<size_t> seen;
+        // !TBD: improve this algorithm
+        while( indices.size() < selectionSize ) {
+            auto index = uid( rng() );
+            if( seen.insert( index ).second )
+                indices.push_back( index );
+        }
+        return indices;
+    }
+
+    auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
+        return getResultCapture().acquireGeneratorTracker( lineInfo );
+    }
+
+    template<>
+    auto all<int>() -> Generator<int> {
+        return range( std::numeric_limits<int>::min(), std::numeric_limits<int>::max() );
+    }
+
+} // namespace Generators
+} // namespace Catch
diff --git a/packages/Catch2/include/internal/catch_generators.hpp b/packages/Catch2/include/internal/catch_generators.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..4a446be131e36ac309790f4744ae8b3efd084d4e
--- /dev/null
+++ b/packages/Catch2/include/internal/catch_generators.hpp
@@ -0,0 +1,253 @@
+/*
+ *  Created by Phil Nash on 15/6/2018.
+ *
+ *  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_CATCH_GENERATORS_HPP_INCLUDED
+#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
+
+#include "catch_interfaces_generatortracker.h"
+#include "catch_common.h"
+#include "catch_enforce.h"
+
+#include <memory>
+#include <vector>
+#include <cassert>
+
+#include <utility>
+
+namespace Catch {
+namespace Generators {
+
+    // !TBD move this into its own location?
+    namespace pf{
+        template<typename T, typename... Args>
+        std::unique_ptr<T> make_unique( Args&&... args ) {
+            return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
+        }
+    }
+
+    template<typename T>
+    struct IGenerator {
+        virtual ~IGenerator() {}
+        virtual auto get( size_t index ) const -> T = 0;
+    };
+
+    template<typename T>
+    class SingleValueGenerator : public IGenerator<T> {
+        T m_value;
+    public:
+        SingleValueGenerator( T const& value ) : m_value( value ) {}
+
+        auto get( size_t ) const -> T override {
+            return m_value;
+        }
+    };
+
+    template<typename T>
+    class FixedValuesGenerator : public IGenerator<T> {
+        std::vector<T> m_values;
+
+    public:
+        FixedValuesGenerator( std::initializer_list<T> values ) : m_values( values ) {}
+
+        auto get( size_t index ) const -> T override {
+            return m_values[index];
+        }
+    };
+
+    template<typename T>
+    class RangeGenerator : public IGenerator<T> {
+        T const m_first;
+        T const m_last;
+
+    public:
+        RangeGenerator( T const& first, T const& last ) : m_first( first ), m_last( last ) {
+            assert( m_last > m_first );
+        }
+
+        auto get( size_t index ) const -> T override {
+            // ToDo:: introduce a safe cast to catch potential overflows
+            return static_cast<T>(m_first+index);
+        }
+    };
+
+
+    template<typename T>
+    struct NullGenerator : IGenerator<T> {
+        auto get( size_t ) const -> T override {
+            CATCH_INTERNAL_ERROR("A Null Generator is always empty");
+        }
+    };
+
+    template<typename T>
+    class Generator {
+        std::unique_ptr<IGenerator<T>> m_generator;
+        size_t m_size;
+
+    public:
+        Generator( size_t size, std::unique_ptr<IGenerator<T>> generator )
+        :   m_generator( std::move( generator ) ),
+            m_size( size )
+        {}
+
+        auto size() const -> size_t { return m_size; }
+        auto operator[]( size_t index ) const -> T {
+            assert( index < m_size );
+            return m_generator->get( index );
+        }
+    };
+
+    std::vector<size_t> randomiseIndices( size_t selectionSize, size_t sourceSize );
+
+    template<typename T>
+    class GeneratorRandomiser : public IGenerator<T> {
+        Generator<T> m_baseGenerator;
+
+        std::vector<size_t> m_indices;
+    public:
+        GeneratorRandomiser( Generator<T>&& baseGenerator, size_t numberOfItems )
+        :   m_baseGenerator( std::move( baseGenerator ) ),
+            m_indices( randomiseIndices( numberOfItems, m_baseGenerator.size() ) )
+        {}
+
+        auto get( size_t index ) const -> T override {
+            return m_baseGenerator[m_indices[index]];
+        }
+    };
+
+    template<typename T>
+    struct RequiresASpecialisationFor;
+
+    template<typename T>
+    auto all() -> Generator<T> { return RequiresASpecialisationFor<T>(); }
+
+    template<>
+    auto all<int>() -> Generator<int>;
+
+
+    template<typename T>
+    auto range( T const& first, T const& last ) -> Generator<T> {
+        return Generator<T>( (last-first), pf::make_unique<RangeGenerator<T>>( first, last ) );
+    }
+
+    template<typename T>
+    auto random( T const& first, T const& last ) -> Generator<T> {
+        auto gen = range( first, last );
+        auto size = gen.size();
+
+        return Generator<T>( size, pf::make_unique<GeneratorRandomiser<T>>( std::move( gen ), size ) );
+    }
+    template<typename T>
+    auto random( size_t size ) -> Generator<T> {
+        return Generator<T>( size, pf::make_unique<GeneratorRandomiser<T>>( all<T>(), size ) );
+    }
+
+    template<typename T>
+    auto values( std::initializer_list<T> values ) -> Generator<T> {
+        return Generator<T>( values.size(), pf::make_unique<FixedValuesGenerator<T>>( values ) );
+    }
+    template<typename T>
+    auto value( T const& val ) -> Generator<T> {
+        return Generator<T>( 1, pf::make_unique<SingleValueGenerator<T>>( val ) );
+    }
+
+    template<typename T>
+    auto as() -> Generator<T> {
+        return Generator<T>( 0, pf::make_unique<NullGenerator<T>>() );
+    }
+
+    template<typename... Ts>
+    auto table( std::initializer_list<std::tuple<Ts...>>&& tuples ) -> Generator<std::tuple<Ts...>> {
+        return values<std::tuple<Ts...>>( std::forward<std::initializer_list<std::tuple<Ts...>>>( tuples ) );
+    }
+
+
+    template<typename T>
+    struct Generators : GeneratorBase {
+        std::vector<Generator<T>> m_generators;
+
+        using type = T;
+
+        Generators() : GeneratorBase( 0 ) {}
+
+        void populate( T&& val ) {
+            m_size += 1;
+            m_generators.emplace_back( value( std::move( val ) ) );
+        }
+        template<typename U>
+        void populate( U&& val ) {
+            populate( T( std::move( val ) ) );
+        }
+        void populate( Generator<T>&& generator ) {
+            m_size += generator.size();
+            m_generators.emplace_back( std::move( generator ) );
+        }
+
+        template<typename U, typename... Gs>
+        void populate( U&& valueOrGenerator, Gs... moreGenerators ) {
+            populate( std::forward<U>( valueOrGenerator ) );
+            populate( std::forward<Gs>( moreGenerators )... );
+        }
+
+        auto operator[]( size_t index ) const -> T {
+            size_t sizes = 0;
+            for( auto const& gen : m_generators ) {
+                auto localIndex = index-sizes;
+                sizes += gen.size();
+                if( index < sizes )
+                    return gen[localIndex];
+            }
+            CATCH_INTERNAL_ERROR("Index '" << index << "' is out of range (" << sizes << ')');
+        }
+    };
+
+    template<typename T, typename... Gs>
+    auto makeGenerators( Generator<T>&& generator, Gs... moreGenerators ) -> Generators<T> {
+        Generators<T> generators;
+        generators.m_generators.reserve( 1+sizeof...(Gs) );
+        generators.populate( std::move( generator ), std::forward<Gs>( moreGenerators )... );
+        return generators;
+    }
+    template<typename T>
+    auto makeGenerators( Generator<T>&& generator ) -> Generators<T> {
+        Generators<T> generators;
+        generators.populate( std::move( generator ) );
+        return generators;
+    }
+    template<typename T, typename... Gs>
+    auto makeGenerators( T&& val, Gs... moreGenerators ) -> Generators<T> {
+        return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... );
+    }
+    template<typename T, typename U, typename... Gs>
+    auto makeGenerators( U&& val, Gs... moreGenerators ) -> Generators<T> {
+        return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... );
+    }
+
+
+    auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
+
+    template<typename L>
+    // Note: The type after -> is weird, because VS2015 cannot parse
+    //       the expression used in the typedef inside, when it is in
+    //       return type. Yeah, ¯\_(ツ)_/¯
+    auto generate( SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>()[0]) {
+        using UnderlyingType = typename decltype(generatorExpression())::type;
+
+        IGeneratorTracker& tracker = acquireGeneratorTracker( lineInfo );
+        if( !tracker.hasGenerator() )
+            tracker.setGenerator( pf::make_unique<Generators<UnderlyingType>>( generatorExpression() ) );
+
+        auto const& generator = static_cast<Generators<UnderlyingType> const&>( *tracker.getGenerator() );
+        return generator[tracker.getIndex()];
+    }
+
+} // namespace Generators
+} // namespace Catch
+
+#define GENERATE( ... ) \
+    Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, []{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
+
+
+#endif // TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_interfaces_capture.h b/packages/Catch2/include/internal/catch_interfaces_capture.h
index 4d091f892e95b86a96e0186bbacc4a509995de52..950d498dce5d9eccc27827ab9ba8913ed7b8caff 100644
--- a/packages/Catch2/include/internal/catch_interfaces_capture.h
+++ b/packages/Catch2/include/internal/catch_interfaces_capture.h
@@ -24,8 +24,10 @@ namespace Catch {
     struct BenchmarkInfo;
     struct BenchmarkStats;
     struct AssertionReaction;
+    struct SourceLineInfo;
 
     struct ITransientExpression;
+    struct IGeneratorTracker;
 
     struct IResultCapture {
 
@@ -36,6 +38,8 @@ namespace Catch {
         virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
         virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
 
+        virtual auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
+
         virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
         virtual void benchmarkEnded( BenchmarkStats const& stats ) = 0;
 
diff --git a/packages/Catch2/include/internal/catch_interfaces_generatortracker.h b/packages/Catch2/include/internal/catch_interfaces_generatortracker.h
new file mode 100644
index 0000000000000000000000000000000000000000..2cf6269e4d05ce81bb02cfa844eca5cd8b2081d1
--- /dev/null
+++ b/packages/Catch2/include/internal/catch_interfaces_generatortracker.h
@@ -0,0 +1,39 @@
+/*
+ *  Created by Phil Nash on 26/6/2018.
+ *
+ *  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_CATCH_INTERFACES_GENERATORTRACKER_INCLUDED
+#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORTRACKER_INCLUDED
+
+#include <memory>
+
+namespace Catch {
+
+    namespace Generators {
+        class GeneratorBase {
+        protected:
+            size_t m_size = 0;
+
+        public:
+            GeneratorBase( size_t size ) : m_size( size ) {}
+            virtual ~GeneratorBase();
+            auto size() const -> size_t { return m_size; }
+        };
+        using GeneratorBasePtr = std::unique_ptr<GeneratorBase>;
+
+    } // namespace Generators
+
+    struct IGeneratorTracker {
+        virtual ~IGeneratorTracker();
+        virtual auto hasGenerator() const -> bool = 0;
+        virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0;
+        virtual void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0;
+        virtual auto getIndex() const -> std::size_t = 0;
+    };
+
+} // namespace Catch
+
+#endif //TWOBLUECUBES_CATCH_INTERFACES_GENERATORTRACKER_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_interfaces_registry_hub.h b/packages/Catch2/include/internal/catch_interfaces_registry_hub.h
index 1afbbec78db314cf2b8bb7de9212d8366ee754a7..8e1da61e029bddca45776b673331aee267d943a9 100644
--- a/packages/Catch2/include/internal/catch_interfaces_registry_hub.h
+++ b/packages/Catch2/include/internal/catch_interfaces_registry_hub.h
@@ -33,7 +33,7 @@ namespace Catch {
         virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
         virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
 
-        virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
+        virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0;
 
 
         virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;
@@ -49,7 +49,7 @@ namespace Catch {
         virtual void registerStartupException() noexcept = 0;
     };
 
-    IRegistryHub& getRegistryHub();
+    IRegistryHub const& getRegistryHub();
     IMutableRegistryHub& getMutableRegistryHub();
     void cleanUp();
     std::string translateActiveException();
diff --git a/packages/Catch2/include/internal/catch_interfaces_reporter.h b/packages/Catch2/include/internal/catch_interfaces_reporter.h
index 76f5fd5ae25b56b39df6aacd047859dca7565a69..9d99c9814aa55e451b0d51d82fe0c4f67d617088 100644
--- a/packages/Catch2/include/internal/catch_interfaces_reporter.h
+++ b/packages/Catch2/include/internal/catch_interfaces_reporter.h
@@ -42,6 +42,7 @@ namespace Catch {
 
     struct ReporterPreferences {
         bool shouldRedirectStdOut = false;
+        bool shouldReportAllAssertions = false;
     };
 
     template<typename T>
diff --git a/packages/Catch2/include/internal/catch_leak_detector.cpp b/packages/Catch2/include/internal/catch_leak_detector.cpp
index 36aba6abc8b5a972ef62e030a7936dbd1831214d..dd160d9c44644f04b2119cf608663260441b7cac 100644
--- a/packages/Catch2/include/internal/catch_leak_detector.cpp
+++ b/packages/Catch2/include/internal/catch_leak_detector.cpp
@@ -13,16 +13,16 @@
 
 namespace Catch {
 
-	LeakDetector::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);
-	}
+    LeakDetector::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
diff --git a/packages/Catch2/include/internal/catch_matchers.h b/packages/Catch2/include/internal/catch_matchers.h
index f2e3aee9ff328a8a9f8a720a2ef4ae5811b0aa17..29692fc05e6e19b55c7271193acbccf89b93dc35 100644
--- a/packages/Catch2/include/internal/catch_matchers.h
+++ b/packages/Catch2/include/internal/catch_matchers.h
@@ -34,6 +34,11 @@ namespace Matchers {
             mutable std::string m_cachedToString;
         };
 
+#ifdef __clang__
+#    pragma clang diagnostic push
+#    pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+
         template<typename ObjectT>
         struct MatcherMethod {
             virtual bool match( ObjectT const& arg ) const = 0;
@@ -43,6 +48,10 @@ namespace Matchers {
             virtual bool match( PtrT* arg ) const = 0;
         };
 
+#ifdef __clang__
+#    pragma clang diagnostic pop
+#endif
+
         template<typename T>
         struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
 
diff --git a/packages/Catch2/include/internal/catch_matchers_floating.cpp b/packages/Catch2/include/internal/catch_matchers_floating.cpp
index 72728a83d2d5f7786317d43d1d274b863cdadfbb..312069867d1ec167cd0a6d8542925e3527b6c684 100644
--- a/packages/Catch2/include/internal/catch_matchers_floating.cpp
+++ b/packages/Catch2/include/internal/catch_matchers_floating.cpp
@@ -6,13 +6,13 @@
  */
 
 #include "catch_matchers_floating.h"
+#include "catch_enforce.h"
 #include "catch_to_string.hpp"
 #include "catch_tostring.h"
 
 #include <cstdlib>
 #include <cstdint>
 #include <cstring>
-#include <stdexcept>
 
 namespace Catch {
 namespace Matchers {
@@ -81,9 +81,8 @@ namespace Matchers {
 namespace Floating {
     WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
         :m_target{ target }, m_margin{ margin } {
-        if (m_margin < 0) {
-            throw std::domain_error("Allowed margin difference has to be >= 0");
-        }
+        CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.'
+            << " Margin has to be non-negative.");
     }
 
     // Performs equivalent check of std::fabs(lhs - rhs) <= margin
@@ -99,11 +98,16 @@ namespace Floating {
 
     WithinUlpsMatcher::WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType)
         :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
-        if (m_ulps < 0) {
-            throw std::domain_error("Allowed ulp difference has to be >= 0");
-        }
+        CATCH_ENFORCE(ulps >= 0, "Invalid ULP setting: " << ulps << '.'
+            << " ULPs have to be non-negative.");
     }
 
+#if defined(__clang__)
+#pragma clang diagnostic push
+// Clang <3.5 reports on the default branch in the switch below
+#pragma clang diagnostic ignored "-Wunreachable-code"
+#endif
+
     bool WithinUlpsMatcher::match(double const& matchee) const {
         switch (m_type) {
         case FloatingPointKind::Float:
@@ -111,10 +115,14 @@ namespace Floating {
         case FloatingPointKind::Double:
             return almostEqualUlps<double>(matchee, m_target, m_ulps);
         default:
-            throw std::domain_error("Unknown FloatingPointKind value");
+            CATCH_INTERNAL_ERROR( "Unknown FloatingPointKind value" );
         }
     }
 
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+
     std::string WithinUlpsMatcher::describe() const {
         return "is within " + Catch::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float)? "f" : "");
     }
diff --git a/packages/Catch2/include/internal/catch_matchers_vector.h b/packages/Catch2/include/internal/catch_matchers_vector.h
index 833d7dc2c4d04600aa5b5c83f76345e2968558d3..1e29cc940327629762d2fde514af142f658a9d1d 100644
--- a/packages/Catch2/include/internal/catch_matchers_vector.h
+++ b/packages/Catch2/include/internal/catch_matchers_vector.h
@@ -124,7 +124,7 @@ namespace Matchers {
                 auto lfirst = m_target.begin(), llast = m_target.end();
                 auto rfirst = vec.begin(), rlast = vec.end();
                 // Cut common prefix to optimize checking of permuted parts
-                while (lfirst != llast && *lfirst != *rfirst) {
+                while (lfirst != llast && *lfirst == *rfirst) {
                     ++lfirst; ++rfirst;
                 }
                 if (lfirst == llast) {
diff --git a/packages/Catch2/include/internal/catch_message.cpp b/packages/Catch2/include/internal/catch_message.cpp
index 8684970a97eed63429ba53fb66904e83a63b60d7..df905bf6b498dd40c28175471dee11f0b1e8c80a 100644
--- a/packages/Catch2/include/internal/catch_message.cpp
+++ b/packages/Catch2/include/internal/catch_message.cpp
@@ -10,9 +10,11 @@
 #include "catch_interfaces_capture.h"
 #include "catch_uncaught_exceptions.h"
 
+#include <cassert>
+
 namespace Catch {
 
-    MessageInfo::MessageInfo(   std::string const& _macroName,
+    MessageInfo::MessageInfo(   StringRef const& _macroName,
                                 SourceLineInfo const& _lineInfo,
                                 ResultWas::OfType _type )
     :   macroName( _macroName ),
@@ -35,7 +37,7 @@ namespace Catch {
 
     ////////////////////////////////////////////////////////////////////////////
 
-    Catch::MessageBuilder::MessageBuilder( std::string const& macroName,
+    Catch::MessageBuilder::MessageBuilder( StringRef const& macroName,
                                            SourceLineInfo const& lineInfo,
                                            ResultWas::OfType type )
         :m_info(macroName, lineInfo, type) {}
@@ -55,4 +57,36 @@ namespace Catch {
             getResultCapture().popScopedMessage(m_info);
         }
     }
+
+
+    Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) {
+        auto start = std::string::npos;
+        for( size_t pos = 0; pos <= names.size(); ++pos ) {
+            char c = names[pos];
+            if( pos == names.size() || c == ' ' || c == '\t' || c == ',' || c == ']' ) {
+                if( start != std::string::npos ) {
+                    m_messages.push_back( MessageInfo( macroName, lineInfo, resultType ) );
+                    m_messages.back().message = names.substr( start, pos-start) + " := ";
+                    start = std::string::npos;
+                }
+            }
+            else if( c != '[' && c != ']' && start == std::string::npos )
+                start = pos;
+        }
+    }
+    Capturer::~Capturer() {
+        if ( !uncaught_exceptions() ){
+            assert( m_captured == m_messages.size() );
+            for( size_t i = 0; i < m_captured; ++i  )
+                m_resultCapture.popScopedMessage( m_messages[i] );
+        }
+    }
+
+    void Capturer::captureValue( size_t index, StringRef value ) {
+        assert( index < m_messages.size() );
+        m_messages[index].message += value;
+        m_resultCapture.pushScopedMessage( m_messages[index] );
+        m_captured++;
+    }
+
 } // end namespace Catch
diff --git a/packages/Catch2/include/internal/catch_message.h b/packages/Catch2/include/internal/catch_message.h
index 0a512ed578eae4c908fd6d22b518ef99197c4bb9..73f9efd16231623d88372cd18b2b1f56e7d56413 100644
--- a/packages/Catch2/include/internal/catch_message.h
+++ b/packages/Catch2/include/internal/catch_message.h
@@ -8,19 +8,23 @@
 #ifndef TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
 #define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
 
-#include <string>
 #include "catch_result_type.h"
 #include "catch_common.h"
 #include "catch_stream.h"
+#include "catch_interfaces_capture.h"
+#include "catch_tostring.h"
+
+#include <string>
+#include <vector>
 
 namespace Catch {
 
     struct MessageInfo {
-        MessageInfo(    std::string const& _macroName,
+        MessageInfo(    StringRef const& _macroName,
                         SourceLineInfo const& _lineInfo,
                         ResultWas::OfType _type );
 
-        std::string macroName;
+        StringRef macroName;
         std::string message;
         SourceLineInfo lineInfo;
         ResultWas::OfType type;
@@ -44,7 +48,7 @@ namespace Catch {
     };
 
     struct MessageBuilder : MessageStream {
-        MessageBuilder( std::string const& macroName,
+        MessageBuilder( StringRef const& macroName,
                         SourceLineInfo const& lineInfo,
                         ResultWas::OfType type );
 
@@ -65,6 +69,28 @@ namespace Catch {
         MessageInfo m_info;
     };
 
+    class Capturer {
+        std::vector<MessageInfo> m_messages;
+        IResultCapture& m_resultCapture = getResultCapture();
+        size_t m_captured = 0;
+    public:
+        Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
+        ~Capturer();
+
+        void captureValue( size_t index, StringRef value );
+
+        template<typename T>
+        void captureValues( size_t index, T&& value ) {
+            captureValue( index, Catch::Detail::stringify( value ) );
+        }
+
+        template<typename T, typename... Ts>
+        void captureValues( size_t index, T&& value, Ts&&... values ) {
+            captureValues( index, value );
+            captureValues( index+1, values... );
+        }
+    };
+
 } // end namespace Catch
 
 #endif // TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_output_redirect.cpp b/packages/Catch2/include/internal/catch_output_redirect.cpp
index c43dca04870026d742dceeb0a18fef89b1fc4e1d..86b0f6a0ed2065cc1844c5f352f824e87e211204 100644
--- a/packages/Catch2/include/internal/catch_output_redirect.cpp
+++ b/packages/Catch2/include/internal/catch_output_redirect.cpp
@@ -6,8 +6,7 @@
  */
 
 #include "catch_output_redirect.h"
-
-
+#include "catch_enforce.h"
 
 #include <cstdio>
 #include <cstring>
@@ -15,15 +14,18 @@
 #include <sstream>
 #include <stdexcept>
 
-#if defined(_MSC_VER)
-#include <io.h>      //_dup and _dup2
-#define dup _dup
-#define dup2 _dup2
-#define fileno _fileno
-#else
-#include <unistd.h>  // dup and dup2
+#if defined(CATCH_CONFIG_NEW_CAPTURE)
+    #if defined(_MSC_VER)
+    #include <io.h>      //_dup and _dup2
+    #define dup _dup
+    #define dup2 _dup2
+    #define fileno _fileno
+    #else
+    #include <unistd.h>  // dup and dup2
+    #endif
 #endif
 
+
 namespace Catch {
 
     RedirectedStream::RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream )
@@ -48,25 +50,26 @@ namespace Catch {
     auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); }
 
 
+#if defined(CATCH_CONFIG_NEW_CAPTURE)
 
 #if defined(_MSC_VER)
     TempFile::TempFile() {
         if (tmpnam_s(m_buffer)) {
-            throw std::runtime_error("Could not get a temp filename");
+            CATCH_RUNTIME_ERROR("Could not get a temp filename");
         }
         if (fopen_s(&m_file, m_buffer, "w")) {
             char buffer[100];
             if (strerror_s(buffer, errno)) {
-                throw std::runtime_error("Could not translate errno to string");
+                CATCH_RUNTIME_ERROR("Could not translate errno to a string");
             }
-            throw std::runtime_error("Could not open the temp file: " + std::string(m_buffer) + buffer);
+            CATCH_RUNTIME_ERROR("Coul dnot open the temp file: '" << m_buffer << "' because: " << buffer);
         }
     }
 #else
     TempFile::TempFile() {
         m_file = std::tmpfile();
         if (!m_file) {
-            throw std::runtime_error("Could not create a temp file.");
+            CATCH_RUNTIME_ERROR("Could not create a temp file.");
         }
     }
 
@@ -122,11 +125,14 @@ namespace Catch {
         m_stderrDest += m_stderrFile.getContents();
     }
 
+#endif // CATCH_CONFIG_NEW_CAPTURE
 
 } // namespace Catch
 
-#if defined(_MSC_VER)
-#undef dup
-#undef dup2
-#undef fileno
+#if defined(CATCH_CONFIG_NEW_CAPTURE)
+    #if defined(_MSC_VER)
+    #undef dup
+    #undef dup2
+    #undef fileno
+    #endif
 #endif
diff --git a/packages/Catch2/include/internal/catch_output_redirect.h b/packages/Catch2/include/internal/catch_output_redirect.h
index f052bd2b3dbbaf13831a598d64a516de24904f2e..ac04040550f0c205569da76c9a7d81b50a7518c6 100644
--- a/packages/Catch2/include/internal/catch_output_redirect.h
+++ b/packages/Catch2/include/internal/catch_output_redirect.h
@@ -47,6 +47,8 @@ namespace Catch {
     };
 
 
+#if defined(CATCH_CONFIG_NEW_CAPTURE)
+
     // Windows's implementation of std::tmpfile is terrible (it tries
     // to create a file inside system folder, thus requiring elevated
     // privileges for the binary), so we have to use tmpnam(_s) and
@@ -92,6 +94,7 @@ namespace Catch {
         std::string& m_stderrDest;
     };
 
+#endif
 
 } // end namespace Catch
 
diff --git a/packages/Catch2/include/internal/catch_random_number_generator.cpp b/packages/Catch2/include/internal/catch_random_number_generator.cpp
index 412faebae82531d0916cc1e3b31ee9e61d0e3131..ec8a5eb96f1f45fec312057959795843134a7dfb 100644
--- a/packages/Catch2/include/internal/catch_random_number_generator.cpp
+++ b/packages/Catch2/include/internal/catch_random_number_generator.cpp
@@ -9,23 +9,21 @@
 #include "catch_context.h"
 #include "catch_interfaces_config.h"
 
-#include <cstdlib>
-
 namespace Catch {
 
+    std::mt19937& rng() {
+        static std::mt19937 s_rng;
+        return s_rng;
+    }
+
     void seedRng( IConfig const& config ) {
-        if( config.rngSeed() != 0 )
+        if( config.rngSeed() != 0 ) {
             std::srand( config.rngSeed() );
+            rng().seed( config.rngSeed() );
+        }
     }
+
     unsigned int rngSeed() {
         return getCurrentContext().getConfig()->rngSeed();
     }
-
-    RandomNumberGenerator::result_type RandomNumberGenerator::operator()( result_type n ) const {
-        return std::rand() % n;
-    }
-    RandomNumberGenerator::result_type RandomNumberGenerator::operator()() const {
-        return std::rand() % (max)();
-    }
-
 }
diff --git a/packages/Catch2/include/internal/catch_random_number_generator.h b/packages/Catch2/include/internal/catch_random_number_generator.h
index d18cffd5efa9efde7e6b1b7e4b26060ba3513b9f..817b7841aef513bbeabc4e25ecd8e68990487c0d 100644
--- a/packages/Catch2/include/internal/catch_random_number_generator.h
+++ b/packages/Catch2/include/internal/catch_random_number_generator.h
@@ -8,31 +8,16 @@
 #define TWOBLUECUBES_CATCH_RANDOM_NUMBER_GENERATOR_H_INCLUDED
 
 #include <algorithm>
+#include <random>
 
 namespace Catch {
 
     struct IConfig;
 
+    std::mt19937& rng();
     void seedRng( IConfig const& config );
-
     unsigned int rngSeed();
 
-    struct RandomNumberGenerator {
-        using result_type = unsigned int;
-
-        static constexpr result_type (min)() { return 0; }
-        static constexpr result_type (max)() { return 1000000; }
-
-        result_type operator()( result_type n ) const;
-        result_type operator()() const;
-
-        template<typename V>
-        static void shuffle( V& vector ) {
-            RandomNumberGenerator rng;
-            std::shuffle( vector.begin(), vector.end(), rng );
-        }
-    };
-
 }
 
 #endif // TWOBLUECUBES_CATCH_RANDOM_NUMBER_GENERATOR_H_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_registry_hub.cpp b/packages/Catch2/include/internal/catch_registry_hub.cpp
index d98708c58434734fa463a46557874b5375c25e3d..a5062398519ce923a4e4f0ad36f35a2e1f7bdfd1 100644
--- a/packages/Catch2/include/internal/catch_registry_hub.cpp
+++ b/packages/Catch2/include/internal/catch_registry_hub.cpp
@@ -14,6 +14,7 @@
 #include "catch_exception_translator_registry.h"
 #include "catch_tag_alias_registry.h"
 #include "catch_startup_exception_registry.h"
+#include "catch_singletons.hpp"
 
 namespace Catch {
 
@@ -30,7 +31,7 @@ namespace Catch {
             ITestCaseRegistry const& getTestCaseRegistry() const override {
                 return m_testCaseRegistry;
             }
-            IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() override {
+            IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const override {
                 return m_exceptionTranslatorRegistry;
             }
             ITagAliasRegistry const& getTagAliasRegistry() const override {
@@ -67,27 +68,19 @@ namespace Catch {
             TagAliasRegistry m_tagAliasRegistry;
             StartupExceptionRegistry m_exceptionRegistry;
         };
-
-        // Single, global, instance
-        RegistryHub*& getTheRegistryHub() {
-            static RegistryHub* theRegistryHub = nullptr;
-            if( !theRegistryHub )
-                theRegistryHub = new RegistryHub();
-            return theRegistryHub;
-        }
     }
 
-    IRegistryHub& getRegistryHub() {
-        return *getTheRegistryHub();
+    using RegistryHubSingleton = Singleton<RegistryHub, IRegistryHub, IMutableRegistryHub>;
+
+    IRegistryHub const& getRegistryHub() {
+        return RegistryHubSingleton::get();
     }
     IMutableRegistryHub& getMutableRegistryHub() {
-        return *getTheRegistryHub();
+        return RegistryHubSingleton::getMutable();
     }
     void cleanUp() {
-        delete getTheRegistryHub();
-        getTheRegistryHub() = nullptr;
+        cleanupSingletons();
         cleanUpContext();
-        ReusableStringStream::cleanup();
     }
     std::string translateActiveException() {
         return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
diff --git a/packages/Catch2/include/internal/catch_run_context.cpp b/packages/Catch2/include/internal/catch_run_context.cpp
index 97700bef9bf03c85c6631881c9345fa685139acb..ffdd2ebbf6ac1cb3897f35a580828010e3efa11a 100644
--- a/packages/Catch2/include/internal/catch_run_context.cpp
+++ b/packages/Catch2/include/internal/catch_run_context.cpp
@@ -1,4 +1,5 @@
 #include "catch_run_context.h"
+#include "catch_compiler_capabilities.h"
 #include "catch_context.h"
 #include "catch_enforce.h"
 #include "catch_random_number_generator.h"
@@ -11,13 +12,77 @@
 
 namespace Catch {
 
+    namespace Generators {
+        struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker {
+            size_t m_index = static_cast<size_t>( -1 );
+            GeneratorBasePtr m_generator;
+
+            GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
+            :   TrackerBase( nameAndLocation, ctx, parent )
+            {}
+            ~GeneratorTracker();
+
+            static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {
+                std::shared_ptr<GeneratorTracker> tracker;
+
+                ITracker& currentTracker = ctx.currentTracker();
+                if( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
+                    assert( childTracker );
+                    assert( childTracker->isIndexTracker() );
+                    tracker = std::static_pointer_cast<GeneratorTracker>( childTracker );
+                }
+                else {
+                    tracker = std::make_shared<GeneratorTracker>( nameAndLocation, ctx, &currentTracker );
+                    currentTracker.addChild( tracker );
+                }
+
+                if( !ctx.completedCycle() && !tracker->isComplete() ) {
+                    if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
+                        tracker->moveNext();
+                    tracker->open();
+                }
+
+                return *tracker;
+            }
+
+            void moveNext() {
+                m_index++;
+                m_children.clear();
+            }
+
+            // TrackerBase interface
+            bool isIndexTracker() const override { return true; }
+            auto hasGenerator() const -> bool override {
+                return !!m_generator;
+            }
+            void close() override {
+                TrackerBase::close();
+                if( m_runState == CompletedSuccessfully && m_index < m_generator->size()-1 )
+                    m_runState = Executing;
+            }
+
+            // IGeneratorTracker interface
+            auto getGenerator() const -> GeneratorBasePtr const& override {
+                return m_generator;
+            }
+            void setGenerator( GeneratorBasePtr&& generator ) override {
+                m_generator = std::move( generator );
+            }
+            auto getIndex() const -> size_t override {
+                return m_index;
+            }
+        };
+        GeneratorTracker::~GeneratorTracker() {}
+    }
+
+
     RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
     :   m_runInfo(_config->name()),
         m_context(getCurrentMutableContext()),
         m_config(_config),
         m_reporter(std::move(reporter)),
         m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
-        m_includeSuccessfulResults( m_config->includeSuccessfulResults() )
+        m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions )
     {
         m_context.setRunner(this);
         m_context.setConfig(m_config);
@@ -128,6 +193,13 @@ namespace Catch {
 
         return true;
     }
+    auto RunContext::acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
+        using namespace Generators;
+        GeneratorTracker& tracker = GeneratorTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( "generator", lineInfo ) );
+        assert( tracker.isOpen() );
+        m_lastAssertionInfo.lineInfo = lineInfo;
+        return tracker;
+    }
 
     bool RunContext::testForMissingAssertions(Counts& assertions) {
         if (assertions.total() != 0)
@@ -208,7 +280,7 @@ namespace Catch {
 
         // Recreate section for test case (as we will lose the one that was in scope)
         auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
-        SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description);
+        SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
 
         Counts assertions;
         assertions.failed = 1;
@@ -241,12 +313,12 @@ namespace Catch {
     }
 
     bool RunContext::aborting() const {
-        return m_totals.assertions.failed == static_cast<std::size_t>(m_config->abortAfter());
+        return m_totals.assertions.failed >= static_cast<std::size_t>(m_config->abortAfter());
     }
 
     void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
         auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
-        SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description);
+        SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
         m_reporter->sectionStarting(testCaseSection);
         Counts prevAssertions = m_totals.assertions;
         double duration = 0;
@@ -256,7 +328,7 @@ namespace Catch {
         seedRng(*m_config);
 
         Timer timer;
-        try {
+        CATCH_TRY {
             if (m_reporter->getPreferences().shouldRedirectStdOut) {
 #if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
                 RedirectedStdOut redirectedStdOut;
@@ -276,9 +348,9 @@ namespace Catch {
                 invokeActiveTestCase();
             }
             duration = timer.getElapsedSeconds();
-        } catch (TestFailureException&) {
+        } CATCH_CATCH_ANON (TestFailureException&) {
             // This just means the test was aborted due to failure
-        } catch (...) {
+        } CATCH_CATCH_ALL {
             // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
             // are reported without translation at the point of origin.
             if( m_shouldReportUnexpected ) {
diff --git a/packages/Catch2/include/internal/catch_run_context.h b/packages/Catch2/include/internal/catch_run_context.h
index 6b8941739f2b7cc6cdf6a1a4c8dca229da89d3f0..952ef14781f92ff3a03c5827acde252774a6826e 100644
--- a/packages/Catch2/include/internal/catch_run_context.h
+++ b/packages/Catch2/include/internal/catch_run_context.h
@@ -8,6 +8,7 @@
 #ifndef TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
 #define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
 
+#include "catch_interfaces_generatortracker.h"
 #include "catch_interfaces_runner.h"
 #include "catch_interfaces_reporter.h"
 #include "catch_interfaces_exception.h"
@@ -79,6 +80,8 @@ namespace Catch {
         void sectionEnded( SectionEndInfo const& endInfo ) override;
         void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
 
+        auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
+
         void benchmarkStarting( BenchmarkInfo const& info ) override;
         void benchmarkEnded( BenchmarkStats const& stats ) override;
 
diff --git a/packages/Catch2/include/internal/catch_section.cpp b/packages/Catch2/include/internal/catch_section.cpp
index 72a57d517461fedb0bc7668dbc52d1972217873a..0646d36fe0094ec63bba9e7f696a315507ce4238 100644
--- a/packages/Catch2/include/internal/catch_section.cpp
+++ b/packages/Catch2/include/internal/catch_section.cpp
@@ -21,7 +21,7 @@ namespace Catch {
 
     Section::~Section() {
         if( m_sectionIncluded ) {
-            SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
+            SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() };
             if( uncaught_exceptions() )
                 getResultCapture().sectionEndedEarly( endInfo );
             else
diff --git a/packages/Catch2/include/internal/catch_section.h b/packages/Catch2/include/internal/catch_section.h
index 1e5b1c3ce76a87285526ccb7373a23bcc59d62ea..00c254b67168d6f310b0da60858f38c7d8c99be2 100644
--- a/packages/Catch2/include/internal/catch_section.h
+++ b/packages/Catch2/include/internal/catch_section.h
@@ -8,6 +8,7 @@
 #ifndef TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
 #define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
 
+#include "catch_compiler_capabilities.h"
 #include "catch_section_info.h"
 #include "catch_totals.h"
 #include "catch_timer.h"
@@ -35,7 +36,14 @@ namespace Catch {
 
 } // end namespace Catch
 
-    #define INTERNAL_CATCH_SECTION( ... ) \
-        if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
+#define INTERNAL_CATCH_SECTION( ... ) \
+    CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
+    if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
+    CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
+
+#define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
+    CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
+    if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \
+    CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
 
 #endif // TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_section_info.cpp b/packages/Catch2/include/internal/catch_section_info.cpp
index e2846b8a0f82db0239b23260320683fd27ba98e3..89714e35e842eada5971fae048c7a689f56574f1 100644
--- a/packages/Catch2/include/internal/catch_section_info.cpp
+++ b/packages/Catch2/include/internal/catch_section_info.cpp
@@ -11,15 +11,9 @@ namespace Catch {
 
     SectionInfo::SectionInfo
         (   SourceLineInfo const& _lineInfo,
-            std::string const& _name,
-            std::string const& _description )
+            std::string const& _name )
     :   name( _name ),
-        description( _description ),
         lineInfo( _lineInfo )
     {}
 
-    SectionEndInfo::SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds )
-    : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
-    {}
-
 } // end namespace Catch
diff --git a/packages/Catch2/include/internal/catch_section_info.h b/packages/Catch2/include/internal/catch_section_info.h
index 86681ba70468c82da46d68621db4b9abfd7bf81d..9cf792e8c89fe50f982ba930baf6c83181d68194 100644
--- a/packages/Catch2/include/internal/catch_section_info.h
+++ b/packages/Catch2/include/internal/catch_section_info.h
@@ -16,19 +16,22 @@
 namespace Catch {
 
     struct SectionInfo {
+        SectionInfo
+            (   SourceLineInfo const& _lineInfo,
+                std::string const& _name );
+
+        // Deprecated
         SectionInfo
             (   SourceLineInfo const& _lineInfo,
                 std::string const& _name,
-                std::string const& _description = std::string() );
+                std::string const& ) : SectionInfo( _lineInfo, _name ) {}
 
         std::string name;
-        std::string description;
+        std::string description; // !Deprecated: this will always be empty
         SourceLineInfo lineInfo;
     };
 
     struct SectionEndInfo {
-        SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds );
-
         SectionInfo sectionInfo;
         Counts prevAssertions;
         double durationInSeconds;
diff --git a/packages/Catch2/include/internal/catch_session.cpp b/packages/Catch2/include/internal/catch_session.cpp
index 2c5fe08e40cca2b6304c12300216d785e55ed25f..5d028ed21e84186c9094fbc8039394ee7c5db1fc 100644
--- a/packages/Catch2/include/internal/catch_session.cpp
+++ b/packages/Catch2/include/internal/catch_session.cpp
@@ -119,10 +119,12 @@ namespace Catch {
     Session::Session() {
         static bool alreadyInstantiated = false;
         if( alreadyInstantiated ) {
-            try         { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); }
-            catch(...)  { getMutableRegistryHub().registerStartupException(); }
+            CATCH_TRY { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); }
+            CATCH_CATCH_ALL { getMutableRegistryHub().registerStartupException(); }
         }
 
+        // There cannot be exceptions at startup in no-exception mode.
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
         const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
         if ( !exceptions.empty() ) {
             m_startupExceptions = true;
@@ -137,6 +139,7 @@ namespace Catch {
                 }
             }
         }
+#endif
 
         alreadyInstantiated = true;
         m_cli = makeCommandLineParser( m_configData );
@@ -251,11 +254,11 @@ namespace Catch {
         if( m_startupExceptions )
             return 1;
 
-        if( m_configData.showHelp || m_configData.libIdentify )
+        if (m_configData.showHelp || m_configData.libIdentify) {
             return 0;
+        }
 
-        try
-        {
+        CATCH_TRY {
             config(); // Force config to be constructed
 
             seedRng( *m_config );
@@ -273,10 +276,12 @@ namespace Catch {
             // of 256 tests has failed
             return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast<int>(totals.assertions.failed)));
         }
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
         catch( std::exception& ex ) {
             Catch::cerr() << ex.what() << std::endl;
             return MaxExitCode;
         }
+#endif
     }
 
 } // end namespace Catch
diff --git a/packages/Catch2/include/internal/catch_singletons.cpp b/packages/Catch2/include/internal/catch_singletons.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e5367cadc0fc3e2809e3ab054b1f8412e08df12b
--- /dev/null
+++ b/packages/Catch2/include/internal/catch_singletons.cpp
@@ -0,0 +1,36 @@
+/*
+ *  Created by Phil Nash on 15/6/2018.
+ *
+ *  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)
+ */
+
+#include "catch_singletons.hpp"
+
+#include <vector>
+
+namespace Catch {
+
+    namespace {
+        static auto getSingletons() -> std::vector<ISingleton*>*& {
+            static std::vector<ISingleton*>* g_singletons = nullptr;
+            if( !g_singletons )
+                g_singletons = new std::vector<ISingleton*>();
+            return g_singletons;
+        }
+    }
+
+    ISingleton::~ISingleton() {}
+
+    void addSingleton(ISingleton* singleton ) {
+        getSingletons()->push_back( singleton );
+    }
+    void cleanupSingletons() {
+        auto& singletons = getSingletons();
+        for( auto singleton : *singletons )
+            delete singleton;
+        delete singletons;
+        singletons = nullptr;
+    }
+
+} // namespace Catch
diff --git a/packages/Catch2/include/internal/catch_singletons.hpp b/packages/Catch2/include/internal/catch_singletons.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..fbc4b32c47ba5be0f54b41384c8b6ae25c6be339
--- /dev/null
+++ b/packages/Catch2/include/internal/catch_singletons.hpp
@@ -0,0 +1,44 @@
+/*
+ *  Created by Phil Nash on 15/6/2018.
+ *
+ *  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_CATCH_SINGLETONS_HPP_INCLUDED
+#define TWOBLUECUBES_CATCH_SINGLETONS_HPP_INCLUDED
+
+namespace Catch {
+
+    struct ISingleton {
+        virtual ~ISingleton();
+    };
+
+
+    void addSingleton( ISingleton* singleton );
+    void cleanupSingletons();
+
+
+    template<typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT>
+    class Singleton : SingletonImplT, public ISingleton {
+
+        static auto getInternal() -> Singleton* {
+            static Singleton* s_instance = nullptr;
+            if( !s_instance ) {
+                s_instance = new Singleton;
+                addSingleton( s_instance );
+            }
+            return s_instance;
+        }
+
+    public:
+        static auto get() -> InterfaceT const& {
+            return *getInternal();
+        }
+        static auto getMutable() -> MutableInterfaceT& {
+            return *getInternal();
+        }
+    };
+
+} // namespace Catch
+
+#endif // TWOBLUECUBES_CATCH_SINGLETONS_HPP_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_startup_exception_registry.cpp b/packages/Catch2/include/internal/catch_startup_exception_registry.cpp
index d58d18a5ba578e6b9b8e96223b150d09bf62a9ee..3c5bd22f5f8353fe725bef16c0748a9e1b8230ff 100644
--- a/packages/Catch2/include/internal/catch_startup_exception_registry.cpp
+++ b/packages/Catch2/include/internal/catch_startup_exception_registry.cpp
@@ -7,13 +7,13 @@
  */
 
 #include "catch_startup_exception_registry.h"
+#include "catch_compiler_capabilities.h"
 
 namespace Catch {
-    void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
-        try {
+void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
+        CATCH_TRY {
             m_exceptions.push_back(exception);
-        }
-        catch(...) {
+        } CATCH_CATCH_ALL {
             // If we run out of memory during start-up there's really not a lot more we can do about it
             std::terminate();
         }
diff --git a/packages/Catch2/include/internal/catch_stream.cpp b/packages/Catch2/include/internal/catch_stream.cpp
index 125fd471e6ddd8eed841d57bf2231ee2dfdc084e..ba2d2be253fc38572d517a3e682db78bf594b553 100644
--- a/packages/Catch2/include/internal/catch_stream.cpp
+++ b/packages/Catch2/include/internal/catch_stream.cpp
@@ -12,6 +12,7 @@
 #include "catch_stream.h"
 #include "catch_debug_console.h"
 #include "catch_stringref.h"
+#include "catch_singletons.hpp"
 
 #include <cstdio>
 #include <iostream>
@@ -20,11 +21,6 @@
 #include <vector>
 #include <memory>
 
-#if defined(__clang__)
-#    pragma clang diagnostic push
-#    pragma clang diagnostic ignored "-Wexit-time-destructors"
-#endif
-
 namespace Catch {
 
     Catch::IStream::~IStream() = default;
@@ -145,7 +141,6 @@ namespace Catch {
         std::vector<std::unique_ptr<std::ostringstream>> m_streams;
         std::vector<std::size_t> m_unused;
         std::ostringstream m_referenceStream; // Used for copy state/ flags from
-        static StringStreams* s_instance;
 
         auto add() -> std::size_t {
             if( m_unused.empty() ) {
@@ -163,34 +158,17 @@ namespace Catch {
             m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state
             m_unused.push_back(index);
         }
-
-        // !TBD: put in TLS
-        static auto instance() -> StringStreams& {
-            if( !s_instance )
-                s_instance = new StringStreams();
-            return *s_instance;
-        }
-        static void cleanup() {
-            delete s_instance;
-            s_instance = nullptr;
-        }
     };
 
-    StringStreams* StringStreams::s_instance = nullptr;
-
-    void ReusableStringStream::cleanup() {
-        StringStreams::cleanup();
-    }
-
     ReusableStringStream::ReusableStringStream()
-    :   m_index( StringStreams::instance().add() ),
-        m_oss( StringStreams::instance().m_streams[m_index].get() )
+    :   m_index( Singleton<StringStreams>::getMutable().add() ),
+        m_oss( Singleton<StringStreams>::getMutable().m_streams[m_index].get() )
     {}
 
     ReusableStringStream::~ReusableStringStream() {
         static_cast<std::ostringstream*>( m_oss )->str("");
         m_oss->clear();
-        StringStreams::instance().release( m_index );
+        Singleton<StringStreams>::getMutable().release( m_index );
     }
 
     auto ReusableStringStream::str() const -> std::string {
@@ -207,7 +185,3 @@ namespace Catch {
     std::ostream& clog() { return std::clog; }
 #endif
 }
-
-#if defined(__clang__)
-#    pragma clang diagnostic pop
-#endif
diff --git a/packages/Catch2/include/internal/catch_stream.h b/packages/Catch2/include/internal/catch_stream.h
index c5e78b226f3d5324a8cecdf6ac48048eb154f87b..2b41adbd9ed28ba30311b827e9ddd7fcdfcec163 100644
--- a/packages/Catch2/include/internal/catch_stream.h
+++ b/packages/Catch2/include/internal/catch_stream.h
@@ -43,8 +43,6 @@ namespace Catch {
             return *this;
         }
         auto get() -> std::ostream& { return *m_oss; }
-
-        static void cleanup();
     };
 }
 
diff --git a/packages/Catch2/include/internal/catch_stringref.h b/packages/Catch2/include/internal/catch_stringref.h
index 757d70cc1a3068b454811f2e89d7459b67191c40..05206b0b14c8996dc224b144f391e8aa2b8e1263 100644
--- a/packages/Catch2/include/internal/catch_stringref.h
+++ b/packages/Catch2/include/internal/catch_stringref.h
@@ -127,4 +127,8 @@ namespace Catch {
 
 } // namespace Catch
 
+inline auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
+    return Catch::StringRef( rawChars, size );
+}
+
 #endif // CATCH_STRINGREF_H_INCLUDED
diff --git a/packages/Catch2/include/internal/catch_suppress_warnings.h b/packages/Catch2/include/internal/catch_suppress_warnings.h
index 4d0e9bd3f4fd7794f6143030e73c8d9ff97660b3..25d90125b5d6645dedf41a86824313c23034b4ed 100644
--- a/packages/Catch2/include/internal/catch_suppress_warnings.h
+++ b/packages/Catch2/include/internal/catch_suppress_warnings.h
@@ -10,13 +10,15 @@
 #       pragma warning(push)
 #       pragma warning(disable: 161 1682)
 #   else // __ICC
-#       pragma clang diagnostic ignored "-Wunused-variable"
 #       pragma clang diagnostic push
 #       pragma clang diagnostic ignored "-Wpadded"
 #       pragma clang diagnostic ignored "-Wswitch-enum"
 #       pragma clang diagnostic ignored "-Wcovered-switch-default"
 #    endif
 #elif defined __GNUC__
+     // GCC likes to warn on REQUIREs, and we cannot suppress them
+     // locally because g++'s support for _Pragma is lacking in older,
+     // still supported, versions
 #    pragma GCC diagnostic ignored "-Wparentheses"
 #    pragma GCC diagnostic push
 #    pragma GCC diagnostic ignored "-Wunused-variable"
diff --git a/packages/Catch2/include/internal/catch_tag_alias_autoregistrar.cpp b/packages/Catch2/include/internal/catch_tag_alias_autoregistrar.cpp
index 35ed059fd56eefc0504169d2c9aa4cdce23bd5b5..6a292edf0bf7e6efeb55652b7e43b40ed4cac24a 100644
--- a/packages/Catch2/include/internal/catch_tag_alias_autoregistrar.cpp
+++ b/packages/Catch2/include/internal/catch_tag_alias_autoregistrar.cpp
@@ -1,12 +1,13 @@
 #include "catch_tag_alias_autoregistrar.h"
+#include "catch_compiler_capabilities.h"
 #include "catch_interfaces_registry_hub.h"
 
 namespace Catch {
-    
+
     RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {
-        try {
+        CATCH_TRY {
             getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);
-        } catch (...) {
+        } CATCH_CATCH_ALL {
             // Do not throw when constructing global objects, instead register the exception to be processed later
             getMutableRegistryHub().registerStartupException();
         }
diff --git a/packages/Catch2/include/internal/catch_test_case_registry_impl.cpp b/packages/Catch2/include/internal/catch_test_case_registry_impl.cpp
index b30b112ae0942cf1ebb238b9cc54247c57f81537..a6b7f57039b38141ce4eb8bc01933d44150817c8 100644
--- a/packages/Catch2/include/internal/catch_test_case_registry_impl.cpp
+++ b/packages/Catch2/include/internal/catch_test_case_registry_impl.cpp
@@ -28,7 +28,7 @@ namespace Catch {
                 break;
             case RunTests::InRandomOrder:
                 seedRng( config );
-                RandomNumberGenerator::shuffle( sorted );
+                std::shuffle( sorted.begin(), sorted.end(), rng() );
                 break;
             case RunTests::InDeclarationOrder:
                 // already in declaration order
diff --git a/packages/Catch2/include/internal/catch_test_case_tracker.cpp b/packages/Catch2/include/internal/catch_test_case_tracker.cpp
index 8502b405f65a8c2fd3fcc8a0e1d91bf0196f6739..7839a71b45c27d6e04d0970095b1a1bd96a21642 100644
--- a/packages/Catch2/include/internal/catch_test_case_tracker.cpp
+++ b/packages/Catch2/include/internal/catch_test_case_tracker.cpp
@@ -69,14 +69,6 @@ namespace TestCaseTracking {
     }
 
 
-
-    TrackerBase::TrackerHasName::TrackerHasName( NameAndLocation const& nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {}
-    bool TrackerBase::TrackerHasName::operator ()( ITrackerPtr const& tracker ) const {
-        return
-            tracker->nameAndLocation().name == m_nameAndLocation.name &&
-            tracker->nameAndLocation().location == m_nameAndLocation.location;
-    }
-
     TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
     :   m_nameAndLocation( nameAndLocation ),
         m_ctx( ctx ),
@@ -105,7 +97,12 @@ namespace TestCaseTracking {
     }
 
     ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) {
-        auto it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( nameAndLocation ) );
+        auto it = std::find_if( m_children.begin(), m_children.end(),
+            [&nameAndLocation]( ITrackerPtr const& tracker ){
+                return
+                    tracker->nameAndLocation().location == nameAndLocation.location &&
+                    tracker->nameAndLocation().name == nameAndLocation.name;
+            } );
         return( it != m_children.end() )
             ? *it
             : nullptr;
diff --git a/packages/Catch2/include/internal/catch_test_case_tracker.h b/packages/Catch2/include/internal/catch_test_case_tracker.h
index a4b0440a3fe5912f152791d56d70b2d755d728ca..72b506a9f51022262dbb0116876a441cb6d0dce2 100644
--- a/packages/Catch2/include/internal/catch_test_case_tracker.h
+++ b/packages/Catch2/include/internal/catch_test_case_tracker.h
@@ -95,13 +95,6 @@ namespace TestCaseTracking {
             Failed
         };
 
-        class TrackerHasName {
-            NameAndLocation m_nameAndLocation;
-        public:
-            TrackerHasName( NameAndLocation const& nameAndLocation );
-            bool operator ()( ITrackerPtr const& tracker ) const;
-        };
-
         using Children = std::vector<ITrackerPtr>;
         NameAndLocation m_nameAndLocation;
         TrackerContext& m_ctx;
diff --git a/packages/Catch2/include/internal/catch_test_registry.cpp b/packages/Catch2/include/internal/catch_test_registry.cpp
index ac83f33327821ea6c344ff89d5c58c319da8a6d2..248bee4ca8926675ba12a986a05a550653bf562e 100644
--- a/packages/Catch2/include/internal/catch_test_registry.cpp
+++ b/packages/Catch2/include/internal/catch_test_registry.cpp
@@ -6,6 +6,7 @@
  */
 
 #include "catch_test_registry.h"
+#include "catch_compiler_capabilities.h"
 #include "catch_test_case_registry_impl.h"
 #include "catch_interfaces_registry_hub.h"
 
@@ -18,7 +19,7 @@ namespace Catch {
     NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {}
 
     AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept {
-        try {
+        CATCH_TRY {
             getMutableRegistryHub()
                     .registerTest(
                         makeTestCase(
@@ -26,7 +27,7 @@ namespace Catch {
                             extractClassName( classOrMethod ),
                             nameAndTags,
                             lineInfo));
-        } catch (...) {
+        } CATCH_CATCH_ALL {
             // Do not throw when constructing global objects, instead register the exception to be processed later
             getMutableRegistryHub().registerStartupException();
         }
diff --git a/packages/Catch2/include/internal/catch_test_registry.h b/packages/Catch2/include/internal/catch_test_registry.h
index f7fe325899e0cd5b4bf933b6da7c7ecb63a878d2..71304483486780207f365a19f44033778c349b05 100644
--- a/packages/Catch2/include/internal/catch_test_registry.h
+++ b/packages/Catch2/include/internal/catch_test_registry.h
@@ -69,7 +69,7 @@ struct AutoReg : NonCopyable {
     #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
         static void TestName(); \
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
-        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
+        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
         static void TestName()
     #define INTERNAL_CATCH_TESTCASE( ... ) \
@@ -98,7 +98,7 @@ struct AutoReg : NonCopyable {
     ///////////////////////////////////////////////////////////////////////////////
     #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
-        Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
+        Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
 
 
diff --git a/packages/Catch2/include/internal/catch_tostring.cpp b/packages/Catch2/include/internal/catch_tostring.cpp
index ee6a815f9aa76196ed3949305fffdbb3fa965000..4e0c027d3b0e09931bd7403e0669e84b38f748fe 100644
--- a/packages/Catch2/include/internal/catch_tostring.cpp
+++ b/packages/Catch2/include/internal/catch_tostring.cpp
@@ -116,14 +116,9 @@ std::string StringMaker<std::string>::convert(const std::string& str) {
     return s;
 }
 
-#ifdef CATCH_CONFIG_WCHAR
-std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
-    std::string s;
-    s.reserve(wstr.size());
-    for (auto c : wstr) {
-        s += (c <= 0xff) ? static_cast<char>(c) : '?';
-    }
-    return ::Catch::Detail::stringify(s);
+#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
+std::string StringMaker<std::string_view>::convert(std::string_view str) {
+    return ::Catch::Detail::stringify(std::string{ str });
 }
 #endif
 
@@ -141,7 +136,23 @@ std::string StringMaker<char*>::convert(char* str) {
         return{ "{null string}" };
     }
 }
+
 #ifdef CATCH_CONFIG_WCHAR
+std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
+    std::string s;
+    s.reserve(wstr.size());
+    for (auto c : wstr) {
+        s += (c <= 0xff) ? static_cast<char>(c) : '?';
+    }
+    return ::Catch::Detail::stringify(s);
+}
+
+# ifdef CATCH_CONFIG_CPP17_STRING_VIEW
+std::string StringMaker<std::wstring_view>::convert(std::wstring_view str) {
+    return StringMaker<std::wstring>::convert(std::wstring(str));
+}
+# endif
+
 std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) {
     if (str) {
         return ::Catch::Detail::stringify(std::wstring{ str });
@@ -231,8 +242,8 @@ std::string StringMaker<double>::convert(double value) {
 
 std::string ratio_string<std::atto>::symbol() { return "a"; }
 std::string ratio_string<std::femto>::symbol() { return "f"; }
-std::string  ratio_string<std::pico>::symbol() { return "p"; }
-std::string  ratio_string<std::nano>::symbol() { return "n"; }
+std::string ratio_string<std::pico>::symbol() { return "p"; }
+std::string ratio_string<std::nano>::symbol() { return "n"; }
 std::string ratio_string<std::micro>::symbol() { return "u"; }
 std::string ratio_string<std::milli>::symbol() { return "m"; }
 
diff --git a/packages/Catch2/include/internal/catch_tostring.h b/packages/Catch2/include/internal/catch_tostring.h
index 2aa06f442752e891ec651c8281f648393a3cb580..137d97592f9c97653ba49e97b5223d2e519b7ef6 100644
--- a/packages/Catch2/include/internal/catch_tostring.h
+++ b/packages/Catch2/include/internal/catch_tostring.h
@@ -16,6 +16,10 @@
 #include "catch_compiler_capabilities.h"
 #include "catch_stream.h"
 
+#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
+#include <string_view>
+#endif
+
 #ifdef __OBJC__
 #include "catch_objc_arc.hpp"
 #endif
@@ -152,10 +156,11 @@ namespace Catch {
     struct StringMaker<std::string> {
         static std::string convert(const std::string& str);
     };
-#ifdef CATCH_CONFIG_WCHAR
+
+#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
     template<>
-    struct StringMaker<std::wstring> {
-        static std::string convert(const std::wstring& wstr);
+    struct StringMaker<std::string_view> {
+        static std::string convert(std::string_view str);
     };
 #endif
 
@@ -169,6 +174,18 @@ namespace Catch {
     };
 
 #ifdef CATCH_CONFIG_WCHAR
+    template<>
+    struct StringMaker<std::wstring> {
+        static std::string convert(const std::wstring& wstr);
+    };
+
+# ifdef CATCH_CONFIG_CPP17_STRING_VIEW
+    template<>
+    struct StringMaker<std::wstring_view> {
+        static std::string convert(std::wstring_view str);
+    };
+# endif
+
     template<>
     struct StringMaker<wchar_t const *> {
         static std::string convert(wchar_t const * str);
@@ -337,6 +354,7 @@ namespace Catch {
 #if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
 #  define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
 #  define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
+#  define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
 #  define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
 #endif
 
@@ -401,6 +419,34 @@ namespace Catch {
 }
 #endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
 
+#if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
+#include <variant>
+namespace Catch {
+    template<>
+    struct StringMaker<std::monostate> {
+        static std::string convert(const std::monostate&) {
+            return "{ }";
+        }
+    };
+
+    template<typename... Elements>
+    struct StringMaker<std::variant<Elements...>> {
+        static std::string convert(const std::variant<Elements...>& variant) {
+            if (variant.valueless_by_exception()) {
+                return "{valueless variant}";
+            } else {
+                return std::visit(
+                    [](const auto& value) {
+                        return ::Catch::Detail::stringify(value);
+                    },
+                    variant
+                );
+            }
+        }
+    };
+}
+#endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
+
 namespace Catch {
     struct not_this_one {}; // Tag type for detecting which begin/ end are being selected
 
diff --git a/packages/Catch2/include/internal/catch_version.cpp b/packages/Catch2/include/internal/catch_version.cpp
index 94e11e0851ec6ef6a68db8cb03cb6c86bb897017..a57553c0d0b9382e5e98eb1d91df924a1f0f186f 100644
--- a/packages/Catch2/include/internal/catch_version.cpp
+++ b/packages/Catch2/include/internal/catch_version.cpp
@@ -37,7 +37,7 @@ namespace Catch {
     }
 
     Version const& libraryVersion() {
-        static Version version( 2, 2, 3, "", 0 );
+        static Version version( 2, 4, 1, "", 0 );
         return version;
     }
 
diff --git a/packages/Catch2/include/reporters/catch_reporter_bases.hpp b/packages/Catch2/include/reporters/catch_reporter_bases.hpp
index f198d214283d4272582dff3b3411a7b37f4f1cce..ae1618fe4150bcf830ed4cd42e2677fd1d1307de 100644
--- a/packages/Catch2/include/reporters/catch_reporter_bases.hpp
+++ b/packages/Catch2/include/reporters/catch_reporter_bases.hpp
@@ -8,6 +8,7 @@
 #ifndef TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
 #define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
 
+#include "../internal/catch_enforce.h"
 #include "../internal/catch_interfaces_reporter.h"
 
 #include <algorithm>
@@ -33,7 +34,7 @@ namespace Catch {
         {
             m_reporterPrefs.shouldRedirectStdOut = false;
             if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
-                throw std::domain_error( "Verbosity level not supported by this reporter" );
+                CATCH_ERROR( "Verbosity level not supported by this reporter" );
         }
 
         ReporterPreferences getPreferences() const override {
@@ -148,7 +149,7 @@ namespace Catch {
         {
             m_reporterPrefs.shouldRedirectStdOut = false;
             if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
-                throw std::domain_error( "Verbosity level not supported by this reporter" );
+                CATCH_ERROR( "Verbosity level not supported by this reporter" );
         }
         ~CumulativeReporterBase() override = default;
 
diff --git a/packages/Catch2/include/reporters/catch_reporter_compact.cpp b/packages/Catch2/include/reporters/catch_reporter_compact.cpp
index caf4d3f9f33f0133a88cf77a2fc90a4b39cfb432..65f70266dd6503f61bcfaed651a944f8b28741ea 100644
--- a/packages/Catch2/include/reporters/catch_reporter_compact.cpp
+++ b/packages/Catch2/include/reporters/catch_reporter_compact.cpp
@@ -245,9 +245,7 @@ private:
         }
 
         ReporterPreferences CompactReporter::getPreferences() const {
-            ReporterPreferences prefs;
-            prefs.shouldRedirectStdOut = false;
-            return prefs;
+            return m_reporterPrefs;
         }
 
         void CompactReporter::noMatchingTestCases( std::string const& spec ) {
diff --git a/packages/Catch2/include/reporters/catch_reporter_junit.cpp b/packages/Catch2/include/reporters/catch_reporter_junit.cpp
index 55129b76705e6bfcef0bd7f2863c1a6cb3d511d4..03dc35c1bcbc34fd09458d9e1376e10d346dceeb 100644
--- a/packages/Catch2/include/reporters/catch_reporter_junit.cpp
+++ b/packages/Catch2/include/reporters/catch_reporter_junit.cpp
@@ -62,6 +62,7 @@ namespace Catch {
             xml( _config.stream() )
         {
             m_reporterPrefs.shouldRedirectStdOut = true;
+            m_reporterPrefs.shouldReportAllAssertions = true;
         }
 
     JunitReporter::~JunitReporter() {}
diff --git a/packages/Catch2/include/reporters/catch_reporter_listening.cpp b/packages/Catch2/include/reporters/catch_reporter_listening.cpp
index cd6251541f16a3ee934d9f63b35c9dcd4cc3b033..9ddae2f2ed894fc75115bfa06287800dcaa2eeae 100644
--- a/packages/Catch2/include/reporters/catch_reporter_listening.cpp
+++ b/packages/Catch2/include/reporters/catch_reporter_listening.cpp
@@ -11,6 +11,11 @@
 
 namespace Catch {
 
+    ListeningReporter::ListeningReporter() {
+        // We will assume that listeners will always want all assertions
+        m_preferences.shouldReportAllAssertions = true;
+    }
+
     void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) {
         m_listeners.push_back( std::move( listener ) );
     }
@@ -18,10 +23,11 @@ namespace Catch {
     void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) {
         assert(!m_reporter && "Listening reporter can wrap only 1 real reporter");
         m_reporter = std::move( reporter );
+        m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;
     }
 
     ReporterPreferences ListeningReporter::getPreferences() const {
-        return m_reporter->getPreferences();
+        return m_preferences;
     }
 
     std::set<Verbosity> ListeningReporter::getSupportedVerbosities() {
diff --git a/packages/Catch2/include/reporters/catch_reporter_listening.h b/packages/Catch2/include/reporters/catch_reporter_listening.h
index bf97edef369f9b3a125ab295e80eaad615ef1d23..dddd7a518664f9b38c52a2fbd83bfd91c32accda 100644
--- a/packages/Catch2/include/reporters/catch_reporter_listening.h
+++ b/packages/Catch2/include/reporters/catch_reporter_listening.h
@@ -15,8 +15,11 @@ namespace Catch {
         using Reporters = std::vector<IStreamingReporterPtr>;
         Reporters m_listeners;
         IStreamingReporterPtr m_reporter = nullptr;
+        ReporterPreferences m_preferences;
 
     public:
+        ListeningReporter();
+
         void addListener( IStreamingReporterPtr&& listener );
         void addReporter( IStreamingReporterPtr&& reporter );
 
diff --git a/packages/Catch2/include/reporters/catch_reporter_tap.hpp b/packages/Catch2/include/reporters/catch_reporter_tap.hpp
index 19e54ed197b69e43ddbf4e41213255f0108f0f63..ccc4051be00e60fbf46e25c1b73cb58103d6cb7d 100644
--- a/packages/Catch2/include/reporters/catch_reporter_tap.hpp
+++ b/packages/Catch2/include/reporters/catch_reporter_tap.hpp
@@ -30,9 +30,7 @@ namespace Catch {
         }
 
         ReporterPreferences getPreferences() const override {
-            ReporterPreferences prefs;
-            prefs.shouldRedirectStdOut = false;
-            return prefs;
+            return m_reporterPrefs;
         }
 
         void noMatchingTestCases( std::string const& spec ) override {
diff --git a/packages/Catch2/include/reporters/catch_reporter_teamcity.hpp b/packages/Catch2/include/reporters/catch_reporter_teamcity.hpp
index dbd0db532c1536aee08f9a20ac8002109519d098..eca2885cd4e9fde3b5e7008388f4b57f203ce9bc 100644
--- a/packages/Catch2/include/reporters/catch_reporter_teamcity.hpp
+++ b/packages/Catch2/include/reporters/catch_reporter_teamcity.hpp
@@ -97,12 +97,12 @@ namespace Catch {
                     case ResultWas::Ok:
                     case ResultWas::Info:
                     case ResultWas::Warning:
-                        throw std::domain_error( "Internal error in TeamCity reporter" );
+                        CATCH_ERROR( "Internal error in TeamCity reporter" );
                     // These cases are here to prevent compiler warnings
                     case ResultWas::Unknown:
                     case ResultWas::FailureBit:
                     case ResultWas::Exception:
-                        throw std::domain_error( "Not implemented" );
+                        CATCH_ERROR( "Not implemented" );
                 }
                 if( assertionStats.infoMessages.size() == 1 )
                     msg << " with message:";
diff --git a/packages/Catch2/include/reporters/catch_reporter_xml.cpp b/packages/Catch2/include/reporters/catch_reporter_xml.cpp
index b721d449edd83a241f2b24d4418b28c56b692816..c32005370dc6652eb205cbbd14d1de030ab1bb5e 100644
--- a/packages/Catch2/include/reporters/catch_reporter_xml.cpp
+++ b/packages/Catch2/include/reporters/catch_reporter_xml.cpp
@@ -24,6 +24,7 @@ namespace Catch {
         m_xml(_config.stream())
     {
         m_reporterPrefs.shouldRedirectStdOut = true;
+        m_reporterPrefs.shouldReportAllAssertions = true;
     }
 
     XmlReporter::~XmlReporter() = default;
@@ -80,8 +81,7 @@ namespace Catch {
         StreamingReporterBase::sectionStarting( sectionInfo );
         if( m_sectionDepth++ > 0 ) {
             m_xml.startElement( "Section" )
-                .writeAttribute( "name", trim( sectionInfo.name ) )
-                .writeAttribute( "description", sectionInfo.description );
+                .writeAttribute( "name", trim( sectionInfo.name ) );
             writeSourceInfo( sectionInfo.lineInfo );
             m_xml.ensureTagClosed();
         }
diff --git a/packages/Catch2/misc/SelfTest.vcxproj.user b/packages/Catch2/misc/SelfTest.vcxproj.user
new file mode 100644
index 0000000000000000000000000000000000000000..ffffc575138a1edf2c57d8a664c282d307538782
--- /dev/null
+++ b/packages/Catch2/misc/SelfTest.vcxproj.user
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <UseFullPaths>false</UseFullPaths>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <UseFullPaths>false</UseFullPaths>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <UseFullPaths>false</UseFullPaths>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <UseFullPaths>false</UseFullPaths>
+    </ClCompile>
+  </ItemDefinitionGroup>
+</Project>
diff --git a/packages/Catch2/misc/appveyorBuildConfigurationScript.bat b/packages/Catch2/misc/appveyorBuildConfigurationScript.bat
index 1e91a588f7d4a299228c68a0fc227d75ae0a0b4d..f07bb707c1a0aaede2b6e4e519ff7bdf5a1d559a 100644
--- a/packages/Catch2/misc/appveyorBuildConfigurationScript.bat
+++ b/packages/Catch2/misc/appveyorBuildConfigurationScript.bat
@@ -1,3 +1,4 @@
+SETLOCAL EnableDelayedExpansion
 
 @REM  # Possibilities:
 @REM  # Debug build + coverage
@@ -7,21 +8,15 @@
 if "%CONFIGURATION%"=="Debug" (
   if "%coverage%"=="1" (
     @REM # coverage needs to build the special helper as well as the main
-    cmake -Hmisc -Bbuild-misc -A%PLATFORM%
-    cmake --build build-misc
-    cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain% -DMEMORYCHECK_COMMAND=build-misc\Debug\CoverageHelper.exe -DMEMORYCHECK_COMMAND_OPTIONS=--sep-- -DMEMORYCHECK_TYPE=Valgrind
+    cmake -Hmisc -Bbuild-misc -A%PLATFORM% || exit /b !ERRORLEVEL!
+    cmake --build build-misc || exit /b !ERRORLEVEL!
+    cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain% -DMEMORYCHECK_COMMAND=build-misc\Debug\CoverageHelper.exe -DMEMORYCHECK_COMMAND_OPTIONS=--sep-- -DMEMORYCHECK_TYPE=Valgrind || exit /b !ERRORLEVEL! || exit /b !ERRORLEVEL!
   ) else (
     @REM # We know that coverage is 0
-    if "%examples%"=="1" (
-      @REM # Examples live off the single header, so it needs to be regenerated
-      python scripts\generateSingleHeader.py
-      cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain% -DCATCH_BUILD_EXAMPLES=ON
-    ) else (
-      @REM # This is just a plain debug build
-      cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain%
-    )
+    python scripts\generateSingleHeader.py || exit /b !ERRORLEVEL!
+    cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain% -DCATCH_BUILD_EXAMPLES=%examples% -DCATCH_BUILD_EXTRA_TESTS=%examples% || exit /b !ERRORLEVEL!
   )
 )
 if "%CONFIGURATION%"=="Release" (
-  cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain%
+  cmake -H. -BBuild -A%PLATFORM% -DUSE_WMAIN=%wmain% || exit /b !ERRORLEVEL!
 )
diff --git a/packages/Catch2/misc/appveyorTestRunScript.bat b/packages/Catch2/misc/appveyorTestRunScript.bat
index 19a364be12f127bb68b52d45535af4c97b8312eb..c129d99eabf3d649e88a98880bf145cfa2a78e2d 100644
--- a/packages/Catch2/misc/appveyorTestRunScript.bat
+++ b/packages/Catch2/misc/appveyorTestRunScript.bat
@@ -1,13 +1,15 @@
+SETLOCAL EnableDelayedExpansion
+
 cd Build
 if "%CONFIGURATION%"=="Debug" (
   if "%coverage%"=="1" (
-    ctest -j 2 -C %CONFIGURATION% -D ExperimentalMemCheck
-    python ..\misc\appveyorMergeCoverageScript.py
-    codecov --root .. --no-color --disable gcov -f cobertura.xml -t %CODECOV_TOKEN%
+    ctest -j 2 -C %CONFIGURATION% -D ExperimentalMemCheck || exit /b !ERRORLEVEL!
+    python ..\misc\appveyorMergeCoverageScript.py || exit /b !ERRORLEVEL!
+    codecov --root .. --no-color --disable gcov -f cobertura.xml -t %CODECOV_TOKEN% || exit /b !ERRORLEVEL!
   ) else (
-    ctest -j 2 -C %CONFIGURATION%
+    ctest -j 2 -C %CONFIGURATION% || exit /b !ERRORLEVEL!
   )
 )
 if "%CONFIGURATION%"=="Release" (
-  ctest -j 2 -C %CONFIGURATION%
+  ctest -j 2 -C %CONFIGURATION% || exit /b !ERRORLEVEL!
 )
diff --git a/packages/Catch2/projects/Benchmark/BenchMain.cpp b/packages/Catch2/projects/Benchmark/BenchMain.cpp
deleted file mode 100644
index 32ef4ed9c239c140d1b10c422c89c6021d734df0..0000000000000000000000000000000000000000
--- a/packages/Catch2/projects/Benchmark/BenchMain.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- *  Created by Martin on 16/01/2017.
- *
- *  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)
- */
-
-#define CATCH_CONFIG_MAIN
-#include "catch.hpp"
diff --git a/packages/Catch2/projects/Benchmark/StringificationBench.cpp b/packages/Catch2/projects/Benchmark/StringificationBench.cpp
deleted file mode 100644
index 765b4e9652b495d4ceae0a419127744efd19dcd4..0000000000000000000000000000000000000000
--- a/packages/Catch2/projects/Benchmark/StringificationBench.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  Created by Martin on 16/01/2017.
- *
- *  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)
- */
-
-#include "catch.hpp"
-
-#include <vector>
-
-///////////////////////////////////////////////////////////////////////////////
-TEST_CASE("Successful tests -- REQUIRE", "[Success]") {
-    const std::size_t sz = 1 * 1024 * 1024;
-
-
-    std::vector<std::size_t> vec; vec.reserve(sz);
-    for (std::size_t i = 0; i < sz; ++i){
-        vec.push_back(i);
-        REQUIRE(vec.back() == i);
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-TEST_CASE("Successful tests -- CHECK", "[Success]") {
-    const std::size_t sz = 1 * 1024 * 1024;
-
-
-    std::vector<std::size_t> vec; vec.reserve(sz);
-    for (std::size_t i = 0; i < sz; ++i){
-        vec.push_back(i);
-        CHECK(vec.back() == i);
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-TEST_CASE("Unsuccessful tests -- CHECK", "[Failure]") {
-    const std::size_t sz = 1024 * 1024;
-
-
-    std::vector<std::size_t> vec; vec.reserve(sz);
-    for (std::size_t i = 0; i < sz; ++i){
-        vec.push_back(i);
-        CHECK(vec.size() == i);
-    }
-}
diff --git a/packages/Catch2/projects/Benchmark/readme.txt b/packages/Catch2/projects/Benchmark/readme.txt
deleted file mode 100644
index c4d2fabd921ee75e0af4e5d4853208acc18f10a1..0000000000000000000000000000000000000000
--- a/packages/Catch2/projects/Benchmark/readme.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is very much a work in progress.
-The past results are standardized to a developer's machine,
-the benchmarking script is basic and there are only 3 benchmarks,
-but this should get better in time. For now, at least there is something to go by.
diff --git a/packages/Catch2/projects/Benchmark/results/2017-01-14T21-53-49-e3659cdddd43ba4df9e4846630be6a6a7bd85a07.result b/packages/Catch2/projects/Benchmark/results/2017-01-14T21-53-49-e3659cdddd43ba4df9e4846630be6a6a7bd85a07.result
deleted file mode 100644
index 4b6fc6590eeaaaa8601e7975a157483ee05725dc..0000000000000000000000000000000000000000
--- a/packages/Catch2/projects/Benchmark/results/2017-01-14T21-53-49-e3659cdddd43ba4df9e4846630be6a6a7bd85a07.result
+++ /dev/null
@@ -1,3 +0,0 @@
-Successful tests -- CHECK: median: 3.38116 (s), stddev: 0.11567366292001534 (s)
-Successful tests -- REQUIRE: median: 3.479955 (s), stddev: 0.16295972890734556 (s)
-Unsuccessful tests -- CHECK: median: 1.966895 (s), stddev: 0.06323488524716572 (s)
diff --git a/packages/Catch2/projects/Benchmark/results/2017-01-14T21-59-08-a1e9b841ff500b2f39ccfd4193ae450cb653da05.result b/packages/Catch2/projects/Benchmark/results/2017-01-14T21-59-08-a1e9b841ff500b2f39ccfd4193ae450cb653da05.result
deleted file mode 100644
index 98c846017800471c1bddf09d841d406cbd52b198..0000000000000000000000000000000000000000
--- a/packages/Catch2/projects/Benchmark/results/2017-01-14T21-59-08-a1e9b841ff500b2f39ccfd4193ae450cb653da05.result
+++ /dev/null
@@ -1,3 +0,0 @@
-Successful tests -- CHECK: median: 1.30312 (s), stddev: 0.08759818557862176 (s)
-Successful tests -- REQUIRE: median: 1.341535 (s), stddev: 0.1479193390143576 (s)
-Unsuccessful tests -- CHECK: median: 1.967755 (s), stddev: 0.07921104121269959 (s)
diff --git a/packages/Catch2/projects/Benchmark/results/2017-01-15T09-35-14-3b98a0166f7b7196eba2ad518174d1a77165166d.result b/packages/Catch2/projects/Benchmark/results/2017-01-15T09-35-14-3b98a0166f7b7196eba2ad518174d1a77165166d.result
deleted file mode 100644
index fe6366b89d18b9f68356da7599fe4e5fb038b9d5..0000000000000000000000000000000000000000
--- a/packages/Catch2/projects/Benchmark/results/2017-01-15T09-35-14-3b98a0166f7b7196eba2ad518174d1a77165166d.result
+++ /dev/null
@@ -1,3 +0,0 @@
-Successful tests -- CHECK: median: 1.2982 (s), stddev: 0.019540648829214084 (s)
-Successful tests -- REQUIRE: median: 1.30102 (s), stddev: 0.014758430547392974 (s)
-Unsuccessful tests -- CHECK: median: 15.520199999999999 (s), stddev: 0.09536359426485094 (s)
diff --git a/packages/Catch2/projects/Benchmark/results/2017-01-29T22-08-36-60f8ebec49c5bc58d3604bf1a72cd3f7d129bf2e.result b/packages/Catch2/projects/Benchmark/results/2017-01-29T22-08-36-60f8ebec49c5bc58d3604bf1a72cd3f7d129bf2e.result
deleted file mode 100644
index c9b4d640b4e8990bc589a1d570f849947e82f4fb..0000000000000000000000000000000000000000
--- a/packages/Catch2/projects/Benchmark/results/2017-01-29T22-08-36-60f8ebec49c5bc58d3604bf1a72cd3f7d129bf2e.result
+++ /dev/null
@@ -1,3 +0,0 @@
-Successful tests -- CHECK: median: 0.7689014999999999 (s), stddev: 0.02127512078801068 (s)
-Successful tests -- REQUIRE: median: 0.772845 (s), stddev: 0.03011638381365052 (s)
-Unsuccessful tests -- CHECK: median: 15.49 (s), stddev: 0.536088571143903 (s)
diff --git a/packages/Catch2/projects/Benchmark/results/2017-01-29T23-13-35-bcaa2f9646c5ce50758f8582307c99501a932e1a.result b/packages/Catch2/projects/Benchmark/results/2017-01-29T23-13-35-bcaa2f9646c5ce50758f8582307c99501a932e1a.result
deleted file mode 100644
index 5b82330f9c062a414ea3182f8dc2f4a933265105..0000000000000000000000000000000000000000
--- a/packages/Catch2/projects/Benchmark/results/2017-01-29T23-13-35-bcaa2f9646c5ce50758f8582307c99501a932e1a.result
+++ /dev/null
@@ -1,3 +0,0 @@
-Successful tests -- CHECK: median: 0.775769 (s), stddev: 0.014802129132136525 (s)
-Successful tests -- REQUIRE: median: 0.785235 (s), stddev: 0.03532672836834896 (s)
-Unsuccessful tests -- CHECK: median: 15.156600000000001 (s), stddev: 0.2832375673450742 (s)
diff --git a/packages/Catch2/projects/CMakeLists.txt b/packages/Catch2/projects/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..8e2e4b13eb094863e59e1a0ca0f1361aeff35e20
--- /dev/null
+++ b/packages/Catch2/projects/CMakeLists.txt
@@ -0,0 +1,353 @@
+include(MiscFunctions)
+
+####
+# Temporary workaround for VS toolset changes in 2017
+# We need to disable <UseFullPaths> property, but CMake doesn't support it
+# until 3.13 (not yet released)
+####
+if (MSVC)
+configure_file(${CATCH_DIR}/misc/SelfTest.vcxproj.user
+               ${CMAKE_BINARY_DIR}/projects
+               COPYONLY)
+endif(MSVC) #Temporary workaround
+
+
+# define the sources of the self test
+# Please keep these ordered alphabetically
+set(TEST_SOURCES
+        ${SELF_TEST_DIR}/TestMain.cpp
+        ${SELF_TEST_DIR}/IntrospectiveTests/CmdLine.tests.cpp
+        ${SELF_TEST_DIR}/IntrospectiveTests/GeneratorsImpl.tests.cpp
+        ${SELF_TEST_DIR}/IntrospectiveTests/PartTracker.tests.cpp
+        ${SELF_TEST_DIR}/IntrospectiveTests/TagAlias.tests.cpp
+        ${SELF_TEST_DIR}/IntrospectiveTests/String.tests.cpp
+        ${SELF_TEST_DIR}/IntrospectiveTests/Xml.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/Approx.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/BDD.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/Benchmark.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/Class.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/Compilation.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/Condition.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/Decomposition.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/EnumToString.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/Exception.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/Generators.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/Message.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/Misc.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/ToStringChrono.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/ToStringGeneral.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/ToStringPair.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/ToStringTuple.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/ToStringVariant.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/ToStringVector.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/ToStringWhich.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/Tricky.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/VariadicMacros.tests.cpp
+        ${SELF_TEST_DIR}/UsageTests/Matchers.tests.cpp
+        )
+CheckFileList(TEST_SOURCES ${SELF_TEST_DIR})
+
+# A set of impl files that just #include a single header
+# Please keep these ordered alphabetically
+set(SURROGATE_SOURCES
+        ${SELF_TEST_DIR}/SurrogateCpps/catch_console_colour.cpp
+        ${SELF_TEST_DIR}/SurrogateCpps/catch_debugger.cpp
+        ${SELF_TEST_DIR}/SurrogateCpps/catch_interfaces_reporter.cpp
+        ${SELF_TEST_DIR}/SurrogateCpps/catch_option.cpp
+        ${SELF_TEST_DIR}/SurrogateCpps/catch_stream.cpp
+        ${SELF_TEST_DIR}/SurrogateCpps/catch_test_case_tracker.cpp
+        ${SELF_TEST_DIR}/SurrogateCpps/catch_test_spec.cpp
+        ${SELF_TEST_DIR}/SurrogateCpps/catch_xmlwriter.cpp
+        )
+CheckFileList(SURROGATE_SOURCES ${SELF_TEST_DIR}/SurrogateCpps)
+
+
+# Please keep these ordered alphabetically
+set(TOP_LEVEL_HEADERS
+        ${HEADER_DIR}/catch.hpp
+        ${HEADER_DIR}/catch_with_main.hpp
+        )
+CheckFileList(TOP_LEVEL_HEADERS ${HEADER_DIR})
+
+# Please keep these ordered alphabetically
+set(EXTERNAL_HEADERS
+        ${HEADER_DIR}/external/clara.hpp
+        )
+CheckFileList(EXTERNAL_HEADERS ${HEADER_DIR}/external)
+
+
+# Please keep these ordered alphabetically
+set(INTERNAL_HEADERS
+        ${HEADER_DIR}/internal/catch_approx.h
+        ${HEADER_DIR}/internal/catch_assertionhandler.h
+        ${HEADER_DIR}/internal/catch_assertioninfo.h
+        ${HEADER_DIR}/internal/catch_assertionresult.h
+        ${HEADER_DIR}/internal/catch_capture.hpp
+        ${HEADER_DIR}/internal/catch_capture_matchers.h
+        ${HEADER_DIR}/internal/catch_clara.h
+        ${HEADER_DIR}/internal/catch_commandline.h
+        ${HEADER_DIR}/internal/catch_common.h
+        ${HEADER_DIR}/internal/catch_compiler_capabilities.h
+        ${HEADER_DIR}/internal/catch_config.hpp
+        ${HEADER_DIR}/internal/catch_console_colour.h
+        ${HEADER_DIR}/internal/catch_context.h
+        ${HEADER_DIR}/internal/catch_debug_console.h
+        ${HEADER_DIR}/internal/catch_debugger.h
+        ${HEADER_DIR}/internal/catch_decomposer.h
+        ${HEADER_DIR}/internal/catch_default_main.hpp
+        ${HEADER_DIR}/internal/catch_enforce.h
+        ${HEADER_DIR}/internal/catch_errno_guard.h
+        ${HEADER_DIR}/internal/catch_exception_translator_registry.h
+        ${HEADER_DIR}/internal/catch_external_interfaces.h
+        ${HEADER_DIR}/internal/catch_fatal_condition.h
+        ${HEADER_DIR}/internal/catch_generators.hpp
+        ${HEADER_DIR}/internal/catch_impl.hpp
+        ${HEADER_DIR}/internal/catch_interfaces_capture.h
+        ${HEADER_DIR}/internal/catch_interfaces_config.h
+        ${HEADER_DIR}/internal/catch_interfaces_exception.h
+        ${HEADER_DIR}/internal/catch_interfaces_registry_hub.h
+        ${HEADER_DIR}/internal/catch_interfaces_reporter.h
+        ${HEADER_DIR}/internal/catch_interfaces_runner.h
+        ${HEADER_DIR}/internal/catch_interfaces_tag_alias_registry.h
+        ${HEADER_DIR}/internal/catch_interfaces_testcase.h
+        ${HEADER_DIR}/internal/catch_leak_detector.h
+        ${HEADER_DIR}/internal/catch_list.h
+        ${HEADER_DIR}/internal/catch_matchers.h
+        ${HEADER_DIR}/internal/catch_matchers_floating.h
+        ${HEADER_DIR}/internal/catch_matchers_generic.hpp
+        ${HEADER_DIR}/internal/catch_matchers_string.h
+        ${HEADER_DIR}/internal/catch_matchers_vector.h
+        ${HEADER_DIR}/internal/catch_message.h
+        ${HEADER_DIR}/internal/catch_objc.hpp
+        ${HEADER_DIR}/internal/catch_objc_arc.hpp
+        ${HEADER_DIR}/internal/catch_option.hpp
+        ${HEADER_DIR}/internal/catch_output_redirect.h
+        ${HEADER_DIR}/internal/catch_platform.h
+        ${HEADER_DIR}/internal/catch_random_number_generator.h
+        ${HEADER_DIR}/internal/catch_reenable_warnings.h
+        ${HEADER_DIR}/internal/catch_reporter_registrars.hpp
+        ${HEADER_DIR}/internal/catch_reporter_registry.h
+        ${HEADER_DIR}/internal/catch_result_type.h
+        ${HEADER_DIR}/internal/catch_run_context.h
+        ${HEADER_DIR}/internal/catch_benchmark.h
+        ${HEADER_DIR}/internal/catch_section.h
+        ${HEADER_DIR}/internal/catch_section_info.h
+        ${HEADER_DIR}/internal/catch_session.h
+        ${HEADER_DIR}/internal/catch_singletons.hpp
+        ${HEADER_DIR}/internal/catch_startup_exception_registry.h
+        ${HEADER_DIR}/internal/catch_stream.h
+        ${HEADER_DIR}/internal/catch_stringref.h
+        ${HEADER_DIR}/internal/catch_string_manip.h
+        ${HEADER_DIR}/internal/catch_suppress_warnings.h
+        ${HEADER_DIR}/internal/catch_tag_alias.h
+        ${HEADER_DIR}/internal/catch_tag_alias_autoregistrar.h
+        ${HEADER_DIR}/internal/catch_tag_alias_registry.h
+        ${HEADER_DIR}/internal/catch_test_case_info.h
+        ${HEADER_DIR}/internal/catch_test_case_registry_impl.h
+        ${HEADER_DIR}/internal/catch_test_case_tracker.h
+        ${HEADER_DIR}/internal/catch_test_registry.h
+        ${HEADER_DIR}/internal/catch_test_spec.h
+        ${HEADER_DIR}/internal/catch_test_spec_parser.h
+        ${HEADER_DIR}/internal/catch_text.h
+        ${HEADER_DIR}/internal/catch_timer.h
+        ${HEADER_DIR}/internal/catch_to_string.hpp
+        ${HEADER_DIR}/internal/catch_tostring.h
+        ${HEADER_DIR}/internal/catch_totals.h
+        ${HEADER_DIR}/internal/catch_uncaught_exceptions.h
+        ${HEADER_DIR}/internal/catch_user_interfaces.h
+        ${HEADER_DIR}/internal/catch_version.h
+        ${HEADER_DIR}/internal/catch_wildcard_pattern.h
+        ${HEADER_DIR}/internal/catch_windows_h_proxy.h
+        ${HEADER_DIR}/internal/catch_xmlwriter.h
+        )
+set(IMPL_SOURCES
+        ${HEADER_DIR}/internal/catch_approx.cpp
+        ${HEADER_DIR}/internal/catch_assertionhandler.cpp
+        ${HEADER_DIR}/internal/catch_assertionresult.cpp
+        ${HEADER_DIR}/internal/catch_benchmark.cpp
+        ${HEADER_DIR}/internal/catch_capture_matchers.cpp
+        ${HEADER_DIR}/internal/catch_commandline.cpp
+        ${HEADER_DIR}/internal/catch_common.cpp
+        ${HEADER_DIR}/internal/catch_config.cpp
+        ${HEADER_DIR}/internal/catch_console_colour.cpp
+        ${HEADER_DIR}/internal/catch_context.cpp
+        ${HEADER_DIR}/internal/catch_debug_console.cpp
+        ${HEADER_DIR}/internal/catch_debugger.cpp
+        ${HEADER_DIR}/internal/catch_decomposer.cpp
+        ${HEADER_DIR}/internal/catch_enforce.cpp
+        ${HEADER_DIR}/internal/catch_errno_guard.cpp
+        ${HEADER_DIR}/internal/catch_exception_translator_registry.cpp
+        ${HEADER_DIR}/internal/catch_fatal_condition.cpp
+        ${HEADER_DIR}/internal/catch_generators.cpp
+        ${HEADER_DIR}/internal/catch_interfaces_capture.cpp
+        ${HEADER_DIR}/internal/catch_interfaces_config.cpp
+        ${HEADER_DIR}/internal/catch_interfaces_exception.cpp
+        ${HEADER_DIR}/internal/catch_interfaces_generatortracker.h
+        ${HEADER_DIR}/internal/catch_interfaces_registry_hub.cpp
+        ${HEADER_DIR}/internal/catch_interfaces_runner.cpp
+        ${HEADER_DIR}/internal/catch_interfaces_testcase.cpp
+        ${HEADER_DIR}/internal/catch_list.cpp
+        ${HEADER_DIR}/internal/catch_leak_detector.cpp
+        ${HEADER_DIR}/internal/catch_matchers.cpp
+        ${HEADER_DIR}/internal/catch_matchers_floating.cpp
+        ${HEADER_DIR}/internal/catch_matchers_generic.cpp
+        ${HEADER_DIR}/internal/catch_matchers_string.cpp
+        ${HEADER_DIR}/internal/catch_message.cpp
+        ${HEADER_DIR}/internal/catch_output_redirect.cpp
+        ${HEADER_DIR}/internal/catch_registry_hub.cpp
+        ${HEADER_DIR}/internal/catch_interfaces_reporter.cpp
+        ${HEADER_DIR}/internal/catch_random_number_generator.cpp
+        ${HEADER_DIR}/internal/catch_reporter_registry.cpp
+        ${HEADER_DIR}/internal/catch_result_type.cpp
+        ${HEADER_DIR}/internal/catch_run_context.cpp
+        ${HEADER_DIR}/internal/catch_section.cpp
+        ${HEADER_DIR}/internal/catch_section_info.cpp
+        ${HEADER_DIR}/internal/catch_session.cpp
+        ${HEADER_DIR}/internal/catch_singletons.cpp
+        ${HEADER_DIR}/internal/catch_startup_exception_registry.cpp
+        ${HEADER_DIR}/internal/catch_stream.cpp
+        ${HEADER_DIR}/internal/catch_stringref.cpp
+        ${HEADER_DIR}/internal/catch_string_manip.cpp
+        ${HEADER_DIR}/internal/catch_tag_alias.cpp
+        ${HEADER_DIR}/internal/catch_tag_alias_autoregistrar.cpp
+        ${HEADER_DIR}/internal/catch_tag_alias_registry.cpp
+        ${HEADER_DIR}/internal/catch_test_case_info.cpp
+        ${HEADER_DIR}/internal/catch_test_case_registry_impl.cpp
+        ${HEADER_DIR}/internal/catch_test_case_tracker.cpp
+        ${HEADER_DIR}/internal/catch_test_registry.cpp
+        ${HEADER_DIR}/internal/catch_test_spec.cpp
+        ${HEADER_DIR}/internal/catch_test_spec_parser.cpp
+        ${HEADER_DIR}/internal/catch_timer.cpp
+        ${HEADER_DIR}/internal/catch_tostring.cpp
+        ${HEADER_DIR}/internal/catch_totals.cpp
+        ${HEADER_DIR}/internal/catch_uncaught_exceptions.cpp
+        ${HEADER_DIR}/internal/catch_version.cpp
+        ${HEADER_DIR}/internal/catch_wildcard_pattern.cpp
+        ${HEADER_DIR}/internal/catch_xmlwriter.cpp
+        )
+set(INTERNAL_FILES ${IMPL_SOURCES} ${INTERNAL_HEADERS})
+CheckFileList(INTERNAL_FILES ${HEADER_DIR}/internal)
+
+# Please keep these ordered alphabetically
+set(REPORTER_HEADERS
+        ${HEADER_DIR}/reporters/catch_reporter_automake.hpp
+        ${HEADER_DIR}/reporters/catch_reporter_bases.hpp
+        ${HEADER_DIR}/reporters/catch_reporter_compact.h
+        ${HEADER_DIR}/reporters/catch_reporter_console.h
+        ${HEADER_DIR}/reporters/catch_reporter_junit.h
+        ${HEADER_DIR}/reporters/catch_reporter_listening.h
+        ${HEADER_DIR}/reporters/catch_reporter_tap.hpp
+        ${HEADER_DIR}/reporters/catch_reporter_teamcity.hpp
+        ${HEADER_DIR}/reporters/catch_reporter_xml.h
+        )
+set(REPORTER_SOURCES
+        ${HEADER_DIR}/reporters/catch_reporter_bases.cpp
+        ${HEADER_DIR}/reporters/catch_reporter_compact.cpp
+        ${HEADER_DIR}/reporters/catch_reporter_console.cpp
+        ${HEADER_DIR}/reporters/catch_reporter_junit.cpp
+        ${HEADER_DIR}/reporters/catch_reporter_listening.cpp
+        ${HEADER_DIR}/reporters/catch_reporter_xml.cpp
+        )
+set(REPORTER_FILES ${REPORTER_HEADERS} ${REPORTER_SOURCES})
+CheckFileList(REPORTER_FILES ${HEADER_DIR}/reporters)
+
+# Specify the headers, too, so CLion recognises them as project files
+set(HEADERS
+        ${TOP_LEVEL_HEADERS}
+        ${EXTERNAL_HEADERS}
+        ${INTERNAL_HEADERS}
+        ${REPORTER_HEADERS}
+        )
+
+# Provide some groupings for IDEs
+SOURCE_GROUP("Tests" FILES ${TEST_SOURCES})
+SOURCE_GROUP("Surrogates" FILES ${SURROGATE_SOURCES})
+
+include(CTest)
+
+add_executable(SelfTest ${TEST_SOURCES} ${IMPL_SOURCES} ${REPORTER_SOURCES} ${SURROGATE_SOURCES} ${HEADERS})
+target_include_directories(SelfTest PRIVATE ${HEADER_DIR})
+
+if(USE_CPP17)
+    message(STATUS "Enabling C++17")
+    set_property(TARGET SelfTest PROPERTY CXX_STANDARD 17)
+elseif(USE_CPP14)
+    message(STATUS "Enabling C++14")
+    set_property(TARGET SelfTest PROPERTY CXX_STANDARD 14)
+else()
+    message(STATUS "Enabling C++11")
+    set_property(TARGET SelfTest PROPERTY CXX_STANDARD 11)
+endif()
+
+set_property(TARGET SelfTest PROPERTY CXX_STANDARD_REQUIRED ON)
+set_property(TARGET SelfTest PROPERTY CXX_EXTENSIONS OFF)
+
+if (CATCH_ENABLE_COVERAGE)
+    set(ENABLE_COVERAGE ON CACHE BOOL "Enable coverage build." FORCE)
+    find_package(codecov)
+    add_coverage(SelfTest)
+    list(APPEND LCOV_REMOVE_PATTERNS "'/usr/*'")
+    coverage_evaluate()
+endif()
+
+# Add per compiler options
+if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang|GNU" )
+    target_compile_options( SelfTest PRIVATE -Wall -Wextra -Wunreachable-code -Wpedantic -Wmissing-declarations )
+    if (CATCH_ENABLE_WERROR)
+        target_compile_options( SelfTest PRIVATE -Werror)
+    endif()
+endif()
+# Clang specific options go here
+if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
+    target_compile_options( SelfTest PRIVATE -Wweak-vtables -Wexit-time-destructors -Wglobal-constructors -Wmissing-noreturn )
+endif()
+if ( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
+    STRING(REGEX REPLACE "/W[0-9]" "/W4" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) # override default warning level
+    target_compile_options( SelfTest PRIVATE /w44265 /w44061 /w44062 )
+    if (CATCH_ENABLE_WERROR)
+        target_compile_options( SelfTest PRIVATE /WX)
+    endif()
+    # Force MSVC to consider everything as encoded in utf-8
+    target_compile_options( SelfTest PRIVATE /utf-8 )
+endif()
+
+
+# configure unit tests via CTest
+add_test(NAME RunTests COMMAND $<TARGET_FILE:SelfTest>)
+
+add_test(NAME ListTests COMMAND $<TARGET_FILE:SelfTest> --list-tests --verbosity high)
+set_tests_properties(ListTests PROPERTIES 
+    PASS_REGULAR_EXPRESSION "[0-9]+ test cases"
+    FAIL_REGULAR_EXPRESSION "Hidden Test"
+)
+
+add_test(NAME ListTags COMMAND $<TARGET_FILE:SelfTest> --list-tags)
+set_tests_properties(ListTags PROPERTIES 
+    PASS_REGULAR_EXPRESSION "[0-9]+ tags" 
+    FAIL_REGULAR_EXPRESSION "\\[\\.\\]")
+
+add_test(NAME ListReporters COMMAND $<TARGET_FILE:SelfTest> --list-reporters)
+set_tests_properties(ListReporters PROPERTIES PASS_REGULAR_EXPRESSION "Available reporters:")
+
+add_test(NAME ListTestNamesOnly COMMAND $<TARGET_FILE:SelfTest> --list-test-names-only)
+set_tests_properties(ListTestNamesOnly PROPERTIES 
+    PASS_REGULAR_EXPRESSION "Regex string matcher"
+    FAIL_REGULAR_EXPRESSION "Hidden Test")
+
+add_test(NAME NoAssertions COMMAND $<TARGET_FILE:SelfTest> -w NoAssertions)
+set_tests_properties(NoAssertions PROPERTIES PASS_REGULAR_EXPRESSION "No assertions in test case")
+
+add_test(NAME NoTest COMMAND $<TARGET_FILE:SelfTest> -w NoTests "___nonexistent_test___")
+set_tests_properties(NoTest PROPERTIES PASS_REGULAR_EXPRESSION "No test cases matched")
+
+# AppVeyor has a Python 2.7 in path, but doesn't have .py files as autorunnable
+add_test(NAME ApprovalTests COMMAND ${PYTHON_EXECUTABLE} ${CATCH_DIR}/scripts/approvalTests.py $<TARGET_FILE:SelfTest>)
+set_tests_properties(ApprovalTests PROPERTIES FAIL_REGULAR_EXPRESSION "Results differed")
+
+if (CATCH_USE_VALGRIND)
+    add_test(NAME ValgrindRunTests COMMAND valgrind --leak-check=full --error-exitcode=1 $<TARGET_FILE:SelfTest>)
+    add_test(NAME ValgrindListTests COMMAND valgrind --leak-check=full --error-exitcode=1 $<TARGET_FILE:SelfTest> --list-tests --verbosity high)
+    set_tests_properties(ValgrindListTests PROPERTIES PASS_REGULAR_EXPRESSION "definitely lost: 0 bytes in 0 blocks")
+    add_test(NAME ValgrindListTags COMMAND valgrind --leak-check=full --error-exitcode=1 $<TARGET_FILE:SelfTest> --list-tags)
+    set_tests_properties(ValgrindListTags PROPERTIES PASS_REGULAR_EXPRESSION "definitely lost: 0 bytes in 0 blocks")
+endif()
diff --git a/packages/Catch2/projects/ExtraTests/CMakeLists.txt b/packages/Catch2/projects/ExtraTests/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c0dd82d8f07ab1087b712ff5db552238f6348ba9
--- /dev/null
+++ b/packages/Catch2/projects/ExtraTests/CMakeLists.txt
@@ -0,0 +1,135 @@
+#
+# Build extra tests.
+#
+# Requires CATCH_BUILD_EXTRA_TESTS to be defined 'true', see ../CMakeLists.txt.
+#
+
+cmake_minimum_required( VERSION 3.5 )
+
+project( Catch2ExtraTests LANGUAGES CXX )
+
+message( STATUS "Extra tests included" )
+
+# define folders used:
+
+set( TESTS_DIR   ${CATCH_DIR}/projects/ExtraTests )
+set( SINGLE_INCLUDE_PATH ${CATCH_DIR}/single_include )
+
+
+add_executable(PrefixedMacros ${TESTS_DIR}/X01-PrefixedMacros.cpp)
+target_compile_definitions( PrefixedMacros PRIVATE CATCH_CONFIG_PREFIX_ALL )
+
+add_test(NAME CATCH_CONFIG_PREFIX_ALL COMMAND PrefixedMacros -s)
+set_tests_properties(
+    CATCH_CONFIG_PREFIX_ALL
+  PROPERTIES
+    PASS_REGULAR_EXPRESSION "CATCH_"
+    FAIL_REGULAR_EXPRESSION
+    # The spaces are important -> They disambiguate between CATCH_REQUIRE
+    # and REQUIRE without prefix.
+    " REQUIRE; REQUIRE_FALSE; REQUIRE_THROWS; REQUIRE_THROWS_AS; REQUIRE_THROWS_WITH; REQUIRE_THROWS_MATCHES; REQUIRE_NOTHROW; CHECK; CHECK_FALSE; CHECKED_IF; CHECKED_ELSE; CHECK_NOFAIL; CHECK_THROWS; CHECK_THROWS_AS; CHECK_THROWS_WITH; CHECK_THROWS_MATCHES; CHECK_NOTHROW; REQUIRE_THAT; CHECK_THAT"
+)
+
+add_executable(DisabledMacros ${TESTS_DIR}/X02-DisabledMacros.cpp)
+target_compile_definitions( DisabledMacros PRIVATE CATCH_CONFIG_DISABLE )
+
+add_test(NAME CATCH_CONFIG_DISABLE-1 COMMAND DisabledMacros -s)
+set_tests_properties(
+    CATCH_CONFIG_DISABLE-1
+  PROPERTIES
+    PASS_REGULAR_EXPRESSION "No tests ran"
+    FAIL_REGULAR_EXPRESSION "This should not happen"
+)
+add_test(NAME CATCH_CONFIG_DISABLE-2 COMMAND DisabledMacros --list-tests)
+set_tests_properties(
+    CATCH_CONFIG_DISABLE-2
+  PROPERTIES
+    PASS_REGULAR_EXPRESSION "0 test cases"
+)
+
+
+add_executable( DisabledExceptions-DefaultHandler ${TESTS_DIR}/X03-DisabledExceptions-DefaultHandler.cpp )
+add_executable( DisabledExceptions-CustomHandler ${TESTS_DIR}/X04-DisabledExceptions-CustomHandler.cpp )
+
+foreach(target DisabledExceptions-DefaultHandler DisabledExceptions-CustomHandler)
+target_compile_options( ${target}
+  PRIVATE
+    $<$<CXX_COMPILER_ID:MSVC>:/EHs-c-;/D_HAS_EXCEPTIONS=0>
+    $<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:AppleClang>>:-fno-exceptions>
+#    $<$<CXX_COMPILER_ID:Clang>:-fno-exceptions>
+#    $<$<CXX_COMPILER_ID:GNU>:-fno-exceptions>
+)
+endforeach()
+
+
+add_test(NAME CATCH_CONFIG_DISABLE_EXCEPTIONS-1 COMMAND DisabledExceptions-DefaultHandler "Tests that run")
+set_tests_properties(
+    CATCH_CONFIG_DISABLE_EXCEPTIONS-1
+  PROPERTIES
+    PASS_REGULAR_EXPRESSION "assertions: 4 \| 2 passed \| 2 failed"
+    FAIL_REGULAR_EXPRESSION "abort;terminate;fatal"
+)
+
+add_test(NAME CATCH_CONFIG_DISABLE_EXCEPTIONS-2 COMMAND DisabledExceptions-DefaultHandler "Tests that abort")
+set_tests_properties(
+    CATCH_CONFIG_DISABLE_EXCEPTIONS-2
+  PROPERTIES
+    PASS_REGULAR_EXPRESSION "Catch will terminate"
+)
+
+add_test(NAME CATCH_CONFIG_DISABLE_EXCEPTIONS-3 COMMAND DisabledExceptions-CustomHandler "Tests that run")
+set_tests_properties(
+    CATCH_CONFIG_DISABLE_EXCEPTIONS-3
+  PROPERTIES
+    PASS_REGULAR_EXPRESSION "assertions: 4 \| 2 passed \| 2 failed"
+    FAIL_REGULAR_EXPRESSION "====== CUSTOM HANDLER ======"
+)
+
+add_test(NAME CATCH_CONFIG_DISABLE_EXCEPTIONS-4 COMMAND DisabledExceptions-CustomHandler "Tests that abort")
+set_tests_properties(
+    CATCH_CONFIG_DISABLE_EXCEPTIONS-4
+  PROPERTIES
+    PASS_REGULAR_EXPRESSION "====== CUSTOM HANDLER ======"
+)
+
+
+
+add_executable(FallbackStringifier ${TESTS_DIR}/X10-FallbackStringifier.cpp)
+target_compile_definitions( FallbackStringifier PRIVATE CATCH_CONFIG_FALLBACK_STRINGIFIER=fallbackStringifier )
+
+add_test(NAME FallbackStringifier COMMAND FallbackStringifier -r compact -s)
+set_tests_properties(
+    FallbackStringifier
+  PROPERTIES
+    PASS_REGULAR_EXPRESSION "foo{} for: { !!! }"
+)
+
+
+add_executable(DisableStringification ${TESTS_DIR}/X11-DisableStringification.cpp)
+target_compile_definitions( DisableStringification PRIVATE CATCH_CONFIG_DISABLE_STRINGIFICATION )
+add_test(NAME CATCH_CONFIG_DISABLE_STRINGIFICATION COMMAND DisableStringification -r compact -s)
+set_tests_properties(
+    CATCH_CONFIG_DISABLE_STRINGIFICATION
+  PROPERTIES
+    PASS_REGULAR_EXPRESSION "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
+    FAIL_REGULAR_EXPRESSION  "Hidden{} == Hidden{}"
+)
+
+
+set( EXTRA_TEST_BINARIES
+    PrefixedMacros
+    DisabledMacros
+    DisabledExceptions-DefaultHandler
+    DisabledExceptions-CustomHandler
+    FallbackStringifier
+    DisableStringification
+)
+
+# Shared config
+foreach( test ${EXTRA_TEST_BINARIES} )
+    set_property( TARGET ${test} PROPERTY CXX_STANDARD 11 )
+    set_property( TARGET ${test} PROPERTY CXX_STANDARD_REQUIRED ON )
+    set_property( TARGET ${test} PROPERTY CXX_EXTENSIONS OFF )
+    target_include_directories( ${test} PRIVATE ${SINGLE_INCLUDE_PATH} )
+endforeach()
+
diff --git a/packages/Catch2/projects/ExtraTests/ToDo.txt b/packages/Catch2/projects/ExtraTests/ToDo.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ab68bd3e57d926160f5d06fe142a43fac2348747
--- /dev/null
+++ b/packages/Catch2/projects/ExtraTests/ToDo.txt
@@ -0,0 +1,11 @@
+Configuration options that are left default and thus are not properly tested
+yet:
+
+    CATCH_CONFIG_COUNTER                    // Use __COUNTER__ to generate unique names for test cases
+    CATCH_CONFIG_WINDOWS_SEH                // Enable SEH handling on Windows
+    CATCH_CONFIG_FAST_COMPILE               // Sacrifices some (rather minor) features for compilation speed
+    CATCH_CONFIG_DISABLE_MATCHERS           // Do not compile Matchers in this compilation unit
+    CATCH_CONFIG_POSIX_SIGNALS              // Enable handling POSIX signals
+    CATCH_CONFIG_WINDOWS_CRTDBG             // Enable leak checking using Windows's CRT Debug Heap
+    CATCH_CONFIG_DEFAULT_REPORTER
+    CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS
diff --git a/packages/Catch2/projects/ExtraTests/X01-PrefixedMacros.cpp b/packages/Catch2/projects/ExtraTests/X01-PrefixedMacros.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..08bf404fb8ca4639b38d99dff4c0ecade13dba63
--- /dev/null
+++ b/packages/Catch2/projects/ExtraTests/X01-PrefixedMacros.cpp
@@ -0,0 +1,76 @@
+// X11-DisableStringification.cpp
+// Test that Catch's prefixed macros compile and run properly.
+
+#define CATCH_CONFIG_MAIN
+#include <catch2/catch.hpp>
+
+#include <stdexcept>
+
+[[noreturn]]
+void this_throws() {
+    throw std::runtime_error("Some msg");
+}
+void this_doesnt_throw() {}
+
+CATCH_TEST_CASE("PrefixedMacros") {
+    using namespace Catch::Matchers;
+
+    CATCH_REQUIRE( 1 == 1 );
+    CATCH_REQUIRE_FALSE( 1 != 1 );
+
+    CATCH_REQUIRE_THROWS(this_throws());
+    CATCH_REQUIRE_THROWS_AS(this_throws(), std::runtime_error);
+    CATCH_REQUIRE_THROWS_WITH(this_throws(), "Some msg");
+    CATCH_REQUIRE_THROWS_MATCHES(this_throws(), std::runtime_error, Predicate<std::runtime_error>([](std::runtime_error const&) { return true; }));
+    CATCH_REQUIRE_NOTHROW(this_doesnt_throw());
+    
+    CATCH_CHECK( 1 == 1 );
+    CATCH_CHECK_FALSE( 1 != 1 );
+    CATCH_CHECKED_IF( 1 == 1 ) {
+        CATCH_SUCCEED("don't care");
+    } CATCH_CHECKED_ELSE ( 1 == 1 ) {
+        CATCH_SUCCEED("don't care");
+    }
+    
+    CATCH_CHECK_NOFAIL(1 == 2);
+    
+    CATCH_CHECK_THROWS(this_throws());
+    CATCH_CHECK_THROWS_AS(this_throws(), std::runtime_error);
+    CATCH_CHECK_THROWS_WITH(this_throws(), "Some msg");
+    CATCH_CHECK_THROWS_MATCHES(this_throws(), std::runtime_error, Predicate<std::runtime_error>([](std::runtime_error const&) { return true; }));
+    CATCH_CHECK_NOTHROW(this_doesnt_throw());    
+    
+    CATCH_REQUIRE_THAT("abcd", Equals("abcd"));
+    CATCH_CHECK_THAT("bdef", Equals("bdef"));
+
+    CATCH_INFO( "some info" );
+    CATCH_WARN( "some warn" );
+    CATCH_SECTION("some section") {
+        int i = 1;
+        CATCH_CAPTURE( i );
+        CATCH_DYNAMIC_SECTION("Dynamic section: " << i) {
+            CATCH_FAIL_CHECK( "failure" );
+        }
+    }
+}
+
+CATCH_ANON_TEST_CASE() {
+    CATCH_FAIL("");
+}
+
+// Missing:
+
+//
+// #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__ )
+//
+// // "BDD-style" convenience wrappers
+// #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
+// #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
+// #define CATCH_GIVEN( desc )    INTERNAL_CATCH_DYNAMIC_SECTION( "   Given: " << desc )
+// #define CATCH_WHEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( "    When: " << desc )
+// #define CATCH_AND_WHEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And when: " << desc )
+// #define CATCH_THEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( "    Then: " << desc )
+// #define CATCH_AND_THEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "     And: " << desc )
+//
diff --git a/packages/Catch2/projects/ExtraTests/X02-DisabledMacros.cpp b/packages/Catch2/projects/ExtraTests/X02-DisabledMacros.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3a969d7693b973446118495e8270db333f3907b8
--- /dev/null
+++ b/packages/Catch2/projects/ExtraTests/X02-DisabledMacros.cpp
@@ -0,0 +1,31 @@
+// X02-DisabledMacros.cpp
+// Test that CATCH_CONFIG_DISABLE turns off TEST_CASE autoregistration
+// and expressions in assertion macros are not run.
+
+#define CATCH_CONFIG_MAIN
+#include <catch2/catch.hpp>
+
+
+// CATCH_CONFIG_DISABLE also prevents reporter registration.
+// We need to manually register at least one reporter for our tests
+static Catch::ReporterRegistrar<Catch::ConsoleReporter> temporary( "console" );
+
+#include <iostream>
+
+struct foo {
+    foo(){
+        REQUIRE_NOTHROW( print() );
+    }
+    void print() const {
+        std::cout << "This should not happen\n";
+    }
+};
+
+// Construct foo, but `foo::print` should not be run
+foo f;
+
+// This test should not be run, because it won't be registered
+TEST_CASE( "Disabled Macros" ) {
+    std::cout << "This should not happen\n";
+    FAIL();
+}
diff --git a/packages/Catch2/projects/ExtraTests/X03-DisabledExceptions-DefaultHandler.cpp b/packages/Catch2/projects/ExtraTests/X03-DisabledExceptions-DefaultHandler.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..846c9b0f831cdd0e2d1d263524562e26a4721db5
--- /dev/null
+++ b/packages/Catch2/projects/ExtraTests/X03-DisabledExceptions-DefaultHandler.cpp
@@ -0,0 +1,23 @@
+#define CATCH_CONFIG_MAIN
+#include <catch2/catch.hpp>
+
+TEST_CASE("Tests that run") {
+    // All of these should be run and be reported
+    CHECK(1 == 2);
+    CHECK(1 == 1);
+    CHECK(1 != 3);
+    CHECK(1 == 4);
+}
+
+
+
+TEST_CASE("Tests that abort") {
+    // Avoid abort and other exceptional exits -- there is no way
+    // to tell CMake that abort is the desired outcome of a test.
+    std::set_terminate([](){exit(1);});
+    REQUIRE(1 == 1);
+    REQUIRE(1 != 2);
+    REQUIRE(1 == 3);
+    // We should not get here, because the test above aborts
+    REQUIRE(1 != 4);
+}
diff --git a/packages/Catch2/projects/ExtraTests/X04-DisabledExceptions-CustomHandler.cpp b/packages/Catch2/projects/ExtraTests/X04-DisabledExceptions-CustomHandler.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..96f3ceb84b4e5b3b864bcdc8b1a706a7704a659b
--- /dev/null
+++ b/packages/Catch2/projects/ExtraTests/X04-DisabledExceptions-CustomHandler.cpp
@@ -0,0 +1,33 @@
+#define CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER
+
+#define CATCH_CONFIG_MAIN
+#include <catch2/catch.hpp>
+
+namespace Catch {
+    [[noreturn]]
+    void throw_exception(std::exception const& e) {
+        Catch::cerr() << "====== CUSTOM HANDLER ====== run terminates because an exception was thrown.\n"
+                      << "The message was: " << e.what() << '\n';
+        // Avoid abort and other exceptional exits -- there is no way
+        // to tell CMake that abort is the desired outcome of a test.
+        exit(1);
+    }
+}
+
+TEST_CASE("Tests that run") {
+    // All of these should be run and be reported
+    CHECK(1 == 2);
+    CHECK(1 == 1);
+    CHECK(1 != 3);
+    CHECK(1 == 4);
+}
+
+
+
+TEST_CASE("Tests that abort") {
+    REQUIRE(1 == 1);
+    REQUIRE(1 != 2);
+    REQUIRE(1 == 3);
+    // We should not get here, because the test above aborts
+    REQUIRE(1 != 4);
+}
diff --git a/packages/Catch2/projects/ExtraTests/X10-FallbackStringifier.cpp b/packages/Catch2/projects/ExtraTests/X10-FallbackStringifier.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0522d1af8735412258c09a72ec1586cd6f9b0c1c
--- /dev/null
+++ b/packages/Catch2/projects/ExtraTests/X10-FallbackStringifier.cpp
@@ -0,0 +1,23 @@
+// X10-FallbackStringifier.cpp
+// Test that defining fallbackStringifier compiles
+
+#include <string>
+
+// A catch-all stringifier
+template <typename T>
+std::string fallbackStringifier(T const&) {
+    return "{ !!! }";
+}
+
+#define CATCH_CONFIG_MAIN
+#include <catch2/catch.hpp>
+
+struct foo {
+    explicit operator bool() const {
+        return true;
+    }
+};
+
+TEST_CASE("aa") {
+    REQUIRE(foo{});
+}
diff --git a/packages/Catch2/projects/ExtraTests/X11-DisableStringification.cpp b/packages/Catch2/projects/ExtraTests/X11-DisableStringification.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7a93f6e29b7d9ecbfeda805a014791d2f034205f
--- /dev/null
+++ b/packages/Catch2/projects/ExtraTests/X11-DisableStringification.cpp
@@ -0,0 +1,16 @@
+// X11-DisableStringification.cpp
+// Test that stringification of original expression can be disabled
+// this is a workaround for VS 2017 issue with Raw String literal
+// and preprocessor token pasting. In other words, hopefully this test
+// will be deleted soon :-)
+
+#define CATCH_CONFIG_MAIN
+#include <catch2/catch.hpp>
+
+struct Hidden {};
+
+bool operator==(Hidden, Hidden) { return true; }
+
+TEST_CASE("DisableStringification") {
+    REQUIRE( Hidden{} == Hidden{} );
+}
diff --git a/packages/Catch2/projects/SelfTest/Baselines/compact.sw.approved.txt b/packages/Catch2/projects/SelfTest/Baselines/compact.sw.approved.txt
index 24d9b1b792a14c184280dd16514ef6868f22f301..2138d26ee9b7fe660a03371ca7bcfaa0b4c2f905 100644
--- a/packages/Catch2/projects/SelfTest/Baselines/compact.sw.approved.txt
+++ b/packages/Catch2/projects/SelfTest/Baselines/compact.sw.approved.txt
@@ -56,10 +56,116 @@ Tricky.tests.cpp:<line number>: passed: !is_true<false>::value for: true
 Tricky.tests.cpp:<line number>: passed: !!is_true<true>::value for: true
 Tricky.tests.cpp:<line number>: passed: is_true<true>::value for: true
 Tricky.tests.cpp:<line number>: passed: !(is_true<false>::value) for: !false
+Generators.tests.cpp:<line number>: passed: x < y for: 1 < 101
+Generators.tests.cpp:<line number>: passed: x < y for: 1 < 102
+Generators.tests.cpp:<line number>: passed: x < y for: 1 < 103
+Generators.tests.cpp:<line number>: passed: x < y for: 1 < 104
+Generators.tests.cpp:<line number>: passed: x < y for: 1 < 105
+Generators.tests.cpp:<line number>: passed: x < y for: 1 < 106
+Generators.tests.cpp:<line number>: passed: x < y for: 1 < 107
+Generators.tests.cpp:<line number>: passed: x < y for: 1 < 108
+Generators.tests.cpp:<line number>: passed: x < y for: 1 < 109
+Generators.tests.cpp:<line number>: passed: x < y for: 1 < 110
+Generators.tests.cpp:<line number>: passed: x < y for: 2 < 101
+Generators.tests.cpp:<line number>: passed: x < y for: 2 < 102
+Generators.tests.cpp:<line number>: passed: x < y for: 2 < 103
+Generators.tests.cpp:<line number>: passed: x < y for: 2 < 104
+Generators.tests.cpp:<line number>: passed: x < y for: 2 < 105
+Generators.tests.cpp:<line number>: passed: x < y for: 2 < 106
+Generators.tests.cpp:<line number>: passed: x < y for: 2 < 107
+Generators.tests.cpp:<line number>: passed: x < y for: 2 < 108
+Generators.tests.cpp:<line number>: passed: x < y for: 2 < 109
+Generators.tests.cpp:<line number>: passed: x < y for: 2 < 110
+Generators.tests.cpp:<line number>: passed: x < y for: 3 < 101
+Generators.tests.cpp:<line number>: passed: x < y for: 3 < 102
+Generators.tests.cpp:<line number>: passed: x < y for: 3 < 103
+Generators.tests.cpp:<line number>: passed: x < y for: 3 < 104
+Generators.tests.cpp:<line number>: passed: x < y for: 3 < 105
+Generators.tests.cpp:<line number>: passed: x < y for: 3 < 106
+Generators.tests.cpp:<line number>: passed: x < y for: 3 < 107
+Generators.tests.cpp:<line number>: passed: x < y for: 3 < 108
+Generators.tests.cpp:<line number>: passed: x < y for: 3 < 109
+Generators.tests.cpp:<line number>: passed: x < y for: 3 < 110
+Generators.tests.cpp:<line number>: passed: x < y for: 4 < 101
+Generators.tests.cpp:<line number>: passed: x < y for: 4 < 102
+Generators.tests.cpp:<line number>: passed: x < y for: 4 < 103
+Generators.tests.cpp:<line number>: passed: x < y for: 4 < 104
+Generators.tests.cpp:<line number>: passed: x < y for: 4 < 105
+Generators.tests.cpp:<line number>: passed: x < y for: 4 < 106
+Generators.tests.cpp:<line number>: passed: x < y for: 4 < 107
+Generators.tests.cpp:<line number>: passed: x < y for: 4 < 108
+Generators.tests.cpp:<line number>: passed: x < y for: 4 < 109
+Generators.tests.cpp:<line number>: passed: x < y for: 4 < 110
+Generators.tests.cpp:<line number>: passed: x < y for: 5 < 101
+Generators.tests.cpp:<line number>: passed: x < y for: 5 < 102
+Generators.tests.cpp:<line number>: passed: x < y for: 5 < 103
+Generators.tests.cpp:<line number>: passed: x < y for: 5 < 104
+Generators.tests.cpp:<line number>: passed: x < y for: 5 < 105
+Generators.tests.cpp:<line number>: passed: x < y for: 5 < 106
+Generators.tests.cpp:<line number>: passed: x < y for: 5 < 107
+Generators.tests.cpp:<line number>: passed: x < y for: 5 < 108
+Generators.tests.cpp:<line number>: passed: x < y for: 5 < 109
+Generators.tests.cpp:<line number>: passed: x < y for: 5 < 110
+Generators.tests.cpp:<line number>: passed: x < y for: 6 < 101
+Generators.tests.cpp:<line number>: passed: x < y for: 6 < 102
+Generators.tests.cpp:<line number>: passed: x < y for: 6 < 103
+Generators.tests.cpp:<line number>: passed: x < y for: 6 < 104
+Generators.tests.cpp:<line number>: passed: x < y for: 6 < 105
+Generators.tests.cpp:<line number>: passed: x < y for: 6 < 106
+Generators.tests.cpp:<line number>: passed: x < y for: 6 < 107
+Generators.tests.cpp:<line number>: passed: x < y for: 6 < 108
+Generators.tests.cpp:<line number>: passed: x < y for: 6 < 109
+Generators.tests.cpp:<line number>: passed: x < y for: 6 < 110
+Generators.tests.cpp:<line number>: passed: x < y for: 7 < 101
+Generators.tests.cpp:<line number>: passed: x < y for: 7 < 102
+Generators.tests.cpp:<line number>: passed: x < y for: 7 < 103
+Generators.tests.cpp:<line number>: passed: x < y for: 7 < 104
+Generators.tests.cpp:<line number>: passed: x < y for: 7 < 105
+Generators.tests.cpp:<line number>: passed: x < y for: 7 < 106
+Generators.tests.cpp:<line number>: passed: x < y for: 7 < 107
+Generators.tests.cpp:<line number>: passed: x < y for: 7 < 108
+Generators.tests.cpp:<line number>: passed: x < y for: 7 < 109
+Generators.tests.cpp:<line number>: passed: x < y for: 7 < 110
+Generators.tests.cpp:<line number>: passed: x < y for: 8 < 101
+Generators.tests.cpp:<line number>: passed: x < y for: 8 < 102
+Generators.tests.cpp:<line number>: passed: x < y for: 8 < 103
+Generators.tests.cpp:<line number>: passed: x < y for: 8 < 104
+Generators.tests.cpp:<line number>: passed: x < y for: 8 < 105
+Generators.tests.cpp:<line number>: passed: x < y for: 8 < 106
+Generators.tests.cpp:<line number>: passed: x < y for: 8 < 107
+Generators.tests.cpp:<line number>: passed: x < y for: 8 < 108
+Generators.tests.cpp:<line number>: passed: x < y for: 8 < 109
+Generators.tests.cpp:<line number>: passed: x < y for: 8 < 110
+Generators.tests.cpp:<line number>: passed: x < y for: 9 < 101
+Generators.tests.cpp:<line number>: passed: x < y for: 9 < 102
+Generators.tests.cpp:<line number>: passed: x < y for: 9 < 103
+Generators.tests.cpp:<line number>: passed: x < y for: 9 < 104
+Generators.tests.cpp:<line number>: passed: x < y for: 9 < 105
+Generators.tests.cpp:<line number>: passed: x < y for: 9 < 106
+Generators.tests.cpp:<line number>: passed: x < y for: 9 < 107
+Generators.tests.cpp:<line number>: passed: x < y for: 9 < 108
+Generators.tests.cpp:<line number>: passed: x < y for: 9 < 109
+Generators.tests.cpp:<line number>: passed: x < y for: 9 < 110
+Generators.tests.cpp:<line number>: passed: x < y for: 10 < 101
+Generators.tests.cpp:<line number>: passed: x < y for: 10 < 102
+Generators.tests.cpp:<line number>: passed: x < y for: 10 < 103
+Generators.tests.cpp:<line number>: passed: x < y for: 10 < 104
+Generators.tests.cpp:<line number>: passed: x < y for: 10 < 105
+Generators.tests.cpp:<line number>: passed: x < y for: 10 < 106
+Generators.tests.cpp:<line number>: passed: x < y for: 10 < 107
+Generators.tests.cpp:<line number>: passed: x < y for: 10 < 108
+Generators.tests.cpp:<line number>: passed: x < y for: 10 < 109
+Generators.tests.cpp:<line number>: passed: x < y for: 10 < 110
 Class.tests.cpp:<line number>: failed: s == "world" for: "hello" == "world"
 Class.tests.cpp:<line number>: passed: s == "hello" for: "hello" == "hello"
 Class.tests.cpp:<line number>: failed: m_a == 2 for: 1 == 2
 Class.tests.cpp:<line number>: passed: m_a == 1 for: 1 == 1
+Approx.tests.cpp:<line number>: passed: d == 1.23_a for: 1.23 == Approx( 1.23 )
+Approx.tests.cpp:<line number>: passed: d != 1.22_a for: 1.23 != Approx( 1.22 )
+Approx.tests.cpp:<line number>: passed: -d == -1.23_a for: -1.23 == Approx( -1.23 )
+Approx.tests.cpp:<line number>: passed: d == 1.2_a .epsilon(.1) for: 1.23 == Approx( 1.2 )
+Approx.tests.cpp:<line number>: passed: d != 1.2_a .epsilon(.001) for: 1.23 != Approx( 1.2 )
+Approx.tests.cpp:<line number>: passed: d == 1_a .epsilon(.3) for: 1.23 == Approx( 1.0 )
 Misc.tests.cpp:<line number>: passed: with 1 message: 'that's not flying - that's failing in style'
 Misc.tests.cpp:<line number>: failed: explicitly with 1 message: 'to infinity and beyond'
 Tricky.tests.cpp:<line number>: failed: &o1 == &o2 for: 0x<hex digits> == 0x<hex digits>
@@ -291,6 +397,48 @@ Matchers.tests.cpp:<line number>: passed: WithinAbs(1.f, 0.f)
 Matchers.tests.cpp:<line number>: passed: WithinAbs(1.f, -1.f), std::domain_error
 Matchers.tests.cpp:<line number>: passed: WithinULP(1.f, 0)
 Matchers.tests.cpp:<line number>: passed: WithinULP(1.f, -1), std::domain_error
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "a"' and 'j := 8'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "a"' and 'j := 9'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "a"' and 'j := 10'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "a"' and 'j := 2'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "a"' and 'j := 3.141'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "a"' and 'j := 1.379'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "b"' and 'j := 8'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "b"' and 'j := 9'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "b"' and 'j := 10'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "b"' and 'j := 2'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "b"' and 'j := 3.141'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "b"' and 'j := 1.379'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "c"' and 'j := 8'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "c"' and 'j := 9'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "c"' and 'j := 10'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "c"' and 'j := 2'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "c"' and 'j := 3.141'
+Generators.tests.cpp:<line number>: passed: with 2 messages: 'i := "c"' and 'j := 1.379'
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.size() == 2 for: 2 == 2
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[0] == 1 for: 1 == 1
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[1] == 2 for: 2 == 2
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.size() == 4 for: 4 == 4
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[0] == 3 for: 3 == 3
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[1] == 1 for: 1 == 1
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[2] == 4 for: 4 == 4
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[3] == 1 for: 1 == 1
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.size() == 4 for: 4 == 4
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[0] == 1 for: 1 == 1
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[1] == 2 for: 2 == 2
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[2] == 9 for: 9 == 9
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[3] == 7 for: 7 == 7
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.size() == 2 for: 2 == 2
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[0] == 3 for: 3 == 3
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[1] == 1 for: 1 == 1
+GeneratorsImpl.tests.cpp:<line number>: passed: gen.size() == 2 for: 2 == 2
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[0] == 3 for: 3 == 3
+GeneratorsImpl.tests.cpp:<line number>: passed: gen[1] == 1 for: 1 == 1
+GeneratorsImpl.tests.cpp:<line number>: passed: base->size() == 4 for: 4 == 4
+GeneratorsImpl.tests.cpp:<line number>: passed: typed for: 0x<hex digits>
+GeneratorsImpl.tests.cpp:<line number>: passed: typed->size() == 4 for: 4 == 4
+GeneratorsImpl.tests.cpp:<line number>: passed: (*typed)[0] == 7 for: 7 == 7
+GeneratorsImpl.tests.cpp:<line number>: passed: (*typed)[3] == 11 for: 11 == 11
 Approx.tests.cpp:<line number>: passed: d >= Approx( 1.22 ) for: 1.23 >= Approx( 1.22 )
 Approx.tests.cpp:<line number>: passed: d >= Approx( 1.23 ) for: 1.23 >= Approx( 1.23 )
 Approx.tests.cpp:<line number>: passed: !(d >= Approx( 1.24 )) for: !(1.23 >= Approx( 1.24 ))
@@ -520,7 +668,6 @@ CmdLine.tests.cpp:<line number>: passed: spec.matches( tcA ) == false for: false
 CmdLine.tests.cpp:<line number>: passed: spec.matches( tcB ) == false for: false == false
 CmdLine.tests.cpp:<line number>: passed: spec.matches( tcC ) == false for: false == false
 CmdLine.tests.cpp:<line number>: passed: spec.matches( tcD ) == true for: true == true
-Tricky.tests.cpp:<line number>: passed: (std::pair<int, int>( 1, 2 )) == aNicePair for: {?} == {?}
 Condition.tests.cpp:<line number>: passed: p == 0 for: 0 == 0
 Condition.tests.cpp:<line number>: passed: p == pNULL for: 0 == 0
 Condition.tests.cpp:<line number>: passed: p != 0 for: 0x<hex digits> != 0
@@ -593,6 +740,7 @@ Decomposition.tests.cpp:<line number>: failed: truthy(false) for: Hey, its truth
 Matchers.tests.cpp:<line number>: failed: testStringForMatching(), Matches("this STRING contains 'abc' as a substring") for: "this string contains 'abc' as a substring" matches "this STRING contains 'abc' as a substring" case sensitively
 Matchers.tests.cpp:<line number>: failed: testStringForMatching(), Matches("contains 'abc' as a substring") for: "this string contains 'abc' as a substring" matches "contains 'abc' as a substring" case sensitively
 Matchers.tests.cpp:<line number>: failed: testStringForMatching(), Matches("this string contains 'abc' as a") for: "this string contains 'abc' as a substring" matches "this string contains 'abc' as a" case sensitively
+Matchers.tests.cpp:<line number>: passed: actual, !UnorderedEquals(expected) for: { 'a', 'b' } not UnorderedEquals: { 'c', 'b' }
 Message.tests.cpp:<line number>: passed: with 1 message: 'this is a success'
 Message.tests.cpp:<line number>: passed:
 BDD.tests.cpp:<line number>: passed: before == 0 for: 0 == 0
@@ -614,6 +762,8 @@ A string sent to stderr via clog
 Approx.tests.cpp:<line number>: passed: d == Approx( 1.23 ) for: 1.23 == Approx( 1.23 )
 Approx.tests.cpp:<line number>: passed: d != Approx( 1.22 ) for: 1.23 != Approx( 1.22 )
 Approx.tests.cpp:<line number>: passed: d != Approx( 1.24 ) for: 1.23 != Approx( 1.24 )
+Approx.tests.cpp:<line number>: passed: d == 1.23_a for: 1.23 == Approx( 1.23 )
+Approx.tests.cpp:<line number>: passed: d != 1.22_a for: 1.23 != Approx( 1.22 )
 Approx.tests.cpp:<line number>: passed: Approx( d ) == 1.23 for: Approx( 1.23 ) == 1.23
 Approx.tests.cpp:<line number>: passed: Approx( d ) != 1.22 for: Approx( 1.23 ) != 1.22
 Approx.tests.cpp:<line number>: passed: Approx( d ) != 1.24 for: Approx( 1.23 ) != 1.24
@@ -988,6 +1138,15 @@ Misc.tests.cpp:<line number>: passed: l == std::numeric_limits<long long>::max()
 ==
 9223372036854775807 (0x<hex digits>)
 Misc.tests.cpp:<line number>: failed: b > a for: 0 > 1
+Misc.tests.cpp:<line number>: failed: b > a for: 1 > 1
+Misc.tests.cpp:<line number>: passed: b > a for: 2 > 1
+Misc.tests.cpp:<line number>: passed: b > a for: 3 > 1
+Misc.tests.cpp:<line number>: passed: b > a for: 4 > 1
+Misc.tests.cpp:<line number>: passed: b > a for: 5 > 1
+Misc.tests.cpp:<line number>: passed: b > a for: 6 > 1
+Misc.tests.cpp:<line number>: passed: b > a for: 7 > 1
+Misc.tests.cpp:<line number>: passed: b > a for: 8 > 1
+Misc.tests.cpp:<line number>: passed: b > a for: 9 > 1
 Misc.tests.cpp:<line number>: failed: ( fib[i] % 2 ) == 0 for: 1 == 0 with 1 message: 'Testing if fib[0] (1) is even'
 Misc.tests.cpp:<line number>: failed: ( fib[i] % 2 ) == 0 for: 1 == 0 with 1 message: 'Testing if fib[1] (1) is even'
 Misc.tests.cpp:<line number>: passed: ( fib[i] % 2 ) == 0 for: 0 == 0 with 1 message: 'Testing if fib[2] (2) is even'
@@ -1077,6 +1236,10 @@ ToStringWhich.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( v ) =
 ToStringWhich.tests.cpp:<line number>: passed: ::Catch::Detail::stringify( v ) == "{ operator<<( has_operator ) }" for: "{ operator<<( has_operator ) }"
 ==
 "{ operator<<( has_operator ) }"
+Generators.tests.cpp:<line number>: passed: data.str.size() == data.len for: 3 == 3
+Generators.tests.cpp:<line number>: passed: data.str.size() == data.len for: 3 == 3
+Generators.tests.cpp:<line number>: passed: data.str.size() == data.len for: 5 == 5
+Generators.tests.cpp:<line number>: passed: data.str.size() == data.len for: 4 == 4
 Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'Why would you throw a std::string?'
 Misc.tests.cpp:<line number>: passed: result == "/"wide load/"" for: ""wide load"" == ""wide load""
 Misc.tests.cpp:<line number>: passed: result == "/"wide load/"" for: ""wide load"" == ""wide load""
@@ -1144,5 +1307,5 @@ Misc.tests.cpp:<line number>: passed: v.size() == 5 for: 5 == 5
 Misc.tests.cpp:<line number>: passed: v.capacity() >= 5 for: 5 >= 5
 Misc.tests.cpp:<line number>: passed:
 Misc.tests.cpp:<line number>: passed:
-Failed 62 test cases, failed 121 assertions.
+Failed 62 test cases, failed 122 assertions.
 
diff --git a/packages/Catch2/projects/SelfTest/Baselines/console.std.approved.txt b/packages/Catch2/projects/SelfTest/Baselines/console.std.approved.txt
index 1992fb9fc2ca43773f4e551132aec016ef1b0ad3..24755c802bbc3872813830ba0df7385d00aa1ea1 100644
--- a/packages/Catch2/projects/SelfTest/Baselines/console.std.approved.txt
+++ b/packages/Catch2/projects/SelfTest/Baselines/console.std.approved.txt
@@ -968,7 +968,7 @@ explicitly with message:
 
 -------------------------------------------------------------------------------
 looped SECTION tests
-  s1
+  b is currently: 0
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
@@ -978,6 +978,18 @@ Misc.tests.cpp:<line number>: FAILED:
 with expansion:
   0 > 1
 
+-------------------------------------------------------------------------------
+looped SECTION tests
+  b is currently: 1
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: FAILED:
+  CHECK( b > a )
+with expansion:
+  1 > 1
+
 -------------------------------------------------------------------------------
 looped tests
 -------------------------------------------------------------------------------
@@ -1028,8 +1040,8 @@ with message:
 
 -------------------------------------------------------------------------------
 more nested SECTION tests
-  s1
-  s2
+  doesn't equal
+  equal
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
@@ -1084,6 +1096,6 @@ due to unexpected exception with message:
   Why would you throw a std::string?
 
 ===============================================================================
-test cases:  208 | 155 passed |  49 failed |  4 failed as expected
-assertions: 1065 | 937 passed | 107 failed | 21 failed as expected
+test cases:  213 |  160 passed |  49 failed |  4 failed as expected
+assertions: 1228 | 1099 passed | 108 failed | 21 failed as expected
 
diff --git a/packages/Catch2/projects/SelfTest/Baselines/console.sw.approved.txt b/packages/Catch2/projects/SelfTest/Baselines/console.sw.approved.txt
index 047c7163754c18b2da9eebdea8f0b12e95674fdc..27fa5c59db610747d3a9125fc215bf64e1e89d2e 100644
--- a/packages/Catch2/projects/SelfTest/Baselines/console.sw.approved.txt
+++ b/packages/Catch2/projects/SelfTest/Baselines/console.sw.approved.txt
@@ -490,1047 +490,2289 @@ with expansion:
   !false
 
 -------------------------------------------------------------------------------
-A METHOD_AS_TEST_CASE based test run that fails
+10x10 ints
 -------------------------------------------------------------------------------
-Class.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Class.tests.cpp:<line number>: FAILED:
-  REQUIRE( s == "world" )
+Generators.tests.cpp:<line number>:
+PASSED:
+  CHECK( x < y )
 with expansion:
-  "hello" == "world"
+  1 < 101
 
 -------------------------------------------------------------------------------
-A METHOD_AS_TEST_CASE based test run that succeeds
+10x10 ints
 -------------------------------------------------------------------------------
-Class.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Class.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( s == "hello" )
+  CHECK( x < y )
 with expansion:
-  "hello" == "hello"
+  1 < 102
 
 -------------------------------------------------------------------------------
-A TEST_CASE_METHOD based test run that fails
+10x10 ints
 -------------------------------------------------------------------------------
-Class.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Class.tests.cpp:<line number>: FAILED:
-  REQUIRE( m_a == 2 )
+Generators.tests.cpp:<line number>:
+PASSED:
+  CHECK( x < y )
 with expansion:
-  1 == 2
+  1 < 103
 
 -------------------------------------------------------------------------------
-A TEST_CASE_METHOD based test run that succeeds
+10x10 ints
 -------------------------------------------------------------------------------
-Class.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Class.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( m_a == 1 )
+  CHECK( x < y )
 with expansion:
-  1 == 1
+  1 < 104
 
 -------------------------------------------------------------------------------
-A couple of nested sections followed by a failure
-  Outer
-  Inner
+10x10 ints
 -------------------------------------------------------------------------------
-Misc.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Misc.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-with message:
-  that's not flying - that's failing in style
+  CHECK( x < y )
+with expansion:
+  1 < 105
 
 -------------------------------------------------------------------------------
-A couple of nested sections followed by a failure
+10x10 ints
 -------------------------------------------------------------------------------
-Misc.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Misc.tests.cpp:<line number>: FAILED:
-explicitly with message:
-  to infinity and beyond
+Generators.tests.cpp:<line number>:
+PASSED:
+  CHECK( x < y )
+with expansion:
+  1 < 106
 
 -------------------------------------------------------------------------------
-A failing expression with a non streamable type is still captured
+10x10 ints
 -------------------------------------------------------------------------------
-Tricky.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Tricky.tests.cpp:<line number>: FAILED:
-  CHECK( &o1 == &o2 )
-with expansion:
-  0x<hex digits> == 0x<hex digits>
-
-Tricky.tests.cpp:<line number>: FAILED:
-  CHECK( o1 == o2 )
+Generators.tests.cpp:<line number>:
+PASSED:
+  CHECK( x < y )
 with expansion:
-  {?} == {?}
+  1 < 107
 
 -------------------------------------------------------------------------------
-Absolute margin
+10x10 ints
 -------------------------------------------------------------------------------
-Approx.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 104.0 != Approx(100.0) )
+  CHECK( x < y )
 with expansion:
-  104.0 != Approx( 100.0 )
+  1 < 108
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( 104.0 == Approx(100.0).margin(5) )
-with expansion:
-  104.0 == Approx( 100.0 )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 104.0 == Approx(100.0).margin(4) )
+  CHECK( x < y )
 with expansion:
-  104.0 == Approx( 100.0 )
+  1 < 109
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( 104.0 != Approx(100.0).margin(3) )
-with expansion:
-  104.0 != Approx( 100.0 )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 100.3 != Approx(100.0) )
+  CHECK( x < y )
 with expansion:
-  100.3 != Approx( 100.0 )
+  1 < 110
 
-Approx.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 100.3 == Approx(100.0).margin(0.5) )
+  CHECK( x < y )
 with expansion:
-  100.3 == Approx( 100.0 )
+  2 < 101
 
 -------------------------------------------------------------------------------
-An empty test with no assertions
+10x10 ints
 -------------------------------------------------------------------------------
-Misc.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-
-No assertions in test case 'An empty test with no assertions'
+Generators.tests.cpp:<line number>:
+PASSED:
+  CHECK( x < y )
+with expansion:
+  2 < 102
 
 -------------------------------------------------------------------------------
-An expression with side-effects should only be evaluated once
+10x10 ints
 -------------------------------------------------------------------------------
-Tricky.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( i++ == 7 )
+  CHECK( x < y )
 with expansion:
-  7 == 7
+  2 < 103
 
-Tricky.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( i++ == 8 )
+  CHECK( x < y )
 with expansion:
-  8 == 8
+  2 < 104
 
 -------------------------------------------------------------------------------
-An unchecked exception reports the line of the last assertion
+10x10 ints
 -------------------------------------------------------------------------------
-Exception.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Exception.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( 1 == 1 )
-
-Exception.tests.cpp:<line number>: FAILED:
-  {Unknown expression after the reported line}
-due to unexpected exception with message:
-  unexpected exception
+  CHECK( x < y )
+with expansion:
+  2 < 105
 
 -------------------------------------------------------------------------------
-Anonymous test case 1
+10x10 ints
 -------------------------------------------------------------------------------
-VariadicMacros.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-VariadicMacros.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-with message:
-  anonymous test case
+  CHECK( x < y )
+with expansion:
+  2 < 106
 
 -------------------------------------------------------------------------------
-Approx setters validate their arguments
+10x10 ints
 -------------------------------------------------------------------------------
-Approx.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_NOTHROW( Approx(0).margin(0) )
+  CHECK( x < y )
+with expansion:
+  2 < 107
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  REQUIRE_NOTHROW( Approx(0).margin(1234656) )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THROWS_AS( Approx(0).margin(-2), std::domain_error )
+  CHECK( x < y )
+with expansion:
+  2 < 108
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  REQUIRE_NOTHROW( Approx(0).epsilon(0) )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_NOTHROW( Approx(0).epsilon(1) )
+  CHECK( x < y )
+with expansion:
+  2 < 109
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  REQUIRE_THROWS_AS( Approx(0).epsilon(-0.001), std::domain_error )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THROWS_AS( Approx(0).epsilon(1.0001), std::domain_error )
+  CHECK( x < y )
+with expansion:
+  2 < 110
 
 -------------------------------------------------------------------------------
-Approx with exactly-representable margin
+10x10 ints
 -------------------------------------------------------------------------------
-Approx.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( 0.25f == Approx(0.0f).margin(0.25f) )
+  CHECK( x < y )
 with expansion:
-  0.25f == Approx( 0.0 )
+  3 < 101
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  CHECK( 0.0f == Approx(0.25f).margin(0.25f) )
-with expansion:
-  0.0f == Approx( 0.25 )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( 0.5f == Approx(0.25f).margin(0.25f) )
+  CHECK( x < y )
 with expansion:
-  0.5f == Approx( 0.25 )
+  3 < 102
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  CHECK( 245.0f == Approx(245.25f).margin(0.25f) )
-with expansion:
-  245.0f == Approx( 245.25 )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( 245.5f == Approx(245.25f).margin(0.25f) )
+  CHECK( x < y )
 with expansion:
-  245.5f == Approx( 245.25 )
+  3 < 103
 
 -------------------------------------------------------------------------------
-Approximate PI
+10x10 ints
 -------------------------------------------------------------------------------
-Approx.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( divide( 22, 7 ) == Approx( 3.141 ).epsilon( 0.001 ) )
+  CHECK( x < y )
 with expansion:
-  3.1428571429 == Approx( 3.141 )
+  3 < 104
 
-Approx.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 ) )
+  CHECK( x < y )
 with expansion:
-  3.1428571429 != Approx( 3.141 )
+  3 < 105
 
 -------------------------------------------------------------------------------
-Approximate comparisons with different epsilons
+10x10 ints
 -------------------------------------------------------------------------------
-Approx.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( d != Approx( 1.231 ) )
+  CHECK( x < y )
 with expansion:
-  1.23 != Approx( 1.231 )
+  3 < 106
 
-Approx.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( d == Approx( 1.231 ).epsilon( 0.1 ) )
+  CHECK( x < y )
 with expansion:
-  1.23 == Approx( 1.231 )
+  3 < 107
 
 -------------------------------------------------------------------------------
-Approximate comparisons with floats
+10x10 ints
 -------------------------------------------------------------------------------
-Approx.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 1.23f == Approx( 1.23f ) )
+  CHECK( x < y )
 with expansion:
-  1.23f == Approx( 1.2300000191 )
+  3 < 108
 
-Approx.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 0.0f == Approx( 0.0f ) )
+  CHECK( x < y )
 with expansion:
-  0.0f == Approx( 0.0 )
+  3 < 109
 
 -------------------------------------------------------------------------------
-Approximate comparisons with ints
+10x10 ints
 -------------------------------------------------------------------------------
-Approx.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 1 == Approx( 1 ) )
+  CHECK( x < y )
 with expansion:
-  1 == Approx( 1.0 )
+  3 < 110
 
-Approx.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 0 == Approx( 0 ) )
+  CHECK( x < y )
 with expansion:
-  0 == Approx( 0.0 )
+  4 < 101
 
 -------------------------------------------------------------------------------
-Approximate comparisons with mixed numeric types
+10x10 ints
 -------------------------------------------------------------------------------
-Approx.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 1.0f == Approx( 1 ) )
+  CHECK( x < y )
 with expansion:
-  1.0f == Approx( 1.0 )
+  4 < 102
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( 0 == Approx( dZero) )
-with expansion:
-  0 == Approx( 0.0 )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 0 == Approx( dSmall ).margin( 0.001 ) )
+  CHECK( x < y )
 with expansion:
-  0 == Approx( 0.00001 )
+  4 < 103
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( 1.234f == Approx( dMedium ) )
-with expansion:
-  1.234f == Approx( 1.234 )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( dMedium == Approx( 1.234f ) )
+  CHECK( x < y )
 with expansion:
-  1.234 == Approx( 1.2339999676 )
+  4 < 104
 
 -------------------------------------------------------------------------------
-Arbitrary predicate matcher
-  Function pointer
+10x10 ints
 -------------------------------------------------------------------------------
-Matchers.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Matchers.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 1, Predicate<int>(alwaysTrue, "always true") )
+  CHECK( x < y )
 with expansion:
-  1 matches predicate: "always true"
+  4 < 105
 
-Matchers.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 1, !Predicate<int>(alwaysFalse, "always false") )
+  CHECK( x < y )
 with expansion:
-  1 not matches predicate: "always false"
+  4 < 106
 
 -------------------------------------------------------------------------------
-Arbitrary predicate matcher
-  Lambdas + different type
+10x10 ints
 -------------------------------------------------------------------------------
-Matchers.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Matchers.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( "Hello olleH", Predicate<std::string>( [] (std::string const& str) -> bool { return str.front() == str.back(); }, "First and last character should be equal") )
+  CHECK( x < y )
 with expansion:
-  "Hello olleH" matches predicate: "First and last character should be equal"
+  4 < 107
 
-Matchers.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( "This wouldn't pass", !Predicate<std::string>( [] (std::string const& str) -> bool { return str.front() == str.back(); } ) )
+  CHECK( x < y )
 with expansion:
-  "This wouldn't pass" not matches undescribed predicate
+  4 < 108
 
 -------------------------------------------------------------------------------
-Assertions then sections
+10x10 ints
 -------------------------------------------------------------------------------
-Tricky.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( true )
+  CHECK( x < y )
+with expansion:
+  4 < 109
 
 -------------------------------------------------------------------------------
-Assertions then sections
-  A section
+10x10 ints
 -------------------------------------------------------------------------------
-Tricky.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( true )
+  CHECK( x < y )
+with expansion:
+  4 < 110
 
 -------------------------------------------------------------------------------
-Assertions then sections
-  A section
-  Another section
+10x10 ints
 -------------------------------------------------------------------------------
-Tricky.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( true )
+  CHECK( x < y )
+with expansion:
+  5 < 101
 
 -------------------------------------------------------------------------------
-Assertions then sections
+10x10 ints
 -------------------------------------------------------------------------------
-Tricky.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( true )
+  CHECK( x < y )
+with expansion:
+  5 < 102
 
 -------------------------------------------------------------------------------
-Assertions then sections
-  A section
+10x10 ints
 -------------------------------------------------------------------------------
-Tricky.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( true )
+  CHECK( x < y )
+with expansion:
+  5 < 103
 
 -------------------------------------------------------------------------------
-Assertions then sections
-  A section
-  Another other section
+10x10 ints
 -------------------------------------------------------------------------------
-Tricky.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( true )
+  CHECK( x < y )
+with expansion:
+  5 < 104
 
 -------------------------------------------------------------------------------
-Assorted miscellaneous tests
+10x10 ints
 -------------------------------------------------------------------------------
-Approx.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( INFINITY == Approx(INFINITY) )
+  CHECK( x < y )
 with expansion:
-  inff == Approx( inf )
+  5 < 105
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( NAN != Approx(NAN) )
-with expansion:
-  nanf != Approx( nan )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_FALSE( NAN == Approx(NAN) )
+  CHECK( x < y )
 with expansion:
-  !(nanf == Approx( nan ))
+  5 < 106
 
 -------------------------------------------------------------------------------
-Bitfields can be captured (#1027)
+10x10 ints
 -------------------------------------------------------------------------------
-Tricky.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( y.v == 0 )
+  CHECK( x < y )
 with expansion:
-  0 == 0
+  5 < 107
 
-Tricky.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 0 == y.v )
+  CHECK( x < y )
 with expansion:
-  0 == 0
+  5 < 108
 
 -------------------------------------------------------------------------------
-Capture and info messages
-  Capture should stringify like assertions
+10x10 ints
 -------------------------------------------------------------------------------
-ToStringGeneral.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-ToStringGeneral.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( true )
-with message:
-  i := 2
+  CHECK( x < y )
+with expansion:
+  5 < 109
 
 -------------------------------------------------------------------------------
-Capture and info messages
-  Info should NOT stringify the way assertions do
+10x10 ints
 -------------------------------------------------------------------------------
-ToStringGeneral.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-ToStringGeneral.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( true )
-with message:
-  3
+  CHECK( x < y )
+with expansion:
+  5 < 110
 
 -------------------------------------------------------------------------------
-Character pretty printing
-  Specifically escaped
+10x10 ints
 -------------------------------------------------------------------------------
-ToStringGeneral.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-ToStringGeneral.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( tab == '\t' )
+  CHECK( x < y )
 with expansion:
-  '\t' == '\t'
+  6 < 101
 
-ToStringGeneral.tests.cpp:<line number>:
-PASSED:
-  CHECK( newline == '\n' )
-with expansion:
-  '\n' == '\n'
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-ToStringGeneral.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( carr_return == '\r' )
+  CHECK( x < y )
 with expansion:
-  '\r' == '\r'
+  6 < 102
 
-ToStringGeneral.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( form_feed == '\f' )
+  CHECK( x < y )
 with expansion:
-  '\f' == '\f'
+  6 < 103
 
 -------------------------------------------------------------------------------
-Character pretty printing
-  General chars
+10x10 ints
 -------------------------------------------------------------------------------
-ToStringGeneral.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-ToStringGeneral.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( space == ' ' )
+  CHECK( x < y )
 with expansion:
-  ' ' == ' '
+  6 < 104
 
-ToStringGeneral.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( c == chars[i] )
-with expansion:
-  'a' == 'a'
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-ToStringGeneral.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( c == chars[i] )
+  CHECK( x < y )
 with expansion:
-  'z' == 'z'
+  6 < 105
 
-ToStringGeneral.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( c == chars[i] )
-with expansion:
-  'A' == 'A'
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-ToStringGeneral.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( c == chars[i] )
+  CHECK( x < y )
 with expansion:
-  'Z' == 'Z'
+  6 < 106
 
 -------------------------------------------------------------------------------
-Character pretty printing
-  Low ASCII
+10x10 ints
 -------------------------------------------------------------------------------
-ToStringGeneral.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-ToStringGeneral.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( null_terminator == '\0' )
+  CHECK( x < y )
 with expansion:
-  0 == 0
+  6 < 107
 
-ToStringGeneral.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( c == i )
-with expansion:
-  2 == 2
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-ToStringGeneral.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( c == i )
+  CHECK( x < y )
 with expansion:
-  3 == 3
+  6 < 108
 
-ToStringGeneral.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( c == i )
-with expansion:
-  4 == 4
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-ToStringGeneral.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( c == i )
+  CHECK( x < y )
 with expansion:
-  5 == 5
+  6 < 109
 
 -------------------------------------------------------------------------------
-Commas in various macros are allowed
+10x10 ints
 -------------------------------------------------------------------------------
-Tricky.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THROWS( std::vector<constructor_throws>{constructor_throws{}, constructor_throws{}} )
+  CHECK( x < y )
+with expansion:
+  6 < 110
 
-Tricky.tests.cpp:<line number>:
-PASSED:
-  CHECK_THROWS( std::vector<constructor_throws>{constructor_throws{}, constructor_throws{}} )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_NOTHROW( std::vector<int>{1, 2, 3} == std::vector<int>{1, 2, 3} )
+  CHECK( x < y )
+with expansion:
+  7 < 101
 
-Tricky.tests.cpp:<line number>:
-PASSED:
-  CHECK_NOTHROW( std::vector<int>{1, 2, 3} == std::vector<int>{1, 2, 3} )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( std::vector<int>{1, 2} == std::vector<int>{1, 2} )
+  CHECK( x < y )
 with expansion:
-  { 1, 2 } == { 1, 2 }
+  7 < 102
 
-Tricky.tests.cpp:<line number>:
-PASSED:
-  CHECK( std::vector<int>{1, 2} == std::vector<int>{1, 2} )
-with expansion:
-  { 1, 2 } == { 1, 2 }
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_FALSE( std::vector<int>{1, 2} == std::vector<int>{1, 2, 3} )
+  CHECK( x < y )
 with expansion:
-  !({ 1, 2 } == { 1, 2, 3 })
+  7 < 103
 
-Tricky.tests.cpp:<line number>:
-PASSED:
-  CHECK_FALSE( std::vector<int>{1, 2} == std::vector<int>{1, 2, 3} )
-with expansion:
-  !({ 1, 2 } == { 1, 2, 3 })
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK_NOFAIL( std::vector<int>{1, 2} == std::vector<int>{1, 2} )
+  CHECK( x < y )
 with expansion:
-  { 1, 2 } == { 1, 2 }
+  7 < 104
 
-Tricky.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECKED_IF( std::vector<int>{1, 2} == std::vector<int>{1, 2} )
+  CHECK( x < y )
 with expansion:
-  { 1, 2 } == { 1, 2 }
+  7 < 105
 
-Tricky.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( true )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECKED_ELSE( std::vector<int>{1, 2} == std::vector<int>{1, 2} )
+  CHECK( x < y )
 with expansion:
-  { 1, 2 } == { 1, 2 }
+  7 < 106
 
 -------------------------------------------------------------------------------
-Comparing function pointers
+10x10 ints
 -------------------------------------------------------------------------------
-Tricky.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Tricky.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( a )
+  CHECK( x < y )
 with expansion:
-  0x<hex digits>
+  7 < 107
 
-Tricky.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( a == &foo )
+  CHECK( x < y )
 with expansion:
-  0x<hex digits> == 0x<hex digits>
+  7 < 108
 
 -------------------------------------------------------------------------------
-Comparison with explicitly convertible types
+10x10 ints
 -------------------------------------------------------------------------------
-Approx.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( td == Approx(10.0) )
+  CHECK( x < y )
 with expansion:
-  StrongDoubleTypedef(10) == Approx( 10.0 )
+  7 < 109
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( Approx(10.0) == td )
-with expansion:
-  Approx( 10.0 ) == StrongDoubleTypedef(10)
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( td != Approx(11.0) )
+  CHECK( x < y )
 with expansion:
-  StrongDoubleTypedef(10) != Approx( 11.0 )
+  7 < 110
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( Approx(11.0) != td )
-with expansion:
-  Approx( 11.0 ) != StrongDoubleTypedef(10)
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( td <= Approx(10.0) )
+  CHECK( x < y )
 with expansion:
-  StrongDoubleTypedef(10) <= Approx( 10.0 )
+  8 < 101
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( td <= Approx(11.0) )
-with expansion:
-  StrongDoubleTypedef(10) <= Approx( 11.0 )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( Approx(10.0) <= td )
+  CHECK( x < y )
 with expansion:
-  Approx( 10.0 ) <= StrongDoubleTypedef(10)
+  8 < 102
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( Approx(9.0) <= td )
-with expansion:
-  Approx( 9.0 ) <= StrongDoubleTypedef(10)
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( td >= Approx(9.0) )
+  CHECK( x < y )
 with expansion:
-  StrongDoubleTypedef(10) >= Approx( 9.0 )
+  8 < 103
 
-Approx.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( td >= Approx(td) )
-with expansion:
-  StrongDoubleTypedef(10) >= Approx( 10.0 )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( Approx(td) >= td )
+  CHECK( x < y )
 with expansion:
-  Approx( 10.0 ) >= StrongDoubleTypedef(10)
+  8 < 104
 
-Approx.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( Approx(11.0) >= td )
+  CHECK( x < y )
 with expansion:
-  Approx( 11.0 ) >= StrongDoubleTypedef(10)
+  8 < 105
 
 -------------------------------------------------------------------------------
-Comparisons between ints where one side is computed
+10x10 ints
 -------------------------------------------------------------------------------
-Condition.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Condition.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( 54 == 6*9 )
+  CHECK( x < y )
 with expansion:
-  54 == 54
+  8 < 106
 
 -------------------------------------------------------------------------------
-Comparisons between unsigned ints and negative signed ints match c++ standard
-behaviour
+10x10 ints
 -------------------------------------------------------------------------------
-Condition.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Condition.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( ( -1 > 2u ) )
+  CHECK( x < y )
 with expansion:
-  true
+  8 < 107
 
-Condition.tests.cpp:<line number>:
-PASSED:
-  CHECK( -1 > 2u )
-with expansion:
-  -1 > 2
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Condition.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( ( 2u < -1 ) )
+  CHECK( x < y )
 with expansion:
-  true
+  8 < 108
 
-Condition.tests.cpp:<line number>:
-PASSED:
-  CHECK( 2u < -1 )
-with expansion:
-  2 < -1
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Condition.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( ( minInt > 2u ) )
+  CHECK( x < y )
 with expansion:
-  true
+  8 < 109
 
-Condition.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  CHECK( minInt > 2u )
+  CHECK( x < y )
 with expansion:
-  -2147483648 > 2
+  8 < 110
 
 -------------------------------------------------------------------------------
-Comparisons with int literals don't warn when mixing signed/ unsigned
+10x10 ints
 -------------------------------------------------------------------------------
-Condition.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Condition.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( i == 1 )
+  CHECK( x < y )
 with expansion:
-  1 == 1
+  9 < 101
 
-Condition.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( ui == 2 )
-with expansion:
-  2 == 2
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Condition.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( l == 3 )
+  CHECK( x < y )
 with expansion:
-  3 == 3
+  9 < 102
 
-Condition.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( ul == 4 )
-with expansion:
-  4 == 4
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Condition.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( c == 5 )
+  CHECK( x < y )
 with expansion:
-  5 == 5
+  9 < 103
 
-Condition.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( uc == 6 )
-with expansion:
-  6 == 6
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Condition.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 1 == i )
+  CHECK( x < y )
 with expansion:
-  1 == 1
+  9 < 104
 
-Condition.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( 2 == ui )
-with expansion:
-  2 == 2
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
 
-Condition.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 3 == l )
+  CHECK( x < y )
 with expansion:
-  3 == 3
+  9 < 105
 
-Condition.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 4 == ul )
+  CHECK( x < y )
 with expansion:
-  4 == 4
+  9 < 106
 
-Condition.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 5 == c )
+  CHECK( x < y )
 with expansion:
-  5 == 5
+  9 < 107
 
-Condition.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 6 == uc )
+  CHECK( x < y )
 with expansion:
-  6 == 6
+  9 < 108
 
-Condition.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( (std::numeric_limits<uint32_t>::max)() > ul )
+  CHECK( x < y )
 with expansion:
-  4294967295 (0x<hex digits>) > 4
+  9 < 109
 
 -------------------------------------------------------------------------------
-Contains string matcher
+10x10 ints
 -------------------------------------------------------------------------------
-Matchers.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Matchers.tests.cpp:<line number>: FAILED:
-  CHECK_THAT( testStringForMatching(), Contains("not there", Catch::CaseSensitive::No) )
+Generators.tests.cpp:<line number>:
+PASSED:
+  CHECK( x < y )
 with expansion:
-  "this string contains 'abc' as a substring" contains: "not there" (case
-  insensitive)
+  9 < 110
 
-Matchers.tests.cpp:<line number>: FAILED:
-  CHECK_THAT( testStringForMatching(), Contains("STRING") )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+  CHECK( x < y )
 with expansion:
-  "this string contains 'abc' as a substring" contains: "STRING"
+  10 < 101
 
 -------------------------------------------------------------------------------
-Custom exceptions can be translated when testing for nothrow
+10x10 ints
 -------------------------------------------------------------------------------
-Exception.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Exception.tests.cpp:<line number>: FAILED:
-  REQUIRE_NOTHROW( throwCustom() )
-due to unexpected exception with message:
-  custom exception - not std
+Generators.tests.cpp:<line number>:
+PASSED:
+  CHECK( x < y )
+with expansion:
+  10 < 102
 
 -------------------------------------------------------------------------------
-Custom exceptions can be translated when testing for throwing as something else
+10x10 ints
 -------------------------------------------------------------------------------
-Exception.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Exception.tests.cpp:<line number>: FAILED:
-  REQUIRE_THROWS_AS( throwCustom(), std::exception )
-due to unexpected exception with message:
-  custom exception - not std
+Generators.tests.cpp:<line number>:
+PASSED:
+  CHECK( x < y )
+with expansion:
+  10 < 103
 
 -------------------------------------------------------------------------------
-Custom std-exceptions can be custom translated
+10x10 ints
 -------------------------------------------------------------------------------
-Exception.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Exception.tests.cpp:<line number>: FAILED:
-due to unexpected exception with message:
-  custom std exception
+Generators.tests.cpp:<line number>:
+PASSED:
+  CHECK( x < y )
+with expansion:
+  10 < 104
 
 -------------------------------------------------------------------------------
-Default scale is invisible to comparison
+10x10 ints
 -------------------------------------------------------------------------------
-Approx.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 101.000001 != Approx(100).epsilon(0.01) )
+  CHECK( x < y )
 with expansion:
-  101.000001 != Approx( 100.0 )
+  10 < 105
 
-Approx.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( std::pow(10, -5) != Approx(std::pow(10, -7)) )
+  CHECK( x < y )
 with expansion:
-  0.00001 != Approx( 0.0000001 )
+  10 < 106
 
 -------------------------------------------------------------------------------
-EndsWith string matcher
+10x10 ints
 -------------------------------------------------------------------------------
-Matchers.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Matchers.tests.cpp:<line number>: FAILED:
-  CHECK_THAT( testStringForMatching(), EndsWith("Substring") )
+Generators.tests.cpp:<line number>:
+PASSED:
+  CHECK( x < y )
 with expansion:
-  "this string contains 'abc' as a substring" ends with: "Substring"
+  10 < 107
 
-Matchers.tests.cpp:<line number>: FAILED:
-  CHECK_THAT( testStringForMatching(), EndsWith("this", Catch::CaseSensitive::No) )
+-------------------------------------------------------------------------------
+10x10 ints
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+  CHECK( x < y )
 with expansion:
-  "this string contains 'abc' as a substring" ends with: "this" (case
-  insensitive)
+  10 < 108
 
 -------------------------------------------------------------------------------
-Epsilon only applies to Approx's value
+10x10 ints
 -------------------------------------------------------------------------------
-Approx.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Approx.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE( 101.01 != Approx(100).epsilon(0.01) )
+  CHECK( x < y )
 with expansion:
-  101.01 != Approx( 100.0 )
+  10 < 109
 
 -------------------------------------------------------------------------------
-Equality checks that should fail
+10x10 ints
 -------------------------------------------------------------------------------
-Condition.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Condition.tests.cpp:<line number>: FAILED:
-  CHECK( data.int_seven == 6 )
+Generators.tests.cpp:<line number>:
+PASSED:
+  CHECK( x < y )
+with expansion:
+  10 < 110
+
+-------------------------------------------------------------------------------
+A METHOD_AS_TEST_CASE based test run that fails
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: FAILED:
+  REQUIRE( s == "world" )
+with expansion:
+  "hello" == "world"
+
+-------------------------------------------------------------------------------
+A METHOD_AS_TEST_CASE based test run that succeeds
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( s == "hello" )
+with expansion:
+  "hello" == "hello"
+
+-------------------------------------------------------------------------------
+A TEST_CASE_METHOD based test run that fails
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>: FAILED:
+  REQUIRE( m_a == 2 )
+with expansion:
+  1 == 2
+
+-------------------------------------------------------------------------------
+A TEST_CASE_METHOD based test run that succeeds
+-------------------------------------------------------------------------------
+Class.tests.cpp:<line number>
+...............................................................................
+
+Class.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( m_a == 1 )
+with expansion:
+  1 == 1
+
+-------------------------------------------------------------------------------
+A comparison that uses literals instead of the normal constructor
+-------------------------------------------------------------------------------
+Approx.tests.cpp:<line number>
+...............................................................................
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( d == 1.23_a )
+with expansion:
+  1.23 == Approx( 1.23 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( d != 1.22_a )
+with expansion:
+  1.23 != Approx( 1.22 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( -d == -1.23_a )
+with expansion:
+  -1.23 == Approx( -1.23 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( d == 1.2_a .epsilon(.1) )
+with expansion:
+  1.23 == Approx( 1.2 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( d != 1.2_a .epsilon(.001) )
+with expansion:
+  1.23 != Approx( 1.2 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( d == 1_a .epsilon(.3) )
+with expansion:
+  1.23 == Approx( 1.0 )
+
+-------------------------------------------------------------------------------
+A couple of nested sections followed by a failure
+  Outer
+  Inner
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>:
+PASSED:
+with message:
+  that's not flying - that's failing in style
+
+-------------------------------------------------------------------------------
+A couple of nested sections followed by a failure
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: FAILED:
+explicitly with message:
+  to infinity and beyond
+
+-------------------------------------------------------------------------------
+A failing expression with a non streamable type is still captured
+-------------------------------------------------------------------------------
+Tricky.tests.cpp:<line number>
+...............................................................................
+
+Tricky.tests.cpp:<line number>: FAILED:
+  CHECK( &o1 == &o2 )
+with expansion:
+  0x<hex digits> == 0x<hex digits>
+
+Tricky.tests.cpp:<line number>: FAILED:
+  CHECK( o1 == o2 )
+with expansion:
+  {?} == {?}
+
+-------------------------------------------------------------------------------
+Absolute margin
+-------------------------------------------------------------------------------
+Approx.tests.cpp:<line number>
+...............................................................................
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 104.0 != Approx(100.0) )
+with expansion:
+  104.0 != Approx( 100.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 104.0 == Approx(100.0).margin(5) )
+with expansion:
+  104.0 == Approx( 100.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 104.0 == Approx(100.0).margin(4) )
+with expansion:
+  104.0 == Approx( 100.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 104.0 != Approx(100.0).margin(3) )
+with expansion:
+  104.0 != Approx( 100.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 100.3 != Approx(100.0) )
+with expansion:
+  100.3 != Approx( 100.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 100.3 == Approx(100.0).margin(0.5) )
+with expansion:
+  100.3 == Approx( 100.0 )
+
+-------------------------------------------------------------------------------
+An empty test with no assertions
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+
+No assertions in test case 'An empty test with no assertions'
+
+-------------------------------------------------------------------------------
+An expression with side-effects should only be evaluated once
+-------------------------------------------------------------------------------
+Tricky.tests.cpp:<line number>
+...............................................................................
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( i++ == 7 )
+with expansion:
+  7 == 7
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( i++ == 8 )
+with expansion:
+  8 == 8
+
+-------------------------------------------------------------------------------
+An unchecked exception reports the line of the last assertion
+-------------------------------------------------------------------------------
+Exception.tests.cpp:<line number>
+...............................................................................
+
+Exception.tests.cpp:<line number>:
+PASSED:
+  CHECK( 1 == 1 )
+
+Exception.tests.cpp:<line number>: FAILED:
+  {Unknown expression after the reported line}
+due to unexpected exception with message:
+  unexpected exception
+
+-------------------------------------------------------------------------------
+Anonymous test case 1
+-------------------------------------------------------------------------------
+VariadicMacros.tests.cpp:<line number>
+...............................................................................
+
+VariadicMacros.tests.cpp:<line number>:
+PASSED:
+with message:
+  anonymous test case
+
+-------------------------------------------------------------------------------
+Approx setters validate their arguments
+-------------------------------------------------------------------------------
+Approx.tests.cpp:<line number>
+...............................................................................
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_NOTHROW( Approx(0).margin(0) )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_NOTHROW( Approx(0).margin(1234656) )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THROWS_AS( Approx(0).margin(-2), std::domain_error )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_NOTHROW( Approx(0).epsilon(0) )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_NOTHROW( Approx(0).epsilon(1) )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THROWS_AS( Approx(0).epsilon(-0.001), std::domain_error )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THROWS_AS( Approx(0).epsilon(1.0001), std::domain_error )
+
+-------------------------------------------------------------------------------
+Approx with exactly-representable margin
+-------------------------------------------------------------------------------
+Approx.tests.cpp:<line number>
+...............................................................................
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  CHECK( 0.25f == Approx(0.0f).margin(0.25f) )
+with expansion:
+  0.25f == Approx( 0.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  CHECK( 0.0f == Approx(0.25f).margin(0.25f) )
+with expansion:
+  0.0f == Approx( 0.25 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  CHECK( 0.5f == Approx(0.25f).margin(0.25f) )
+with expansion:
+  0.5f == Approx( 0.25 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  CHECK( 245.0f == Approx(245.25f).margin(0.25f) )
+with expansion:
+  245.0f == Approx( 245.25 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  CHECK( 245.5f == Approx(245.25f).margin(0.25f) )
+with expansion:
+  245.5f == Approx( 245.25 )
+
+-------------------------------------------------------------------------------
+Approximate PI
+-------------------------------------------------------------------------------
+Approx.tests.cpp:<line number>
+...............................................................................
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( divide( 22, 7 ) == Approx( 3.141 ).epsilon( 0.001 ) )
+with expansion:
+  3.1428571429 == Approx( 3.141 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 ) )
+with expansion:
+  3.1428571429 != Approx( 3.141 )
+
+-------------------------------------------------------------------------------
+Approximate comparisons with different epsilons
+-------------------------------------------------------------------------------
+Approx.tests.cpp:<line number>
+...............................................................................
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( d != Approx( 1.231 ) )
+with expansion:
+  1.23 != Approx( 1.231 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( d == Approx( 1.231 ).epsilon( 0.1 ) )
+with expansion:
+  1.23 == Approx( 1.231 )
+
+-------------------------------------------------------------------------------
+Approximate comparisons with floats
+-------------------------------------------------------------------------------
+Approx.tests.cpp:<line number>
+...............................................................................
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 1.23f == Approx( 1.23f ) )
+with expansion:
+  1.23f == Approx( 1.2300000191 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 0.0f == Approx( 0.0f ) )
+with expansion:
+  0.0f == Approx( 0.0 )
+
+-------------------------------------------------------------------------------
+Approximate comparisons with ints
+-------------------------------------------------------------------------------
+Approx.tests.cpp:<line number>
+...............................................................................
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 1 == Approx( 1 ) )
+with expansion:
+  1 == Approx( 1.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 0 == Approx( 0 ) )
+with expansion:
+  0 == Approx( 0.0 )
+
+-------------------------------------------------------------------------------
+Approximate comparisons with mixed numeric types
+-------------------------------------------------------------------------------
+Approx.tests.cpp:<line number>
+...............................................................................
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 1.0f == Approx( 1 ) )
+with expansion:
+  1.0f == Approx( 1.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 0 == Approx( dZero) )
+with expansion:
+  0 == Approx( 0.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 0 == Approx( dSmall ).margin( 0.001 ) )
+with expansion:
+  0 == Approx( 0.00001 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 1.234f == Approx( dMedium ) )
+with expansion:
+  1.234f == Approx( 1.234 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( dMedium == Approx( 1.234f ) )
+with expansion:
+  1.234 == Approx( 1.2339999676 )
+
+-------------------------------------------------------------------------------
+Arbitrary predicate matcher
+  Function pointer
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( 1, Predicate<int>(alwaysTrue, "always true") )
+with expansion:
+  1 matches predicate: "always true"
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( 1, !Predicate<int>(alwaysFalse, "always false") )
+with expansion:
+  1 not matches predicate: "always false"
+
+-------------------------------------------------------------------------------
+Arbitrary predicate matcher
+  Lambdas + different type
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( "Hello olleH", Predicate<std::string>( [] (std::string const& str) -> bool { return str.front() == str.back(); }, "First and last character should be equal") )
+with expansion:
+  "Hello olleH" matches predicate: "First and last character should be equal"
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( "This wouldn't pass", !Predicate<std::string>( [] (std::string const& str) -> bool { return str.front() == str.back(); } ) )
+with expansion:
+  "This wouldn't pass" not matches undescribed predicate
+
+-------------------------------------------------------------------------------
+Assertions then sections
+-------------------------------------------------------------------------------
+Tricky.tests.cpp:<line number>
+...............................................................................
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( true )
+
+-------------------------------------------------------------------------------
+Assertions then sections
+  A section
+-------------------------------------------------------------------------------
+Tricky.tests.cpp:<line number>
+...............................................................................
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( true )
+
+-------------------------------------------------------------------------------
+Assertions then sections
+  A section
+  Another section
+-------------------------------------------------------------------------------
+Tricky.tests.cpp:<line number>
+...............................................................................
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( true )
+
+-------------------------------------------------------------------------------
+Assertions then sections
+-------------------------------------------------------------------------------
+Tricky.tests.cpp:<line number>
+...............................................................................
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( true )
+
+-------------------------------------------------------------------------------
+Assertions then sections
+  A section
+-------------------------------------------------------------------------------
+Tricky.tests.cpp:<line number>
+...............................................................................
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( true )
+
+-------------------------------------------------------------------------------
+Assertions then sections
+  A section
+  Another other section
+-------------------------------------------------------------------------------
+Tricky.tests.cpp:<line number>
+...............................................................................
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( true )
+
+-------------------------------------------------------------------------------
+Assorted miscellaneous tests
+-------------------------------------------------------------------------------
+Approx.tests.cpp:<line number>
+...............................................................................
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( INFINITY == Approx(INFINITY) )
+with expansion:
+  inff == Approx( inf )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( NAN != Approx(NAN) )
+with expansion:
+  nanf != Approx( nan )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_FALSE( NAN == Approx(NAN) )
+with expansion:
+  !(nanf == Approx( nan ))
+
+-------------------------------------------------------------------------------
+Bitfields can be captured (#1027)
+-------------------------------------------------------------------------------
+Tricky.tests.cpp:<line number>
+...............................................................................
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( y.v == 0 )
+with expansion:
+  0 == 0
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 0 == y.v )
+with expansion:
+  0 == 0
+
+-------------------------------------------------------------------------------
+Capture and info messages
+  Capture should stringify like assertions
+-------------------------------------------------------------------------------
+ToStringGeneral.tests.cpp:<line number>
+...............................................................................
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( true )
+with message:
+  i := 2
+
+-------------------------------------------------------------------------------
+Capture and info messages
+  Info should NOT stringify the way assertions do
+-------------------------------------------------------------------------------
+ToStringGeneral.tests.cpp:<line number>
+...............................................................................
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( true )
+with message:
+  3
+
+-------------------------------------------------------------------------------
+Character pretty printing
+  Specifically escaped
+-------------------------------------------------------------------------------
+ToStringGeneral.tests.cpp:<line number>
+...............................................................................
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  CHECK( tab == '\t' )
+with expansion:
+  '\t' == '\t'
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  CHECK( newline == '\n' )
+with expansion:
+  '\n' == '\n'
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  CHECK( carr_return == '\r' )
+with expansion:
+  '\r' == '\r'
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  CHECK( form_feed == '\f' )
+with expansion:
+  '\f' == '\f'
+
+-------------------------------------------------------------------------------
+Character pretty printing
+  General chars
+-------------------------------------------------------------------------------
+ToStringGeneral.tests.cpp:<line number>
+...............................................................................
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  CHECK( space == ' ' )
+with expansion:
+  ' ' == ' '
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( c == chars[i] )
+with expansion:
+  'a' == 'a'
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( c == chars[i] )
+with expansion:
+  'z' == 'z'
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( c == chars[i] )
+with expansion:
+  'A' == 'A'
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( c == chars[i] )
+with expansion:
+  'Z' == 'Z'
+
+-------------------------------------------------------------------------------
+Character pretty printing
+  Low ASCII
+-------------------------------------------------------------------------------
+ToStringGeneral.tests.cpp:<line number>
+...............................................................................
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  CHECK( null_terminator == '\0' )
+with expansion:
+  0 == 0
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( c == i )
+with expansion:
+  2 == 2
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( c == i )
+with expansion:
+  3 == 3
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( c == i )
+with expansion:
+  4 == 4
+
+ToStringGeneral.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( c == i )
+with expansion:
+  5 == 5
+
+-------------------------------------------------------------------------------
+Commas in various macros are allowed
+-------------------------------------------------------------------------------
+Tricky.tests.cpp:<line number>
+...............................................................................
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THROWS( std::vector<constructor_throws>{constructor_throws{}, constructor_throws{}} )
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  CHECK_THROWS( std::vector<constructor_throws>{constructor_throws{}, constructor_throws{}} )
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_NOTHROW( std::vector<int>{1, 2, 3} == std::vector<int>{1, 2, 3} )
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  CHECK_NOTHROW( std::vector<int>{1, 2, 3} == std::vector<int>{1, 2, 3} )
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( std::vector<int>{1, 2} == std::vector<int>{1, 2} )
+with expansion:
+  { 1, 2 } == { 1, 2 }
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  CHECK( std::vector<int>{1, 2} == std::vector<int>{1, 2} )
+with expansion:
+  { 1, 2 } == { 1, 2 }
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_FALSE( std::vector<int>{1, 2} == std::vector<int>{1, 2, 3} )
+with expansion:
+  !({ 1, 2 } == { 1, 2, 3 })
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  CHECK_FALSE( std::vector<int>{1, 2} == std::vector<int>{1, 2, 3} )
+with expansion:
+  !({ 1, 2 } == { 1, 2, 3 })
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  CHECK_NOFAIL( std::vector<int>{1, 2} == std::vector<int>{1, 2} )
+with expansion:
+  { 1, 2 } == { 1, 2 }
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  CHECKED_IF( std::vector<int>{1, 2} == std::vector<int>{1, 2} )
+with expansion:
+  { 1, 2 } == { 1, 2 }
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( true )
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  CHECKED_ELSE( std::vector<int>{1, 2} == std::vector<int>{1, 2} )
+with expansion:
+  { 1, 2 } == { 1, 2 }
+
+-------------------------------------------------------------------------------
+Comparing function pointers
+-------------------------------------------------------------------------------
+Tricky.tests.cpp:<line number>
+...............................................................................
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( a )
+with expansion:
+  0x<hex digits>
+
+Tricky.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( a == &foo )
+with expansion:
+  0x<hex digits> == 0x<hex digits>
+
+-------------------------------------------------------------------------------
+Comparison with explicitly convertible types
+-------------------------------------------------------------------------------
+Approx.tests.cpp:<line number>
+...............................................................................
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( td == Approx(10.0) )
+with expansion:
+  StrongDoubleTypedef(10) == Approx( 10.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( Approx(10.0) == td )
+with expansion:
+  Approx( 10.0 ) == StrongDoubleTypedef(10)
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( td != Approx(11.0) )
+with expansion:
+  StrongDoubleTypedef(10) != Approx( 11.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( Approx(11.0) != td )
+with expansion:
+  Approx( 11.0 ) != StrongDoubleTypedef(10)
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( td <= Approx(10.0) )
+with expansion:
+  StrongDoubleTypedef(10) <= Approx( 10.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( td <= Approx(11.0) )
+with expansion:
+  StrongDoubleTypedef(10) <= Approx( 11.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( Approx(10.0) <= td )
+with expansion:
+  Approx( 10.0 ) <= StrongDoubleTypedef(10)
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( Approx(9.0) <= td )
+with expansion:
+  Approx( 9.0 ) <= StrongDoubleTypedef(10)
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( td >= Approx(9.0) )
+with expansion:
+  StrongDoubleTypedef(10) >= Approx( 9.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( td >= Approx(td) )
+with expansion:
+  StrongDoubleTypedef(10) >= Approx( 10.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( Approx(td) >= td )
+with expansion:
+  Approx( 10.0 ) >= StrongDoubleTypedef(10)
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( Approx(11.0) >= td )
+with expansion:
+  Approx( 11.0 ) >= StrongDoubleTypedef(10)
+
+-------------------------------------------------------------------------------
+Comparisons between ints where one side is computed
+-------------------------------------------------------------------------------
+Condition.tests.cpp:<line number>
+...............................................................................
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  CHECK( 54 == 6*9 )
+with expansion:
+  54 == 54
+
+-------------------------------------------------------------------------------
+Comparisons between unsigned ints and negative signed ints match c++ standard
+behaviour
+-------------------------------------------------------------------------------
+Condition.tests.cpp:<line number>
+...............................................................................
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  CHECK( ( -1 > 2u ) )
+with expansion:
+  true
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  CHECK( -1 > 2u )
+with expansion:
+  -1 > 2
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  CHECK( ( 2u < -1 ) )
+with expansion:
+  true
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  CHECK( 2u < -1 )
+with expansion:
+  2 < -1
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  CHECK( ( minInt > 2u ) )
+with expansion:
+  true
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  CHECK( minInt > 2u )
+with expansion:
+  -2147483648 > 2
+
+-------------------------------------------------------------------------------
+Comparisons with int literals don't warn when mixing signed/ unsigned
+-------------------------------------------------------------------------------
+Condition.tests.cpp:<line number>
+...............................................................................
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( i == 1 )
+with expansion:
+  1 == 1
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( ui == 2 )
+with expansion:
+  2 == 2
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( l == 3 )
+with expansion:
+  3 == 3
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( ul == 4 )
+with expansion:
+  4 == 4
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( c == 5 )
+with expansion:
+  5 == 5
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( uc == 6 )
+with expansion:
+  6 == 6
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 1 == i )
+with expansion:
+  1 == 1
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 2 == ui )
+with expansion:
+  2 == 2
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 3 == l )
+with expansion:
+  3 == 3
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 4 == ul )
+with expansion:
+  4 == 4
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 5 == c )
+with expansion:
+  5 == 5
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 6 == uc )
+with expansion:
+  6 == 6
+
+Condition.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( (std::numeric_limits<uint32_t>::max)() > ul )
+with expansion:
+  4294967295 (0x<hex digits>) > 4
+
+-------------------------------------------------------------------------------
+Contains string matcher
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>: FAILED:
+  CHECK_THAT( testStringForMatching(), Contains("not there", Catch::CaseSensitive::No) )
+with expansion:
+  "this string contains 'abc' as a substring" contains: "not there" (case
+  insensitive)
+
+Matchers.tests.cpp:<line number>: FAILED:
+  CHECK_THAT( testStringForMatching(), Contains("STRING") )
+with expansion:
+  "this string contains 'abc' as a substring" contains: "STRING"
+
+-------------------------------------------------------------------------------
+Custom exceptions can be translated when testing for nothrow
+-------------------------------------------------------------------------------
+Exception.tests.cpp:<line number>
+...............................................................................
+
+Exception.tests.cpp:<line number>: FAILED:
+  REQUIRE_NOTHROW( throwCustom() )
+due to unexpected exception with message:
+  custom exception - not std
+
+-------------------------------------------------------------------------------
+Custom exceptions can be translated when testing for throwing as something else
+-------------------------------------------------------------------------------
+Exception.tests.cpp:<line number>
+...............................................................................
+
+Exception.tests.cpp:<line number>: FAILED:
+  REQUIRE_THROWS_AS( throwCustom(), std::exception )
+due to unexpected exception with message:
+  custom exception - not std
+
+-------------------------------------------------------------------------------
+Custom std-exceptions can be custom translated
+-------------------------------------------------------------------------------
+Exception.tests.cpp:<line number>
+...............................................................................
+
+Exception.tests.cpp:<line number>: FAILED:
+due to unexpected exception with message:
+  custom std exception
+
+-------------------------------------------------------------------------------
+Default scale is invisible to comparison
+-------------------------------------------------------------------------------
+Approx.tests.cpp:<line number>
+...............................................................................
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 101.000001 != Approx(100).epsilon(0.01) )
+with expansion:
+  101.000001 != Approx( 100.0 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( std::pow(10, -5) != Approx(std::pow(10, -7)) )
+with expansion:
+  0.00001 != Approx( 0.0000001 )
+
+-------------------------------------------------------------------------------
+EndsWith string matcher
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>: FAILED:
+  CHECK_THAT( testStringForMatching(), EndsWith("Substring") )
+with expansion:
+  "this string contains 'abc' as a substring" ends with: "Substring"
+
+Matchers.tests.cpp:<line number>: FAILED:
+  CHECK_THAT( testStringForMatching(), EndsWith("this", Catch::CaseSensitive::No) )
+with expansion:
+  "this string contains 'abc' as a substring" ends with: "this" (case
+  insensitive)
+
+-------------------------------------------------------------------------------
+Epsilon only applies to Approx's value
+-------------------------------------------------------------------------------
+Approx.tests.cpp:<line number>
+...............................................................................
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( 101.01 != Approx(100).epsilon(0.01) )
+with expansion:
+  101.01 != Approx( 100.0 )
+
+-------------------------------------------------------------------------------
+Equality checks that should fail
+-------------------------------------------------------------------------------
+Condition.tests.cpp:<line number>
+...............................................................................
+
+Condition.tests.cpp:<line number>: FAILED:
+  CHECK( data.int_seven == 6 )
 with expansion:
   7 == 6
 
@@ -1921,7 +3163,165 @@ with expansion:
   3628800 (0x<hex digits>) == 3628800 (0x<hex digits>)
 
 -------------------------------------------------------------------------------
-Floating point matchers: double
+Floating point matchers: double
+  Margin
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( 1., WithinAbs(1., 0) )
+with expansion:
+  1.0 is within 0.0 of 1.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( 0., WithinAbs(1., 1) )
+with expansion:
+  0.0 is within 1.0 of 1.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( 0., !WithinAbs(1., 0.99) )
+with expansion:
+  0.0 not is within 0.99 of 1.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( 0., !WithinAbs(1., 0.99) )
+with expansion:
+  0.0 not is within 0.99 of 1.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( NAN, !WithinAbs(NAN, 0) )
+with expansion:
+  nanf not is within 0.0 of nan
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( 11., !WithinAbs(10., 0.5) )
+with expansion:
+  11.0 not is within 0.5 of 10.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( 10., !WithinAbs(11., 0.5) )
+with expansion:
+  10.0 not is within 0.5 of 11.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( -10., WithinAbs(-10., 0.5) )
+with expansion:
+  -10.0 is within 0.5 of -10.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( -10., WithinAbs(-9.6, 0.5) )
+with expansion:
+  -10.0 is within 0.5 of -9.6
+
+-------------------------------------------------------------------------------
+Floating point matchers: double
+  ULPs
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( 1., WithinULP(1., 0) )
+with expansion:
+  1.0 is within 0 ULPs of 1.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( nextafter(1., 2.), WithinULP(1., 1) )
+with expansion:
+  1.0 is within 1 ULPs of 1.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( nextafter(1., 0.), WithinULP(1., 1) )
+with expansion:
+  1.0 is within 1 ULPs of 1.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( nextafter(1., 2.), !WithinULP(1., 0) )
+with expansion:
+  1.0 not is within 0 ULPs of 1.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( 1., WithinULP(1., 0) )
+with expansion:
+  1.0 is within 0 ULPs of 1.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( -0., WithinULP(0., 0) )
+with expansion:
+  -0.0 is within 0 ULPs of 0.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( NAN, !WithinULP(NAN, 123) )
+with expansion:
+  nanf not is within 123 ULPs of nanf
+
+-------------------------------------------------------------------------------
+Floating point matchers: double
+  Composed
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( 1., WithinAbs(1., 0.5) || WithinULP(2., 1) )
+with expansion:
+  1.0 ( is within 0.5 of 1.0 or is within 1 ULPs of 2.0 )
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( 1., WithinAbs(2., 0.5) || WithinULP(1., 0) )
+with expansion:
+  1.0 ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0 )
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123)) )
+with expansion:
+  nanf not ( is within 100.0 of nan or is within 123 ULPs of nanf )
+
+-------------------------------------------------------------------------------
+Floating point matchers: double
+  Constructor validation
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_NOTHROW( WithinAbs(1., 0.) )
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THROWS_AS( WithinAbs(1., -1.), std::domain_error )
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_NOTHROW( WithinULP(1., 0) )
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THROWS_AS( WithinULP(1., -1), std::domain_error )
+
+-------------------------------------------------------------------------------
+Floating point matchers: float
   Margin
 -------------------------------------------------------------------------------
 Matchers.tests.cpp:<line number>
@@ -1929,27 +3329,33 @@ Matchers.tests.cpp:<line number>
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 1., WithinAbs(1., 0) )
+  REQUIRE_THAT( 1.f, WithinAbs(1.f, 0) )
 with expansion:
-  1.0 is within 0.0 of 1.0
+  1.0f is within 0.0 of 1.0
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 0., WithinAbs(1., 1) )
+  REQUIRE_THAT( 0.f, WithinAbs(1.f, 1) )
 with expansion:
-  0.0 is within 1.0 of 1.0
+  0.0f is within 1.0 of 1.0
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 0., !WithinAbs(1., 0.99) )
+  REQUIRE_THAT( 0.f, !WithinAbs(1.f, 0.99f) )
 with expansion:
-  0.0 not is within 0.99 of 1.0
+  0.0f not is within 0.9900000095 of 1.0
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 0., !WithinAbs(1., 0.99) )
+  REQUIRE_THAT( 0.f, !WithinAbs(1.f, 0.99f) )
 with expansion:
-  0.0 not is within 0.99 of 1.0
+  0.0f not is within 0.9900000095 of 1.0
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  REQUIRE_THAT( 0.f, WithinAbs(-0.f, 0) )
+with expansion:
+  0.0f is within 0.0 of -0.0
 
 Matchers.tests.cpp:<line number>:
 PASSED:
@@ -1959,30 +3365,30 @@ with expansion:
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 11., !WithinAbs(10., 0.5) )
+  REQUIRE_THAT( 11.f, !WithinAbs(10.f, 0.5f) )
 with expansion:
-  11.0 not is within 0.5 of 10.0
+  11.0f not is within 0.5 of 10.0
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 10., !WithinAbs(11., 0.5) )
+  REQUIRE_THAT( 10.f, !WithinAbs(11.f, 0.5f) )
 with expansion:
-  10.0 not is within 0.5 of 11.0
+  10.0f not is within 0.5 of 11.0
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( -10., WithinAbs(-10., 0.5) )
+  REQUIRE_THAT( -10.f, WithinAbs(-10.f, 0.5f) )
 with expansion:
-  -10.0 is within 0.5 of -10.0
+  -10.0f is within 0.5 of -10.0
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( -10., WithinAbs(-9.6, 0.5) )
+  REQUIRE_THAT( -10.f, WithinAbs(-9.6f, 0.5f) )
 with expansion:
-  -10.0 is within 0.5 of -9.6
+  -10.0f is within 0.5 of -9.6000003815
 
 -------------------------------------------------------------------------------
-Floating point matchers: double
+Floating point matchers: float
   ULPs
 -------------------------------------------------------------------------------
 Matchers.tests.cpp:<line number>
@@ -1990,39 +3396,39 @@ Matchers.tests.cpp:<line number>
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 1., WithinULP(1., 0) )
+  REQUIRE_THAT( 1.f, WithinULP(1.f, 0) )
 with expansion:
-  1.0 is within 0 ULPs of 1.0
+  1.0f is within 0 ULPs of 1.0f
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( nextafter(1., 2.), WithinULP(1., 1) )
+  REQUIRE_THAT( nextafter(1.f, 2.f), WithinULP(1.f, 1) )
 with expansion:
-  1.0 is within 1 ULPs of 1.0
+  1.0f is within 1 ULPs of 1.0f
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( nextafter(1., 0.), WithinULP(1., 1) )
+  REQUIRE_THAT( nextafter(1.f, 0.f), WithinULP(1.f, 1) )
 with expansion:
-  1.0 is within 1 ULPs of 1.0
+  1.0f is within 1 ULPs of 1.0f
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( nextafter(1., 2.), !WithinULP(1., 0) )
+  REQUIRE_THAT( nextafter(1.f, 2.f), !WithinULP(1.f, 0) )
 with expansion:
-  1.0 not is within 0 ULPs of 1.0
+  1.0f not is within 0 ULPs of 1.0f
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 1., WithinULP(1., 0) )
+  REQUIRE_THAT( 1.f, WithinULP(1.f, 0) )
 with expansion:
-  1.0 is within 0 ULPs of 1.0
+  1.0f is within 0 ULPs of 1.0f
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( -0., WithinULP(0., 0) )
+  REQUIRE_THAT( -0.f, WithinULP(0.f, 0) )
 with expansion:
-  -0.0 is within 0 ULPs of 0.0
+  -0.0f is within 0 ULPs of 0.0f
 
 Matchers.tests.cpp:<line number>:
 PASSED:
@@ -2031,7 +3437,7 @@ with expansion:
   nanf not is within 123 ULPs of nanf
 
 -------------------------------------------------------------------------------
-Floating point matchers: double
+Floating point matchers: float
   Composed
 -------------------------------------------------------------------------------
 Matchers.tests.cpp:<line number>
@@ -2039,15 +3445,15 @@ Matchers.tests.cpp:<line number>
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 1., WithinAbs(1., 0.5) || WithinULP(2., 1) )
+  REQUIRE_THAT( 1.f, WithinAbs(1.f, 0.5) || WithinULP(1.f, 1) )
 with expansion:
-  1.0 ( is within 0.5 of 1.0 or is within 1 ULPs of 2.0 )
+  1.0f ( is within 0.5 of 1.0 or is within 1 ULPs of 1.0f )
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 1., WithinAbs(2., 0.5) || WithinULP(1., 0) )
+  REQUIRE_THAT( 1.f, WithinAbs(2.f, 0.5) || WithinULP(1.f, 0) )
 with expansion:
-  1.0 ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0 )
+  1.0f ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0f )
 
 Matchers.tests.cpp:<line number>:
 PASSED:
@@ -2056,7 +3462,7 @@ with expansion:
   nanf not ( is within 100.0 of nan or is within 123 ULPs of nanf )
 
 -------------------------------------------------------------------------------
-Floating point matchers: double
+Floating point matchers: float
   Constructor validation
 -------------------------------------------------------------------------------
 Matchers.tests.cpp:<line number>
@@ -2064,183 +3470,439 @@ Matchers.tests.cpp:<line number>
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_NOTHROW( WithinAbs(1., 0.) )
+  REQUIRE_NOTHROW( WithinAbs(1.f, 0.f) )
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THROWS_AS( WithinAbs(1., -1.), std::domain_error )
+  REQUIRE_THROWS_AS( WithinAbs(1.f, -1.f), std::domain_error )
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_NOTHROW( WithinULP(1., 0) )
+  REQUIRE_NOTHROW( WithinULP(1.f, 0) )
 
 Matchers.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THROWS_AS( WithinULP(1., -1), std::domain_error )
+  REQUIRE_THROWS_AS( WithinULP(1.f, -1), std::domain_error )
 
 -------------------------------------------------------------------------------
-Floating point matchers: float
-  Margin
+Generators
+  one
 -------------------------------------------------------------------------------
-Matchers.tests.cpp:<line number>
+Generators.tests.cpp:<line number>
 ...............................................................................
 
-Matchers.tests.cpp:<line number>:
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 1.f, WithinAbs(1.f, 0) )
-with expansion:
-  1.0f is within 0.0 of 1.0
+with messages:
+  i := "a"
+  j := 8
 
-Matchers.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+Generators
+  one
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 0.f, WithinAbs(1.f, 1) )
-with expansion:
-  0.0f is within 1.0 of 1.0
+with messages:
+  i := "a"
+  j := 9
 
-Matchers.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+Generators
+  one
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 0.f, !WithinAbs(1.f, 0.99f) )
+with messages:
+  i := "a"
+  j := 10
+
+-------------------------------------------------------------------------------
+Generators
+  one
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "a"
+  j := 2
+
+-------------------------------------------------------------------------------
+Generators
+  two
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "a"
+  j := 3.141
+
+-------------------------------------------------------------------------------
+Generators
+  two
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "a"
+  j := 1.379
+
+-------------------------------------------------------------------------------
+Generators
+  one
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "b"
+  j := 8
+
+-------------------------------------------------------------------------------
+Generators
+  one
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "b"
+  j := 9
+
+-------------------------------------------------------------------------------
+Generators
+  one
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "b"
+  j := 10
+
+-------------------------------------------------------------------------------
+Generators
+  one
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "b"
+  j := 2
+
+-------------------------------------------------------------------------------
+Generators
+  two
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "b"
+  j := 3.141
+
+-------------------------------------------------------------------------------
+Generators
+  two
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "b"
+  j := 1.379
+
+-------------------------------------------------------------------------------
+Generators
+  one
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "c"
+  j := 8
+
+-------------------------------------------------------------------------------
+Generators
+  one
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "c"
+  j := 9
+
+-------------------------------------------------------------------------------
+Generators
+  one
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "c"
+  j := 10
+
+-------------------------------------------------------------------------------
+Generators
+  one
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "c"
+  j := 2
+
+-------------------------------------------------------------------------------
+Generators
+  two
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "c"
+  j := 3.141
+
+-------------------------------------------------------------------------------
+Generators
+  two
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+with messages:
+  i := "c"
+  j := 1.379
+
+-------------------------------------------------------------------------------
+Generators impl
+  range
+-------------------------------------------------------------------------------
+GeneratorsImpl.tests.cpp:<line number>
+...............................................................................
+
+GeneratorsImpl.tests.cpp:<line number>:
+PASSED:
+  CHECK( gen.size() == 2 )
 with expansion:
-  0.0f not is within 0.9900000095 of 1.0
+  2 == 2
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 0.f, !WithinAbs(1.f, 0.99f) )
+  CHECK( gen[0] == 1 )
 with expansion:
-  0.0f not is within 0.9900000095 of 1.0
+  1 == 1
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 0.f, WithinAbs(-0.f, 0) )
+  CHECK( gen[1] == 2 )
 with expansion:
-  0.0f is within 0.0 of -0.0
+  2 == 2
+
+-------------------------------------------------------------------------------
+Generators impl
+  fixed values
+-------------------------------------------------------------------------------
+GeneratorsImpl.tests.cpp:<line number>
+...............................................................................
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( NAN, !WithinAbs(NAN, 0) )
+  CHECK( gen.size() == 4 )
 with expansion:
-  nanf not is within 0.0 of nan
+  4 == 4
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 11.f, !WithinAbs(10.f, 0.5f) )
+  CHECK( gen[0] == 3 )
 with expansion:
-  11.0f not is within 0.5 of 10.0
+  3 == 3
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 10.f, !WithinAbs(11.f, 0.5f) )
+  CHECK( gen[1] == 1 )
 with expansion:
-  10.0f not is within 0.5 of 11.0
+  1 == 1
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( -10.f, WithinAbs(-10.f, 0.5f) )
+  CHECK( gen[2] == 4 )
 with expansion:
-  -10.0f is within 0.5 of -10.0
+  4 == 4
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( -10.f, WithinAbs(-9.6f, 0.5f) )
+  CHECK( gen[3] == 1 )
 with expansion:
-  -10.0f is within 0.5 of -9.6000003815
+  1 == 1
 
 -------------------------------------------------------------------------------
-Floating point matchers: float
-  ULPs
+Generators impl
+  combined
 -------------------------------------------------------------------------------
-Matchers.tests.cpp:<line number>
+GeneratorsImpl.tests.cpp:<line number>
 ...............................................................................
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 1.f, WithinULP(1.f, 0) )
+  CHECK( gen.size() == 4 )
 with expansion:
-  1.0f is within 0 ULPs of 1.0f
+  4 == 4
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( nextafter(1.f, 2.f), WithinULP(1.f, 1) )
+  CHECK( gen[0] == 1 )
 with expansion:
-  1.0f is within 1 ULPs of 1.0f
+  1 == 1
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( nextafter(1.f, 0.f), WithinULP(1.f, 1) )
+  CHECK( gen[1] == 2 )
 with expansion:
-  1.0f is within 1 ULPs of 1.0f
+  2 == 2
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( nextafter(1.f, 2.f), !WithinULP(1.f, 0) )
+  CHECK( gen[2] == 9 )
 with expansion:
-  1.0f not is within 0 ULPs of 1.0f
+  9 == 9
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 1.f, WithinULP(1.f, 0) )
+  CHECK( gen[3] == 7 )
 with expansion:
-  1.0f is within 0 ULPs of 1.0f
+  7 == 7
 
-Matchers.tests.cpp:<line number>:
+-------------------------------------------------------------------------------
+Generators impl
+  values
+-------------------------------------------------------------------------------
+GeneratorsImpl.tests.cpp:<line number>
+...............................................................................
+
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( -0.f, WithinULP(0.f, 0) )
+  CHECK( gen.size() == 2 )
 with expansion:
-  -0.0f is within 0 ULPs of 0.0f
+  2 == 2
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( NAN, !WithinULP(NAN, 123) )
+  CHECK( gen[0] == 3 )
 with expansion:
-  nanf not is within 123 ULPs of nanf
+  3 == 3
+
+GeneratorsImpl.tests.cpp:<line number>:
+PASSED:
+  CHECK( gen[1] == 1 )
+with expansion:
+  1 == 1
 
 -------------------------------------------------------------------------------
-Floating point matchers: float
-  Composed
+Generators impl
+  values2
 -------------------------------------------------------------------------------
-Matchers.tests.cpp:<line number>
+GeneratorsImpl.tests.cpp:<line number>
 ...............................................................................
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 1.f, WithinAbs(1.f, 0.5) || WithinULP(1.f, 1) )
+  CHECK( gen.size() == 2 )
 with expansion:
-  1.0f ( is within 0.5 of 1.0 or is within 1 ULPs of 1.0f )
+  2 == 2
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( 1.f, WithinAbs(2.f, 0.5) || WithinULP(1.f, 0) )
+  CHECK( gen[0] == 3 )
 with expansion:
-  1.0f ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0f )
+  3 == 3
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THAT( NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123)) )
+  CHECK( gen[1] == 1 )
 with expansion:
-  nanf not ( is within 100.0 of nan or is within 123 ULPs of nanf )
+  1 == 1
 
 -------------------------------------------------------------------------------
-Floating point matchers: float
-  Constructor validation
+Generators impl
+  type erasure
 -------------------------------------------------------------------------------
-Matchers.tests.cpp:<line number>
+GeneratorsImpl.tests.cpp:<line number>
 ...............................................................................
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_NOTHROW( WithinAbs(1.f, 0.f) )
+  CHECK( base->size() == 4 )
+with expansion:
+  4 == 4
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THROWS_AS( WithinAbs(1.f, -1.f), std::domain_error )
+  REQUIRE( typed )
+with expansion:
+  0x<hex digits>
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_NOTHROW( WithinULP(1.f, 0) )
+  CHECK( typed->size() == 4 )
+with expansion:
+  4 == 4
 
-Matchers.tests.cpp:<line number>:
+GeneratorsImpl.tests.cpp:<line number>:
 PASSED:
-  REQUIRE_THROWS_AS( WithinULP(1.f, -1), std::domain_error )
+  CHECK( (*typed)[0] == 7 )
+with expansion:
+  7 == 7
+
+GeneratorsImpl.tests.cpp:<line number>:
+PASSED:
+  CHECK( (*typed)[3] == 11 )
+with expansion:
+  11 == 11
 
 -------------------------------------------------------------------------------
 Greater-than inequalities with different epsilons
@@ -3993,18 +5655,6 @@ PASSED:
 with expansion:
   true == true
 
--------------------------------------------------------------------------------
-Parsing a std::pair
--------------------------------------------------------------------------------
-Tricky.tests.cpp:<line number>
-...............................................................................
-
-Tricky.tests.cpp:<line number>:
-PASSED:
-  REQUIRE( (std::pair<int, int>( 1, 2 )) == aNicePair )
-with expansion:
-  {?} == {?}
-
 -------------------------------------------------------------------------------
 Pointers can be compared to null
 -------------------------------------------------------------------------------
@@ -4130,7 +5780,7 @@ with expansion:
 -------------------------------------------------------------------------------
 Process can be configured on command line
   test lists
-  1 test
+  Specify one test case using
 -------------------------------------------------------------------------------
 CmdLine.tests.cpp:<line number>
 ...............................................................................
@@ -4646,6 +6296,18 @@ with expansion:
   "this string contains 'abc' as a substring" matches "this string contains
   'abc' as a" case sensitively
 
+-------------------------------------------------------------------------------
+Regression test #1
+-------------------------------------------------------------------------------
+Matchers.tests.cpp:<line number>
+...............................................................................
+
+Matchers.tests.cpp:<line number>:
+PASSED:
+  CHECK_THAT( actual, !UnorderedEquals(expected) )
+with expansion:
+  { 'a', 'b' } not UnorderedEquals: { 'c', 'b' }
+
 -------------------------------------------------------------------------------
 SUCCEED counts as a test pass
 -------------------------------------------------------------------------------
@@ -4669,7 +6331,7 @@ PASSED:
 -------------------------------------------------------------------------------
 Scenario: BDD tests requiring Fixtures to provide commonly-accessed data or
           methods
-     Given: No operations precede me
+      Given: No operations precede me
 -------------------------------------------------------------------------------
 BDD.tests.cpp:<line number>
 ...............................................................................
@@ -4683,9 +6345,9 @@ with expansion:
 -------------------------------------------------------------------------------
 Scenario: BDD tests requiring Fixtures to provide commonly-accessed data or
           methods
-     Given: No operations precede me
-      When: We get the count
-      Then: Subsequently values are higher
+      Given: No operations precede me
+       When: We get the count
+       Then: Subsequently values are higher
 -------------------------------------------------------------------------------
 BDD.tests.cpp:<line number>
 ...............................................................................
@@ -4698,9 +6360,10 @@ with expansion:
 
 -------------------------------------------------------------------------------
 Scenario: Do that thing with the thing
-     Given: This stuff exists
-      When: I do this
-      Then: it should do this
+      Given: This stuff exists
+  And given: And some assumption
+       When: I do this
+       Then: it should do this
 -------------------------------------------------------------------------------
 BDD.tests.cpp:<line number>
 ...............................................................................
@@ -4713,10 +6376,11 @@ with expansion:
 
 -------------------------------------------------------------------------------
 Scenario: Do that thing with the thing
-     Given: This stuff exists
-      When: I do this
-      Then: it should do this
-       And: do that
+      Given: This stuff exists
+  And given: And some assumption
+       When: I do this
+       Then: it should do this
+        And: do that
 -------------------------------------------------------------------------------
 BDD.tests.cpp:<line number>
 ...............................................................................
@@ -4730,12 +6394,12 @@ with expansion:
 -------------------------------------------------------------------------------
 Scenario: This is a really long scenario name to see how the list command deals
           with wrapping
-     Given: A section name that is so long that it cannot fit in a single
-            console width
-      When: The test headers are printed as part of the normal running of the
-            scenario
-      Then: The, deliberately very long and overly verbose (you see what I did
-            there?) section names must wrap, along with an indent
+      Given: A section name that is so long that it cannot fit in a single
+             console width
+       When: The test headers are printed as part of the normal running of the
+             scenario
+       Then: The, deliberately very long and overly verbose (you see what I did
+             there?) section names must wrap, along with an indent
 -------------------------------------------------------------------------------
 BDD.tests.cpp:<line number>
 ...............................................................................
@@ -4747,7 +6411,7 @@ with message:
 
 -------------------------------------------------------------------------------
 Scenario: Vector resizing affects size and capacity
-     Given: an empty vector
+      Given: an empty vector
 -------------------------------------------------------------------------------
 BDD.tests.cpp:<line number>
 ...............................................................................
@@ -4760,9 +6424,9 @@ with expansion:
 
 -------------------------------------------------------------------------------
 Scenario: Vector resizing affects size and capacity
-     Given: an empty vector
-      When: it is made larger
-      Then: the size and capacity go up
+      Given: an empty vector
+       When: it is made larger
+       Then: the size and capacity go up
 -------------------------------------------------------------------------------
 BDD.tests.cpp:<line number>
 ...............................................................................
@@ -4781,11 +6445,11 @@ with expansion:
 
 -------------------------------------------------------------------------------
 Scenario: Vector resizing affects size and capacity
-     Given: an empty vector
-      When: it is made larger
-      Then: the size and capacity go up
-  And when: it is made smaller again
-      Then: the size goes down but the capacity stays the same
+      Given: an empty vector
+       When: it is made larger
+       Then: the size and capacity go up
+   And when: it is made smaller again
+       Then: the size goes down but the capacity stays the same
 -------------------------------------------------------------------------------
 BDD.tests.cpp:<line number>
 ...............................................................................
@@ -4804,7 +6468,7 @@ with expansion:
 
 -------------------------------------------------------------------------------
 Scenario: Vector resizing affects size and capacity
-     Given: an empty vector
+      Given: an empty vector
 -------------------------------------------------------------------------------
 BDD.tests.cpp:<line number>
 ...............................................................................
@@ -4817,9 +6481,9 @@ with expansion:
 
 -------------------------------------------------------------------------------
 Scenario: Vector resizing affects size and capacity
-     Given: an empty vector
-      When: we reserve more space
-      Then: The capacity is increased but the size remains the same
+      Given: an empty vector
+       When: we reserve more space
+       Then: The capacity is increased but the size remains the same
 -------------------------------------------------------------------------------
 BDD.tests.cpp:<line number>
 ...............................................................................
@@ -4872,6 +6536,18 @@ PASSED:
 with expansion:
   1.23 != Approx( 1.24 )
 
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( d == 1.23_a )
+with expansion:
+  1.23 == Approx( 1.23 )
+
+Approx.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( d != 1.22_a )
+with expansion:
+  1.23 != Approx( 1.22 )
+
 Approx.tests.cpp:<line number>:
 PASSED:
   REQUIRE( Approx( d ) == 1.23 )
@@ -7754,7 +9430,7 @@ with expansion:
 
 -------------------------------------------------------------------------------
 looped SECTION tests
-  s1
+  b is currently: 0
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
@@ -7764,6 +9440,122 @@ Misc.tests.cpp:<line number>: FAILED:
 with expansion:
   0 > 1
 
+-------------------------------------------------------------------------------
+looped SECTION tests
+  b is currently: 1
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>: FAILED:
+  CHECK( b > a )
+with expansion:
+  1 > 1
+
+-------------------------------------------------------------------------------
+looped SECTION tests
+  b is currently: 2
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>:
+PASSED:
+  CHECK( b > a )
+with expansion:
+  2 > 1
+
+-------------------------------------------------------------------------------
+looped SECTION tests
+  b is currently: 3
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>:
+PASSED:
+  CHECK( b > a )
+with expansion:
+  3 > 1
+
+-------------------------------------------------------------------------------
+looped SECTION tests
+  b is currently: 4
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>:
+PASSED:
+  CHECK( b > a )
+with expansion:
+  4 > 1
+
+-------------------------------------------------------------------------------
+looped SECTION tests
+  b is currently: 5
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>:
+PASSED:
+  CHECK( b > a )
+with expansion:
+  5 > 1
+
+-------------------------------------------------------------------------------
+looped SECTION tests
+  b is currently: 6
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>:
+PASSED:
+  CHECK( b > a )
+with expansion:
+  6 > 1
+
+-------------------------------------------------------------------------------
+looped SECTION tests
+  b is currently: 7
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>:
+PASSED:
+  CHECK( b > a )
+with expansion:
+  7 > 1
+
+-------------------------------------------------------------------------------
+looped SECTION tests
+  b is currently: 8
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>:
+PASSED:
+  CHECK( b > a )
+with expansion:
+  8 > 1
+
+-------------------------------------------------------------------------------
+looped SECTION tests
+  b is currently: 9
+-------------------------------------------------------------------------------
+Misc.tests.cpp:<line number>
+...............................................................................
+
+Misc.tests.cpp:<line number>:
+PASSED:
+  CHECK( b > a )
+with expansion:
+  9 > 1
+
 -------------------------------------------------------------------------------
 looped tests
 -------------------------------------------------------------------------------
@@ -7830,8 +9622,8 @@ with message:
 
 -------------------------------------------------------------------------------
 more nested SECTION tests
-  s1
-  s2
+  doesn't equal
+  equal
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
@@ -7843,8 +9635,8 @@ with expansion:
 
 -------------------------------------------------------------------------------
 more nested SECTION tests
-  s1
-  s3
+  doesn't equal
+  not equal
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
@@ -7857,8 +9649,8 @@ with expansion:
 
 -------------------------------------------------------------------------------
 more nested SECTION tests
-  s1
-  s4
+  doesn't equal
+  less than
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
@@ -7871,7 +9663,7 @@ with expansion:
 
 -------------------------------------------------------------------------------
 nested SECTION tests
-  s1
+  doesn't equal
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
@@ -7890,8 +9682,8 @@ with expansion:
 
 -------------------------------------------------------------------------------
 nested SECTION tests
-  s1
-  s2
+  doesn't equal
+  not equal
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
@@ -7993,7 +9785,7 @@ with expansion:
 
 -------------------------------------------------------------------------------
 random SECTION tests
-  s1
+  doesn't equal
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
@@ -8012,7 +9804,7 @@ with expansion:
 
 -------------------------------------------------------------------------------
 random SECTION tests
-  s2
+  not equal
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
@@ -8463,6 +10255,54 @@ with expansion:
   ==
   "{ operator<<( has_operator ) }"
 
+-------------------------------------------------------------------------------
+strlen3
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( data.str.size() == data.len )
+with expansion:
+  3 == 3
+
+-------------------------------------------------------------------------------
+strlen3
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( data.str.size() == data.len )
+with expansion:
+  3 == 3
+
+-------------------------------------------------------------------------------
+strlen3
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( data.str.size() == data.len )
+with expansion:
+  5 == 5
+
+-------------------------------------------------------------------------------
+strlen3
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>:
+PASSED:
+  REQUIRE( data.str.size() == data.len )
+with expansion:
+  4 == 4
+
 -------------------------------------------------------------------------------
 thrown std::strings are translated
 -------------------------------------------------------------------------------
@@ -8973,7 +10813,9 @@ with expansion:
 
 -------------------------------------------------------------------------------
 xmlentitycheck
-  embedded xml
+  embedded xml: <test>it should be possible to embed xml characters, such as <,
+                " or &, or even whole <xml>documents</xml> within an attribute</test>
+                </test>
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
@@ -8983,7 +10825,7 @@ PASSED:
 
 -------------------------------------------------------------------------------
 xmlentitycheck
-  encoded chars
+  encoded chars: these should all be encoded: &&&"""<<<&"<<&"
 -------------------------------------------------------------------------------
 Misc.tests.cpp:<line number>
 ...............................................................................
@@ -8992,6 +10834,6 @@ Misc.tests.cpp:<line number>:
 PASSED:
 
 ===============================================================================
-test cases:  208 | 142 passed |  62 failed |  4 failed as expected
-assertions: 1079 | 937 passed | 121 failed | 21 failed as expected
+test cases:  213 |  147 passed |  62 failed |  4 failed as expected
+assertions: 1242 | 1099 passed | 122 failed | 21 failed as expected
 
diff --git a/packages/Catch2/projects/SelfTest/Baselines/junit.sw.approved.txt b/packages/Catch2/projects/SelfTest/Baselines/junit.sw.approved.txt
index 62ca9094090e9e63f1578f64beb88a31f4d7173f..ad5caeb17976c45856b83aa42adecff16e6e624b 100644
--- a/packages/Catch2/projects/SelfTest/Baselines/junit.sw.approved.txt
+++ b/packages/Catch2/projects/SelfTest/Baselines/junit.sw.approved.txt
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <testsuitesloose text artifact
 >
-  <testsuite name="<exe-name>" errors="17" failures="105" tests="1080" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
+  <testsuite name="<exe-name>" errors="17" failures="106" tests="1243" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
     <testcase classname="<exe-name>.global" name="# A test name that starts with a #" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="#1005: Comparing pointer to int and long (NULL can be either on various systems)" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="#1027" time="{duration}"/>
@@ -69,6 +69,7 @@ Condition.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="(unimplemented) static bools can be evaluated/negation" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="(unimplemented) static bools can be evaluated/double negation" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="(unimplemented) static bools can be evaluated/direct" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="10x10 ints" time="{duration}"/>
     <testcase classname="<exe-name>.TestClass" name="A METHOD_AS_TEST_CASE based test run that fails" time="{duration}">
       <failure message="&quot;hello&quot; == &quot;world&quot;" type="REQUIRE">
 Class.tests.cpp:<line number>
@@ -81,6 +82,7 @@ Class.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.Fixture" name="A TEST_CASE_METHOD based test run that succeeds" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="A comparison that uses literals instead of the normal constructor" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="A couple of nested sections followed by a failure" time="{duration}">
       <failure type="FAIL">
 to infinity and beyond
@@ -288,6 +290,14 @@ Message.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="Floating point matchers: float/ULPs" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Floating point matchers: float/Composed" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Floating point matchers: float/Constructor validation" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Generators/one" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Generators/two" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Generators impl/range" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Generators impl/fixed values" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Generators impl/combined" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Generators impl/values" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Generators impl/values2" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Generators impl/type erasure" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Greater-than inequalities with different epsilons" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="INFO and WARN do not abort tests" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="INFO gets logged on failure" time="{duration}">
@@ -467,11 +477,10 @@ Message.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="Parse test names and tags/empty tag" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Parse test names and tags/empty quoted name" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Parse test names and tags/quoted string followed by tag exclusion" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="Parsing a std::pair" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Pointers can be compared to null" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Process can be configured on command line/empty args don't cause a crash" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Process can be configured on command line/default - no arguments" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="Process can be configured on command line/test lists/1 test" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Process can be configured on command line/test lists/Specify one test case using" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Process can be configured on command line/test lists/Specify one test case exclusion using exclude:" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Process can be configured on command line/test lists/Specify one test case exclusion using ~" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Process can be configured on command line/reporter/-r/console" time="{duration}"/>
@@ -509,12 +518,13 @@ Matchers.tests.cpp:<line number>
 Matchers.tests.cpp:<line number>
       </failure>
     </testcase>
+    <testcase classname="<exe-name>.global" name="Regression test #1" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="SUCCEED counts as a test pass" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="SUCCEED does not require an argument" time="{duration}"/>
     <testcase classname="<exe-name>.Fixture" name="Scenario: BDD tests requiring Fixtures to provide commonly-accessed data or methods/Given: No operations precede me" time="{duration}"/>
     <testcase classname="<exe-name>.Fixture" name="Scenario: BDD tests requiring Fixtures to provide commonly-accessed data or methods/Given: No operations precede me/When: We get the count/Then: Subsequently values are higher" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="Scenario: Do that thing with the thing/Given: This stuff exists/When: I do this/Then: it should do this" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="Scenario: Do that thing with the thing/Given: This stuff exists/When: I do this/Then: it should do this/And: do that" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Scenario: Do that thing with the thing/Given: This stuff exists/And given: And some assumption/When: I do this/Then: it should do this" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="Scenario: Do that thing with the thing/Given: This stuff exists/And given: And some assumption/When: I do this/Then: it should do this/And: do that" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Scenario: This is a really long scenario name to see how the list command deals with wrapping/Given: A section name that is so long that it cannot fit in a single console width/When: The test headers are printed as part of the normal running of the scenario/Then: The, deliberately very long and overly verbose (you see what I did there?) section names must wrap, along with an indent" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Scenario: Vector resizing affects size and capacity/Given: an empty vector" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Scenario: Vector resizing affects size and capacity/Given: an empty vector/When: it is made larger/Then: the size and capacity go up" time="{duration}"/>
@@ -750,11 +760,24 @@ Message.tests.cpp:<line number>
       </failure>
     </testcase>
     <testcase classname="<exe-name>.global" name="long long" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="looped SECTION tests/s1" time="{duration}">
+    <testcase classname="<exe-name>.global" name="looped SECTION tests/b is currently: 0" time="{duration}">
       <failure message="0 > 1" type="CHECK">
 Misc.tests.cpp:<line number>
       </failure>
     </testcase>
+    <testcase classname="<exe-name>.global" name="looped SECTION tests/b is currently: 1" time="{duration}">
+      <failure message="1 > 1" type="CHECK">
+Misc.tests.cpp:<line number>
+      </failure>
+    </testcase>
+    <testcase classname="<exe-name>.global" name="looped SECTION tests/b is currently: 2" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="looped SECTION tests/b is currently: 3" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="looped SECTION tests/b is currently: 4" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="looped SECTION tests/b is currently: 5" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="looped SECTION tests/b is currently: 6" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="looped SECTION tests/b is currently: 7" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="looped SECTION tests/b is currently: 8" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="looped SECTION tests/b is currently: 9" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="looped tests" time="{duration}">
       <failure message="1 == 0" type="CHECK">
 Testing if fib[0] (1) is even
@@ -781,15 +804,15 @@ Testing if fib[7] (21) is even
 Misc.tests.cpp:<line number>
       </failure>
     </testcase>
-    <testcase classname="<exe-name>.global" name="more nested SECTION tests/s2/s1" time="{duration}">
+    <testcase classname="<exe-name>.global" name="more nested SECTION tests/equal/doesn't equal" time="{duration}">
       <failure message="1 == 2" type="REQUIRE">
 Misc.tests.cpp:<line number>
       </failure>
     </testcase>
-    <testcase classname="<exe-name>.global" name="more nested SECTION tests/s1/s3" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="more nested SECTION tests/s1/s4" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="nested SECTION tests/s1" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="nested SECTION tests/s1/s2" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="more nested SECTION tests/doesn't equal/not equal" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="more nested SECTION tests/doesn't equal/less than" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="nested SECTION tests/doesn't equal" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="nested SECTION tests/doesn't equal/not equal" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="non streamable - with conv. op" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="non-copyable objects" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="not allowed" time="{duration}"/>
@@ -797,8 +820,8 @@ Misc.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="null_ptr" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="pair&lt;pair&lt;int,const char *,pair&lt;std::string,int> > -> toString" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="pointer to class" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="random SECTION tests/s1" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="random SECTION tests/s2" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="random SECTION tests/doesn't equal" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="random SECTION tests/not equal" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="replaceInPlace/replace single char" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="replaceInPlace/replace two chars" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="replaceInPlace/replace first char" time="{duration}"/>
@@ -842,6 +865,7 @@ Tricky.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="stringify( vectors&lt;has_maker> )" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="stringify( vectors&lt;has_maker_and_operator> )" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="stringify( vectors&lt;has_operator> )" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="strlen3" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="thrown std::strings are translated" time="{duration}">
       <error type="TEST_CASE">
 Why would you throw a std::string?
@@ -873,8 +897,8 @@ Exception.tests.cpp:<line number>
     <testcase classname="<exe-name>.global" name="vectors can be sized and resized/resizing smaller changes size but not capacity/We can use the 'swap trick' to reset the capacity" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="vectors can be sized and resized/reserving bigger changes capacity but not size" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="vectors can be sized and resized/reserving smaller does not change size or capacity" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="xmlentitycheck/embedded xml" time="{duration}"/>
-    <testcase classname="<exe-name>.global" name="xmlentitycheck/encoded chars" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="xmlentitycheck/embedded xml: &lt;test>it should be possible to embed xml characters, such as &lt;, &quot; or &amp;, or even whole &lt;xml>documents&lt;/xml> within an attribute&lt;/test>" time="{duration}"/>
+    <testcase classname="<exe-name>.global" name="xmlentitycheck/encoded chars: these should all be encoded: &amp;&amp;&amp;&quot;&quot;&quot;&lt;&lt;&lt;&amp;&quot;&lt;&lt;&amp;&quot;" time="{duration}"/>
     <system-out>
 A string sent directly to stdout
 Message from section one
diff --git a/packages/Catch2/projects/SelfTest/Baselines/xml.sw.approved.txt b/packages/Catch2/projects/SelfTest/Baselines/xml.sw.approved.txt
index 5452f2fa36c8a3d3b3fc992f60531413233d6828..3428787441dc597b7b16bd01346c68079725eadc 100644
--- a/packages/Catch2/projects/SelfTest/Baselines/xml.sw.approved.txt
+++ b/packages/Catch2/projects/SelfTest/Baselines/xml.sw.approved.txt
@@ -510,472 +510,1326 @@
       </Section>
       <OverallResult success="true"/>
     </TestCase>
-    <TestCase name="A METHOD_AS_TEST_CASE based test run that fails" tags="[.][class][failing]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
-      <Expression success="false" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+    <TestCase name="10x10 ints" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          s == "world"
+          x &lt; y
         </Original>
         <Expanded>
-          "hello" == "world"
+          1 &lt; 101
         </Expanded>
       </Expression>
-      <OverallResult success="false"/>
-    </TestCase>
-    <TestCase name="A METHOD_AS_TEST_CASE based test run that succeeds" tags="[class]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          s == "hello"
+          x &lt; y
         </Original>
         <Expanded>
-          "hello" == "hello"
+          1 &lt; 102
         </Expanded>
       </Expression>
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="A TEST_CASE_METHOD based test run that fails" tags="[.][class][failing]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
-      <Expression success="false" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          m_a == 2
+          x &lt; y
         </Original>
         <Expanded>
-          1 == 2
+          1 &lt; 103
         </Expanded>
       </Expression>
-      <OverallResult success="false"/>
-    </TestCase>
-    <TestCase name="A TEST_CASE_METHOD based test run that succeeds" tags="[class]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          m_a == 1
+          x &lt; y
         </Original>
         <Expanded>
-          1 == 1
+          1 &lt; 104
         </Expanded>
       </Expression>
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="A couple of nested sections followed by a failure" tags="[.][failing]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
-      <Section name="Outer" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
-        <Section name="Inner" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
-          <OverallResults successes="1" failures="0" expectedFailures="0"/>
-        </Section>
-        <OverallResults successes="1" failures="0" expectedFailures="0"/>
-      </Section>
-      <Failure filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
-        to infinity and beyond
-      </Failure>
-      <OverallResult success="false"/>
-    </TestCase>
-    <TestCase name="A failing expression with a non streamable type is still captured" tags="[.][Tricky][failing]" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
-      <Expression success="false" type="CHECK" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          &amp;o1 == &amp;o2
+          x &lt; y
         </Original>
         <Expanded>
-          0x<hex digits> == 0x<hex digits>
+          1 &lt; 105
         </Expanded>
       </Expression>
-      <Expression success="false" type="CHECK" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          o1 == o2
+          x &lt; y
         </Original>
         <Expanded>
-          {?} == {?}
+          1 &lt; 106
         </Expanded>
       </Expression>
-      <OverallResult success="false"/>
-    </TestCase>
-    <TestCase name="Absolute margin" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          104.0 != Approx(100.0)
+          x &lt; y
         </Original>
         <Expanded>
-          104.0 != Approx( 100.0 )
+          1 &lt; 107
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          104.0 == Approx(100.0).margin(5)
+          x &lt; y
         </Original>
         <Expanded>
-          104.0 == Approx( 100.0 )
+          1 &lt; 108
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          104.0 == Approx(100.0).margin(4)
+          x &lt; y
         </Original>
         <Expanded>
-          104.0 == Approx( 100.0 )
+          1 &lt; 109
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          104.0 != Approx(100.0).margin(3)
+          x &lt; y
         </Original>
         <Expanded>
-          104.0 != Approx( 100.0 )
+          1 &lt; 110
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          100.3 != Approx(100.0)
+          x &lt; y
         </Original>
         <Expanded>
-          100.3 != Approx( 100.0 )
+          2 &lt; 101
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          100.3 == Approx(100.0).margin(0.5)
+          x &lt; y
         </Original>
         <Expanded>
-          100.3 == Approx( 100.0 )
+          2 &lt; 102
         </Expanded>
       </Expression>
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="An empty test with no assertions" tags="[empty]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
-      <OverallResult success="false"/>
-    </TestCase>
-    <TestCase name="An expression with side-effects should only be evaluated once" tags="[Tricky]" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          i++ == 7
+          x &lt; y
         </Original>
         <Expanded>
-          7 == 7
+          2 &lt; 103
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          i++ == 8
+          x &lt; y
         </Original>
         <Expanded>
-          8 == 8
+          2 &lt; 104
         </Expanded>
       </Expression>
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="An unchecked exception reports the line of the last assertion" tags="[!throws][.][failing]" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
-      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          1 == 1
+          x &lt; y
         </Original>
         <Expanded>
-          1 == 1
+          2 &lt; 105
         </Expanded>
       </Expression>
-      <Expression success="false" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          {Unknown expression after the reported line}
+          x &lt; y
         </Original>
         <Expanded>
-          {Unknown expression after the reported line}
+          2 &lt; 106
         </Expanded>
-        <Exception filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
-          unexpected exception
-        </Exception>
       </Expression>
-      <OverallResult success="false"/>
-    </TestCase>
-    <TestCase name="Anonymous test case 1" filename="projects/<exe-name>/UsageTests/VariadicMacros.tests.cpp" >
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="Approx setters validate their arguments" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
-      <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          Approx(0).margin(0)
+          x &lt; y
         </Original>
         <Expanded>
-          Approx(0).margin(0)
+          2 &lt; 107
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          Approx(0).margin(1234656)
+          x &lt; y
         </Original>
         <Expanded>
-          Approx(0).margin(1234656)
+          2 &lt; 108
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          Approx(0).margin(-2), std::domain_error
+          x &lt; y
         </Original>
         <Expanded>
-          Approx(0).margin(-2), std::domain_error
+          2 &lt; 109
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          Approx(0).epsilon(0)
+          x &lt; y
         </Original>
         <Expanded>
-          Approx(0).epsilon(0)
+          2 &lt; 110
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          Approx(0).epsilon(1)
+          x &lt; y
         </Original>
         <Expanded>
-          Approx(0).epsilon(1)
+          3 &lt; 101
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          Approx(0).epsilon(-0.001), std::domain_error
+          x &lt; y
         </Original>
         <Expanded>
-          Approx(0).epsilon(-0.001), std::domain_error
+          3 &lt; 102
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          Approx(0).epsilon(1.0001), std::domain_error
+          x &lt; y
         </Original>
         <Expanded>
-          Approx(0).epsilon(1.0001), std::domain_error
+          3 &lt; 103
         </Expanded>
       </Expression>
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="Approx with exactly-representable margin" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
-      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          0.25f == Approx(0.0f).margin(0.25f)
+          x &lt; y
         </Original>
         <Expanded>
-          0.25f == Approx( 0.0 )
+          3 &lt; 104
         </Expanded>
       </Expression>
-      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          0.0f == Approx(0.25f).margin(0.25f)
+          x &lt; y
         </Original>
         <Expanded>
-          0.0f == Approx( 0.25 )
+          3 &lt; 105
         </Expanded>
       </Expression>
-      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          0.5f == Approx(0.25f).margin(0.25f)
+          x &lt; y
         </Original>
         <Expanded>
-          0.5f == Approx( 0.25 )
+          3 &lt; 106
         </Expanded>
       </Expression>
-      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          245.0f == Approx(245.25f).margin(0.25f)
+          x &lt; y
         </Original>
         <Expanded>
-          245.0f == Approx( 245.25 )
+          3 &lt; 107
         </Expanded>
       </Expression>
-      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          245.5f == Approx(245.25f).margin(0.25f)
+          x &lt; y
         </Original>
         <Expanded>
-          245.5f == Approx( 245.25 )
+          3 &lt; 108
         </Expanded>
       </Expression>
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="Approximate PI" tags="[Approx][PI]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          divide( 22, 7 ) == Approx( 3.141 ).epsilon( 0.001 )
+          x &lt; y
         </Original>
         <Expanded>
-          3.1428571429 == Approx( 3.141 )
+          3 &lt; 109
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 )
+          x &lt; y
         </Original>
         <Expanded>
-          3.1428571429 != Approx( 3.141 )
+          3 &lt; 110
         </Expanded>
       </Expression>
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="Approximate comparisons with different epsilons" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          d != Approx( 1.231 )
+          x &lt; y
         </Original>
         <Expanded>
-          1.23 != Approx( 1.231 )
+          4 &lt; 101
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          d == Approx( 1.231 ).epsilon( 0.1 )
+          x &lt; y
         </Original>
         <Expanded>
-          1.23 == Approx( 1.231 )
+          4 &lt; 102
         </Expanded>
       </Expression>
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="Approximate comparisons with floats" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          1.23f == Approx( 1.23f )
+          x &lt; y
         </Original>
         <Expanded>
-          1.23f == Approx( 1.2300000191 )
+          4 &lt; 103
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          0.0f == Approx( 0.0f )
+          x &lt; y
         </Original>
         <Expanded>
-          0.0f == Approx( 0.0 )
+          4 &lt; 104
         </Expanded>
       </Expression>
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="Approximate comparisons with ints" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          1 == Approx( 1 )
+          x &lt; y
         </Original>
         <Expanded>
-          1 == Approx( 1.0 )
+          4 &lt; 105
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          0 == Approx( 0 )
+          x &lt; y
         </Original>
         <Expanded>
-          0 == Approx( 0.0 )
+          4 &lt; 106
         </Expanded>
       </Expression>
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="Approximate comparisons with mixed numeric types" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          1.0f == Approx( 1 )
+          x &lt; y
         </Original>
         <Expanded>
-          1.0f == Approx( 1.0 )
+          4 &lt; 107
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          0 == Approx( dZero)
+          x &lt; y
         </Original>
         <Expanded>
-          0 == Approx( 0.0 )
+          4 &lt; 108
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          0 == Approx( dSmall ).margin( 0.001 )
+          x &lt; y
         </Original>
         <Expanded>
-          0 == Approx( 0.00001 )
+          4 &lt; 109
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          1.234f == Approx( dMedium )
+          x &lt; y
         </Original>
         <Expanded>
-          1.234f == Approx( 1.234 )
+          4 &lt; 110
         </Expanded>
       </Expression>
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          dMedium == Approx( 1.234f )
+          x &lt; y
         </Original>
         <Expanded>
-          1.234 == Approx( 1.2339999676 )
+          5 &lt; 101
         </Expanded>
       </Expression>
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="Arbitrary predicate matcher" tags="[generic][matchers]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
-      <Section name="Function pointer" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
-          <Original>
-            1, Predicate&lt;int>(alwaysTrue, "always true")
-          </Original>
-          <Expanded>
-            1 matches predicate: "always true"
-          </Expanded>
-        </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
-          <Original>
-            1, !Predicate&lt;int>(alwaysFalse, "always false")
-          </Original>
-          <Expanded>
-            1 not matches predicate: "always false"
-          </Expanded>
-        </Expression>
-        <OverallResults successes="2" failures="0" expectedFailures="0"/>
-      </Section>
-      <Section name="Lambdas + different type" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
-          <Original>
-            "Hello olleH", Predicate&lt;std::string>( [] (std::string const&amp; str) -> bool { return str.front() == str.back(); }, "First and last character should be equal")
-          </Original>
-          <Expanded>
-            "Hello olleH" matches predicate: "First and last character should be equal"
-          </Expanded>
-        </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
-          <Original>
-            "This wouldn't pass", !Predicate&lt;std::string>( [] (std::string const&amp; str) -> bool { return str.front() == str.back(); } )
-          </Original>
-          <Expanded>
-            "This wouldn't pass" not matches undescribed predicate
-          </Expanded>
-        </Expression>
-        <OverallResults successes="2" failures="0" expectedFailures="0"/>
-      </Section>
-      <OverallResult success="true"/>
-    </TestCase>
-    <TestCase name="Assertions then sections" tags="[Tricky]" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
         <Original>
-          true
+          x &lt; y
         </Original>
         <Expanded>
-          true
+          5 &lt; 102
         </Expanded>
       </Expression>
-      <Section name="A section" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
-        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
-          <Original>
-            true
-          </Original>
-          <Expanded>
-            true
-          </Expanded>
-        </Expression>
-        <Section name="Another section" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
-          <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
-            <Original>
-              true
-            </Original>
-            <Expanded>
-              true
-            </Expanded>
-          </Expression>
-          <OverallResults successes="1" failures="0" expectedFailures="0"/>
-        </Section>
-        <OverallResults successes="2" failures="0" expectedFailures="0"/>
-      </Section>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          5 &lt; 103
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          5 &lt; 104
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          5 &lt; 105
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          5 &lt; 106
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          5 &lt; 107
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          5 &lt; 108
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          5 &lt; 109
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          5 &lt; 110
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          6 &lt; 101
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          6 &lt; 102
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          6 &lt; 103
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          6 &lt; 104
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          6 &lt; 105
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          6 &lt; 106
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          6 &lt; 107
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          6 &lt; 108
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          6 &lt; 109
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          6 &lt; 110
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          7 &lt; 101
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          7 &lt; 102
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          7 &lt; 103
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          7 &lt; 104
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          7 &lt; 105
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          7 &lt; 106
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          7 &lt; 107
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          7 &lt; 108
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          7 &lt; 109
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          7 &lt; 110
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          8 &lt; 101
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          8 &lt; 102
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          8 &lt; 103
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          8 &lt; 104
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          8 &lt; 105
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          8 &lt; 106
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          8 &lt; 107
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          8 &lt; 108
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          8 &lt; 109
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          8 &lt; 110
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          9 &lt; 101
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          9 &lt; 102
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          9 &lt; 103
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          9 &lt; 104
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          9 &lt; 105
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          9 &lt; 106
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          9 &lt; 107
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          9 &lt; 108
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          9 &lt; 109
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          9 &lt; 110
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          10 &lt; 101
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          10 &lt; 102
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          10 &lt; 103
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          10 &lt; 104
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          10 &lt; 105
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          10 &lt; 106
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          10 &lt; 107
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          10 &lt; 108
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          10 &lt; 109
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          x &lt; y
+        </Original>
+        <Expanded>
+          10 &lt; 110
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="A METHOD_AS_TEST_CASE based test run that fails" tags="[.][class][failing]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="false" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+        <Original>
+          s == "world"
+        </Original>
+        <Expanded>
+          "hello" == "world"
+        </Expanded>
+      </Expression>
+      <OverallResult success="false"/>
+    </TestCase>
+    <TestCase name="A METHOD_AS_TEST_CASE based test run that succeeds" tags="[class]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+        <Original>
+          s == "hello"
+        </Original>
+        <Expanded>
+          "hello" == "hello"
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="A TEST_CASE_METHOD based test run that fails" tags="[.][class][failing]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="false" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+        <Original>
+          m_a == 2
+        </Original>
+        <Expanded>
+          1 == 2
+        </Expanded>
+      </Expression>
+      <OverallResult success="false"/>
+    </TestCase>
+    <TestCase name="A TEST_CASE_METHOD based test run that succeeds" tags="[class]" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Class.tests.cpp" >
+        <Original>
+          m_a == 1
+        </Original>
+        <Expanded>
+          1 == 1
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="A comparison that uses literals instead of the normal constructor" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          d == 1.23_a
+        </Original>
+        <Expanded>
+          1.23 == Approx( 1.23 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          d != 1.22_a
+        </Original>
+        <Expanded>
+          1.23 != Approx( 1.22 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          -d == -1.23_a
+        </Original>
+        <Expanded>
+          -1.23 == Approx( -1.23 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          d == 1.2_a .epsilon(.1)
+        </Original>
+        <Expanded>
+          1.23 == Approx( 1.2 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          d != 1.2_a .epsilon(.001)
+        </Original>
+        <Expanded>
+          1.23 != Approx( 1.2 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          d == 1_a .epsilon(.3)
+        </Original>
+        <Expanded>
+          1.23 == Approx( 1.0 )
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="A couple of nested sections followed by a failure" tags="[.][failing]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Section name="Outer" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Section name="Inner" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <OverallResults successes="1" failures="0" expectedFailures="0"/>
+        </Section>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Failure filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        to infinity and beyond
+      </Failure>
+      <OverallResult success="false"/>
+    </TestCase>
+    <TestCase name="A failing expression with a non streamable type is still captured" tags="[.][Tricky][failing]" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+      <Expression success="false" type="CHECK" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+        <Original>
+          &amp;o1 == &amp;o2
+        </Original>
+        <Expanded>
+          0x<hex digits> == 0x<hex digits>
+        </Expanded>
+      </Expression>
+      <Expression success="false" type="CHECK" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+        <Original>
+          o1 == o2
+        </Original>
+        <Expanded>
+          {?} == {?}
+        </Expanded>
+      </Expression>
+      <OverallResult success="false"/>
+    </TestCase>
+    <TestCase name="Absolute margin" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          104.0 != Approx(100.0)
+        </Original>
+        <Expanded>
+          104.0 != Approx( 100.0 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          104.0 == Approx(100.0).margin(5)
+        </Original>
+        <Expanded>
+          104.0 == Approx( 100.0 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          104.0 == Approx(100.0).margin(4)
+        </Original>
+        <Expanded>
+          104.0 == Approx( 100.0 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          104.0 != Approx(100.0).margin(3)
+        </Original>
+        <Expanded>
+          104.0 != Approx( 100.0 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          100.3 != Approx(100.0)
+        </Original>
+        <Expanded>
+          100.3 != Approx( 100.0 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          100.3 == Approx(100.0).margin(0.5)
+        </Original>
+        <Expanded>
+          100.3 == Approx( 100.0 )
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="An empty test with no assertions" tags="[empty]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <OverallResult success="false"/>
+    </TestCase>
+    <TestCase name="An expression with side-effects should only be evaluated once" tags="[Tricky]" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+        <Original>
+          i++ == 7
+        </Original>
+        <Expanded>
+          7 == 7
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+        <Original>
+          i++ == 8
+        </Original>
+        <Expanded>
+          8 == 8
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="An unchecked exception reports the line of the last assertion" tags="[!throws][.][failing]" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
+        <Original>
+          1 == 1
+        </Original>
+        <Expanded>
+          1 == 1
+        </Expanded>
+      </Expression>
+      <Expression success="false" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
+        <Original>
+          {Unknown expression after the reported line}
+        </Original>
+        <Expanded>
+          {Unknown expression after the reported line}
+        </Expanded>
+        <Exception filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
+          unexpected exception
+        </Exception>
+      </Expression>
+      <OverallResult success="false"/>
+    </TestCase>
+    <TestCase name="Anonymous test case 1" filename="projects/<exe-name>/UsageTests/VariadicMacros.tests.cpp" >
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Approx setters validate their arguments" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          Approx(0).margin(0)
+        </Original>
+        <Expanded>
+          Approx(0).margin(0)
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          Approx(0).margin(1234656)
+        </Original>
+        <Expanded>
+          Approx(0).margin(1234656)
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          Approx(0).margin(-2), std::domain_error
+        </Original>
+        <Expanded>
+          Approx(0).margin(-2), std::domain_error
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          Approx(0).epsilon(0)
+        </Original>
+        <Expanded>
+          Approx(0).epsilon(0)
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          Approx(0).epsilon(1)
+        </Original>
+        <Expanded>
+          Approx(0).epsilon(1)
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          Approx(0).epsilon(-0.001), std::domain_error
+        </Original>
+        <Expanded>
+          Approx(0).epsilon(-0.001), std::domain_error
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          Approx(0).epsilon(1.0001), std::domain_error
+        </Original>
+        <Expanded>
+          Approx(0).epsilon(1.0001), std::domain_error
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Approx with exactly-representable margin" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          0.25f == Approx(0.0f).margin(0.25f)
+        </Original>
+        <Expanded>
+          0.25f == Approx( 0.0 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          0.0f == Approx(0.25f).margin(0.25f)
+        </Original>
+        <Expanded>
+          0.0f == Approx( 0.25 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          0.5f == Approx(0.25f).margin(0.25f)
+        </Original>
+        <Expanded>
+          0.5f == Approx( 0.25 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          245.0f == Approx(245.25f).margin(0.25f)
+        </Original>
+        <Expanded>
+          245.0f == Approx( 245.25 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          245.5f == Approx(245.25f).margin(0.25f)
+        </Original>
+        <Expanded>
+          245.5f == Approx( 245.25 )
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Approximate PI" tags="[Approx][PI]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          divide( 22, 7 ) == Approx( 3.141 ).epsilon( 0.001 )
+        </Original>
+        <Expanded>
+          3.1428571429 == Approx( 3.141 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 )
+        </Original>
+        <Expanded>
+          3.1428571429 != Approx( 3.141 )
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Approximate comparisons with different epsilons" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          d != Approx( 1.231 )
+        </Original>
+        <Expanded>
+          1.23 != Approx( 1.231 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          d == Approx( 1.231 ).epsilon( 0.1 )
+        </Original>
+        <Expanded>
+          1.23 == Approx( 1.231 )
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Approximate comparisons with floats" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          1.23f == Approx( 1.23f )
+        </Original>
+        <Expanded>
+          1.23f == Approx( 1.2300000191 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          0.0f == Approx( 0.0f )
+        </Original>
+        <Expanded>
+          0.0f == Approx( 0.0 )
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Approximate comparisons with ints" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          1 == Approx( 1 )
+        </Original>
+        <Expanded>
+          1 == Approx( 1.0 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          0 == Approx( 0 )
+        </Original>
+        <Expanded>
+          0 == Approx( 0.0 )
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Approximate comparisons with mixed numeric types" tags="[Approx]" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          1.0f == Approx( 1 )
+        </Original>
+        <Expanded>
+          1.0f == Approx( 1.0 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          0 == Approx( dZero)
+        </Original>
+        <Expanded>
+          0 == Approx( 0.0 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          0 == Approx( dSmall ).margin( 0.001 )
+        </Original>
+        <Expanded>
+          0 == Approx( 0.00001 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          1.234f == Approx( dMedium )
+        </Original>
+        <Expanded>
+          1.234f == Approx( 1.234 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          dMedium == Approx( 1.234f )
+        </Original>
+        <Expanded>
+          1.234 == Approx( 1.2339999676 )
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Arbitrary predicate matcher" tags="[generic][matchers]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+      <Section name="Function pointer" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            1, Predicate&lt;int>(alwaysTrue, "always true")
+          </Original>
+          <Expanded>
+            1 matches predicate: "always true"
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            1, !Predicate&lt;int>(alwaysFalse, "always false")
+          </Original>
+          <Expanded>
+            1 not matches predicate: "always false"
+          </Expanded>
+        </Expression>
+        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="Lambdas + different type" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            "Hello olleH", Predicate&lt;std::string>( [] (std::string const&amp; str) -> bool { return str.front() == str.back(); }, "First and last character should be equal")
+          </Original>
+          <Expanded>
+            "Hello olleH" matches predicate: "First and last character should be equal"
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            "This wouldn't pass", !Predicate&lt;std::string>( [] (std::string const&amp; str) -> bool { return str.front() == str.back(); } )
+          </Original>
+          <Expanded>
+            "This wouldn't pass" not matches undescribed predicate
+          </Expanded>
+        </Expression>
+        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+      </Section>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Assertions then sections" tags="[Tricky]" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+        <Original>
+          true
+        </Original>
+        <Expanded>
+          true
+        </Expanded>
+      </Expression>
+      <Section name="A section" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+          <Original>
+            true
+          </Original>
+          <Expanded>
+            true
+          </Expanded>
+        </Expression>
+        <Section name="Another section" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+          <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
+            <Original>
+              true
+            </Original>
+            <Expanded>
+              true
+            </Expanded>
+          </Expression>
+          <OverallResults successes="1" failures="0" expectedFailures="0"/>
+        </Section>
+        <OverallResults successes="2" failures="0" expectedFailures="0"/>
+      </Section>
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
         <Original>
           true
@@ -2172,38 +3026,245 @@
       </Expression>
       <OverallResult success="true"/>
     </TestCase>
-    <TestCase name="Floating point matchers: double" tags="[floating-point][matchers]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+    <TestCase name="Floating point matchers: double" tags="[floating-point][matchers]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+      <Section name="Margin" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            1., WithinAbs(1., 0)
+          </Original>
+          <Expanded>
+            1.0 is within 0.0 of 1.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            0., WithinAbs(1., 1)
+          </Original>
+          <Expanded>
+            0.0 is within 1.0 of 1.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            0., !WithinAbs(1., 0.99)
+          </Original>
+          <Expanded>
+            0.0 not is within 0.99 of 1.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            0., !WithinAbs(1., 0.99)
+          </Original>
+          <Expanded>
+            0.0 not is within 0.99 of 1.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            NAN, !WithinAbs(NAN, 0)
+          </Original>
+          <Expanded>
+            nanf not is within 0.0 of nan
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            11., !WithinAbs(10., 0.5)
+          </Original>
+          <Expanded>
+            11.0 not is within 0.5 of 10.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            10., !WithinAbs(11., 0.5)
+          </Original>
+          <Expanded>
+            10.0 not is within 0.5 of 11.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            -10., WithinAbs(-10., 0.5)
+          </Original>
+          <Expanded>
+            -10.0 is within 0.5 of -10.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            -10., WithinAbs(-9.6, 0.5)
+          </Original>
+          <Expanded>
+            -10.0 is within 0.5 of -9.6
+          </Expanded>
+        </Expression>
+        <OverallResults successes="9" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="ULPs" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            1., WithinULP(1., 0)
+          </Original>
+          <Expanded>
+            1.0 is within 0 ULPs of 1.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            nextafter(1., 2.), WithinULP(1., 1)
+          </Original>
+          <Expanded>
+            1.0 is within 1 ULPs of 1.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            nextafter(1., 0.), WithinULP(1., 1)
+          </Original>
+          <Expanded>
+            1.0 is within 1 ULPs of 1.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            nextafter(1., 2.), !WithinULP(1., 0)
+          </Original>
+          <Expanded>
+            1.0 not is within 0 ULPs of 1.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            1., WithinULP(1., 0)
+          </Original>
+          <Expanded>
+            1.0 is within 0 ULPs of 1.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            -0., WithinULP(0., 0)
+          </Original>
+          <Expanded>
+            -0.0 is within 0 ULPs of 0.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            NAN, !WithinULP(NAN, 123)
+          </Original>
+          <Expanded>
+            nanf not is within 123 ULPs of nanf
+          </Expanded>
+        </Expression>
+        <OverallResults successes="7" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="Composed" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            1., WithinAbs(1., 0.5) || WithinULP(2., 1)
+          </Original>
+          <Expanded>
+            1.0 ( is within 0.5 of 1.0 or is within 1 ULPs of 2.0 )
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            1., WithinAbs(2., 0.5) || WithinULP(1., 0)
+          </Original>
+          <Expanded>
+            1.0 ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0 )
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123))
+          </Original>
+          <Expanded>
+            nanf not ( is within 100.0 of nan or is within 123 ULPs of nanf )
+          </Expanded>
+        </Expression>
+        <OverallResults successes="3" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="Constructor validation" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            WithinAbs(1., 0.)
+          </Original>
+          <Expanded>
+            WithinAbs(1., 0.)
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            WithinAbs(1., -1.), std::domain_error
+          </Original>
+          <Expanded>
+            WithinAbs(1., -1.), std::domain_error
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            WithinULP(1., 0)
+          </Original>
+          <Expanded>
+            WithinULP(1., 0)
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            WithinULP(1., -1), std::domain_error
+          </Original>
+          <Expanded>
+            WithinULP(1., -1), std::domain_error
+          </Expanded>
+        </Expression>
+        <OverallResults successes="4" failures="0" expectedFailures="0"/>
+      </Section>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Floating point matchers: float" tags="[floating-point][matchers]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
       <Section name="Margin" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            1., WithinAbs(1., 0)
+            1.f, WithinAbs(1.f, 0)
           </Original>
           <Expanded>
-            1.0 is within 0.0 of 1.0
+            1.0f is within 0.0 of 1.0
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            0., WithinAbs(1., 1)
+            0.f, WithinAbs(1.f, 1)
           </Original>
           <Expanded>
-            0.0 is within 1.0 of 1.0
+            0.0f is within 1.0 of 1.0
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            0., !WithinAbs(1., 0.99)
+            0.f, !WithinAbs(1.f, 0.99f)
           </Original>
           <Expanded>
-            0.0 not is within 0.99 of 1.0
+            0.0f not is within 0.9900000095 of 1.0
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            0., !WithinAbs(1., 0.99)
+            0.f, !WithinAbs(1.f, 0.99f)
           </Original>
           <Expanded>
-            0.0 not is within 0.99 of 1.0
+            0.0f not is within 0.9900000095 of 1.0
+          </Expanded>
+        </Expression>
+        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+          <Original>
+            0.f, WithinAbs(-0.f, 0)
+          </Original>
+          <Expanded>
+            0.0f is within 0.0 of -0.0
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
@@ -2216,85 +3277,85 @@
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            11., !WithinAbs(10., 0.5)
+            11.f, !WithinAbs(10.f, 0.5f)
           </Original>
           <Expanded>
-            11.0 not is within 0.5 of 10.0
+            11.0f not is within 0.5 of 10.0
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            10., !WithinAbs(11., 0.5)
+            10.f, !WithinAbs(11.f, 0.5f)
           </Original>
           <Expanded>
-            10.0 not is within 0.5 of 11.0
+            10.0f not is within 0.5 of 11.0
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            -10., WithinAbs(-10., 0.5)
+            -10.f, WithinAbs(-10.f, 0.5f)
           </Original>
           <Expanded>
-            -10.0 is within 0.5 of -10.0
+            -10.0f is within 0.5 of -10.0
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            -10., WithinAbs(-9.6, 0.5)
+            -10.f, WithinAbs(-9.6f, 0.5f)
           </Original>
           <Expanded>
-            -10.0 is within 0.5 of -9.6
+            -10.0f is within 0.5 of -9.6000003815
           </Expanded>
         </Expression>
-        <OverallResults successes="9" failures="0" expectedFailures="0"/>
+        <OverallResults successes="10" failures="0" expectedFailures="0"/>
       </Section>
       <Section name="ULPs" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            1., WithinULP(1., 0)
+            1.f, WithinULP(1.f, 0)
           </Original>
           <Expanded>
-            1.0 is within 0 ULPs of 1.0
+            1.0f is within 0 ULPs of 1.0f
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            nextafter(1., 2.), WithinULP(1., 1)
+            nextafter(1.f, 2.f), WithinULP(1.f, 1)
           </Original>
           <Expanded>
-            1.0 is within 1 ULPs of 1.0
+            1.0f is within 1 ULPs of 1.0f
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            nextafter(1., 0.), WithinULP(1., 1)
+            nextafter(1.f, 0.f), WithinULP(1.f, 1)
           </Original>
           <Expanded>
-            1.0 is within 1 ULPs of 1.0
+            1.0f is within 1 ULPs of 1.0f
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            nextafter(1., 2.), !WithinULP(1., 0)
+            nextafter(1.f, 2.f), !WithinULP(1.f, 0)
           </Original>
           <Expanded>
-            1.0 not is within 0 ULPs of 1.0
+            1.0f not is within 0 ULPs of 1.0f
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            1., WithinULP(1., 0)
+            1.f, WithinULP(1.f, 0)
           </Original>
           <Expanded>
-            1.0 is within 0 ULPs of 1.0
+            1.0f is within 0 ULPs of 1.0f
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            -0., WithinULP(0., 0)
+            -0.f, WithinULP(0.f, 0)
           </Original>
           <Expanded>
-            -0.0 is within 0 ULPs of 0.0
+            -0.0f is within 0 ULPs of 0.0f
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
@@ -2310,18 +3371,18 @@
       <Section name="Composed" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            1., WithinAbs(1., 0.5) || WithinULP(2., 1)
+            1.f, WithinAbs(1.f, 0.5) || WithinULP(1.f, 1)
           </Original>
           <Expanded>
-            1.0 ( is within 0.5 of 1.0 or is within 1 ULPs of 2.0 )
+            1.0f ( is within 0.5 of 1.0 or is within 1 ULPs of 1.0f )
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            1., WithinAbs(2., 0.5) || WithinULP(1., 0)
+            1.f, WithinAbs(2.f, 0.5) || WithinULP(1.f, 0)
           </Original>
           <Expanded>
-            1.0 ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0 )
+            1.0f ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0f )
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
@@ -2337,244 +3398,415 @@
       <Section name="Constructor validation" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
         <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            WithinAbs(1., 0.)
+            WithinAbs(1.f, 0.f)
           </Original>
           <Expanded>
-            WithinAbs(1., 0.)
+            WithinAbs(1.f, 0.f)
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            WithinAbs(1., -1.), std::domain_error
+            WithinAbs(1.f, -1.f), std::domain_error
           </Original>
           <Expanded>
-            WithinAbs(1., -1.), std::domain_error
+            WithinAbs(1.f, -1.f), std::domain_error
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            WithinULP(1., 0)
+            WithinULP(1.f, 0)
           </Original>
           <Expanded>
-            WithinULP(1., 0)
+            WithinULP(1.f, 0)
           </Expanded>
         </Expression>
         <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
           <Original>
-            WithinULP(1., -1), std::domain_error
+            WithinULP(1.f, -1), std::domain_error
           </Original>
           <Expanded>
-            WithinULP(1., -1), std::domain_error
+            WithinULP(1.f, -1), std::domain_error
           </Expanded>
         </Expression>
         <OverallResults successes="4" failures="0" expectedFailures="0"/>
       </Section>
       <OverallResult success="true"/>
     </TestCase>
-    <TestCase name="Floating point matchers: float" tags="[floating-point][matchers]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
-      <Section name="Margin" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+    <TestCase name="Generators" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+      <Section name="one" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "a"
+        </Info>
+        <Info>
+          j := 8
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="one" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "a"
+        </Info>
+        <Info>
+          j := 9
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="one" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "a"
+        </Info>
+        <Info>
+          j := 10
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="one" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "a"
+        </Info>
+        <Info>
+          j := 2
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="two" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "a"
+        </Info>
+        <Info>
+          j := 3.141
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="two" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "a"
+        </Info>
+        <Info>
+          j := 1.379
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="one" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "b"
+        </Info>
+        <Info>
+          j := 8
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="one" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "b"
+        </Info>
+        <Info>
+          j := 9
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="one" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "b"
+        </Info>
+        <Info>
+          j := 10
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="one" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "b"
+        </Info>
+        <Info>
+          j := 2
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="two" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "b"
+        </Info>
+        <Info>
+          j := 3.141
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="two" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "b"
+        </Info>
+        <Info>
+          j := 1.379
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="one" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "c"
+        </Info>
+        <Info>
+          j := 8
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="one" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "c"
+        </Info>
+        <Info>
+          j := 9
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="one" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "c"
+        </Info>
+        <Info>
+          j := 10
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="one" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "c"
+        </Info>
+        <Info>
+          j := 2
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="two" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "c"
+        </Info>
+        <Info>
+          j := 3.141
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="two" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Info>
+          i := "c"
+        </Info>
+        <Info>
+          j := 1.379
+        </Info>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <OverallResult success="true"/>
+    </TestCase>
+    <TestCase name="Generators impl" tags="[impl]" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+      <Section name="range" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            1.f, WithinAbs(1.f, 0)
+            gen.size() == 2
           </Original>
           <Expanded>
-            1.0f is within 0.0 of 1.0
+            2 == 2
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            0.f, WithinAbs(1.f, 1)
+            gen[0] == 1
           </Original>
           <Expanded>
-            0.0f is within 1.0 of 1.0
+            1 == 1
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            0.f, !WithinAbs(1.f, 0.99f)
+            gen[1] == 2
           </Original>
           <Expanded>
-            0.0f not is within 0.9900000095 of 1.0
+            2 == 2
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <OverallResults successes="3" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="fixed values" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            0.f, !WithinAbs(1.f, 0.99f)
+            gen.size() == 4
           </Original>
           <Expanded>
-            0.0f not is within 0.9900000095 of 1.0
+            4 == 4
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            0.f, WithinAbs(-0.f, 0)
+            gen[0] == 3
           </Original>
           <Expanded>
-            0.0f is within 0.0 of -0.0
+            3 == 3
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            NAN, !WithinAbs(NAN, 0)
+            gen[1] == 1
           </Original>
           <Expanded>
-            nanf not is within 0.0 of nan
+            1 == 1
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            11.f, !WithinAbs(10.f, 0.5f)
+            gen[2] == 4
           </Original>
           <Expanded>
-            11.0f not is within 0.5 of 10.0
+            4 == 4
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            10.f, !WithinAbs(11.f, 0.5f)
+            gen[3] == 1
           </Original>
           <Expanded>
-            10.0f not is within 0.5 of 11.0
+            1 == 1
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <OverallResults successes="5" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="combined" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            -10.f, WithinAbs(-10.f, 0.5f)
+            gen.size() == 4
           </Original>
           <Expanded>
-            -10.0f is within 0.5 of -10.0
+            4 == 4
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            -10.f, WithinAbs(-9.6f, 0.5f)
+            gen[0] == 1
           </Original>
           <Expanded>
-            -10.0f is within 0.5 of -9.6000003815
+            1 == 1
           </Expanded>
         </Expression>
-        <OverallResults successes="10" failures="0" expectedFailures="0"/>
-      </Section>
-      <Section name="ULPs" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            1.f, WithinULP(1.f, 0)
+            gen[1] == 2
           </Original>
           <Expanded>
-            1.0f is within 0 ULPs of 1.0f
+            2 == 2
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            nextafter(1.f, 2.f), WithinULP(1.f, 1)
+            gen[2] == 9
           </Original>
           <Expanded>
-            1.0f is within 1 ULPs of 1.0f
+            9 == 9
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            nextafter(1.f, 0.f), WithinULP(1.f, 1)
+            gen[3] == 7
           </Original>
           <Expanded>
-            1.0f is within 1 ULPs of 1.0f
+            7 == 7
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <OverallResults successes="5" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="values" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            nextafter(1.f, 2.f), !WithinULP(1.f, 0)
+            gen.size() == 2
           </Original>
           <Expanded>
-            1.0f not is within 0 ULPs of 1.0f
+            2 == 2
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            1.f, WithinULP(1.f, 0)
+            gen[0] == 3
           </Original>
           <Expanded>
-            1.0f is within 0 ULPs of 1.0f
+            3 == 3
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            -0.f, WithinULP(0.f, 0)
+            gen[1] == 1
           </Original>
           <Expanded>
-            -0.0f is within 0 ULPs of 0.0f
+            1 == 1
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <OverallResults successes="3" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="values2" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            NAN, !WithinULP(NAN, 123)
+            gen.size() == 2
           </Original>
           <Expanded>
-            nanf not is within 123 ULPs of nanf
+            2 == 2
           </Expanded>
         </Expression>
-        <OverallResults successes="7" failures="0" expectedFailures="0"/>
-      </Section>
-      <Section name="Composed" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            1.f, WithinAbs(1.f, 0.5) || WithinULP(1.f, 1)
+            gen[0] == 3
           </Original>
           <Expanded>
-            1.0f ( is within 0.5 of 1.0 or is within 1 ULPs of 1.0f )
+            3 == 3
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            1.f, WithinAbs(2.f, 0.5) || WithinULP(1.f, 0)
+            gen[1] == 1
           </Original>
           <Expanded>
-            1.0f ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0f )
+            1 == 1
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <OverallResults successes="3" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="type erasure" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123))
+            base->size() == 4
           </Original>
           <Expanded>
-            nanf not ( is within 100.0 of nan or is within 123 ULPs of nanf )
+            4 == 4
           </Expanded>
         </Expression>
-        <OverallResults successes="3" failures="0" expectedFailures="0"/>
-      </Section>
-      <Section name="Constructor validation" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
-        <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            WithinAbs(1.f, 0.f)
+            typed
           </Original>
           <Expanded>
-            WithinAbs(1.f, 0.f)
+            0x<hex digits>
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            WithinAbs(1.f, -1.f), std::domain_error
+            typed->size() == 4
           </Original>
           <Expanded>
-            WithinAbs(1.f, -1.f), std::domain_error
+            4 == 4
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            WithinULP(1.f, 0)
+            (*typed)[0] == 7
           </Original>
           <Expanded>
-            WithinULP(1.f, 0)
+            7 == 7
           </Expanded>
         </Expression>
-        <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/GeneratorsImpl.tests.cpp" >
           <Original>
-            WithinULP(1.f, -1), std::domain_error
+            (*typed)[3] == 11
           </Original>
           <Expanded>
-            WithinULP(1.f, -1), std::domain_error
+            11 == 11
           </Expanded>
         </Expression>
-        <OverallResults successes="4" failures="0" expectedFailures="0"/>
+        <OverallResults successes="5" failures="0" expectedFailures="0"/>
       </Section>
       <OverallResult success="true"/>
     </TestCase>
@@ -4650,17 +5882,6 @@
       </Section>
       <OverallResult success="true"/>
     </TestCase>
-    <TestCase name="Parsing a std::pair" tags="[Tricky][std::pair]" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
-      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Tricky.tests.cpp" >
-        <Original>
-          (std::pair&lt;int, int>( 1, 2 )) == aNicePair
-        </Original>
-        <Expanded>
-          {?} == {?}
-        </Expanded>
-      </Expression>
-      <OverallResult success="true"/>
-    </TestCase>
     <TestCase name="Pointers can be compared to null" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
         <Original>
@@ -4808,7 +6029,7 @@
         <OverallResults successes="7" failures="0" expectedFailures="0"/>
       </Section>
       <Section name="test lists" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
-        <Section name="1 test" description="Specify one test case using" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
+        <Section name="Specify one test case using" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
           <Expression success="true" type="CHECK" filename="projects/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
             <Original>
               result
@@ -5387,6 +6608,17 @@
       </Expression>
       <OverallResult success="false"/>
     </TestCase>
+    <TestCase name="Regression test #1" tags="[matchers][vector]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+      <Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" >
+        <Original>
+          actual, !UnorderedEquals(expected)
+        </Original>
+        <Expanded>
+          { 'a', 'b' } not UnorderedEquals: { 'c', 'b' }
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
     <TestCase name="SUCCEED counts as a test pass" tags="[messages]" filename="projects/<exe-name>/UsageTests/Message.tests.cpp" >
       <OverallResult success="true"/>
     </TestCase>
@@ -5423,26 +6655,29 @@
     </TestCase>
     <TestCase name="Scenario: Do that thing with the thing" tags="[Tags]" filename="projects/<exe-name>/UsageTests/BDD.tests.cpp" >
       <Section name="Given: This stuff exists" filename="projects/<exe-name>/UsageTests/BDD.tests.cpp" >
-        <Section name="When: I do this" filename="projects/<exe-name>/UsageTests/BDD.tests.cpp" >
-          <Section name="Then: it should do this" filename="projects/<exe-name>/UsageTests/BDD.tests.cpp" >
-            <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/BDD.tests.cpp" >
-              <Original>
-                itDoesThis()
-              </Original>
-              <Expanded>
-                true
-              </Expanded>
-            </Expression>
-            <Section name="And: do that" filename="projects/<exe-name>/UsageTests/BDD.tests.cpp" >
+        <Section name="And given: And some assumption" filename="projects/<exe-name>/UsageTests/BDD.tests.cpp" >
+          <Section name="When: I do this" filename="projects/<exe-name>/UsageTests/BDD.tests.cpp" >
+            <Section name="Then: it should do this" filename="projects/<exe-name>/UsageTests/BDD.tests.cpp" >
               <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/BDD.tests.cpp" >
                 <Original>
-                  itDoesThat()
+                  itDoesThis()
                 </Original>
                 <Expanded>
                   true
                 </Expanded>
               </Expression>
-              <OverallResults successes="1" failures="0" expectedFailures="0"/>
+              <Section name="And: do that" filename="projects/<exe-name>/UsageTests/BDD.tests.cpp" >
+                <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/BDD.tests.cpp" >
+                  <Original>
+                    itDoesThat()
+                  </Original>
+                  <Expanded>
+                    true
+                  </Expanded>
+                </Expression>
+                <OverallResults successes="1" failures="0" expectedFailures="0"/>
+              </Section>
+              <OverallResults successes="2" failures="0" expectedFailures="0"/>
             </Section>
             <OverallResults successes="2" failures="0" expectedFailures="0"/>
           </Section>
@@ -5591,6 +6826,22 @@ A string sent to stderr via clog
           1.23 != Approx( 1.24 )
         </Expanded>
       </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          d == 1.23_a
+        </Original>
+        <Expanded>
+          1.23 == Approx( 1.23 )
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
+        <Original>
+          d != 1.22_a
+        </Original>
+        <Expanded>
+          1.23 != Approx( 1.22 )
+        </Expanded>
+      </Expression>
       <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Approx.tests.cpp" >
         <Original>
           Approx( d ) == 1.23
@@ -8691,7 +9942,7 @@ loose text artifact
       <OverallResult success="true"/>
     </TestCase>
     <TestCase name="looped SECTION tests" tags="[.][failing][sections]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
-      <Section name="s1" description="b is currently: 0" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Section name="b is currently: 0" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Expression success="false" type="CHECK" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Original>
             b > a
@@ -8702,6 +9953,105 @@ loose text artifact
         </Expression>
         <OverallResults successes="0" failures="1" expectedFailures="0"/>
       </Section>
+      <Section name="b is currently: 1" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="false" type="CHECK" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            b > a
+          </Original>
+          <Expanded>
+            1 > 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="0" failures="1" expectedFailures="0"/>
+      </Section>
+      <Section name="b is currently: 2" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            b > a
+          </Original>
+          <Expanded>
+            2 > 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="b is currently: 3" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            b > a
+          </Original>
+          <Expanded>
+            3 > 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="b is currently: 4" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            b > a
+          </Original>
+          <Expanded>
+            4 > 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="b is currently: 5" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            b > a
+          </Original>
+          <Expanded>
+            5 > 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="b is currently: 6" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            b > a
+          </Original>
+          <Expanded>
+            6 > 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="b is currently: 7" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            b > a
+          </Original>
+          <Expanded>
+            7 > 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="b is currently: 8" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            b > a
+          </Original>
+          <Expanded>
+            8 > 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
+      <Section name="b is currently: 9" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Expression success="true" type="CHECK" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+          <Original>
+            b > a
+          </Original>
+          <Expanded>
+            9 > 1
+          </Expanded>
+        </Expression>
+        <OverallResults successes="1" failures="0" expectedFailures="0"/>
+      </Section>
       <OverallResult success="false"/>
     </TestCase>
     <TestCase name="looped tests" tags="[.][failing]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
@@ -8796,8 +10146,8 @@ loose text artifact
       <OverallResult success="false"/>
     </TestCase>
     <TestCase name="more nested SECTION tests" tags="[.][failing][sections]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
-      <Section name="s1" description="doesn't equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
-        <Section name="s2" description="equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Section name="doesn't equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Section name="equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Expression success="false" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
             <Original>
               a == b
@@ -8810,8 +10160,8 @@ loose text artifact
         </Section>
         <OverallResults successes="0" failures="1" expectedFailures="0"/>
       </Section>
-      <Section name="s1" description="doesn't equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
-        <Section name="s3" description="not equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Section name="doesn't equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Section name="not equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
             <Original>
               a != b
@@ -8824,8 +10174,8 @@ loose text artifact
         </Section>
         <OverallResults successes="1" failures="0" expectedFailures="0"/>
       </Section>
-      <Section name="s1" description="doesn't equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
-        <Section name="s4" description="less than" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Section name="doesn't equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Section name="less than" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
             <Original>
               a &lt; b
@@ -8841,7 +10191,7 @@ loose text artifact
       <OverallResult success="false"/>
     </TestCase>
     <TestCase name="nested SECTION tests" tags="[.][failing][sections]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
-      <Section name="s1" description="doesn't equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Section name="doesn't equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Original>
             a != b
@@ -8858,7 +10208,7 @@ loose text artifact
             2 != 1
           </Expanded>
         </Expression>
-        <Section name="s2" description="not equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+        <Section name="not equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
             <Original>
               a != b
@@ -8953,7 +10303,7 @@ loose text artifact
       <OverallResult success="true"/>
     </TestCase>
     <TestCase name="random SECTION tests" tags="[.][failing][sections]" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
-      <Section name="s1" description="doesn't equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Section name="doesn't equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Original>
             a != b
@@ -8972,7 +10322,7 @@ loose text artifact
         </Expression>
         <OverallResults successes="2" failures="0" expectedFailures="0"/>
       </Section>
-      <Section name="s2" description="not equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Section name="not equal" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
           <Original>
             a != b
@@ -9418,6 +10768,41 @@ loose text artifact
       </Expression>
       <OverallResult success="true"/>
     </TestCase>
+    <TestCase name="strlen3" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          data.str.size() == data.len
+        </Original>
+        <Expanded>
+          3 == 3
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          data.str.size() == data.len
+        </Original>
+        <Expanded>
+          3 == 3
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          data.str.size() == data.len
+        </Original>
+        <Expanded>
+          5 == 5
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          data.str.size() == data.len
+        </Original>
+        <Expanded>
+          4 == 4
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
     <TestCase name="thrown std::strings are translated" tags="[!throws][.][failing]" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
       <Exception filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
         Why would you throw a std::string?
@@ -9928,15 +11313,15 @@ loose text artifact
       <OverallResult success="true"/>
     </TestCase>
     <TestCase name="xmlentitycheck" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
-      <Section name="embedded xml" description="&lt;test>it should be possible to embed xml characters, such as &lt;, &quot; or &amp;, or even whole &lt;xml>documents&lt;/xml> within an attribute&lt;/test>" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Section name="embedded xml: &lt;test>it should be possible to embed xml characters, such as &lt;, &quot; or &amp;, or even whole &lt;xml>documents&lt;/xml> within an attribute&lt;/test>" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <OverallResults successes="1" failures="0" expectedFailures="0"/>
       </Section>
-      <Section name="encoded chars" description="these should all be encoded: &amp;&amp;&amp;&quot;&quot;&quot;&lt;&lt;&lt;&amp;&quot;&lt;&lt;&amp;&quot;" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
+      <Section name="encoded chars: these should all be encoded: &amp;&amp;&amp;&quot;&quot;&quot;&lt;&lt;&lt;&amp;&quot;&lt;&lt;&amp;&quot;" filename="projects/<exe-name>/UsageTests/Misc.tests.cpp" >
         <OverallResults successes="1" failures="0" expectedFailures="0"/>
       </Section>
       <OverallResult success="true"/>
     </TestCase>
-    <OverallResults successes="937" failures="122" expectedFailures="21"/>
+    <OverallResults successes="1099" failures="123" expectedFailures="21"/>
   </Group>
-  <OverallResults successes="937" failures="121" expectedFailures="21"/>
+  <OverallResults successes="1099" failures="122" expectedFailures="21"/>
 </Catch>
diff --git a/packages/Catch2/projects/SelfTest/IntrospectiveTests/CmdLine.tests.cpp b/packages/Catch2/projects/SelfTest/IntrospectiveTests/CmdLine.tests.cpp
index 1da3fa08412b41680b00db8856591209ed68e786..cb635eade97a2ffab998cbcf059081b3e665469e 100644
--- a/packages/Catch2/projects/SelfTest/IntrospectiveTests/CmdLine.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/IntrospectiveTests/CmdLine.tests.cpp
@@ -295,7 +295,7 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]"
     }
 
     SECTION("test lists") {
-        SECTION("1 test", "Specify one test case using") {
+        SECTION("Specify one test case using") {
             auto result = cli.parse({"test", "test1"});
             CHECK(result);
 
diff --git a/packages/Catch2/projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp b/packages/Catch2/projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b3074b2e178ebbceb584a8dbca599a92379d76b9
--- /dev/null
+++ b/packages/Catch2/projects/SelfTest/IntrospectiveTests/GeneratorsImpl.tests.cpp
@@ -0,0 +1,93 @@
+#include "catch.hpp"
+
+// Tests of generartor implementation details
+
+TEST_CASE("Generators impl", "[impl]") {
+    using namespace Catch::Generators;
+
+    SECTION( "range" ) {
+        auto gen = range(1,3);
+
+        CHECK( gen.size() == 2 );
+
+        CHECK( gen[0] == 1 );
+        CHECK( gen[1] == 2 );
+    }
+    SECTION( "fixed values" ) {
+        auto gen = values( { 3, 1, 4, 1 } );
+
+        CHECK( gen.size() == 4 );
+        CHECK( gen[0] == 3 );
+        CHECK( gen[1] == 1 );
+        CHECK( gen[2] == 4 );
+        CHECK( gen[3] == 1 );
+    }
+    SECTION( "combined" ) {
+        auto gen = makeGenerators( range( 1, 3 ), values( { 9, 7 } ) );
+
+        CHECK( gen.size() == 4 );
+        CHECK( gen[0] == 1 );
+        CHECK( gen[1] == 2 );
+        CHECK( gen[2] == 9 );
+        CHECK( gen[3] == 7 );
+    }
+
+    SECTION( "values" ) {
+        auto gen = makeGenerators( 3, 1 );
+
+        CHECK( gen.size() == 2 );
+        CHECK( gen[0] == 3 );
+        CHECK( gen[1] == 1 );
+    }
+    SECTION( "values2" ) {
+        auto gen = makeGenerators( 3, 1 );
+
+        CHECK( gen.size() == 2 );
+        CHECK( gen[0] == 3 );
+        CHECK( gen[1] == 1 );
+    }
+
+
+    SECTION( "type erasure" ) {
+        auto gen = makeGenerators( range( 7, 10 ), 11 );
+
+        // Make type erased version
+        auto dynCopy = pf::make_unique<Generators<int>>( std::move( gen ) );
+        std::unique_ptr<GeneratorBase const> base = std::move( dynCopy );
+
+        // Only thing we can do is ask for the size
+        CHECK( base->size() == 4 );
+
+        // Restore typed version
+        auto typed = dynamic_cast<Generators<int> const*>( base.get() );
+        REQUIRE( typed );
+        CHECK( typed->size() == 4 );
+        CHECK( (*typed)[0] == 7 );
+        CHECK( (*typed)[3] == 11 );
+    }
+}
+
+TEST_CASE("Generators impl - random", "[approvals]") {
+    using namespace Catch::Generators;
+
+    SECTION( "random range" ) {
+        auto gen = random( 3, 9 );
+
+        CHECK( gen.size() == 6 );
+        for( size_t i = 0; i < 6; ++i ) {
+            CHECK( gen[i] >= 3 );
+            CHECK( gen[i] <= 8 );
+            if( i > 0 )
+                CHECK( gen[i] != gen[i-1] );
+        }
+    }
+    SECTION( "random selection" ) {
+        auto gen = random<int>( 10 );
+
+        CHECK( gen.size() == 10 );
+        for( size_t i = 0; i < 10; ++i ) {
+            if( i > 0 )
+                CHECK( gen[i] != gen[i-1] );
+        }
+    }
+}
diff --git a/packages/Catch2/projects/SelfTest/IntrospectiveTests/PartTracker.tests.cpp b/packages/Catch2/projects/SelfTest/IntrospectiveTests/PartTracker.tests.cpp
index 042c03a71aa8b1280dfbb3fc5419d96c20145b19..7e7f14b457d71cd0f867fd3bd0bbdea6975b1ff9 100644
--- a/packages/Catch2/projects/SelfTest/IntrospectiveTests/PartTracker.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/IntrospectiveTests/PartTracker.tests.cpp
@@ -21,24 +21,17 @@ namespace Catch
 
 } // namespace Catch
 
-inline Catch::TrackerContext& C_A_T_C_H_Context() {
-    return Catch::TrackerContext::instance();
-}
-
 // -------------------
 
 #include "catch.hpp"
 
 using namespace Catch;
 
-//inline void testCase( Catch::LocalContext const& C_A_T_C_H_Context ) {
-//
-//    REQUIRE( C_A_T_C_H_Context().i() == 42 );
-//}
-
+namespace {
 Catch::TestCaseTracking::NameAndLocation makeNAL( std::string const& name ) {
     return Catch::TestCaseTracking::NameAndLocation( name, Catch::SourceLineInfo("",0) );
 }
+}
 
 TEST_CASE( "Tracker" ) {
 
diff --git a/packages/Catch2/projects/SelfTest/IntrospectiveTests/String.tests.cpp b/packages/Catch2/projects/SelfTest/IntrospectiveTests/String.tests.cpp
index ee6e4c58e8c2effe590265aa3c528c551924bc3e..ae21bb3ce8274321a1112e0f54d505be483b3e53 100644
--- a/packages/Catch2/projects/SelfTest/IntrospectiveTests/String.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/IntrospectiveTests/String.tests.cpp
@@ -16,23 +16,22 @@ namespace Catch {
         }
     };
 
+
+    namespace {
     auto isOwned( StringRef const& stringRef ) -> bool {
         return StringRefTestAccess::isOwned( stringRef );
     }
     auto isSubstring( StringRef const& stringRef ) -> bool {
         return StringRefTestAccess::isSubstring( stringRef );
     }
-} // namespace Catch2
+    } // end anonymous namespace
 
-namespace Catch {
-    inline auto toString( Catch::StringRef const& stringRef ) -> std::string {
-        return std::string( stringRef.currentData(), stringRef.size() );
-    }
 } // namespace Catch
 
 TEST_CASE( "StringRef", "[Strings][StringRef]" ) {
 
     using Catch::StringRef;
+    using Catch::isOwned; using Catch::isSubstring;
 
     SECTION( "Empty string" ) {
         StringRef empty;
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/Approx.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/Approx.tests.cpp
index 5930075d124c627dfd8eb67723ee2566f503cb0d..b95394a06b065c640a6e624373a9bea59d4f10df 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/Approx.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/Approx.tests.cpp
@@ -33,8 +33,21 @@ namespace { namespace ApproxTests {
 
 #endif
 
+using namespace Catch::literals;
 
 ///////////////////////////////////////////////////////////////////////////////
+TEST_CASE( "A comparison that uses literals instead of the normal constructor", "[Approx]" ) {
+    double d = 1.23;
+
+    REQUIRE( d == 1.23_a );
+    REQUIRE( d != 1.22_a );
+    REQUIRE( -d == -1.23_a );
+
+    REQUIRE( d == 1.2_a .epsilon(.1) );
+    REQUIRE( d != 1.2_a .epsilon(.001) );
+    REQUIRE( d == 1_a .epsilon(.3) );
+}
+
 TEST_CASE( "Some simple comparisons between doubles", "[Approx]" ) {
     double d = 1.23;
 
@@ -42,6 +55,9 @@ TEST_CASE( "Some simple comparisons between doubles", "[Approx]" ) {
     REQUIRE( d != Approx( 1.22 ) );
     REQUIRE( d != Approx( 1.24 ) );
 
+    REQUIRE( d == 1.23_a );
+    REQUIRE( d != 1.22_a );
+
     REQUIRE( Approx( d ) == 1.23 );
     REQUIRE( Approx( d ) != 1.22 );
     REQUIRE( Approx( d ) != 1.24 );
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/BDD.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/BDD.tests.cpp
index f43fd96dc2ba5099984a57fd5f85f8a2685b5a98..d0d3e0387826c91389773aa21b882cc332ccef49 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/BDD.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/BDD.tests.cpp
@@ -38,11 +38,14 @@ namespace { namespace BDDTests {
     SCENARIO("Do that thing with the thing", "[Tags]") {
         GIVEN("This stuff exists") {
             // make stuff exist
-            WHEN("I do this") {
-                // do this
-                THEN("it should do this") {
-                    REQUIRE(itDoesThis());
-                    AND_THEN("do that")REQUIRE(itDoesThat());
+            AND_GIVEN("And some assumption") {
+                // Validate assumption
+                WHEN("I do this") {
+                    // do this
+                    THEN("it should do this") {
+                        REQUIRE(itDoesThis());
+                        AND_THEN("do that")REQUIRE(itDoesThat());
+                    }
                 }
             }
         }
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/Decomposition.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/Decomposition.tests.cpp
index 1b44b602ee04fea4a477bde687a2919f86a80c44..5bb19cd6d3a3526337c0895b694ec9799978ee19 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/Decomposition.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/Decomposition.tests.cpp
@@ -9,6 +9,8 @@
 #include <iostream>
 #include <cstdio>
 
+namespace {
+
 struct truthy {
     truthy(bool b):m_value(b){}
     operator bool() const {
@@ -22,6 +24,8 @@ std::ostream& operator<<(std::ostream& o, truthy) {
     return o;
 }
 
+} // end anonymous namespace
+
 #include "catch.hpp"
 
 TEST_CASE( "Reconstruction should be based on stringification: #914" , "[Decomposition][failing][.]") {
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/EnumToString.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/EnumToString.tests.cpp
index 7d18a292cdb76ac214d130616552f31d87963d81..0b188a8262d0410d8fa97e34730bc23ec1451fce 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/EnumToString.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/EnumToString.tests.cpp
@@ -1,22 +1,24 @@
 #include "catch.hpp"
 
 
+namespace {
 // Enum without user-provided stream operator
 enum Enum1 { Enum1Value0, Enum1Value1 };
 
-TEST_CASE( "toString(enum)", "[toString][enum]" ) {
-    Enum1 e0 = Enum1Value0;
-    CHECK( ::Catch::Detail::stringify(e0) == "0" );
-    Enum1 e1 = Enum1Value1;
-    CHECK( ::Catch::Detail::stringify(e1) == "1" );
-}
-
 // Enum with user-provided stream operator
 enum Enum2 { Enum2Value0, Enum2Value1 };
 
 std::ostream& operator<<( std::ostream& os, Enum2 v ) {
     return os << "E2{" << static_cast<int>(v) << "}";
 }
+} // end anonymous namespace
+
+TEST_CASE( "toString(enum)", "[toString][enum]" ) {
+    Enum1 e0 = Enum1Value0;
+    CHECK( ::Catch::Detail::stringify(e0) == "0" );
+    Enum1 e1 = Enum1Value1;
+    CHECK( ::Catch::Detail::stringify(e1) == "1" );
+}
 
 TEST_CASE( "toString(enum w/operator<<)", "[toString][enum]" ) {
     Enum2 e0 = Enum2Value0;
@@ -26,17 +28,11 @@ TEST_CASE( "toString(enum w/operator<<)", "[toString][enum]" ) {
 }
 
 // Enum class without user-provided stream operator
+namespace {
 enum class EnumClass1 { EnumClass1Value0, EnumClass1Value1 };
 
-TEST_CASE( "toString(enum class)", "[toString][enum][enumClass]" ) {
-    EnumClass1 e0 = EnumClass1::EnumClass1Value0;
-    CHECK( ::Catch::Detail::stringify(e0) == "0" );
-    EnumClass1 e1 = EnumClass1::EnumClass1Value1;
-    CHECK( ::Catch::Detail::stringify(e1) == "1" );
-}
-
 // Enum class with user-provided stream operator
-enum class EnumClass2 : short { EnumClass2Value0, EnumClass2Value1 };
+enum class EnumClass2 { EnumClass2Value0, EnumClass2Value1 };
 
 std::ostream& operator<<( std::ostream& os, EnumClass2 e2 ) {
     switch( static_cast<int>( e2 ) ) {
@@ -49,6 +45,16 @@ std::ostream& operator<<( std::ostream& os, EnumClass2 e2 ) {
     }
 }
 
+} // end anonymous namespace
+
+TEST_CASE( "toString(enum class)", "[toString][enum][enumClass]" ) {
+    EnumClass1 e0 = EnumClass1::EnumClass1Value0;
+    CHECK( ::Catch::Detail::stringify(e0) == "0" );
+    EnumClass1 e1 = EnumClass1::EnumClass1Value1;
+    CHECK( ::Catch::Detail::stringify(e1) == "1" );
+}
+
+
 TEST_CASE( "toString(enum class w/operator<<)", "[toString][enum][enumClass]" ) {
     EnumClass2 e0 = EnumClass2::EnumClass2Value0;
     CHECK( ::Catch::Detail::stringify(e0) == "E2/V0" );
@@ -58,4 +64,3 @@ TEST_CASE( "toString(enum class w/operator<<)", "[toString][enum][enumClass]" )
     EnumClass2 e3 = static_cast<EnumClass2>(10);
     CHECK( ::Catch::Detail::stringify(e3) == "Unknown enum value 10" );
 }
-
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/Exception.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/Exception.tests.cpp
index f9c73ed5380cc989f84d34358c3ae3843a034ae9..9c198dfbd1bc8b6395e98cec283c6673b007dd36 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/Exception.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/Exception.tests.cpp
@@ -18,6 +18,7 @@
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wweak-vtables"
 #pragma clang diagnostic ignored "-Wmissing-noreturn"
+#pragma clang diagnostic ignored "-Wunreachable-code"
 #endif
 
 namespace { namespace ExceptionTests {
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/Generators.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/Generators.tests.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9242174a8a81be74f93176a8ba746ef0f89aeb28
--- /dev/null
+++ b/packages/Catch2/projects/SelfTest/UsageTests/Generators.tests.cpp
@@ -0,0 +1,134 @@
+#include "catch.hpp"
+
+// Examples of usage of Generators
+
+// This test doesn't do much - it just shows how you can have several generators, of different
+// types (ie `i` and `j` are different types), can be sequenced using `,` and
+// can be expressed as named generators (like range) or as individual values.
+// Generators can be mixed with SECTIONs.
+// At time of writing the generated values are not automatically reported as part of the test
+// name or associated values - so we explicitly CAPTURE then (run this with `-s` to see them).
+// We could also incorporate them into the section names using DYNAMIC_SECTION. See the BDD
+// example later for more information.
+TEST_CASE("Generators") {
+
+    auto i = GENERATE( as<std::string>(), "a", "b", "c" );
+
+    SECTION( "one" ) {
+        auto j = GENERATE( range( 8, 11 ), 2 );
+
+        CAPTURE( i, j );
+        SUCCEED();
+    }
+    SECTION( "two" ) {
+        auto j = GENERATE( 3.141, 1.379 );
+        CAPTURE( i, j );
+        SUCCEED();
+    }
+}
+
+// This one generates the cross-product of two ranges.
+// It's mostly here to demonstrate the performance which, at time of writing,
+// leaves a lot to be desired.
+TEST_CASE( "100x100 ints", "[.][approvals]" ) {
+    auto x = GENERATE( range( 0,100 ) );
+    auto y = GENERATE( range( 200,300 ) );
+
+    CHECK( x < y );
+}
+
+// smaller version
+TEST_CASE( "10x10 ints" ) {
+    auto x = GENERATE( range( 1,11 ) );
+    auto y = GENERATE( range( 101, 111 ) );
+
+    CHECK( x < y );
+}
+
+// Some of the following tests use structured bindings for convenience and so are
+// conditionally compiled using the de-facto (and soon to be formally) standard
+// feature macros
+
+#ifdef __cpp_structured_bindings
+
+// One way to do pairs of values (actual/ expected?)
+// For a simple case like this I'd recommend writing out a series of REQUIREs
+// but it demonstrates a possible usage.
+// Spelling out the pair like this is a bit verbose, so read on for better examples
+// - the use of structured bindings here is an optional convenience
+TEST_CASE( "strlen", "[approvals]" ) {
+    auto [test_input, expected] = GENERATE( values<std::pair<std::string_view, size_t>>({
+            {"one", 3},
+            {"two", 3},
+            {"three", 5},
+            {"four", 4}
+        }));
+
+    REQUIRE( test_input.size() == expected );
+}
+
+// A nicer way to do pairs (or more) of values - using the table generator.
+// Note, you must specify the types up-front.
+TEST_CASE( "strlen2", "[approvals]" ) {
+    auto [test_input, expected] = GENERATE( table<std::string, size_t>({
+            {"one", 3},
+            {"two", 3},
+            {"three", 5},
+            {"four", 4}
+        }));
+
+    REQUIRE( test_input.size() == expected );
+}
+#endif
+
+// An alternate way of doing data tables without structure bindings
+// - I'd prefer to have the Data class within the test case but gcc 4.x doesn't seem to like it
+struct Data { std::string str; size_t len; };
+
+TEST_CASE( "strlen3" ) {
+    auto data = GENERATE( values<Data>({
+            {"one", 3},
+            {"two", 3},
+            {"three", 5},
+            {"four", 4}
+        }));
+
+    REQUIRE( data.str.size() == data.len );
+}
+
+// A nod towards property-based testing - generate a random selection of numbers
+// in a range and assert on global properties those numbers.
+static auto square( int i ) -> int { return i*i; }
+
+TEST_CASE( "Random numbers in a range", "[.][approvals]" ) {
+    auto x = GENERATE( random( -10000, 10000 ) );
+    CAPTURE( x );
+    REQUIRE( square(x) >= 0 );
+}
+
+#ifdef __cpp_structured_bindings
+
+// Based on example from https://docs.cucumber.io/gherkin/reference/#scenario-outline
+// (thanks to https://github.com/catchorg/Catch2/issues/850#issuecomment-399504851)
+
+// Note that GIVEN, WHEN, and THEN now forward onto DYNAMIC_SECTION instead of SECTION.
+// DYNAMIC_SECTION takes its name as a stringstream-style expression, so can be formatted using
+// variables in scope - such as the generated variables here. This reads quite nicely in the
+// test name output (the full scenario description).
+
+static auto eatCucumbers( int start, int eat ) -> int { return start-eat; }
+
+SCENARIO("Eating cucumbers", "[approvals]") {
+
+    auto [start, eat, left] = GENERATE( table<int,int,int> ({
+            { 12, 5, 7 },
+            { 20, 5, 15 }
+        }));
+
+    GIVEN( "there are " << start << " cucumbers" )
+    WHEN( "I eat " << eat << " cucumbers" )
+    THEN( "I should have " << left << " cucumbers" ) {
+        REQUIRE( eatCucumbers( start, eat ) == left );
+    }
+}
+#endif
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/Matchers.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/Matchers.tests.cpp
index 71abb8688dbeb3400e3710b621c6f3ee98d0bc97..e09dad14e3cf18dad3e035438cfd70c6d1869a18 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/Matchers.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/Matchers.tests.cpp
@@ -423,6 +423,15 @@ namespace { namespace MatchersTests {
             }
         }
 
+        TEST_CASE("Regression test #1", "[matchers][vector]") {
+            // At some point, UnorderedEqualsMatcher skipped
+            // mismatched prefixed before doing the comparison itself
+            std::vector<char> actual = { 'a', 'b' };
+            std::vector<char> expected = { 'c', 'b' };
+
+            CHECK_THAT(actual, !UnorderedEquals(expected));
+        }
+
 } } // namespace MatchersTests
 
 #endif // CATCH_CONFIG_DISABLE_MATCHERS
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/Misc.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/Misc.tests.cpp
index e5059e9f4d6cada84ce3220b49af2df5d48764f7..820e801976939b609815849dc46bf8b8f72fec78 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/Misc.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/Misc.tests.cpp
@@ -67,12 +67,12 @@ TEST_CASE( "random SECTION tests", "[.][sections][failing]" ) {
     int a = 1;
     int b = 2;
 
-    SECTION( "s1", "doesn't equal" ) {
+    SECTION( "doesn't equal" ) {
         REQUIRE( a != b );
         REQUIRE( b != a );
     }
 
-    SECTION( "s2", "not equal" ) {
+    SECTION( "not equal" ) {
         REQUIRE( a != b);
     }
 }
@@ -81,11 +81,11 @@ TEST_CASE( "nested SECTION tests", "[.][sections][failing]" ) {
     int a = 1;
     int b = 2;
 
-    SECTION( "s1", "doesn't equal" ) {
+    SECTION( "doesn't equal" ) {
         REQUIRE( a != b );
         REQUIRE( b != a );
 
-        SECTION( "s2", "not equal" ) {
+        SECTION( "not equal" ) {
             REQUIRE( a != b);
         }
     }
@@ -95,15 +95,15 @@ TEST_CASE( "more nested SECTION tests", "[sections][failing][.]" ) {
     int a = 1;
     int b = 2;
 
-    SECTION( "s1", "doesn't equal" ) {
-        SECTION( "s2", "equal" ) {
+    SECTION( "doesn't equal" ) {
+        SECTION( "equal" ) {
             REQUIRE( a == b );
         }
 
-        SECTION( "s3", "not equal" ) {
+        SECTION( "not equal" ) {
             REQUIRE( a != b );
         }
-        SECTION( "s4", "less than" ) {
+        SECTION( "less than" ) {
             REQUIRE( a < b );
         }
     }
@@ -112,16 +112,16 @@ TEST_CASE( "more nested SECTION tests", "[sections][failing][.]" ) {
 TEST_CASE( "even more nested SECTION tests", "[sections]" ) {
     SECTION( "c" ) {
         SECTION( "d (leaf)" ) {
-            SUCCEED(""); // avoid failing due to no tests
+            SUCCEED(); // avoid failing due to no tests
         }
 
         SECTION( "e (leaf)" ) {
-            SUCCEED(""); // avoid failing due to no tests
+            SUCCEED(); // avoid failing due to no tests
         }
     }
 
     SECTION( "f (leaf)" ) {
-        SUCCEED(""); // avoid failing due to no tests
+        SUCCEED(); // avoid failing due to no tests
     }
 }
 
@@ -129,9 +129,7 @@ TEST_CASE( "looped SECTION tests", "[.][failing][sections]" ) {
     int a = 1;
 
     for( int b = 0; b < 10; ++b ) {
-        std::ostringstream oss;
-        oss << "b is currently: " << b;
-        SECTION( "s1", oss.str() ) {
+        DYNAMIC_SECTION( "b is currently: " << b ) {
             CHECK( b > a );
         }
     }
@@ -174,11 +172,11 @@ TEST_CASE( "checkedElse, failing", "[failing][.]" ) {
 }
 
 TEST_CASE( "xmlentitycheck" ) {
-    SECTION( "embedded xml", "<test>it should be possible to embed xml characters, such as <, \" or &, or even whole <xml>documents</xml> within an attribute</test>" ) {
-        SUCCEED(""); // We need this here to stop it failing due to no tests
+    SECTION( "embedded xml: <test>it should be possible to embed xml characters, such as <, \" or &, or even whole <xml>documents</xml> within an attribute</test>" ) {
+        SUCCEED(); // We need this here to stop it failing due to no tests
     }
-    SECTION( "encoded chars", "these should all be encoded: &&&\"\"\"<<<&\"<<&\"" ) {
-        SUCCEED(""); // We need this here to stop it failing due to no tests
+    SECTION( "encoded chars: these should all be encoded: &&&\"\"\"<<<&\"<<&\"" ) {
+        SUCCEED(); // We need this here to stop it failing due to no tests
     }
 }
 
@@ -265,8 +263,8 @@ TEST_CASE( "vectors can be sized and resized", "[vector]" ) {
 
 // https://github.com/philsquared/Catch/issues/166
 TEST_CASE("A couple of nested sections followed by a failure", "[failing][.]") {
-    SECTION("Outer", "")
-        SECTION("Inner", "")
+    SECTION("Outer")
+        SECTION("Inner")
             SUCCEED("that's not flying - that's failing in style");
 
     FAIL("to infinity and beyond");
@@ -274,7 +272,7 @@ TEST_CASE("A couple of nested sections followed by a failure", "[failing][.]") {
 
 TEST_CASE("not allowed", "[!throws]") {
     // This test case should not be included if you run with -e on the command line
-    SUCCEED( "" );
+    SUCCEED();
 }
 
 //TEST_CASE( "Is big endian" ) {
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/ToStringGeneral.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/ToStringGeneral.tests.cpp
index a1f8c233a25e3d386410470ed08ffff7ba05c844..acddf223822a590a61f9eb285e87711214afe292 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/ToStringGeneral.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/ToStringGeneral.tests.cpp
@@ -116,6 +116,20 @@ TEST_CASE("Static arrays are convertible to string", "[toString]") {
     }
 }
 
+#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
+
+TEST_CASE("String views are stringified like other strings", "[toString][approvals]") {
+    std::string_view view{"abc"};
+    CHECK(Catch::Detail::stringify(view) == R"("abc")");
+
+    std::string_view arr[] { view };
+    CHECK(Catch::Detail::stringify(arr) == R"({ "abc" })");
+}
+
+#endif
+
+namespace {
+
 struct WhatException : std::exception {
     char const* what() const noexcept override {
         return "This exception has overriden what() method";
@@ -136,6 +150,8 @@ struct StringMakerException : std::exception {
     ~StringMakerException() override;
 };
 
+} // end anonymous namespace
+
 namespace Catch {
 template <>
 struct StringMaker<StringMakerException> {
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/ToStringVariant.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/ToStringVariant.tests.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..62f923f06382584185cd60bf40996dd2133ae6d5
--- /dev/null
+++ b/packages/Catch2/projects/SelfTest/UsageTests/ToStringVariant.tests.cpp
@@ -0,0 +1,84 @@
+#define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
+#include "catch.hpp"
+
+#if defined(CATCH_CONFIG_CPP17_VARIANT)
+
+#include <string>
+#include <variant>
+
+TEST_CASE( "variant<std::monostate>", "[toString][variant][approvals]")
+{
+    using type = std::variant<std::monostate>;
+    CHECK( "{ }" == ::Catch::Detail::stringify(type{}) );
+    type value {};
+    CHECK( "{ }" == ::Catch::Detail::stringify(value) );
+    CHECK( "{ }" == ::Catch::Detail::stringify(std::get<0>(value)) );
+}
+
+TEST_CASE( "variant<int>", "[toString][variant][approvals]")
+{
+    using type = std::variant<int>;
+    CHECK( "0" == ::Catch::Detail::stringify(type{0}) );
+}
+
+TEST_CASE( "variant<float, int>", "[toString][variant][approvals]")
+{
+    using type = std::variant<float, int>;
+    CHECK( "0.5f" == ::Catch::Detail::stringify(type{0.5f}) );
+    CHECK( "0" == ::Catch::Detail::stringify(type{0}) );
+
+    SECTION("valueless by exception") {
+        struct sample {
+            operator int() const { throw 42; }
+        };
+
+        type value{1.5f};
+        REQUIRE_THROWS_AS( value.emplace<int>(sample{}), int );
+        REQUIRE( value.valueless_by_exception() );
+        CHECK( "{valueless variant}" == ::Catch::Detail::stringify(value) );
+    }
+}
+
+TEST_CASE( "variant<string, int>", "[toString][variant][approvals]")
+{
+    using type = std::variant<std::string, int>;
+    CHECK( "\"foo\"" == ::Catch::Detail::stringify(type{"foo"}) );
+    CHECK( "0" == ::Catch::Detail::stringify(type{0}) );
+}
+
+TEST_CASE( "variant<variant<float, int>, string>", "[toString][variant][approvals]")
+{
+    using inner = std::variant<float, int>;
+    using type = std::variant<inner, std::string>;
+    CHECK( "0.5f" == ::Catch::Detail::stringify(type{0.5f}) );
+    CHECK( "0" == ::Catch::Detail::stringify(type{0}) );
+    CHECK( "\"foo\"" == ::Catch::Detail::stringify(type{"foo"}) );
+
+    struct sample {
+        operator int() const { throw 42; }
+    };
+
+    SECTION("valueless nested variant") {
+        type value = inner{0.5f};
+        REQUIRE( std::holds_alternative<inner>(value) );
+        REQUIRE( std::holds_alternative<float>(std::get<inner>(value)) );
+
+        REQUIRE_THROWS_AS( std::get<0>(value).emplace<int>(sample{}), int );
+
+        // outer variant is still valid and contains inner
+        REQUIRE( std::holds_alternative<inner>(value) );
+        // inner variant is valueless
+        REQUIRE( std::get<inner>(value).valueless_by_exception() );
+        CHECK( "{valueless variant}" == ::Catch::Detail::stringify(value) );
+    }
+}
+
+TEST_CASE( "variant<nullptr,int,const char *>", "[toString][variant][approvals]" )
+{
+    using type = std::variant<std::nullptr_t,int,const char *>;
+    CHECK( "nullptr" == ::Catch::Detail::stringify(type{nullptr}) );
+    CHECK( "42" == ::Catch::Detail::stringify(type{42}) );
+    CHECK( "\"Catch me\"" == ::Catch::Detail::stringify(type{"Catch me"}) );
+}
+
+#endif // CATCH_INTERNAL_CONFIG_CPP17_VARIANT
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/ToStringWhich.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/ToStringWhich.tests.cpp
index 26afa3b12fcea142a72f92b217564dec21962b22..cd4a15183b2bb335b155ea2c43c5f9edfe0027d9 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/ToStringWhich.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/ToStringWhich.tests.cpp
@@ -16,6 +16,16 @@ std::string fallbackStringifier(T const&) {
 #include "catch.hpp"
 
 
+
+#if defined(__GNUC__)
+// This has to be left enabled until end of the TU, because the GCC
+// frontend reports operator<<(std::ostream& os, const has_maker_and_operator&)
+// as unused anyway
+#    pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+
+namespace {
+
 struct has_operator { };
 struct has_maker {};
 struct has_maker_and_operator {};
@@ -38,6 +48,8 @@ StreamT& operator<<(StreamT& os, const has_template_operator&) {
     return os;
 }
 
+} // end anonymous namespace
+
 namespace Catch {
     template<>
     struct StringMaker<has_maker> {
@@ -100,6 +112,8 @@ TEST_CASE( "stringify( vectors<has_maker_and_operator> )", "[toString]" ) {
     REQUIRE( ::Catch::Detail::stringify( v ) == "{ StringMaker<has_maker_and_operator> }" );
 }
 
+namespace {
+
 // Range-based conversion should only be used if other possibilities fail
 struct int_iterator {
     using iterator_category = std::input_iterator_tag;
@@ -139,6 +153,8 @@ struct stringmaker_range {
     int_iterator end() const { return {}; }
 };
 
+} // end anonymous namespace
+
 namespace Catch {
 template <>
 struct StringMaker<stringmaker_range> {
@@ -148,6 +164,8 @@ struct StringMaker<stringmaker_range> {
 };
 }
 
+namespace {
+
 struct just_range {
     int_iterator begin() const { return int_iterator{ 1 }; }
     int_iterator end() const { return {}; }
@@ -158,6 +176,8 @@ struct disabled_range {
     int_iterator end() const { return {}; }
 };
 
+} // end anonymous namespace
+
 namespace Catch {
 template <>
 struct is_range<disabled_range> {
diff --git a/packages/Catch2/projects/SelfTest/UsageTests/Tricky.tests.cpp b/packages/Catch2/projects/SelfTest/UsageTests/Tricky.tests.cpp
index 1c352ce9816ed57bb5eb538185129f9e2bcfe99c..b0363d4202510c1d643f1e135eae292a02ec1325 100644
--- a/packages/Catch2/projects/SelfTest/UsageTests/Tricky.tests.cpp
+++ b/packages/Catch2/projects/SelfTest/UsageTests/Tricky.tests.cpp
@@ -20,26 +20,6 @@
 #include <stdio.h>
 #include <sstream>
 
-namespace Catch {
-    std::string toString( const std::pair<int, int>& value ) {
-        std::ostringstream oss;
-        oss << "std::pair( " << value.first << ", " << value.second << " )";
-        return oss.str();
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-TEST_CASE
-(
-    "Parsing a std::pair",
-    "[Tricky][std::pair]"
-)
-{
-    std::pair<int, int> aNicePair( 1, 2 );
-
-    REQUIRE( (std::pair<int, int>( 1, 2 )) == aNicePair );
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 TEST_CASE
 (
@@ -175,7 +155,7 @@ namespace ObjectWithConversions
     ///////////////////////////////////////////////////////////////////////////////
     TEST_CASE
     (
-        "Operators at different namespace levels not hijacked by Koenig lookup",
+        "Implicit conversions are supported inside assertion macros",
         "[Tricky][approvals]"
     )
     {
@@ -232,28 +212,28 @@ struct is_true
 
 TEST_CASE( "(unimplemented) static bools can be evaluated", "[Tricky]" )
 {
-    SECTION("compare to true","")
+    SECTION("compare to true")
     {
         REQUIRE( is_true<true>::value == true );
         REQUIRE( true == is_true<true>::value );
     }
-    SECTION("compare to false","")
+    SECTION("compare to false")
     {
         REQUIRE( is_true<false>::value == false );
         REQUIRE( false == is_true<false>::value );
     }
 
-    SECTION("negation", "")
+    SECTION("negation")
     {
         REQUIRE( !is_true<false>::value );
     }
 
-    SECTION("double negation","")
+    SECTION("double negation")
     {
         REQUIRE( !!is_true<true>::value );
     }
 
-    SECTION("direct","")
+    SECTION("direct")
     {
         REQUIRE( is_true<true>::value );
         REQUIRE_FALSE( is_true<false>::value );
diff --git a/packages/Catch2/scripts/approvalTests.py b/packages/Catch2/scripts/approvalTests.py
index 3293c938885036f7723dd95dd12a3dc2d402c931..e2b0ce937732302a550b5780636925d4e196e44e 100755
--- a/packages/Catch2/scripts/approvalTests.py
+++ b/packages/Catch2/scripts/approvalTests.py
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 
-from  __future__ import print_function
+from __future__ import print_function
 
 import io
 import os
@@ -13,8 +13,8 @@ import scriptCommon
 from scriptCommon import catchPath
 
 if os.name == 'nt':
-	# Enable console colours on windows
-	os.system('')
+    # Enable console colours on windows
+    os.system('')
 
 rootPath = os.path.join(catchPath, 'projects/SelfTest/Baselines')
 
@@ -98,7 +98,6 @@ def filterLine(line, isCompact):
         # go from \ in windows paths to /
         line = line.replace('\\', '/')
 
-
     # strip source line numbers
     m = filelocParser.match(line)
     if m:
@@ -112,7 +111,7 @@ def filterLine(line, isCompact):
     if isCompact:
         line = line.replace(': FAILED', ': failed')
         line = line.replace(': PASSED', ': passed')
-        
+
     # strip Catch version number
     line = versionParser.sub("<version>", line)
 
@@ -180,19 +179,19 @@ print("Running approvals against executable:")
 print("  " + cmdPath)
 
 
-### Keep default reporters here
+# ## Keep default reporters here ##
 # Standard console reporter
-approve("console.std", ["~[!nonportable]~[!benchmark]~[approvals]", "--order", "lex"])
+approve("console.std", ["~[!nonportable]~[!benchmark]~[approvals]", "--order", "lex", "--rng-seed", "0"])
 # console reporter, include passes, warn about No Assertions
-approve("console.sw", ["~[!nonportable]~[!benchmark]~[approvals]", "-s", "-w", "NoAssertions", "--order", "lex"])
+approve("console.sw", ["~[!nonportable]~[!benchmark]~[approvals]", "-s", "-w", "NoAssertions", "--order", "lex", "--rng-seed", "0"])
 # console reporter, include passes, warn about No Assertions, limit failures to first 4
-approve("console.swa4", ["~[!nonportable]~[!benchmark]~[approvals]", "-s", "-w", "NoAssertions", "-x", "4", "--order", "lex"])
+approve("console.swa4", ["~[!nonportable]~[!benchmark]~[approvals]", "-s", "-w", "NoAssertions", "-x", "4", "--order", "lex", "--rng-seed", "0"])
 # junit reporter, include passes, warn about No Assertions
-approve("junit.sw", ["~[!nonportable]~[!benchmark]~[approvals]", "-s", "-w", "NoAssertions", "-r", "junit", "--order", "lex"])
+approve("junit.sw", ["~[!nonportable]~[!benchmark]~[approvals]", "-s", "-w", "NoAssertions", "-r", "junit", "--order", "lex", "--rng-seed", "0"])
 # xml reporter, include passes, warn about No Assertions
-approve("xml.sw", ["~[!nonportable]~[!benchmark]~[approvals]", "-s", "-w", "NoAssertions", "-r", "xml", "--order", "lex"])
+approve("xml.sw", ["~[!nonportable]~[!benchmark]~[approvals]", "-s", "-w", "NoAssertions", "-r", "xml", "--order", "lex", "--rng-seed", "0"])
 # compact reporter, include passes, warn about No Assertions
-approve('compact.sw', ['~[!nonportable]~[!benchmark]~[approvals]', '-s', '-w', 'NoAssertions', '-r', 'compact', '--order', 'lex'])
+approve('compact.sw', ['~[!nonportable]~[!benchmark]~[approvals]', '-s', '-w', 'NoAssertions', '-r', 'compact', '--order', 'lex', "--rng-seed", "0"])
 
 if overallResult != 0:
     print("If these differences are expected, run approve.py to approve new baselines.")
diff --git a/packages/Catch2/scripts/generateSingleHeader.py b/packages/Catch2/scripts/generateSingleHeader.py
index c3ce1aecb80fea5aba97adde94fa52c030b98a17..31033d6831a47ed16056286839e15100999d2c4b 100755
--- a/packages/Catch2/scripts/generateSingleHeader.py
+++ b/packages/Catch2/scripts/generateSingleHeader.py
@@ -24,7 +24,7 @@ def generate(v):
 
     seenHeaders = set([])
     rootPath = os.path.join( catchPath, 'include/' )
-    outputPath = os.path.join( catchPath, 'single_include/catch.hpp' )
+    outputPath = os.path.join( catchPath, 'single_include/catch2/catch.hpp' )
 
     globals = {
         'includeImpl' : True,
@@ -46,7 +46,7 @@ def generate(v):
     outDir = os.path.dirname(outputPath)
     if not os.path.exists(outDir):
         os.makedirs(outDir)
-    out = io.open( outputPath, 'w', newline='\n')
+    out = io.open( outputPath, 'w', newline='\n', encoding='utf-8')
 
     def write( line ):
         if globals['includeImpl'] or globals['implIfDefs'] == -1:
diff --git a/packages/Catch2/scripts/releaseCommon.py b/packages/Catch2/scripts/releaseCommon.py
index 6e44da2400c378b2cd10ac7759e04de7e1598edf..1a8ee2c87e1a66a12968c085cea73e2c4e13262b 100644
--- a/packages/Catch2/scripts/releaseCommon.py
+++ b/packages/Catch2/scripts/releaseCommon.py
@@ -169,7 +169,7 @@ def performUpdates(version):
     import shutil
     for rep in ('automake', 'tap', 'teamcity'):
         sourceFile = os.path.join(catchPath, 'include/reporters/catch_reporter_{}.hpp'.format(rep))
-        destFile = os.path.join(catchPath, 'single_include/catch_reporter_{}.hpp'.format(rep))
+        destFile = os.path.join(catchPath, 'single_include', 'catch2', 'catch_reporter_{}.hpp'.format(rep))
         shutil.copyfile(sourceFile, destFile)
 
     updateReadmeFile(version)
diff --git a/packages/Catch2/scripts/scriptCommon.py b/packages/Catch2/scripts/scriptCommon.py
index 1415be0b798b6ce0b47a023a827d540ce085d6f0..4b70f9613c2dc77cd14a5fb26f98c6702267c210 100644
--- a/packages/Catch2/scripts/scriptCommon.py
+++ b/packages/Catch2/scripts/scriptCommon.py
@@ -6,7 +6,7 @@ import subprocess
 catchPath = os.path.dirname(os.path.realpath( os.path.dirname(sys.argv[0])))
 
 def getBuildExecutable():
-    dir = os.environ.get('CATCH_DEV_OUT_DIR', "cmake-build-debug/SelfTest")
+    dir = os.environ.get('CATCH_DEV_OUT_DIR', "cmake-build-debug/projects/SelfTest")
     return dir
 
 def runAndCapture( args ):
diff --git a/packages/Catch2/scripts/updateDocumentToC.py b/packages/Catch2/scripts/updateDocumentToC.py
index d3b8bf0ffee7921c9a48109b98f639b969a38b2d..325c8a3c2e8bc378896928d2688db1d9e856f15a 100644
--- a/packages/Catch2/scripts/updateDocumentToC.py
+++ b/packages/Catch2/scripts/updateDocumentToC.py
@@ -26,7 +26,7 @@ from scriptCommon import catchPath
 minTocEntries = 4
 
 headingExcludeDefault = [1,3,4,5]  # use level 2 headers for at default
-headingExcludeRelease = [2,3,4,5]  # use level 1 headers for release-notes.md
+headingExcludeRelease = [1,3,4,5]  # use level 1 headers for release-notes.md
 
 documentsDefault = os.path.join(os.path.relpath(catchPath), 'docs/*.md')
 releaseNotesName = 'release-notes.md'
@@ -91,18 +91,20 @@ def dashifyHeadline(line):
     level = len(stripped_right) - len(stripped_both)
     stripped_wspace = stripped_both.strip()
 
-    # character replacements
-    replaced_colon = stripped_wspace.replace('.', '')
-    replaced_slash = replaced_colon.replace('/', '')
-    rem_nonvalids = ''.join([c if c in VALIDS
-                             else '-' for c in replaced_slash])
-
-    lowered = rem_nonvalids.lower()
-    dashified = re.sub(r'(-)\1+', r'\1', lowered)  # remove duplicate dashes
-    dashified = dashified.strip('-')  # strip dashes from start and end
-
-    # exception '&' (double-dash in github)
-    dashified = dashified.replace('-&-', '--')
+    # GitHub's sluggification works in an interesting way
+    # 1) '+', '/', '(', ')' and so on are just removed
+    # 2) spaces are converted into '-' directly
+    # 3) multiple -- are not collapsed
+
+    dashified = ''
+    for c in stripped_wspace:
+        if c in VALIDS:
+            dashified += c.lower()
+        elif c.isspace():
+            dashified += '-'
+        else:
+            # Unknown symbols are just removed
+            continue
 
     return [stripped_wspace, dashified, level]
 
diff --git a/packages/Catch2/scripts/updateWandbox.py b/packages/Catch2/scripts/updateWandbox.py
index 5785feb4695c26cba009d3eabd298e38535a7eef..564f94890db0e199a9c12dd4b4234772cb2f92a2 100644
--- a/packages/Catch2/scripts/updateWandbox.py
+++ b/packages/Catch2/scripts/updateWandbox.py
@@ -34,7 +34,7 @@ def uploadFiles():
         'code': main_file,
         'codes': [{
             'file': 'catch.hpp',
-            'code': open(os.path.join(catchPath, 'single_include', 'catch.hpp')).read()
+            'code': open(os.path.join(catchPath, 'single_include', 'catch2', 'catch.hpp')).read()
         }],
         'options': 'c++11,cpp-no-pedantic,boost-nothing',
         'compiler-option-raw': '-DCATCH_CONFIG_FAST_COMPILE',
diff --git a/packages/Catch2/single_include/catch.hpp b/packages/Catch2/single_include/catch2/catch.hpp
similarity index 91%
rename from packages/Catch2/single_include/catch.hpp
rename to packages/Catch2/single_include/catch2/catch.hpp
index 28448ddb22e17f7f6a536fa8a932489447c2cfd7..4191607a7931fbd827924bd23c852b69381ff5b7 100644
--- a/packages/Catch2/single_include/catch.hpp
+++ b/packages/Catch2/single_include/catch2/catch.hpp
@@ -1,6 +1,6 @@
 /*
- *  Catch v2.2.3
- *  Generated: 2018-06-06 23:11:57.601416
+ *  Catch v2.4.1
+ *  Generated: 2018-09-28 15:50:15.645795
  *  ----------------------------------------------------------
  *  This file has been merged from multiple headers. Please don't edit it directly
  *  Copyright (c) 2018 Two Blue Cubes Ltd. All rights reserved.
@@ -14,8 +14,8 @@
 
 
 #define CATCH_VERSION_MAJOR 2
-#define CATCH_VERSION_MINOR 2
-#define CATCH_VERSION_PATCH 3
+#define CATCH_VERSION_MINOR 4
+#define CATCH_VERSION_PATCH 1
 
 #ifdef __clang__
 #    pragma clang system_header
@@ -30,13 +30,15 @@
 #       pragma warning(push)
 #       pragma warning(disable: 161 1682)
 #   else // __ICC
-#       pragma clang diagnostic ignored "-Wunused-variable"
 #       pragma clang diagnostic push
 #       pragma clang diagnostic ignored "-Wpadded"
 #       pragma clang diagnostic ignored "-Wswitch-enum"
 #       pragma clang diagnostic ignored "-Wcovered-switch-default"
 #    endif
 #elif defined __GNUC__
+     // GCC likes to warn on REQUIREs, and we cannot suppress them
+     // locally because g++'s support for _Pragma is lacking in older,
+     // still supported, versions
 #    pragma GCC diagnostic ignored "-Wparentheses"
 #    pragma GCC diagnostic push
 #    pragma GCC diagnostic ignored "-Wunused-variable"
@@ -55,7 +57,9 @@
 #  if defined(CATCH_CONFIG_DISABLE_MATCHERS)
 #    undef CATCH_CONFIG_DISABLE_MATCHERS
 #  endif
-#  define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
+#  if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)
+#    define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
+#  endif
 #endif
 
 #if !defined(CATCH_CONFIG_IMPL_ONLY)
@@ -104,6 +108,7 @@ namespace Catch {
 // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
 // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
 // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
+// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?
 // ****************
 // Note to maintainers: if new toggles are added please document them
 // in configuration.md, too
@@ -116,11 +121,11 @@ namespace Catch {
 
 #ifdef __cplusplus
 
-#  if __cplusplus >= 201402L
+#  if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
 #    define CATCH_CPP14_OR_GREATER
 #  endif
 
-#  if __cplusplus >= 201703L
+#  if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
 #    define CATCH_CPP17_OR_GREATER
 #  endif
 
@@ -145,6 +150,12 @@ namespace Catch {
 #       define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
             _Pragma( "clang diagnostic pop" )
 
+#       define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
+            _Pragma( "clang diagnostic push" ) \
+            _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
+#       define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS \
+            _Pragma( "clang diagnostic pop" )
+
 #endif // __clang__
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -176,6 +187,12 @@ namespace Catch {
 #    define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
 #endif
 
+////////////////////////////////////////////////////////////////////////////////
+// PS4
+#if defined(__ORBIS__)
+#    define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
+#endif
+
 ////////////////////////////////////////////////////////////////////////////////
 // Cygwin
 #ifdef __CYGWIN__
@@ -183,7 +200,14 @@ namespace Catch {
 // 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
+// some versions of cygwin (most) do not support std::to_string. Use the libstd check.
+// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813
+# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
+	       && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
+
+#	define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
 
+# endif
 #endif // __CYGWIN__
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -205,7 +229,12 @@ namespace Catch {
 #endif // _MSC_VER
 
 ////////////////////////////////////////////////////////////////////////////////
+// Check if we are compiled with -fno-exceptions or equivalent
+#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
+#  define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
+#endif
 
+////////////////////////////////////////////////////////////////////////////////
 // DJGPP
 #ifdef __DJGPP__
 #  define CATCH_INTERNAL_CONFIG_NO_WCHAR
@@ -222,6 +251,32 @@ namespace Catch {
     #define CATCH_INTERNAL_CONFIG_COUNTER
 #endif
 
+////////////////////////////////////////////////////////////////////////////////
+// Check if string_view is available and usable
+// The check is split apart to work around v140 (VS2015) preprocessor issue...
+#if defined(__has_include)
+#if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
+#    define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
+#endif
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// Check if variant is available and usable
+#if defined(__has_include)
+#  if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
+#    if defined(__clang__) && (__clang_major__ < 8)
+       // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
+       // fix should be in clang 8, workaround in libstdc++ 8.2
+#      include <ciso646>
+#      if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
+#        define CATCH_CONFIG_NO_CPP17_VARIANT
+#     else
+#        define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
+#      endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
+#    endif // defined(__clang__) && (__clang_major__ < 8)
+#  endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
+#endif // __has_include
+
 #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
 #   define CATCH_CONFIG_COUNTER
 #endif
@@ -245,6 +300,26 @@ namespace Catch {
 #  define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
 #endif
 
+#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
+#  define CATCH_CONFIG_CPP17_STRING_VIEW
+#endif
+
+#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)
+#  define CATCH_CONFIG_CPP17_VARIANT
+#endif
+
+#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
+#  define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
+#endif
+
+#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE)
+#  define CATCH_CONFIG_NEW_CAPTURE
+#endif
+
+#if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+#  define CATCH_CONFIG_DISABLE_EXCEPTIONS
+#endif
+
 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
 #   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
 #   define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
@@ -253,6 +328,20 @@ namespace Catch {
 #   define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
 #   define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
 #endif
+#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
+#   define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
+#   define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
+#endif
+
+#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+#define CATCH_TRY if ((true))
+#define CATCH_CATCH_ALL if ((false))
+#define CATCH_CATCH_ANON(type) if ((false))
+#else
+#define CATCH_TRY try
+#define CATCH_CATCH_ALL catch (...)
+#define CATCH_CATCH_ANON(type) catch (type)
+#endif
 
 // end catch_compiler_capabilities.h
 #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
@@ -494,6 +583,10 @@ namespace Catch {
 
 } // namespace Catch
 
+inline auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
+    return Catch::StringRef( rawChars, size );
+}
+
 // end catch_stringref.h
 namespace Catch {
 
@@ -551,7 +644,7 @@ struct AutoReg : NonCopyable {
     #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
         static void TestName(); \
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
-        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
+        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
         static void TestName()
     #define INTERNAL_CATCH_TESTCASE( ... ) \
@@ -580,7 +673,7 @@ struct AutoReg : NonCopyable {
     ///////////////////////////////////////////////////////////////////////////////
     #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
-        Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
+        Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
 
 // end catch_test_registry.h
@@ -697,13 +790,15 @@ namespace Catch {
             return *this;
         }
         auto get() -> std::ostream& { return *m_oss; }
-
-        static void cleanup();
     };
 }
 
 // end catch_stream.h
 
+#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
+#include <string_view>
+#endif
+
 #ifdef __OBJC__
 // start catch_objc_arc.hpp
 
@@ -879,10 +974,11 @@ namespace Catch {
     struct StringMaker<std::string> {
         static std::string convert(const std::string& str);
     };
-#ifdef CATCH_CONFIG_WCHAR
+
+#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
     template<>
-    struct StringMaker<std::wstring> {
-        static std::string convert(const std::wstring& wstr);
+    struct StringMaker<std::string_view> {
+        static std::string convert(std::string_view str);
     };
 #endif
 
@@ -896,6 +992,18 @@ namespace Catch {
     };
 
 #ifdef CATCH_CONFIG_WCHAR
+    template<>
+    struct StringMaker<std::wstring> {
+        static std::string convert(const std::wstring& wstr);
+    };
+
+# ifdef CATCH_CONFIG_CPP17_STRING_VIEW
+    template<>
+    struct StringMaker<std::wstring_view> {
+        static std::string convert(std::wstring_view str);
+    };
+# endif
+
     template<>
     struct StringMaker<wchar_t const *> {
         static std::string convert(wchar_t const * str);
@@ -1064,6 +1172,7 @@ namespace Catch {
 #if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)
 #  define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
 #  define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
+#  define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
 #  define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER
 #endif
 
@@ -1127,6 +1236,34 @@ namespace Catch {
 }
 #endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER
 
+#if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)
+#include <variant>
+namespace Catch {
+    template<>
+    struct StringMaker<std::monostate> {
+        static std::string convert(const std::monostate&) {
+            return "{ }";
+        }
+    };
+
+    template<typename... Elements>
+    struct StringMaker<std::variant<Elements...>> {
+        static std::string convert(const std::variant<Elements...>& variant) {
+            if (variant.valueless_by_exception()) {
+                return "{valueless variant}";
+            } else {
+                return std::visit(
+                    [](const auto& value) {
+                        return ::Catch::Detail::stringify(value);
+                    },
+                    variant
+                );
+            }
+        }
+    };
+}
+#endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
+
 namespace Catch {
     struct not_this_one {}; // Tag type for detecting which begin/ end are being selected
 
@@ -1486,8 +1623,10 @@ namespace Catch {
     struct BenchmarkInfo;
     struct BenchmarkStats;
     struct AssertionReaction;
+    struct SourceLineInfo;
 
     struct ITransientExpression;
+    struct IGeneratorTracker;
 
     struct IResultCapture {
 
@@ -1498,6 +1637,8 @@ namespace Catch {
         virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
         virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
 
+        virtual auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
+
         virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;
         virtual void benchmarkEnded( BenchmarkStats const& stats ) = 0;
 
@@ -1579,7 +1720,7 @@ namespace Catch {
 
     public:
         AssertionHandler
-            (   StringRef macroName,
+            (   StringRef const& macroName,
                 SourceLineInfo const& lineInfo,
                 StringRef capturedExpression,
                 ResultDisposition::Flags resultDisposition );
@@ -1610,7 +1751,7 @@ namespace Catch {
         auto allowThrows() const -> bool;
     };
 
-    void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef matcherString );
+    void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString );
 
 } // namespace Catch
 
@@ -1618,15 +1759,16 @@ namespace Catch {
 // start catch_message.h
 
 #include <string>
+#include <vector>
 
 namespace Catch {
 
     struct MessageInfo {
-        MessageInfo(    std::string const& _macroName,
+        MessageInfo(    StringRef const& _macroName,
                         SourceLineInfo const& _lineInfo,
                         ResultWas::OfType _type );
 
-        std::string macroName;
+        StringRef macroName;
         std::string message;
         SourceLineInfo lineInfo;
         ResultWas::OfType type;
@@ -1650,7 +1792,7 @@ namespace Catch {
     };
 
     struct MessageBuilder : MessageStream {
-        MessageBuilder( std::string const& macroName,
+        MessageBuilder( StringRef const& macroName,
                         SourceLineInfo const& lineInfo,
                         ResultWas::OfType type );
 
@@ -1671,6 +1813,28 @@ namespace Catch {
         MessageInfo m_info;
     };
 
+    class Capturer {
+        std::vector<MessageInfo> m_messages;
+        IResultCapture& m_resultCapture = getResultCapture();
+        size_t m_captured = 0;
+    public:
+        Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );
+        ~Capturer();
+
+        void captureValue( size_t index, StringRef value );
+
+        template<typename T>
+        void captureValues( size_t index, T&& value ) {
+            captureValue( index, Catch::Detail::stringify( value ) );
+        }
+
+        template<typename T, typename... Ts>
+        void captureValues( size_t index, T&& value, Ts&&... values ) {
+            captureValues( index, value );
+            captureValues( index+1, values... );
+        }
+    };
+
 } // end namespace Catch
 
 // end catch_message.h
@@ -1682,7 +1846,7 @@ namespace Catch {
   #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION"
 #endif
 
-#if defined(CATCH_CONFIG_FAST_COMPILE)
+#if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
 
 ///////////////////////////////////////////////////////////////////////////////
 // Another way to speed-up compilation is to omit local try-catch for REQUIRE*
@@ -1702,7 +1866,7 @@ namespace Catch {
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
         INTERNAL_CATCH_TRY { \
             CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
             catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
@@ -1725,7 +1889,7 @@ namespace Catch {
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
         try { \
             static_cast<void>(__VA_ARGS__); \
             catchAssertionHandler.handleExceptionNotThrownAsExpected(); \
@@ -1739,7 +1903,7 @@ namespace Catch {
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \
         if( catchAssertionHandler.allowThrows() ) \
             try { \
                 static_cast<void>(__VA_ARGS__); \
@@ -1756,7 +1920,7 @@ namespace Catch {
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \
         if( catchAssertionHandler.allowThrows() ) \
             try { \
                 static_cast<void>(expr); \
@@ -1776,27 +1940,32 @@ namespace Catch {
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \
         catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \
         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
     } while( false )
 
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \
+    auto varName = Catch::Capturer( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \
+    varName.captureValues( 0, __VA_ARGS__ )
+
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_INFO( macroName, log ) \
-    Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
+    Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );
 
 ///////////////////////////////////////////////////////////////////////////////
 // Although this is matcher-based, it can be used with just a string
 #define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
         if( catchAssertionHandler.allowThrows() ) \
             try { \
                 static_cast<void>(__VA_ARGS__); \
                 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
             } \
             catch( ... ) { \
-                Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher ); \
+                Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \
             } \
         else \
             catchAssertionHandler.handleThrowingCallSkipped(); \
@@ -1848,19 +2017,22 @@ namespace Catch {
 namespace Catch {
 
     struct SectionInfo {
+        SectionInfo
+            (   SourceLineInfo const& _lineInfo,
+                std::string const& _name );
+
+        // Deprecated
         SectionInfo
             (   SourceLineInfo const& _lineInfo,
                 std::string const& _name,
-                std::string const& _description = std::string() );
+                std::string const& ) : SectionInfo( _lineInfo, _name ) {}
 
         std::string name;
-        std::string description;
+        std::string description; // !Deprecated: this will always be empty
         SourceLineInfo lineInfo;
     };
 
     struct SectionEndInfo {
-        SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds );
-
         SectionInfo sectionInfo;
         Counts prevAssertions;
         double durationInSeconds;
@@ -1914,8 +2086,15 @@ namespace Catch {
 
 } // end namespace Catch
 
-    #define INTERNAL_CATCH_SECTION( ... ) \
-        if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
+#define INTERNAL_CATCH_SECTION( ... ) \
+    CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
+    if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
+    CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
+
+#define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
+    CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
+    if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \
+    CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
 
 // end catch_section.h
 // start catch_benchmark.h
@@ -1991,7 +2170,7 @@ namespace Catch {
         virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
         virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;
 
-        virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
+        virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0;
 
         virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;
     };
@@ -2006,7 +2185,7 @@ namespace Catch {
         virtual void registerStartupException() noexcept = 0;
     };
 
-    IRegistryHub& getRegistryHub();
+    IRegistryHub const& getRegistryHub();
     IMutableRegistryHub& getMutableRegistryHub();
     void cleanUp();
     std::string translateActiveException();
@@ -2088,7 +2267,6 @@ namespace Catch {
 // start catch_approx.h
 
 #include <type_traits>
-#include <stdexcept>
 
 namespace Catch {
 namespace Detail {
@@ -2096,18 +2274,26 @@ namespace Detail {
     class Approx {
     private:
         bool equalityComparisonImpl(double other) const;
+        // Validates the new margin (margin >= 0)
+        // out-of-line to avoid including stdexcept in the header
+        void setMargin(double margin);
+        // Validates the new epsilon (0 < epsilon < 1)
+        // out-of-line to avoid including stdexcept in the header
+        void setEpsilon(double epsilon);
 
     public:
         explicit Approx ( double value );
 
         static Approx custom();
 
+        Approx operator-() const;
+
         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
         Approx operator()( T const& value ) {
             Approx approx( static_cast<double>(value) );
-            approx.epsilon( m_epsilon );
-            approx.margin( m_margin );
-            approx.scale( m_scale );
+            approx.m_epsilon = m_epsilon;
+            approx.m_margin = m_margin;
+            approx.m_scale = m_scale;
             return approx;
         }
 
@@ -2159,27 +2345,14 @@ namespace Detail {
         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
         Approx& epsilon( T const& newEpsilon ) {
             double epsilonAsDouble = static_cast<double>(newEpsilon);
-            if( epsilonAsDouble < 0 || epsilonAsDouble > 1.0 ) {
-                throw std::domain_error
-                    (   "Invalid Approx::epsilon: " +
-                        Catch::Detail::stringify( epsilonAsDouble ) +
-                        ", Approx::epsilon has to be between 0 and 1" );
-            }
-            m_epsilon = epsilonAsDouble;
+            setEpsilon(epsilonAsDouble);
             return *this;
         }
 
         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
         Approx& margin( T const& newMargin ) {
             double marginAsDouble = static_cast<double>(newMargin);
-            if( marginAsDouble < 0 ) {
-                throw std::domain_error
-                    (   "Invalid Approx::margin: " +
-                         Catch::Detail::stringify( marginAsDouble ) +
-                         ", Approx::Margin has to be non-negative." );
-
-            }
-            m_margin = marginAsDouble;
+            setMargin(marginAsDouble);
             return *this;
         }
 
@@ -2197,7 +2370,12 @@ namespace Detail {
         double m_scale;
         double m_value;
     };
-}
+} // end namespace Detail
+
+namespace literals {
+    Detail::Approx operator "" _a(long double val);
+    Detail::Approx operator "" _a(unsigned long long val);
+} // end namespace literals
 
 template<>
 struct StringMaker<Catch::Detail::Approx> {
@@ -2264,6 +2442,11 @@ namespace Matchers {
             mutable std::string m_cachedToString;
         };
 
+#ifdef __clang__
+#    pragma clang diagnostic push
+#    pragma clang diagnostic ignored "-Wnon-virtual-dtor"
+#endif
+
         template<typename ObjectT>
         struct MatcherMethod {
             virtual bool match( ObjectT const& arg ) const = 0;
@@ -2273,6 +2456,10 @@ namespace Matchers {
             virtual bool match( PtrT* arg ) const = 0;
         };
 
+#ifdef __clang__
+#    pragma clang diagnostic pop
+#endif
+
         template<typename T>
         struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
 
@@ -2661,7 +2848,7 @@ namespace Matchers {
                 auto lfirst = m_target.begin(), llast = m_target.end();
                 auto rfirst = vec.begin(), rlast = vec.end();
                 // Cut common prefix to optimize checking of permuted parts
-                while (lfirst != llast && *lfirst != *rfirst) {
+                while (lfirst != llast && *lfirst == *rfirst) {
                     ++lfirst; ++rfirst;
                 }
                 if (lfirst == llast) {
@@ -2726,7 +2913,7 @@ namespace Catch {
         MatcherT m_matcher;
         StringRef m_matcherString;
     public:
-        MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef matcherString )
+        MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString )
         :   ITransientExpression{ true, matcher.match( arg ) },
             m_arg( arg ),
             m_matcher( matcher ),
@@ -2745,10 +2932,10 @@ namespace Catch {
 
     using StringMatcher = Matchers::Impl::MatcherBase<std::string>;
 
-    void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString  );
+    void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString  );
 
     template<typename ArgT, typename MatcherT>
-    auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef matcherString  ) -> MatchExpr<ArgT, MatcherT> {
+    auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString  ) -> MatchExpr<ArgT, MatcherT> {
         return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );
     }
 
@@ -2757,9 +2944,9 @@ namespace Catch {
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
         INTERNAL_CATCH_TRY { \
-            catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher ) ); \
+            catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \
         } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
         INTERNAL_CATCH_REACT( catchAssertionHandler ) \
     } while( false )
@@ -2767,14 +2954,14 @@ namespace Catch {
 ///////////////////////////////////////////////////////////////////////////////
 #define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \
     do { \
-        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
+        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \
         if( catchAssertionHandler.allowThrows() ) \
             try { \
                 static_cast<void>(__VA_ARGS__ ); \
                 catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \
             } \
             catch( exceptionType const& ex ) { \
-                catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher ) ); \
+                catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \
             } \
             catch( ... ) { \
                 catchAssertionHandler.handleUnexpectedInflightException(); \
@@ -2786,6 +2973,304 @@ namespace Catch {
 
 // end catch_capture_matchers.h
 #endif
+// start catch_generators.hpp
+
+// start catch_interfaces_generatortracker.h
+
+
+#include <memory>
+
+namespace Catch {
+
+    namespace Generators {
+        class GeneratorBase {
+        protected:
+            size_t m_size = 0;
+
+        public:
+            GeneratorBase( size_t size ) : m_size( size ) {}
+            virtual ~GeneratorBase();
+            auto size() const -> size_t { return m_size; }
+        };
+        using GeneratorBasePtr = std::unique_ptr<GeneratorBase>;
+
+    } // namespace Generators
+
+    struct IGeneratorTracker {
+        virtual ~IGeneratorTracker();
+        virtual auto hasGenerator() const -> bool = 0;
+        virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0;
+        virtual void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0;
+        virtual auto getIndex() const -> std::size_t = 0;
+    };
+
+} // namespace Catch
+
+// end catch_interfaces_generatortracker.h
+// start catch_enforce.h
+
+#include <stdexcept>
+
+namespace Catch {
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+    template <typename Ex>
+    [[noreturn]]
+    void throw_exception(Ex const& e) {
+        throw e;
+    }
+#else // ^^ Exceptions are enabled //  Exceptions are disabled vv
+    [[noreturn]]
+    void throw_exception(std::exception const& e);
+#endif
+} // namespace Catch;
+
+#define CATCH_PREPARE_EXCEPTION( type, msg ) \
+    type( ( Catch::ReusableStringStream() << msg ).str() )
+#define CATCH_INTERNAL_ERROR( msg ) \
+    Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg))
+#define CATCH_ERROR( msg ) \
+    Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::domain_error, msg ))
+#define CATCH_RUNTIME_ERROR( msg ) \
+    Catch::throw_exception(CATCH_PREPARE_EXCEPTION( std::runtime_error, msg ))
+#define CATCH_ENFORCE( condition, msg ) \
+    do{ if( !(condition) ) CATCH_ERROR( msg ); } while(false)
+
+// end catch_enforce.h
+#include <memory>
+#include <vector>
+#include <cassert>
+
+#include <utility>
+
+namespace Catch {
+namespace Generators {
+
+    // !TBD move this into its own location?
+    namespace pf{
+        template<typename T, typename... Args>
+        std::unique_ptr<T> make_unique( Args&&... args ) {
+            return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
+        }
+    }
+
+    template<typename T>
+    struct IGenerator {
+        virtual ~IGenerator() {}
+        virtual auto get( size_t index ) const -> T = 0;
+    };
+
+    template<typename T>
+    class SingleValueGenerator : public IGenerator<T> {
+        T m_value;
+    public:
+        SingleValueGenerator( T const& value ) : m_value( value ) {}
+
+        auto get( size_t ) const -> T override {
+            return m_value;
+        }
+    };
+
+    template<typename T>
+    class FixedValuesGenerator : public IGenerator<T> {
+        std::vector<T> m_values;
+
+    public:
+        FixedValuesGenerator( std::initializer_list<T> values ) : m_values( values ) {}
+
+        auto get( size_t index ) const -> T override {
+            return m_values[index];
+        }
+    };
+
+    template<typename T>
+    class RangeGenerator : public IGenerator<T> {
+        T const m_first;
+        T const m_last;
+
+    public:
+        RangeGenerator( T const& first, T const& last ) : m_first( first ), m_last( last ) {
+            assert( m_last > m_first );
+        }
+
+        auto get( size_t index ) const -> T override {
+            // ToDo:: introduce a safe cast to catch potential overflows
+            return static_cast<T>(m_first+index);
+        }
+    };
+
+    template<typename T>
+    struct NullGenerator : IGenerator<T> {
+        auto get( size_t ) const -> T override {
+            CATCH_INTERNAL_ERROR("A Null Generator is always empty");
+        }
+    };
+
+    template<typename T>
+    class Generator {
+        std::unique_ptr<IGenerator<T>> m_generator;
+        size_t m_size;
+
+    public:
+        Generator( size_t size, std::unique_ptr<IGenerator<T>> generator )
+        :   m_generator( std::move( generator ) ),
+            m_size( size )
+        {}
+
+        auto size() const -> size_t { return m_size; }
+        auto operator[]( size_t index ) const -> T {
+            assert( index < m_size );
+            return m_generator->get( index );
+        }
+    };
+
+    std::vector<size_t> randomiseIndices( size_t selectionSize, size_t sourceSize );
+
+    template<typename T>
+    class GeneratorRandomiser : public IGenerator<T> {
+        Generator<T> m_baseGenerator;
+
+        std::vector<size_t> m_indices;
+    public:
+        GeneratorRandomiser( Generator<T>&& baseGenerator, size_t numberOfItems )
+        :   m_baseGenerator( std::move( baseGenerator ) ),
+            m_indices( randomiseIndices( numberOfItems, m_baseGenerator.size() ) )
+        {}
+
+        auto get( size_t index ) const -> T override {
+            return m_baseGenerator[m_indices[index]];
+        }
+    };
+
+    template<typename T>
+    struct RequiresASpecialisationFor;
+
+    template<typename T>
+    auto all() -> Generator<T> { return RequiresASpecialisationFor<T>(); }
+
+    template<>
+    auto all<int>() -> Generator<int>;
+
+    template<typename T>
+    auto range( T const& first, T const& last ) -> Generator<T> {
+        return Generator<T>( (last-first), pf::make_unique<RangeGenerator<T>>( first, last ) );
+    }
+
+    template<typename T>
+    auto random( T const& first, T const& last ) -> Generator<T> {
+        auto gen = range( first, last );
+        auto size = gen.size();
+
+        return Generator<T>( size, pf::make_unique<GeneratorRandomiser<T>>( std::move( gen ), size ) );
+    }
+    template<typename T>
+    auto random( size_t size ) -> Generator<T> {
+        return Generator<T>( size, pf::make_unique<GeneratorRandomiser<T>>( all<T>(), size ) );
+    }
+
+    template<typename T>
+    auto values( std::initializer_list<T> values ) -> Generator<T> {
+        return Generator<T>( values.size(), pf::make_unique<FixedValuesGenerator<T>>( values ) );
+    }
+    template<typename T>
+    auto value( T const& val ) -> Generator<T> {
+        return Generator<T>( 1, pf::make_unique<SingleValueGenerator<T>>( val ) );
+    }
+
+    template<typename T>
+    auto as() -> Generator<T> {
+        return Generator<T>( 0, pf::make_unique<NullGenerator<T>>() );
+    }
+
+    template<typename... Ts>
+    auto table( std::initializer_list<std::tuple<Ts...>>&& tuples ) -> Generator<std::tuple<Ts...>> {
+        return values<std::tuple<Ts...>>( std::forward<std::initializer_list<std::tuple<Ts...>>>( tuples ) );
+    }
+
+    template<typename T>
+    struct Generators : GeneratorBase {
+        std::vector<Generator<T>> m_generators;
+
+        using type = T;
+
+        Generators() : GeneratorBase( 0 ) {}
+
+        void populate( T&& val ) {
+            m_size += 1;
+            m_generators.emplace_back( value( std::move( val ) ) );
+        }
+        template<typename U>
+        void populate( U&& val ) {
+            populate( T( std::move( val ) ) );
+        }
+        void populate( Generator<T>&& generator ) {
+            m_size += generator.size();
+            m_generators.emplace_back( std::move( generator ) );
+        }
+
+        template<typename U, typename... Gs>
+        void populate( U&& valueOrGenerator, Gs... moreGenerators ) {
+            populate( std::forward<U>( valueOrGenerator ) );
+            populate( std::forward<Gs>( moreGenerators )... );
+        }
+
+        auto operator[]( size_t index ) const -> T {
+            size_t sizes = 0;
+            for( auto const& gen : m_generators ) {
+                auto localIndex = index-sizes;
+                sizes += gen.size();
+                if( index < sizes )
+                    return gen[localIndex];
+            }
+            CATCH_INTERNAL_ERROR("Index '" << index << "' is out of range (" << sizes << ')');
+        }
+    };
+
+    template<typename T, typename... Gs>
+    auto makeGenerators( Generator<T>&& generator, Gs... moreGenerators ) -> Generators<T> {
+        Generators<T> generators;
+        generators.m_generators.reserve( 1+sizeof...(Gs) );
+        generators.populate( std::move( generator ), std::forward<Gs>( moreGenerators )... );
+        return generators;
+    }
+    template<typename T>
+    auto makeGenerators( Generator<T>&& generator ) -> Generators<T> {
+        Generators<T> generators;
+        generators.populate( std::move( generator ) );
+        return generators;
+    }
+    template<typename T, typename... Gs>
+    auto makeGenerators( T&& val, Gs... moreGenerators ) -> Generators<T> {
+        return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... );
+    }
+    template<typename T, typename U, typename... Gs>
+    auto makeGenerators( U&& val, Gs... moreGenerators ) -> Generators<T> {
+        return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... );
+    }
+
+    auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
+
+    template<typename L>
+    // Note: The type after -> is weird, because VS2015 cannot parse
+    //       the expression used in the typedef inside, when it is in
+    //       return type. Yeah, ¯\_(ツ)_/¯
+    auto generate( SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>()[0]) {
+        using UnderlyingType = typename decltype(generatorExpression())::type;
+
+        IGeneratorTracker& tracker = acquireGeneratorTracker( lineInfo );
+        if( !tracker.hasGenerator() )
+            tracker.setGenerator( pf::make_unique<Generators<UnderlyingType>>( generatorExpression() ) );
+
+        auto const& generator = static_cast<Generators<UnderlyingType> const&>( *tracker.getGenerator() );
+        return generator[tracker.getIndex()];
+    }
+
+} // namespace Generators
+} // namespace Catch
+
+#define GENERATE( ... ) \
+    Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, []{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
+
+// end catch_generators.hpp
 
 // These files are included here so the single_include script doesn't put them
 // in the conditionally compiled sections
@@ -2962,7 +3447,7 @@ namespace Catch {
                         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("",0) ) );
+                        getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, NameAndTags( name.c_str(), desc.c_str() ), SourceLineInfo("",0) ) );
                         noTestMethods++;
                     }
                 }
@@ -3586,6 +4071,7 @@ namespace Catch {
 
     struct ReporterPreferences {
         bool shouldRedirectStdOut = false;
+        bool shouldReportAllAssertions = false;
     };
 
     template<typename T>
@@ -3796,7 +4282,7 @@ namespace Catch {
         {
             m_reporterPrefs.shouldRedirectStdOut = false;
             if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
-                throw std::domain_error( "Verbosity level not supported by this reporter" );
+                CATCH_ERROR( "Verbosity level not supported by this reporter" );
         }
 
         ReporterPreferences getPreferences() const override {
@@ -3910,7 +4396,7 @@ namespace Catch {
         {
             m_reporterPrefs.shouldRedirectStdOut = false;
             if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )
-                throw std::domain_error( "Verbosity level not supported by this reporter" );
+                CATCH_ERROR( "Verbosity level not supported by this reporter" );
         }
         ~CumulativeReporterBase() override = default;
 
@@ -4550,13 +5036,6 @@ namespace TestCaseTracking {
             Failed
         };
 
-        class TrackerHasName {
-            NameAndLocation m_nameAndLocation;
-        public:
-            TrackerHasName( NameAndLocation const& nameAndLocation );
-            bool operator ()( ITrackerPtr const& tracker ) const;
-        };
-
         using Children = std::vector<ITrackerPtr>;
         NameAndLocation m_nameAndLocation;
         TrackerContext& m_ctx;
@@ -4676,6 +5155,12 @@ namespace Detail {
         return Approx( 0 );
     }
 
+    Approx Approx::operator-() const {
+        auto temp(*this);
+        temp.m_value = -temp.m_value;
+        return temp;
+    }
+
     std::string Approx::toString() const {
         ReusableStringStream rss;
         rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )";
@@ -4688,8 +5173,31 @@ namespace Detail {
         return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
     }
 
+    void Approx::setMargin(double margin) {
+        CATCH_ENFORCE(margin >= 0,
+            "Invalid Approx::margin: " << margin << '.'
+            << " Approx::Margin has to be non-negative.");
+        m_margin = margin;
+    }
+
+    void Approx::setEpsilon(double epsilon) {
+        CATCH_ENFORCE(epsilon >= 0 && epsilon <= 1.0,
+            "Invalid Approx::epsilon: " << epsilon << '.'
+            << " Approx::epsilon has to be in [0, 1]");
+        m_epsilon = epsilon;
+    }
+
 } // end namespace Detail
 
+namespace literals {
+    Detail::Approx operator "" _a(long double val) {
+        return Detail::Approx(val);
+    }
+    Detail::Approx operator "" _a(unsigned long long val) {
+        return Detail::Approx(val);
+    }
+} // end namespace literals
+
 std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {
     return value.toString();
 }
@@ -4931,6 +5439,8 @@ namespace Catch {
         void sectionEnded( SectionEndInfo const& endInfo ) override;
         void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
 
+        auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
+
         void benchmarkStarting( BenchmarkInfo const& info ) override;
         void benchmarkEnded( BenchmarkStats const& stats ) override;
 
@@ -4998,9 +5508,11 @@ namespace Catch {
 // end catch_run_context.h
 namespace Catch {
 
-    auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {
-        expr.streamReconstructedExpression( os );
-        return os;
+    namespace {
+        auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {
+            expr.streamReconstructedExpression( os );
+            return os;
+        }
     }
 
     LazyExpression::LazyExpression( bool isNegated )
@@ -5030,7 +5542,7 @@ namespace Catch {
     }
 
     AssertionHandler::AssertionHandler
-        (   StringRef macroName,
+        (   StringRef const& macroName,
             SourceLineInfo const& lineInfo,
             StringRef capturedExpression,
             ResultDisposition::Flags resultDisposition )
@@ -5059,8 +5571,13 @@ namespace Catch {
             // (To go back to the test and change execution, jump over the throw, next)
             CATCH_BREAK_INTO_DEBUGGER();
         }
-        if( m_reaction.shouldThrow )
-            throw Catch::TestFailureException();
+        if (m_reaction.shouldThrow) {
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+            throw Catch::TestFailureException();
+#else
+            CATCH_ERROR( "Test failure requires aborting test!" );
+#endif
+        }
     }
     void AssertionHandler::setCompleted() {
         m_completed = true;
@@ -5087,7 +5604,7 @@ namespace Catch {
 
     // This is the overload that takes a string and infers the Equals matcher from it
     // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp
-    void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef matcherString  ) {
+    void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString  ) {
         handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString );
     }
 
@@ -5219,7 +5736,7 @@ namespace Catch {
     // This is the general overload that takes a any string matcher
     // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers
     // the Equals matcher (so the header does not mention matchers)
-    void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString  ) {
+    void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString  ) {
         std::string exceptionMessage = Catch::translateActiveException();
         MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString );
         handler.handleExpr( expr );
@@ -6704,7 +7221,9 @@ namespace Catch {
         return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
     }
     bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept {
-        return line < other.line || ( line == other.line && (std::strcmp(file, other.file) < 0));
+        // We can assume that the same file will usually have the same pointer.
+        // Thus, if the pointers are the same, there is no point in calling the strcmp
+        return line < other.line || ( line == other.line && file != other.file && (std::strcmp(file, other.file) < 0));
     }
 
     std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
@@ -6727,20 +7246,6 @@ namespace Catch {
 // end catch_common.cpp
 // start catch_config.cpp
 
-// start catch_enforce.h
-
-#include <stdexcept>
-
-#define CATCH_PREPARE_EXCEPTION( type, msg ) \
-    type( ( Catch::ReusableStringStream() << msg ).str() )
-#define CATCH_INTERNAL_ERROR( msg ) \
-    throw CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg);
-#define CATCH_ERROR( msg ) \
-    throw CATCH_PREPARE_EXCEPTION( std::domain_error, msg )
-#define CATCH_ENFORCE( condition, msg ) \
-    do{ if( !(condition) ) CATCH_ERROR( msg ); } while(false)
-
-// end catch_enforce.h
 namespace Catch {
 
     Config::Config( ConfigData const& data )
@@ -7238,6 +7743,19 @@ namespace Catch {
     }
 }
 // end catch_decomposer.cpp
+// start catch_enforce.cpp
+
+namespace Catch {
+#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER)
+    [[noreturn]]
+    void throw_exception(std::exception const& e) {
+        Catch::cerr() << "Catch will terminate because it needed to throw an exception.\n"
+                      << "The message was: " << e.what() << '\n';
+        std::terminate();
+    }
+#endif
+} // namespace Catch;
+// end catch_enforce.cpp
 // start catch_errno_guard.cpp
 
 #include <cerrno>
@@ -7283,6 +7801,7 @@ namespace Catch {
         m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) );
     }
 
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
     std::string ExceptionTranslatorRegistry::translateActiveException() const {
         try {
 #ifdef __OBJC__
@@ -7325,6 +7844,12 @@ namespace Catch {
         }
     }
 
+#else // ^^ Exceptions are enabled // Exceptions are disabled vv
+    std::string ExceptionTranslatorRegistry::translateActiveException() const {
+        CATCH_INTERNAL_ERROR("Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
+    }
+#endif
+
     std::string ExceptionTranslatorRegistry::tryTranslators() const {
         if( m_translators.empty() )
             std::rethrow_exception(std::current_exception());
@@ -7494,6 +8019,64 @@ namespace Catch {
 #    pragma GCC diagnostic pop
 #endif
 // end catch_fatal_condition.cpp
+// start catch_generators.cpp
+
+// start catch_random_number_generator.h
+
+#include <algorithm>
+#include <random>
+
+namespace Catch {
+
+    struct IConfig;
+
+    std::mt19937& rng();
+    void seedRng( IConfig const& config );
+    unsigned int rngSeed();
+
+}
+
+// end catch_random_number_generator.h
+#include <limits>
+#include <set>
+
+namespace Catch {
+
+IGeneratorTracker::~IGeneratorTracker() {}
+
+namespace Generators {
+
+    GeneratorBase::~GeneratorBase() {}
+
+    std::vector<size_t> randomiseIndices( size_t selectionSize, size_t sourceSize ) {
+
+        assert( selectionSize <= sourceSize );
+        std::vector<size_t> indices;
+        indices.reserve( selectionSize );
+        std::uniform_int_distribution<size_t> uid( 0, sourceSize-1 );
+
+        std::set<size_t> seen;
+        // !TBD: improve this algorithm
+        while( indices.size() < selectionSize ) {
+            auto index = uid( rng() );
+            if( seen.insert( index ).second )
+                indices.push_back( index );
+        }
+        return indices;
+    }
+
+    auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
+        return getResultCapture().acquireGeneratorTracker( lineInfo );
+    }
+
+    template<>
+    auto all<int>() -> Generator<int> {
+        return range( std::numeric_limits<int>::min(), std::numeric_limits<int>::max() );
+    }
+
+} // namespace Generators
+} // namespace Catch
+// end catch_generators.cpp
 // start catch_interfaces_capture.cpp
 
 namespace Catch {
@@ -7530,8 +8113,11 @@ namespace Catch {
         using Reporters = std::vector<IStreamingReporterPtr>;
         Reporters m_listeners;
         IStreamingReporterPtr m_reporter = nullptr;
+        ReporterPreferences m_preferences;
 
     public:
+        ListeningReporter();
+
         void addListener( IStreamingReporterPtr&& listener );
         void addReporter( IStreamingReporterPtr&& reporter );
 
@@ -7689,16 +8275,16 @@ namespace Catch {
 
 namespace Catch {
 
-	LeakDetector::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);
-	}
+    LeakDetector::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
@@ -7929,7 +8515,6 @@ namespace Catch {
 #include <cstdlib>
 #include <cstdint>
 #include <cstring>
-#include <stdexcept>
 
 namespace Catch {
 namespace Matchers {
@@ -7997,9 +8582,8 @@ namespace Matchers {
 namespace Floating {
     WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
         :m_target{ target }, m_margin{ margin } {
-        if (m_margin < 0) {
-            throw std::domain_error("Allowed margin difference has to be >= 0");
-        }
+        CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.'
+            << " Margin has to be non-negative.");
     }
 
     // Performs equivalent check of std::fabs(lhs - rhs) <= margin
@@ -8014,11 +8598,16 @@ namespace Floating {
 
     WithinUlpsMatcher::WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType)
         :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
-        if (m_ulps < 0) {
-            throw std::domain_error("Allowed ulp difference has to be >= 0");
-        }
+        CATCH_ENFORCE(ulps >= 0, "Invalid ULP setting: " << ulps << '.'
+            << " ULPs have to be non-negative.");
     }
 
+#if defined(__clang__)
+#pragma clang diagnostic push
+// Clang <3.5 reports on the default branch in the switch below
+#pragma clang diagnostic ignored "-Wunreachable-code"
+#endif
+
     bool WithinUlpsMatcher::match(double const& matchee) const {
         switch (m_type) {
         case FloatingPointKind::Float:
@@ -8026,10 +8615,14 @@ namespace Floating {
         case FloatingPointKind::Double:
             return almostEqualUlps<double>(matchee, m_target, m_ulps);
         default:
-            throw std::domain_error("Unknown FloatingPointKind value");
+            CATCH_INTERNAL_ERROR( "Unknown FloatingPointKind value" );
         }
     }
 
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+
     std::string WithinUlpsMatcher::describe() const {
         return "is within " + Catch::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float)? "f" : "");
     }
@@ -8173,9 +8766,11 @@ namespace Catch {
 } // end namespace Catch
 
 // end catch_uncaught_exceptions.h
+#include <cassert>
+
 namespace Catch {
 
-    MessageInfo::MessageInfo(   std::string const& _macroName,
+    MessageInfo::MessageInfo(   StringRef const& _macroName,
                                 SourceLineInfo const& _lineInfo,
                                 ResultWas::OfType _type )
     :   macroName( _macroName ),
@@ -8197,7 +8792,7 @@ namespace Catch {
 
     ////////////////////////////////////////////////////////////////////////////
 
-    Catch::MessageBuilder::MessageBuilder( std::string const& macroName,
+    Catch::MessageBuilder::MessageBuilder( StringRef const& macroName,
                                            SourceLineInfo const& lineInfo,
                                            ResultWas::OfType type )
         :m_info(macroName, lineInfo, type) {}
@@ -8216,6 +8811,37 @@ namespace Catch {
             getResultCapture().popScopedMessage(m_info);
         }
     }
+
+    Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) {
+        auto start = std::string::npos;
+        for( size_t pos = 0; pos <= names.size(); ++pos ) {
+            char c = names[pos];
+            if( pos == names.size() || c == ' ' || c == '\t' || c == ',' || c == ']' ) {
+                if( start != std::string::npos ) {
+                    m_messages.push_back( MessageInfo( macroName, lineInfo, resultType ) );
+                    m_messages.back().message = names.substr( start, pos-start) + " := ";
+                    start = std::string::npos;
+                }
+            }
+            else if( c != '[' && c != ']' && start == std::string::npos )
+                start = pos;
+        }
+    }
+    Capturer::~Capturer() {
+        if ( !uncaught_exceptions() ){
+            assert( m_captured == m_messages.size() );
+            for( size_t i = 0; i < m_captured; ++i  )
+                m_resultCapture.popScopedMessage( m_messages[i] );
+        }
+    }
+
+    void Capturer::captureValue( size_t index, StringRef value ) {
+        assert( index < m_messages.size() );
+        m_messages[index].message += value;
+        m_resultCapture.pushScopedMessage( m_messages[index] );
+        m_captured++;
+    }
+
 } // end namespace Catch
 // end catch_message.cpp
 // start catch_output_redirect.cpp
@@ -8260,6 +8886,8 @@ namespace Catch {
         auto str() const -> std::string;
     };
 
+#if defined(CATCH_CONFIG_NEW_CAPTURE)
+
     // Windows's implementation of std::tmpfile is terrible (it tries
     // to create a file inside system folder, thus requiring elevated
     // privileges for the binary), so we have to use tmpnam(_s) and
@@ -8303,6 +8931,8 @@ namespace Catch {
         std::string& m_stderrDest;
     };
 
+#endif
+
 } // end namespace Catch
 
 #endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H
@@ -8313,13 +8943,15 @@ namespace Catch {
 #include <sstream>
 #include <stdexcept>
 
-#if defined(_MSC_VER)
-#include <io.h>      //_dup and _dup2
-#define dup _dup
-#define dup2 _dup2
-#define fileno _fileno
-#else
-#include <unistd.h>  // dup and dup2
+#if defined(CATCH_CONFIG_NEW_CAPTURE)
+    #if defined(_MSC_VER)
+    #include <io.h>      //_dup and _dup2
+    #define dup _dup
+    #define dup2 _dup2
+    #define fileno _fileno
+    #else
+    #include <unistd.h>  // dup and dup2
+    #endif
 #endif
 
 namespace Catch {
@@ -8345,24 +8977,26 @@ namespace Catch {
     {}
     auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); }
 
+#if defined(CATCH_CONFIG_NEW_CAPTURE)
+
 #if defined(_MSC_VER)
     TempFile::TempFile() {
         if (tmpnam_s(m_buffer)) {
-            throw std::runtime_error("Could not get a temp filename");
+            CATCH_RUNTIME_ERROR("Could not get a temp filename");
         }
         if (fopen_s(&m_file, m_buffer, "w")) {
             char buffer[100];
             if (strerror_s(buffer, errno)) {
-                throw std::runtime_error("Could not translate errno to string");
+                CATCH_RUNTIME_ERROR("Could not translate errno to a string");
             }
-            throw std::runtime_error("Could not open the temp file: " + std::string(m_buffer) + buffer);
+            CATCH_RUNTIME_ERROR("Coul dnot open the temp file: '" << m_buffer << "' because: " << buffer);
         }
     }
 #else
     TempFile::TempFile() {
         m_file = std::tmpfile();
         if (!m_file) {
-            throw std::runtime_error("Could not create a temp file.");
+            CATCH_RUNTIME_ERROR("Could not create a temp file.");
         }
     }
 
@@ -8417,66 +9051,37 @@ namespace Catch {
         m_stderrDest += m_stderrFile.getContents();
     }
 
+#endif // CATCH_CONFIG_NEW_CAPTURE
+
 } // namespace Catch
 
-#if defined(_MSC_VER)
-#undef dup
-#undef dup2
-#undef fileno
+#if defined(CATCH_CONFIG_NEW_CAPTURE)
+    #if defined(_MSC_VER)
+    #undef dup
+    #undef dup2
+    #undef fileno
+    #endif
 #endif
 // end catch_output_redirect.cpp
 // start catch_random_number_generator.cpp
 
-// start catch_random_number_generator.h
-
-#include <algorithm>
-
 namespace Catch {
 
-    struct IConfig;
-
-    void seedRng( IConfig const& config );
-
-    unsigned int rngSeed();
-
-    struct RandomNumberGenerator {
-        using result_type = unsigned int;
-
-        static constexpr result_type (min)() { return 0; }
-        static constexpr result_type (max)() { return 1000000; }
-
-        result_type operator()( result_type n ) const;
-        result_type operator()() const;
-
-        template<typename V>
-        static void shuffle( V& vector ) {
-            RandomNumberGenerator rng;
-            std::shuffle( vector.begin(), vector.end(), rng );
-        }
-    };
-
-}
-
-// end catch_random_number_generator.h
-#include <cstdlib>
-
-namespace Catch {
+    std::mt19937& rng() {
+        static std::mt19937 s_rng;
+        return s_rng;
+    }
 
     void seedRng( IConfig const& config ) {
-        if( config.rngSeed() != 0 )
+        if( config.rngSeed() != 0 ) {
             std::srand( config.rngSeed() );
+            rng().seed( config.rngSeed() );
+        }
     }
+
     unsigned int rngSeed() {
         return getCurrentContext().getConfig()->rngSeed();
     }
-
-    RandomNumberGenerator::result_type RandomNumberGenerator::operator()( result_type n ) const {
-        return std::rand() % n;
-    }
-    RandomNumberGenerator::result_type RandomNumberGenerator::operator()() const {
-        return std::rand() % (max)();
-    }
-
 }
 // end catch_random_number_generator.cpp
 // start catch_registry_hub.cpp
@@ -8616,6 +9221,41 @@ namespace Catch {
 } // end namespace Catch
 
 // end catch_startup_exception_registry.h
+// start catch_singletons.hpp
+
+namespace Catch {
+
+    struct ISingleton {
+        virtual ~ISingleton();
+    };
+
+    void addSingleton( ISingleton* singleton );
+    void cleanupSingletons();
+
+    template<typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT>
+    class Singleton : SingletonImplT, public ISingleton {
+
+        static auto getInternal() -> Singleton* {
+            static Singleton* s_instance = nullptr;
+            if( !s_instance ) {
+                s_instance = new Singleton;
+                addSingleton( s_instance );
+            }
+            return s_instance;
+        }
+
+    public:
+        static auto get() -> InterfaceT const& {
+            return *getInternal();
+        }
+        static auto getMutable() -> MutableInterfaceT& {
+            return *getInternal();
+        }
+    };
+
+} // namespace Catch
+
+// end catch_singletons.hpp
 namespace Catch {
 
     namespace {
@@ -8631,7 +9271,7 @@ namespace Catch {
             ITestCaseRegistry const& getTestCaseRegistry() const override {
                 return m_testCaseRegistry;
             }
-            IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() override {
+            IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const override {
                 return m_exceptionTranslatorRegistry;
             }
             ITagAliasRegistry const& getTagAliasRegistry() const override {
@@ -8668,27 +9308,19 @@ namespace Catch {
             TagAliasRegistry m_tagAliasRegistry;
             StartupExceptionRegistry m_exceptionRegistry;
         };
-
-        // Single, global, instance
-        RegistryHub*& getTheRegistryHub() {
-            static RegistryHub* theRegistryHub = nullptr;
-            if( !theRegistryHub )
-                theRegistryHub = new RegistryHub();
-            return theRegistryHub;
-        }
     }
 
-    IRegistryHub& getRegistryHub() {
-        return *getTheRegistryHub();
+    using RegistryHubSingleton = Singleton<RegistryHub, IRegistryHub, IMutableRegistryHub>;
+
+    IRegistryHub const& getRegistryHub() {
+        return RegistryHubSingleton::get();
     }
     IMutableRegistryHub& getMutableRegistryHub() {
-        return *getTheRegistryHub();
+        return RegistryHubSingleton::getMutable();
     }
     void cleanUp() {
-        delete getTheRegistryHub();
-        getTheRegistryHub() = nullptr;
+        cleanupSingletons();
         cleanUpContext();
-        ReusableStringStream::cleanup();
     }
     std::string translateActiveException() {
         return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
@@ -8753,13 +9385,76 @@ namespace Catch {
 
 namespace Catch {
 
+    namespace Generators {
+        struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker {
+            size_t m_index = static_cast<size_t>( -1 );
+            GeneratorBasePtr m_generator;
+
+            GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
+            :   TrackerBase( nameAndLocation, ctx, parent )
+            {}
+            ~GeneratorTracker();
+
+            static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {
+                std::shared_ptr<GeneratorTracker> tracker;
+
+                ITracker& currentTracker = ctx.currentTracker();
+                if( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
+                    assert( childTracker );
+                    assert( childTracker->isIndexTracker() );
+                    tracker = std::static_pointer_cast<GeneratorTracker>( childTracker );
+                }
+                else {
+                    tracker = std::make_shared<GeneratorTracker>( nameAndLocation, ctx, &currentTracker );
+                    currentTracker.addChild( tracker );
+                }
+
+                if( !ctx.completedCycle() && !tracker->isComplete() ) {
+                    if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
+                        tracker->moveNext();
+                    tracker->open();
+                }
+
+                return *tracker;
+            }
+
+            void moveNext() {
+                m_index++;
+                m_children.clear();
+            }
+
+            // TrackerBase interface
+            bool isIndexTracker() const override { return true; }
+            auto hasGenerator() const -> bool override {
+                return !!m_generator;
+            }
+            void close() override {
+                TrackerBase::close();
+                if( m_runState == CompletedSuccessfully && m_index < m_generator->size()-1 )
+                    m_runState = Executing;
+            }
+
+            // IGeneratorTracker interface
+            auto getGenerator() const -> GeneratorBasePtr const& override {
+                return m_generator;
+            }
+            void setGenerator( GeneratorBasePtr&& generator ) override {
+                m_generator = std::move( generator );
+            }
+            auto getIndex() const -> size_t override {
+                return m_index;
+            }
+        };
+        GeneratorTracker::~GeneratorTracker() {}
+    }
+
     RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)
     :   m_runInfo(_config->name()),
         m_context(getCurrentMutableContext()),
         m_config(_config),
         m_reporter(std::move(reporter)),
         m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal },
-        m_includeSuccessfulResults( m_config->includeSuccessfulResults() )
+        m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions )
     {
         m_context.setRunner(this);
         m_context.setConfig(m_config);
@@ -8869,6 +9564,13 @@ namespace Catch {
 
         return true;
     }
+    auto RunContext::acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
+        using namespace Generators;
+        GeneratorTracker& tracker = GeneratorTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( "generator", lineInfo ) );
+        assert( tracker.isOpen() );
+        m_lastAssertionInfo.lineInfo = lineInfo;
+        return tracker;
+    }
 
     bool RunContext::testForMissingAssertions(Counts& assertions) {
         if (assertions.total() != 0)
@@ -8949,7 +9651,7 @@ namespace Catch {
 
         // Recreate section for test case (as we will lose the one that was in scope)
         auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
-        SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description);
+        SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
 
         Counts assertions;
         assertions.failed = 1;
@@ -8982,12 +9684,12 @@ namespace Catch {
     }
 
     bool RunContext::aborting() const {
-        return m_totals.assertions.failed == static_cast<std::size_t>(m_config->abortAfter());
+        return m_totals.assertions.failed >= static_cast<std::size_t>(m_config->abortAfter());
     }
 
     void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {
         auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
-        SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description);
+        SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);
         m_reporter->sectionStarting(testCaseSection);
         Counts prevAssertions = m_totals.assertions;
         double duration = 0;
@@ -8997,7 +9699,7 @@ namespace Catch {
         seedRng(*m_config);
 
         Timer timer;
-        try {
+        CATCH_TRY {
             if (m_reporter->getPreferences().shouldRedirectStdOut) {
 #if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
                 RedirectedStdOut redirectedStdOut;
@@ -9017,9 +9719,9 @@ namespace Catch {
                 invokeActiveTestCase();
             }
             duration = timer.getElapsedSeconds();
-        } catch (TestFailureException&) {
+        } CATCH_CATCH_ANON (TestFailureException&) {
             // This just means the test was aborted due to failure
-        } catch (...) {
+        } CATCH_CATCH_ALL {
             // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
             // are reported without translation at the point of origin.
             if( m_shouldReportUnexpected ) {
@@ -9182,7 +9884,7 @@ namespace Catch {
 
     Section::~Section() {
         if( m_sectionIncluded ) {
-            SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
+            SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() };
             if( uncaught_exceptions() )
                 getResultCapture().sectionEndedEarly( endInfo );
             else
@@ -9203,17 +9905,11 @@ namespace Catch {
 
     SectionInfo::SectionInfo
         (   SourceLineInfo const& _lineInfo,
-            std::string const& _name,
-            std::string const& _description )
+            std::string const& _name )
     :   name( _name ),
-        description( _description ),
         lineInfo( _lineInfo )
     {}
 
-    SectionEndInfo::SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds )
-    : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
-    {}
-
 } // end namespace Catch
 // end catch_section_info.cpp
 // start catch_session.cpp
@@ -9386,10 +10082,12 @@ namespace Catch {
     Session::Session() {
         static bool alreadyInstantiated = false;
         if( alreadyInstantiated ) {
-            try         { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); }
-            catch(...)  { getMutableRegistryHub().registerStartupException(); }
+            CATCH_TRY { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); }
+            CATCH_CATCH_ALL { getMutableRegistryHub().registerStartupException(); }
         }
 
+        // There cannot be exceptions at startup in no-exception mode.
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
         const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
         if ( !exceptions.empty() ) {
             m_startupExceptions = true;
@@ -9404,6 +10102,7 @@ namespace Catch {
                 }
             }
         }
+#endif
 
         alreadyInstantiated = true;
         m_cli = makeCommandLineParser( m_configData );
@@ -9518,11 +10217,11 @@ namespace Catch {
         if( m_startupExceptions )
             return 1;
 
-        if( m_configData.showHelp || m_configData.libIdentify )
+        if (m_configData.showHelp || m_configData.libIdentify) {
             return 0;
+        }
 
-        try
-        {
+        CATCH_TRY {
             config(); // Force config to be constructed
 
             seedRng( *m_config );
@@ -9540,22 +10239,53 @@ namespace Catch {
             // of 256 tests has failed
             return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast<int>(totals.assertions.failed)));
         }
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
         catch( std::exception& ex ) {
             Catch::cerr() << ex.what() << std::endl;
             return MaxExitCode;
         }
+#endif
     }
 
 } // end namespace Catch
 // end catch_session.cpp
+// start catch_singletons.cpp
+
+#include <vector>
+
+namespace Catch {
+
+    namespace {
+        static auto getSingletons() -> std::vector<ISingleton*>*& {
+            static std::vector<ISingleton*>* g_singletons = nullptr;
+            if( !g_singletons )
+                g_singletons = new std::vector<ISingleton*>();
+            return g_singletons;
+        }
+    }
+
+    ISingleton::~ISingleton() {}
+
+    void addSingleton(ISingleton* singleton ) {
+        getSingletons()->push_back( singleton );
+    }
+    void cleanupSingletons() {
+        auto& singletons = getSingletons();
+        for( auto singleton : *singletons )
+            delete singleton;
+        delete singletons;
+        singletons = nullptr;
+    }
+
+} // namespace Catch
+// end catch_singletons.cpp
 // start catch_startup_exception_registry.cpp
 
 namespace Catch {
-    void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
-        try {
+void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
+        CATCH_TRY {
             m_exceptions.push_back(exception);
-        }
-        catch(...) {
+        } CATCH_CATCH_ALL {
             // If we run out of memory during start-up there's really not a lot more we can do about it
             std::terminate();
         }
@@ -9576,11 +10306,6 @@ namespace Catch {
 #include <vector>
 #include <memory>
 
-#if defined(__clang__)
-#    pragma clang diagnostic push
-#    pragma clang diagnostic ignored "-Wexit-time-destructors"
-#endif
-
 namespace Catch {
 
     Catch::IStream::~IStream() = default;
@@ -9700,7 +10425,6 @@ namespace Catch {
         std::vector<std::unique_ptr<std::ostringstream>> m_streams;
         std::vector<std::size_t> m_unused;
         std::ostringstream m_referenceStream; // Used for copy state/ flags from
-        static StringStreams* s_instance;
 
         auto add() -> std::size_t {
             if( m_unused.empty() ) {
@@ -9718,34 +10442,17 @@ namespace Catch {
             m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state
             m_unused.push_back(index);
         }
-
-        // !TBD: put in TLS
-        static auto instance() -> StringStreams& {
-            if( !s_instance )
-                s_instance = new StringStreams();
-            return *s_instance;
-        }
-        static void cleanup() {
-            delete s_instance;
-            s_instance = nullptr;
-        }
     };
 
-    StringStreams* StringStreams::s_instance = nullptr;
-
-    void ReusableStringStream::cleanup() {
-        StringStreams::cleanup();
-    }
-
     ReusableStringStream::ReusableStringStream()
-    :   m_index( StringStreams::instance().add() ),
-        m_oss( StringStreams::instance().m_streams[m_index].get() )
+    :   m_index( Singleton<StringStreams>::getMutable().add() ),
+        m_oss( Singleton<StringStreams>::getMutable().m_streams[m_index].get() )
     {}
 
     ReusableStringStream::~ReusableStringStream() {
         static_cast<std::ostringstream*>( m_oss )->str("");
         m_oss->clear();
-        StringStreams::instance().release( m_index );
+        Singleton<StringStreams>::getMutable().release( m_index );
     }
 
     auto ReusableStringStream::str() const -> std::string {
@@ -9760,10 +10467,6 @@ namespace Catch {
     std::ostream& clog() { return std::clog; }
 #endif
 }
-
-#if defined(__clang__)
-#    pragma clang diagnostic pop
-#endif
 // end catch_stream.cpp
 // start catch_string_manip.cpp
 
@@ -9774,6 +10477,12 @@ namespace Catch {
 
 namespace Catch {
 
+    namespace {
+        char toLowerCh(char c) {
+            return static_cast<char>( std::tolower( c ) );
+        }
+    }
+
     bool startsWith( std::string const& s, std::string const& prefix ) {
         return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
     }
@@ -9789,9 +10498,6 @@ namespace Catch {
     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 );
     }
@@ -9967,9 +10673,9 @@ namespace Catch {
 namespace Catch {
 
     RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {
-        try {
+        CATCH_TRY {
             getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);
-        } catch (...) {
+        } CATCH_CATCH_ALL {
             // Do not throw when constructing global objects, instead register the exception to be processed later
             getMutableRegistryHub().registerStartupException();
         }
@@ -10033,31 +10739,33 @@ namespace Catch {
 
 namespace Catch {
 
-    TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
-        if( startsWith( tag, '.' ) ||
-            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 if( tag == "!benchmark" )
-            return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden );
-        else
-            return TestCaseInfo::None;
-    }
-    bool isReservedTag( std::string const& tag ) {
-        return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) );
-    }
-    void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
-        CATCH_ENFORCE( !isReservedTag(tag),
-                      "Tag name: [" << tag << "] is not allowed.\n"
-                      << "Tag names starting with non alpha-numeric characters are reserved\n"
-                      << _lineInfo );
+    namespace {
+        TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
+            if( startsWith( tag, '.' ) ||
+                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 if( tag == "!benchmark" )
+                return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden );
+            else
+                return TestCaseInfo::None;
+        }
+        bool isReservedTag( std::string const& tag ) {
+            return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) );
+        }
+        void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
+            CATCH_ENFORCE( !isReservedTag(tag),
+                          "Tag name: [" << tag << "] is not allowed.\n"
+                          << "Tag names starting with non alpha-numeric characters are reserved\n"
+                          << _lineInfo );
+        }
     }
 
     TestCase makeTestCase(  ITestInvoker* _testCase,
@@ -10205,7 +10913,7 @@ namespace Catch {
                 break;
             case RunTests::InRandomOrder:
                 seedRng( config );
-                RandomNumberGenerator::shuffle( sorted );
+                std::shuffle( sorted.begin(), sorted.end(), rng() );
                 break;
             case RunTests::InDeclarationOrder:
                 // already in declaration order
@@ -10345,13 +11053,6 @@ namespace TestCaseTracking {
         m_currentTracker = tracker;
     }
 
-    TrackerBase::TrackerHasName::TrackerHasName( NameAndLocation const& nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {}
-    bool TrackerBase::TrackerHasName::operator ()( ITrackerPtr const& tracker ) const {
-        return
-            tracker->nameAndLocation().name == m_nameAndLocation.name &&
-            tracker->nameAndLocation().location == m_nameAndLocation.location;
-    }
-
     TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
     :   m_nameAndLocation( nameAndLocation ),
         m_ctx( ctx ),
@@ -10379,7 +11080,12 @@ namespace TestCaseTracking {
     }
 
     ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) {
-        auto it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( nameAndLocation ) );
+        auto it = std::find_if( m_children.begin(), m_children.end(),
+            [&nameAndLocation]( ITrackerPtr const& tracker ){
+                return
+                    tracker->nameAndLocation().location == nameAndLocation.location &&
+                    tracker->nameAndLocation().name == nameAndLocation.name;
+            } );
         return( it != m_children.end() )
             ? *it
             : nullptr;
@@ -10571,7 +11277,7 @@ namespace Catch {
     NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {}
 
     AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept {
-        try {
+        CATCH_TRY {
             getMutableRegistryHub()
                     .registerTest(
                         makeTestCase(
@@ -10579,7 +11285,7 @@ namespace Catch {
                             extractClassName( classOrMethod ),
                             nameAndTags,
                             lineInfo));
-        } catch (...) {
+        } CATCH_CATCH_ALL {
             // Do not throw when constructing global objects, instead register the exception to be processed later
             getMutableRegistryHub().registerStartupException();
         }
@@ -10733,34 +11439,36 @@ namespace Catch {
         return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();
     }
 
-    auto estimateClockResolution() -> uint64_t {
-        uint64_t sum = 0;
-        static const uint64_t iterations = 1000000;
+    namespace {
+        auto estimateClockResolution() -> uint64_t {
+            uint64_t sum = 0;
+            static const uint64_t iterations = 1000000;
 
-        auto startTime = getCurrentNanosecondsSinceEpoch();
+            auto startTime = getCurrentNanosecondsSinceEpoch();
 
-        for( std::size_t i = 0; i < iterations; ++i ) {
+            for( std::size_t i = 0; i < iterations; ++i ) {
 
-            uint64_t ticks;
-            uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
-            do {
-                ticks = getCurrentNanosecondsSinceEpoch();
-            } while( ticks == baseTicks );
+                uint64_t ticks;
+                uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();
+                do {
+                    ticks = getCurrentNanosecondsSinceEpoch();
+                } while( ticks == baseTicks );
 
-            auto delta = ticks - baseTicks;
-            sum += delta;
+                auto delta = ticks - baseTicks;
+                sum += delta;
 
-            // If we have been calibrating for over 3 seconds -- the clock
-            // is terrible and we should move on.
-            // TBD: How to signal that the measured resolution is probably wrong?
-            if (ticks > startTime + 3 * nanosecondsInSecond) {
-                return sum / i;
+                // If we have been calibrating for over 3 seconds -- the clock
+                // is terrible and we should move on.
+                // TBD: How to signal that the measured resolution is probably wrong?
+                if (ticks > startTime + 3 * nanosecondsInSecond) {
+                    return sum / i;
+                }
             }
-        }
 
-        // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
-        // - and potentially do more iterations if there's a high variance.
-        return sum/iterations;
+            // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers
+            // - and potentially do more iterations if there's a high variance.
+            return sum/iterations;
+        }
     }
     auto getEstimatedClockResolution() -> uint64_t {
         static auto s_resolution = estimateClockResolution();
@@ -10891,14 +11599,9 @@ std::string StringMaker<std::string>::convert(const std::string& str) {
     return s;
 }
 
-#ifdef CATCH_CONFIG_WCHAR
-std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
-    std::string s;
-    s.reserve(wstr.size());
-    for (auto c : wstr) {
-        s += (c <= 0xff) ? static_cast<char>(c) : '?';
-    }
-    return ::Catch::Detail::stringify(s);
+#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
+std::string StringMaker<std::string_view>::convert(std::string_view str) {
+    return ::Catch::Detail::stringify(std::string{ str });
 }
 #endif
 
@@ -10916,7 +11619,23 @@ std::string StringMaker<char*>::convert(char* str) {
         return{ "{null string}" };
     }
 }
+
 #ifdef CATCH_CONFIG_WCHAR
+std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
+    std::string s;
+    s.reserve(wstr.size());
+    for (auto c : wstr) {
+        s += (c <= 0xff) ? static_cast<char>(c) : '?';
+    }
+    return ::Catch::Detail::stringify(s);
+}
+
+# ifdef CATCH_CONFIG_CPP17_STRING_VIEW
+std::string StringMaker<std::wstring_view>::convert(std::wstring_view str) {
+    return StringMaker<std::wstring>::convert(std::wstring(str));
+}
+# endif
+
 std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) {
     if (str) {
         return ::Catch::Detail::stringify(std::wstring{ str });
@@ -11004,8 +11723,8 @@ std::string StringMaker<double>::convert(double value) {
 
 std::string ratio_string<std::atto>::symbol() { return "a"; }
 std::string ratio_string<std::femto>::symbol() { return "f"; }
-std::string  ratio_string<std::pico>::symbol() { return "p"; }
-std::string  ratio_string<std::nano>::symbol() { return "n"; }
+std::string ratio_string<std::pico>::symbol() { return "p"; }
+std::string ratio_string<std::nano>::symbol() { return "n"; }
 std::string ratio_string<std::micro>::symbol() { return "u"; }
 std::string ratio_string<std::milli>::symbol() { return "m"; }
 
@@ -11117,7 +11836,7 @@ namespace Catch {
     }
 
     Version const& libraryVersion() {
-        static Version version( 2, 2, 3, "", 0 );
+        static Version version( 2, 4, 1, "", 0 );
         return version;
     }
 
@@ -11719,9 +12438,7 @@ private:
         }
 
         ReporterPreferences CompactReporter::getPreferences() const {
-            ReporterPreferences prefs;
-            prefs.shouldRedirectStdOut = false;
-            return prefs;
+            return m_reporterPrefs;
         }
 
         void CompactReporter::noMatchingTestCases( std::string const& spec ) {
@@ -12436,6 +13153,7 @@ namespace Catch {
             xml( _config.stream() )
         {
             m_reporterPrefs.shouldRedirectStdOut = true;
+            m_reporterPrefs.shouldReportAllAssertions = true;
         }
 
     JunitReporter::~JunitReporter() {}
@@ -12626,6 +13344,11 @@ namespace Catch {
 
 namespace Catch {
 
+    ListeningReporter::ListeningReporter() {
+        // We will assume that listeners will always want all assertions
+        m_preferences.shouldReportAllAssertions = true;
+    }
+
     void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) {
         m_listeners.push_back( std::move( listener ) );
     }
@@ -12633,10 +13356,11 @@ namespace Catch {
     void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) {
         assert(!m_reporter && "Listening reporter can wrap only 1 real reporter");
         m_reporter = std::move( reporter );
+        m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;
     }
 
     ReporterPreferences ListeningReporter::getPreferences() const {
-        return m_reporter->getPreferences();
+        return m_preferences;
     }
 
     std::set<Verbosity> ListeningReporter::getSupportedVerbosities() {
@@ -12762,6 +13486,7 @@ namespace Catch {
         m_xml(_config.stream())
     {
         m_reporterPrefs.shouldRedirectStdOut = true;
+        m_reporterPrefs.shouldReportAllAssertions = true;
     }
 
     XmlReporter::~XmlReporter() = default;
@@ -12818,8 +13543,7 @@ namespace Catch {
         StreamingReporterBase::sectionStarting( sectionInfo );
         if( m_sectionDepth++ > 0 ) {
             m_xml.startElement( "Section" )
-                .writeAttribute( "name", trim( sectionInfo.name ) )
-                .writeAttribute( "description", sectionInfo.description );
+                .writeAttribute( "name", trim( sectionInfo.name ) );
             writeSourceInfo( sectionInfo.lineInfo );
             m_xml.ensureTagClosed();
         }
@@ -13054,13 +13778,14 @@ int main (int argc, char * const argv[]) {
 
 #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_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg) )
+#define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CATCH_CAPTURE",__VA_ARGS__ )
 
 #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_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_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__ )
@@ -13070,11 +13795,12 @@ int main (int argc, char * const argv[]) {
 // "BDD-style" convenience wrappers
 #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
-#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 )
+#define CATCH_GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( "    Given: " << desc )
+#define CATCH_AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
+#define CATCH_WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     When: " << desc )
+#define CATCH_AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
+#define CATCH_THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     Then: " << desc )
+#define CATCH_AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( "      And: " << desc )
 
 // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
 #else
@@ -13112,13 +13838,14 @@ int main (int argc, char * const argv[]) {
 
 #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg )
 #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )
-#define CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg) )
+#define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), "CAPTURE",__VA_ARGS__ )
 
 #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 DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_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__ )
@@ -13132,15 +13859,17 @@ int main (int argc, char * const argv[]) {
 #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
 
-#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 )
+#define GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( "    Given: " << desc )
+#define AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( "And given: " << desc )
+#define WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     When: " << desc )
+#define AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( " And when: " << desc )
+#define THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( "     Then: " << desc )
+#define AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( "      And: " << desc )
 
 using Catch::Detail::Approx;
 
-#else
+#else // CATCH_CONFIG_DISABLE
+
 //////
 // If this config identifier is defined then all CATCH macros are prefixed with CATCH_
 #ifdef CATCH_CONFIG_PREFIX_ALL
@@ -13185,6 +13914,7 @@ using Catch::Detail::Approx;
 #define CATCH_METHOD_AS_TEST_CASE( method, ... )
 #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
 #define CATCH_SECTION( ... )
+#define CATCH_DYNAMIC_SECTION( ... )
 #define CATCH_FAIL( ... ) (void)(0)
 #define CATCH_FAIL_CHECK( ... ) (void)(0)
 #define CATCH_SUCCEED( ... ) (void)(0)
@@ -13195,6 +13925,7 @@ using Catch::Detail::Approx;
 #define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
 #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
 #define CATCH_GIVEN( desc )
+#define CATCH_AND_GIVEN( desc )
 #define CATCH_WHEN( desc )
 #define CATCH_AND_WHEN( desc )
 #define CATCH_THEN( desc )
@@ -13243,6 +13974,7 @@ using Catch::Detail::Approx;
 #define METHOD_AS_TEST_CASE( method, ... )
 #define REGISTER_TEST_CASE( Function, ... ) (void)(0)
 #define SECTION( ... )
+#define DYNAMIC_SECTION( ... )
 #define FAIL( ... ) (void)(0)
 #define FAIL_CHECK( ... ) (void)(0)
 #define SUCCEED( ... ) (void)(0)
@@ -13257,6 +13989,7 @@ using Catch::Detail::Approx;
 #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
 
 #define GIVEN( desc )
+#define AND_GIVEN( desc )
 #define WHEN( desc )
 #define AND_WHEN( desc )
 #define THEN( desc )
diff --git a/packages/Catch2/single_include/catch_reporter_automake.hpp b/packages/Catch2/single_include/catch2/catch_reporter_automake.hpp
similarity index 100%
rename from packages/Catch2/single_include/catch_reporter_automake.hpp
rename to packages/Catch2/single_include/catch2/catch_reporter_automake.hpp
diff --git a/packages/Catch2/single_include/catch_reporter_tap.hpp b/packages/Catch2/single_include/catch2/catch_reporter_tap.hpp
similarity index 98%
rename from packages/Catch2/single_include/catch_reporter_tap.hpp
rename to packages/Catch2/single_include/catch2/catch_reporter_tap.hpp
index 19e54ed197b69e43ddbf4e41213255f0108f0f63..ccc4051be00e60fbf46e25c1b73cb58103d6cb7d 100644
--- a/packages/Catch2/single_include/catch_reporter_tap.hpp
+++ b/packages/Catch2/single_include/catch2/catch_reporter_tap.hpp
@@ -30,9 +30,7 @@ namespace Catch {
         }
 
         ReporterPreferences getPreferences() const override {
-            ReporterPreferences prefs;
-            prefs.shouldRedirectStdOut = false;
-            return prefs;
+            return m_reporterPrefs;
         }
 
         void noMatchingTestCases( std::string const& spec ) override {
diff --git a/packages/Catch2/single_include/catch_reporter_teamcity.hpp b/packages/Catch2/single_include/catch2/catch_reporter_teamcity.hpp
similarity index 98%
rename from packages/Catch2/single_include/catch_reporter_teamcity.hpp
rename to packages/Catch2/single_include/catch2/catch_reporter_teamcity.hpp
index dbd0db532c1536aee08f9a20ac8002109519d098..eca2885cd4e9fde3b5e7008388f4b57f203ce9bc 100644
--- a/packages/Catch2/single_include/catch_reporter_teamcity.hpp
+++ b/packages/Catch2/single_include/catch2/catch_reporter_teamcity.hpp
@@ -97,12 +97,12 @@ namespace Catch {
                     case ResultWas::Ok:
                     case ResultWas::Info:
                     case ResultWas::Warning:
-                        throw std::domain_error( "Internal error in TeamCity reporter" );
+                        CATCH_ERROR( "Internal error in TeamCity reporter" );
                     // These cases are here to prevent compiler warnings
                     case ResultWas::Unknown:
                     case ResultWas::FailureBit:
                     case ResultWas::Exception:
-                        throw std::domain_error( "Not implemented" );
+                        CATCH_ERROR( "Not implemented" );
                 }
                 if( assertionStats.infoMessages.size() == 1 )
                     msg << " with message:";
diff --git a/packages/Catch2/test_package/MainTest.cpp b/packages/Catch2/test_package/MainTest.cpp
index b8ed744e5974746a7f9f55df7f2c8dd8df23df8f..010feba21d083f8287884549357fb2dcf5200d8f 100644
--- a/packages/Catch2/test_package/MainTest.cpp
+++ b/packages/Catch2/test_package/MainTest.cpp
@@ -6,7 +6,7 @@
  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  */
 #define CATCH_CONFIG_MAIN
-#include "catch.hpp"
+#include <catch2/catch.hpp>
 
 unsigned int Factorial( unsigned int number ) {
   return number > 1 ? Factorial(number-1)*number : 1;
diff --git a/packages/Catch2/test_package/conanfile.py b/packages/Catch2/test_package/conanfile.py
index 7ed77b5cafa1477f80778ccff43b8ae1dcf9a010..e8d50f9a8b4dbdcefd7930c60eca8cb5bb01bbd8 100644
--- a/packages/Catch2/test_package/conanfile.py
+++ b/packages/Catch2/test_package/conanfile.py
@@ -10,7 +10,7 @@ class CatchConanTest(ConanFile):
     settings = "os", "compiler", "arch", "build_type"
     username = getenv("CONAN_USERNAME", "philsquared")
     channel = getenv("CONAN_CHANNEL", "testing")
-    requires = "Catch/2.2.3@%s/%s" % (username, channel)
+    requires = "Catch/2.4.1@%s/%s" % (username, channel)
 
     def build(self):
         cmake = CMake(self)
diff --git a/packages/rang/.gitrepo b/packages/rang/.gitrepo
index ecc95b6969d5bded43ce4e711621eaff74f28229..6733a19fc07f7d2c8a7d3eaa4d716256662b9d5c 100644
--- a/packages/rang/.gitrepo
+++ b/packages/rang/.gitrepo
@@ -6,6 +6,6 @@
 [subrepo]
 	remote = git@github.com:agauniyal/rang.git
 	branch = master
-	commit = c43da1f2a8458d469849d6a2bb04d03c3d7a0c64
-	parent = cc3f3d41a0487437be7afa83828df9d204940172
+	commit = f09d567d5afe5230de0676ddecef93daf4a09667
+	parent = fb68ce0527e9597488748018bf8b37cb651270b3
 	cmdver = 0.3.1
diff --git a/packages/rang/README.md b/packages/rang/README.md
index 73967f36715af1a90d86b9bb787ccb716b6dd767..90a196a263099f2b99edc370f38f6980c1afe162 100644
--- a/packages/rang/README.md
+++ b/packages/rang/README.md
@@ -82,8 +82,8 @@ Supported attributes with their compatiblity are listed below -
 | `rang::style::bold`      | yes   | yes   |
 | `rang::style::dim`       | yes   | no    |
 | `rang::style::italic`    | yes   | no    |
-| `rang::style::underline` | yes   | maybe |
-| `rang::style::blink`     | no    | maybe |
+| `rang::style::underline` | yes   | no    |
+| `rang::style::blink`     | no    | no    |
 | `rang::style::rblink`    | no    | no    |
 | `rang::style::reversed`  | yes   | yes   |
 | `rang::style::conceal`   | maybe | yes   |
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index c36e9a2d570b0a385e679904a61dd3b260c25cd8..94118a24d6104092883f9e6280cfd08c5c4ba5d9 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -13,12 +13,12 @@ add_executable (unit_tests
   test_TinyVector.cpp
   )
 
-target_include_directories(Catch INTERFACE ${CATCH_INCLUDE_DIR})
+target_include_directories(Catch2 INTERFACE ${CATCH_INCLUDE_DIR})
 
 target_link_libraries (unit_tests
   PastisUtils
   kokkos
-  Catch
+  Catch2
   )
 
 enable_testing()
diff --git a/tests/test_TinyMatrix.cpp b/tests/test_TinyMatrix.cpp
index 3d80a485e36874cf7c5406bb794d2f1ce6678bd3..62f6134429af652b7df2668b7d1b8d2b5ede25f2 100644
--- a/tests/test_TinyMatrix.cpp
+++ b/tests/test_TinyMatrix.cpp
@@ -195,8 +195,8 @@ TEST_CASE("TinyMatrix", "[algebra]") {
       const TinyMatrix<2,double> I = inverse(A2)*A2;
 
       REQUIRE(I(0,0) == Approx(1).epsilon(1E-14));
-      REQUIRE(I(0,1) == Approx(0).epsilon(1E-14));
-      REQUIRE(I(1,0) == Approx(0).epsilon(1E-14));
+      REQUIRE(I(0,1) == Approx(0).margin (1E-14));
+      REQUIRE(I(1,0) == Approx(0).margin (1E-14));
       REQUIRE(I(1,1) == Approx(1).epsilon(1E-14));
     }
 
@@ -206,15 +206,14 @@ TEST_CASE("TinyMatrix", "[algebra]") {
                                     -2,3,4);
       const TinyMatrix<3,double> I = inverse(A3)*A3;
 
-      // Strangely Approx fails for some 0 ...
       REQUIRE(I(0,0) == Approx(1).epsilon(1E-14));
-      REQUIRE(std::abs(I(0,1))<1E-14);
-      REQUIRE(std::abs(I(0,2))<1E-14);
-      REQUIRE(std::abs(I(1,0))<1E-14);
+      REQUIRE(I(0,1) == Approx(0).margin (1E-14));
+      REQUIRE(I(0,2) == Approx(0).margin (1E-14));
+      REQUIRE(I(1,0) == Approx(0).margin (1E-14));
       REQUIRE(I(1,1) == Approx(1).epsilon(1E-14));
-      REQUIRE(std::abs(I(1,2))<1E-14);
-      REQUIRE(std::abs(I(2,0))<1E-14);
-      REQUIRE(std::abs(I(2,1))<1E-14);
+      REQUIRE(I(1,2) == Approx(0).margin (1E-14));
+      REQUIRE(I(2,0) == Approx(0).margin (1E-14));
+      REQUIRE(I(2,1) == Approx(0).margin (1E-14));
       REQUIRE(I(2,2) == Approx(1).epsilon(1E-14));
     }
   }