diff --git a/skia/goldens/build.sh b/skia/goldens/build.sh
new file mode 100755
index 0000000..e0d0eb5
--- /dev/null
+++ b/skia/goldens/build.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+# dir=$(pwd)
+
+# cd ../renderer
+# ./build.sh $@
+
+# cd $dir
+
+cd build
+
+OPTION=$1
+
+if [ "$OPTION" = 'help' ]; then
+    echo build.sh - build debug library
+    echo build.sh clean - clean the build
+    echo build.sh release - build release library
+elif [ "$OPTION" = "clean" ]; then
+    echo Cleaning project ...
+    # TODO: fix premake5 clean to bubble the clean command to dependent projects
+    premake5 gmake && make clean
+elif [ "$OPTION" = "release" ]; then
+    premake5 gmake && make config=release -j7
+else
+    premake5 gmake && make -j7
+fi
diff --git a/skia/goldens/build/premake5.lua b/skia/goldens/build/premake5.lua
new file mode 100644
index 0000000..d6c3786
--- /dev/null
+++ b/skia/goldens/build/premake5.lua
@@ -0,0 +1,110 @@
+workspace "rive"
+configurations {"debug", "release"}
+
+BASE_DIR = path.getabsolute("../../../build")
+location("./")
+dofile(path.join(BASE_DIR, "premake5.lua"))
+
+BASE_DIR = path.getabsolute("../../renderer/build")
+location("./")
+dofile(path.join(BASE_DIR, "premake5.lua"))
+
+project "goldens"
+    kind "ConsoleApp"
+    language "C++"
+    cppdialect "C++17"
+    toolset "clang"
+    targetdir "%{cfg.system}/bin/%{cfg.buildcfg}"
+    objdir "obj/%{cfg.buildcfg}"
+    includedirs {
+        "../../../include",
+        "../../utils",
+        "../../renderer/include",
+        "../../dependencies/skia",
+        "../../dependencies/skia/include/core",
+        "../../dependencies/skia/include/effects",
+        "../../dependencies/skia/include/gpu",
+        "../../dependencies/skia/include/config",
+        "/usr/local/include",
+        "/usr/include",
+    }
+
+    if os.host() == 'macosx' then
+        links {
+            "Cocoa.framework",
+            "CoreFoundation.framework",
+--            "CoreMedia.framework",
+--            "CoreServices.framework",
+--            "IOKit.framework",
+--            "OpenGL.framework",
+--            "Security.framework",
+            "bz2",
+            "iconv",
+            "lzma",
+            "rive_skia_renderer",
+            "rive",
+            "skia",
+        }
+    elseif os.host() == "windows" then
+        architecture "x64"
+        links {
+            "rive_skia_renderer",
+            "rive",
+            "skia.lib",
+            "opengl32.lib"
+        }
+        defines {"_USE_MATH_DEFINES"}
+        buildoptions {WINDOWS_CLANG_CL_SUPPRESSED_WARNINGS}
+        staticruntime "on"  -- Match Skia's /MT flag for link compatibility
+        runtime "Release"  -- Use /MT even in debug (/MTd is incompatible with Skia)
+    else
+        links {
+            "m",
+            "rive_skia_renderer",
+            "rive",
+            "skia",
+            "dl",
+            "pthread",
+        }
+    end
+
+    libdirs {
+        "../build/%{cfg.system}/bin/%{cfg.buildcfg}",
+        "../../dependencies/skia/out/static",
+        "../../renderer/build/%{cfg.system}/bin/%{cfg.buildcfg}",
+        "/usr/local/lib",
+        "/usr/lib",
+    }
+
+    files {
+        "../../utils/rive_mgr.cpp",
+        "../src/goldens.cpp",
+        "../src/goldens_grid.cpp"
+    }
+
+    buildoptions {"-Wall", "-fno-rtti"}
+
+    filter "configurations:debug"
+    defines {"DEBUG"}
+    symbols "On"
+
+    filter "configurations:release"
+    defines {"RELEASE"}
+    defines {"NDEBUG"}
+    optimize "On"
+
+
+-- Clean Function --
+newaction {
+    trigger = "clean",
+    description = "clean the build",
+    execute = function()
+        print("clean the build...")
+        os.rmdir("./bin")
+        os.rmdir("./obj")
+        os.remove("Makefile")
+        -- no wildcards in os.remove, so use shell
+        os.execute("rm *.make")
+        print("build cleaned")
+    end
+}
diff --git a/skia/goldens/src/goldens.cpp b/skia/goldens/src/goldens.cpp
new file mode 100644
index 0000000..4656480
--- /dev/null
+++ b/skia/goldens/src/goldens.cpp
@@ -0,0 +1,59 @@
+#ifdef TESTING
+#else
+
+#include "goldens_arguments.hpp"
+#include "goldens_grid.hpp"
+
+#include "rive_mgr.hpp"
+#include "rive/animation/animation.hpp"
+#include "rive/animation/linear_animation_instance.hpp"
+#include "rive/animation/linear_animation.hpp"
+#include "rive/artboard.hpp"
+#include "rive/file.hpp"
+
+#include "SkData.h"
+#include "skia_renderer.hpp"
+#include "SkImage.h"
+#include "SkPixmap.h"
+#include "SkStream.h"
+#include "SkSurface.h"
+
+#define DISTURB false
+
+int main(int argc, const char* argv[]) {
+    try {
+        GoldensArguments args(argc, argv);
+
+        const auto info = SkImageInfo::Make(SW, SH, kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
+        auto surf = SkSurface::MakeRaster(info);
+        auto canvas = surf->getCanvas();
+
+        canvas->clear(SK_ColorWHITE);
+
+        rive::SkiaRenderer renderer(canvas);
+
+        RenderGoldensGrid(&renderer, args.source().c_str(), "", "");
+
+        if (DISTURB) {
+            SkPaint p;
+            p.setColor(0x80FF6622);
+            canvas->drawCircle(500, 500, 300, p);
+        }
+
+        auto img = surf->makeImageSnapshot();
+        auto data = img->encodeToData();
+        SkFILEWStream(args.destination().c_str()).write(data->data(), data->size());
+    } catch (const args::Completion& e) {
+        return 0;
+    } catch (const args::Help&) {
+        return 0;
+    } catch (const args::ParseError& e) {
+        return 1;
+    } catch (args::ValidationError e) {
+        return 1;
+    }
+
+    return 0;
+}
+
+#endif
diff --git a/skia/goldens/src/goldens_arguments.hpp b/skia/goldens/src/goldens_arguments.hpp
new file mode 100644
index 0000000..e89e262
--- /dev/null
+++ b/skia/goldens/src/goldens_arguments.hpp
@@ -0,0 +1,72 @@
+#ifndef GOLDENS_ARGUMENTS_HPP
+#define GOLDENS_ARGUMENTS_HPP
+
+#include <iostream>
+#include <memory>
+#include <string>
+
+#include "args.hxx"
+
+class GoldensArguments {
+
+public:
+    GoldensArguments(int argc, const char** argv) {
+        m_Parser = std::make_unique<args::ArgumentParser>(
+            "Reads a (source) .riv file, and optional artboard and animations names, "
+            "and generates the corresponding png grid image, "
+            "storing it in (destination).");
+
+        args::HelpFlag help(*m_Parser, "help", "Display this help menu", {'h', "help"});
+        args::Group required(*m_Parser, "required arguments:", args::Group::Validators::All);
+        args::Group optional(*m_Parser, "optional arguments:", args::Group::Validators::DontCare);
+
+        args::ValueFlag<std::string> source(
+            required, "path", "source riv filename", {'s', "source"});
+        args::ValueFlag<std::string> destination(
+            required, "path", "destination png filename", {'d', "destination"});
+
+        args::ValueFlag<std::string> artboard(
+            optional, "name", "artboard to draw from", {'t', "artboard"});
+        args::ValueFlag<std::string> animation(
+            optional, "name", "animation to be played, determines", {'a', "animation"});
+
+        args::CompletionFlag completion(*m_Parser, {"complete"});
+        try {
+            m_Parser->ParseCLI(argc, argv);
+        } catch (const std::invalid_argument e) {
+            std::cout << e.what();
+            throw;
+        } catch (const args::Completion& e) {
+            std::cout << e.what();
+            throw;
+        } catch (const args::Help&) {
+            std::cout << *m_Parser;
+            throw;
+        } catch (const args::ParseError& e) {
+            std::cerr << e.what() << std::endl;
+            std::cerr << *m_Parser;
+            throw;
+        } catch (args::ValidationError e) {
+            std::cerr << e.what() << std::endl;
+            std::cerr << *m_Parser;
+            throw;
+        }
+
+        m_Destination = args::get(destination);
+        m_Source = args::get(source);
+    }
+
+    const std::string& source() const { return m_Source; }
+    const std::string& destination() const { return m_Destination; }
+    const std::string& artboard() const { return m_Artboard; }
+    const std::string& animation() const { return m_Animation; }
+
+private:
+    std::unique_ptr<args::ArgumentParser> m_Parser;
+
+    std::string m_Source;
+    std::string m_Destination;
+    std::string m_Artboard;
+    std::string m_Animation;
+};
+#endif
diff --git a/skia/goldens/src/goldens_gpu.cpp b/skia/goldens/src/goldens_gpu.cpp
new file mode 100644
index 0000000..6de6425
--- /dev/null
+++ b/skia/goldens/src/goldens_gpu.cpp
@@ -0,0 +1,102 @@
+#ifdef TESTING
+
+// Don't compile this file as part of the "tests" project.
+
+#else
+
+#include "goldens_grid.hpp"
+
+#include "GLFW/glfw3.h"
+#include "skia_renderer.hpp"
+#include "skia/include/core/SkSurface.h"
+#include "skia/include/gpu/GrDirectContext.h"
+#include "skia/include/gpu/gl/GrGLInterface.h"
+#include "skia/include/gpu/gl/GrGLAssembleInterface.h"
+#include "skia/third_party/externals/libpng/png.h"
+#include "tools/write_png_file.hpp"
+#include <iostream>
+#include <string>
+
+static GrGLFuncPtr get_proc_address(void* ctx, const char name[]) {
+    return glfwGetProcAddress(name);
+}
+
+static bool read_line(std::string& line) {
+    if (!std::getline(std::cin, line)) {
+        return false;
+    }
+    while (!line.empty() && (line.back() == '\n' || line.back() == '\r')) {
+        line.pop_back();
+    }
+    return true;
+}
+
+int main(int argc, const char* argv[]) {
+    if (!glfwInit()) {
+        fprintf(stderr, "Failed to initialize glfw.\n");
+        return -1;
+    }
+
+    glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
+    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
+    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
+    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
+
+    GLFWwindow* window = glfwCreateWindow(SW, SH, "Rive Goldens", nullptr, nullptr);
+    if (!window) {
+        glfwTerminate();
+        fprintf(stderr, "Failed to create window.\n");
+        return -1;
+    }
+
+    glfwMakeContextCurrent(window);
+
+    auto grCtx = GrDirectContext::MakeGL(GrGLMakeAssembledInterface(nullptr, get_proc_address));
+
+    GrBackendRenderTarget backendRT(
+        SW, SH, 1 /*samples*/, 0 /*stencilBits*/, {0 /*fbo 0*/, GL_RGBA8});
+
+    SkSurfaceProps surfProps(0, kUnknown_SkPixelGeometry);
+
+    auto surf = SkSurface::MakeFromBackendRenderTarget(grCtx.get(),
+                                                       backendRT,
+                                                       kBottomLeft_GrSurfaceOrigin,
+                                                       kRGBA_8888_SkColorType,
+                                                       nullptr,
+                                                       &surfProps);
+    auto canvas = surf->getCanvas();
+    rive::SkiaRenderer renderer(canvas);
+
+    std::string source, artboard, animation, destination;
+    while (read_line(source) && read_line(artboard) && read_line(animation) &&
+           read_line(destination)) {
+        try {
+            canvas->clear(SK_ColorWHITE);
+
+            renderer.save();
+
+            RenderGoldensGrid(&renderer, source.c_str(), artboard.c_str(), animation.c_str());
+
+            renderer.restore();
+            canvas->flush();
+
+            std::vector<uint8_t> pixels(SH * SW * 4);
+            glReadPixels(0, 0, SW, SH, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
+            WritePNGFile(pixels.data(), SW, SH, true, destination.c_str());
+
+            glfwSwapBuffers(window);
+        } catch (const char* msg) {
+            fprintf(stderr, "%s: error: %s\n", source.c_str(), msg);
+            fflush(stderr);
+        } catch (...) {
+            fprintf(stderr, "error rendering %s\n", source.c_str());
+            fflush(stderr);
+        }
+        fprintf(stdout, "finished %s\n", source.c_str());
+        fflush(stdout);
+    }
+
+    return 0;
+}
+
+#endif
diff --git a/skia/goldens/src/goldens_grid.cpp b/skia/goldens/src/goldens_grid.cpp
new file mode 100644
index 0000000..8218870
--- /dev/null
+++ b/skia/goldens/src/goldens_grid.cpp
@@ -0,0 +1,60 @@
+#ifdef TESTING
+
+// Don't compile this file as part of the "tests" project.
+
+#else
+
+#include "goldens_grid.hpp"
+
+#include "rive_mgr.hpp"
+#include "rive/animation/animation.hpp"
+#include "rive/animation/linear_animation_instance.hpp"
+#include "rive/animation/linear_animation.hpp"
+#include "rive/artboard.hpp"
+
+void RenderGoldensGrid(rive::Renderer* renderer,
+                       const char* source,
+                       const char* artboardName,
+                       const char* animationName) {
+    RiveMgr mgr;
+    if (!mgr.load(source, artboardName, animationName)) {
+        throw "Can't load animation";
+    }
+    auto artboard = mgr.artboard();
+    if (!artboard) {
+        throw "No artboard";
+    }
+    auto animation = mgr.animation();
+    if (!animation) {
+        throw "No animation";
+    }
+
+    const int FRAMES = H * W;
+    const double duration = animation->durationSeconds();
+    const double frameDuration = duration / FRAMES;
+    const rive::AABB dstBounds = rive::AABB(0, 0, CELL, CELL);
+
+    artboard->advance(0);
+    animation->advance(0);
+
+    renderer->translate(GAP, GAP);
+    for (int y = 0; y < H; ++y) {
+        for (int x = 0; x < W; ++x) {
+            renderer->save();
+
+            animation->apply();
+
+            renderer->translate(x * (CELL + GAP), y * (CELL + GAP));
+            renderer->align(
+                rive::Fit::cover, rive::Alignment::center, dstBounds, artboard->bounds());
+            artboard->draw(renderer);
+
+            animation->advance(frameDuration);
+            artboard->advance(frameDuration);
+
+            renderer->restore();
+        }
+    }
+}
+
+#endif
diff --git a/skia/goldens/src/goldens_grid.hpp b/skia/goldens/src/goldens_grid.hpp
new file mode 100644
index 0000000..881d87d
--- /dev/null
+++ b/skia/goldens/src/goldens_grid.hpp
@@ -0,0 +1,20 @@
+#ifndef GOLDENS_GRID_HPP
+#define GOLDENS_GRID_HPP
+
+namespace rive {
+    class Renderer;
+}
+
+constexpr static int CELL = 256;
+constexpr static int W = 5;
+constexpr static int H = 5;
+constexpr static int GAP = 2;
+constexpr static int SW = W * CELL + (W + 1) * GAP;
+constexpr static int SH = H * CELL + (H + 1) * GAP;
+
+void RenderGoldensGrid(rive::Renderer* renderer,
+                       const char* source,
+                       const char* artboardName,
+                       const char* animationName);
+
+#endif
diff --git a/skia/utils/args.hxx b/skia/utils/args.hxx
new file mode 100644
index 0000000..bbc521d
--- /dev/null
+++ b/skia/utils/args.hxx
@@ -0,0 +1,4260 @@
+/* Copyright (c) 2016-2017 Taylor C. Richberger <taywee@gmx.com> and Pavel
+ * Belikov
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/** \file args.hxx
+ * \brief this single-header lets you use all of the args functionality
+ *
+ * The important stuff is done inside the args namespace
+ */
+
+#ifndef ARGS_HXX
+#define ARGS_HXX
+
+#include <algorithm>
+#include <iterator>
+#include <exception>
+#include <functional>
+#include <sstream>
+#include <string>
+#include <tuple>
+#include <vector>
+#include <unordered_map>
+#include <unordered_set>
+#include <type_traits>
+
+#ifdef ARGS_TESTNAMESPACE
+namespace argstest
+{
+#else
+
+/** \namespace args
+ * \brief contains all the functionality of the args library
+ */
+namespace args
+{
+#endif
+    /** Getter to grab the value from the argument type.
+     *
+     * If the Get() function of the type returns a reference, so does this, and
+     * the value will be modifiable.
+     */
+    template <typename Option>
+    auto get(Option &option_) -> decltype(option_.Get())
+    {
+        return option_.Get();
+    }
+
+    /** (INTERNAL) Count UTF-8 glyphs
+     *
+     * This is not reliable, and will fail for combinatory glyphs, but it's
+     * good enough here for now.
+     *
+     * \param string The string to count glyphs from
+     * \return The UTF-8 glyphs in the string
+     */
+    inline std::string::size_type Glyphs(const std::string &string_)
+    {
+        std::string::size_type length = 0;
+        for (const char c: string_)
+        {
+            if ((c & 0xc0) != 0x80)
+            {
+                ++length;
+            }
+        }
+        return length;
+    }
+
+    /** (INTERNAL) Wrap a vector of words into a vector of lines
+     *
+     * Empty words are skipped. Word "\n" forces wrapping.
+     *
+     * \param begin The begin iterator
+     * \param end The end iterator
+     * \param width The width of the body
+     * \param firstlinewidth the width of the first line, defaults to the width of the body
+     * \param firstlineindent the indent of the first line, defaults to 0
+     * \return the vector of lines
+     */
+    template <typename It>
+    inline std::vector<std::string> Wrap(It begin,
+                                         It end,
+                                         const std::string::size_type width,
+                                         std::string::size_type firstlinewidth = 0,
+                                         std::string::size_type firstlineindent = 0)
+    {
+        std::vector<std::string> output;
+        std::string line(firstlineindent, ' ');
+        bool empty = true;
+
+        if (firstlinewidth == 0)
+        {
+            firstlinewidth = width;
+        }
+
+        auto currentwidth = firstlinewidth;
+
+        for (auto it = begin; it != end; ++it)
+        {
+            if (it->empty())
+            {
+                continue;
+            }
+
+            if (*it == "\n")
+            {
+                if (!empty)
+                {
+                    output.push_back(line);
+                    line.clear();
+                    empty = true;
+                    currentwidth = width;
+                }
+
+                continue;
+            }
+
+            auto itemsize = Glyphs(*it);
+            if ((line.length() + 1 + itemsize) > currentwidth)
+            {
+                if (!empty)
+                {
+                    output.push_back(line);
+                    line.clear();
+                    empty = true;
+                    currentwidth = width;
+                }
+            }
+
+            if (itemsize > 0)
+            {
+                if (!empty)
+                {
+                    line += ' ';
+                }
+
+                line += *it;
+                empty = false;
+            }
+        }
+
+        if (!empty)
+        {
+            output.push_back(line);
+        }
+
+        return output;
+    }
+
+    namespace detail
+    {
+        template <typename T>
+        std::string Join(const T& array, const std::string &delimiter)
+        {
+            std::string res;
+            for (auto &element : array)
+            {
+                if (!res.empty())
+                {
+                    res += delimiter;
+                }
+
+                res += element;
+            }
+
+            return res;
+        }
+    }
+
+    /** (INTERNAL) Wrap a string into a vector of lines
+     *
+     * This is quick and hacky, but works well enough.  You can specify a
+     * different width for the first line
+     *
+     * \param width The width of the body
+     * \param firstlinewid the width of the first line, defaults to the width of the body
+     * \return the vector of lines
+     */
+    inline std::vector<std::string> Wrap(const std::string &in, const std::string::size_type width, std::string::size_type firstlinewidth = 0)
+    {
+        // Preserve existing line breaks
+        const auto newlineloc = in.find('\n');
+        if (newlineloc != in.npos)
+        {
+            auto first = Wrap(std::string(in, 0, newlineloc), width);
+            auto second = Wrap(std::string(in, newlineloc + 1), width);
+            first.insert(
+                std::end(first),
+                std::make_move_iterator(std::begin(second)),
+                std::make_move_iterator(std::end(second)));
+            return first;
+        }
+
+        std::istringstream stream(in);
+        std::string::size_type indent = 0;
+
+        for (char c : in)
+        {
+            if (!isspace(c))
+            {
+                break;
+            }
+            ++indent;
+        }
+
+        return Wrap(std::istream_iterator<std::string>(stream), std::istream_iterator<std::string>(),
+                    width, firstlinewidth, indent);
+    }
+
+#ifdef ARGS_NOEXCEPT
+    /// Error class, for when ARGS_NOEXCEPT is defined
+    enum class Error
+    {
+        None,
+        Usage,
+        Parse,
+        Validation,
+        Required,
+        Map,
+        Extra,
+        Help,
+        Subparser,
+        Completion,
+    };
+#else
+    /** Base error class
+     */
+    class Error : public std::runtime_error
+    {
+        public:
+            Error(const std::string &problem) : std::runtime_error(problem) {}
+            virtual ~Error() {}
+    };
+
+    /** Errors that occur during usage
+     */
+    class UsageError : public Error
+    {
+        public:
+            UsageError(const std::string &problem) : Error(problem) {}
+            virtual ~UsageError() {}
+    };
+
+    /** Errors that occur during regular parsing
+     */
+    class ParseError : public Error
+    {
+        public:
+            ParseError(const std::string &problem) : Error(problem) {}
+            virtual ~ParseError() {}
+    };
+
+    /** Errors that are detected from group validation after parsing finishes
+     */
+    class ValidationError : public Error
+    {
+        public:
+            ValidationError(const std::string &problem) : Error(problem) {}
+            virtual ~ValidationError() {}
+    };
+
+    /** Errors that when a required flag is omitted
+     */
+    class RequiredError : public ValidationError
+    {
+        public:
+            RequiredError(const std::string &problem) : ValidationError(problem) {}
+            virtual ~RequiredError() {}
+    };
+
+    /** Errors in map lookups
+     */
+    class MapError : public ParseError
+    {
+        public:
+            MapError(const std::string &problem) : ParseError(problem) {}
+            virtual ~MapError() {}
+    };
+
+    /** Error that occurs when a singular flag is specified multiple times
+     */
+    class ExtraError : public ParseError
+    {
+        public:
+            ExtraError(const std::string &problem) : ParseError(problem) {}
+            virtual ~ExtraError() {}
+    };
+
+    /** An exception that indicates that the user has requested help
+     */
+    class Help : public Error
+    {
+        public:
+            Help(const std::string &flag) : Error(flag) {}
+            virtual ~Help() {}
+    };
+
+    /** (INTERNAL) An exception that emulates coroutine-like control flow for subparsers.
+     */
+    class SubparserError : public Error
+    {
+        public:
+            SubparserError() : Error("") {}
+            virtual ~SubparserError() {}
+    };
+
+    /** An exception that contains autocompletion reply
+     */
+    class Completion : public Error
+    {
+        public:
+            Completion(const std::string &flag) : Error(flag) {}
+            virtual ~Completion() {}
+    };
+#endif
+
+    /** A simple unified option type for unified initializer lists for the Matcher class.
+     */
+    struct EitherFlag
+    {
+        const bool isShort;
+        const char shortFlag;
+        const std::string longFlag;
+        EitherFlag(const std::string &flag) : isShort(false), shortFlag(), longFlag(flag) {}
+        EitherFlag(const char *flag) : isShort(false), shortFlag(), longFlag(flag) {}
+        EitherFlag(const char flag) : isShort(true), shortFlag(flag), longFlag() {}
+
+        /** Get just the long flags from an initializer list of EitherFlags
+         */
+        static std::unordered_set<std::string> GetLong(std::initializer_list<EitherFlag> flags)
+        {
+            std::unordered_set<std::string>  longFlags;
+            for (const EitherFlag &flag: flags)
+            {
+                if (!flag.isShort)
+                {
+                    longFlags.insert(flag.longFlag);
+                }
+            }
+            return longFlags;
+        }
+
+        /** Get just the short flags from an initializer list of EitherFlags
+         */
+        static std::unordered_set<char> GetShort(std::initializer_list<EitherFlag> flags)
+        {
+            std::unordered_set<char>  shortFlags;
+            for (const EitherFlag &flag: flags)
+            {
+                if (flag.isShort)
+                {
+                    shortFlags.insert(flag.shortFlag);
+                }
+            }
+            return shortFlags;
+        }
+
+        std::string str() const
+        {
+            return isShort ? std::string(1, shortFlag) : longFlag;
+        }
+
+        std::string str(const std::string &shortPrefix, const std::string &longPrefix) const
+        {
+            return isShort ? shortPrefix + std::string(1, shortFlag) : longPrefix + longFlag;
+        }
+    };
+
+
+
+    /** A class of "matchers", specifying short and flags that can possibly be
+     * matched.
+     *
+     * This is supposed to be constructed and then passed in, not used directly
+     * from user code.
+     */
+    class Matcher
+    {
+        private:
+            const std::unordered_set<char> shortFlags;
+            const std::unordered_set<std::string> longFlags;
+
+        public:
+            /** Specify short and long flags separately as iterators
+             *
+             * ex: `args::Matcher(shortFlags.begin(), shortFlags.end(), longFlags.begin(), longFlags.end())`
+             */
+            template <typename ShortIt, typename LongIt>
+            Matcher(ShortIt shortFlagsStart, ShortIt shortFlagsEnd, LongIt longFlagsStart, LongIt longFlagsEnd) :
+                shortFlags(shortFlagsStart, shortFlagsEnd),
+                longFlags(longFlagsStart, longFlagsEnd)
+            {
+                if (shortFlags.empty() && longFlags.empty())
+                {
+#ifndef ARGS_NOEXCEPT
+                    throw UsageError("empty Matcher");
+#endif
+                }
+            }
+
+#ifdef ARGS_NOEXCEPT
+            /// Only for ARGS_NOEXCEPT
+            Error GetError() const noexcept
+            {
+                return shortFlags.empty() && longFlags.empty() ? Error::Usage : Error::None;
+            }
+#endif
+
+            /** Specify short and long flags separately as iterables
+             *
+             * ex: `args::Matcher(shortFlags, longFlags)`
+             */
+            template <typename Short, typename Long>
+            Matcher(Short &&shortIn, Long &&longIn) :
+                Matcher(std::begin(shortIn), std::end(shortIn), std::begin(longIn), std::end(longIn))
+            {}
+
+            /** Specify a mixed single initializer-list of both short and long flags
+             *
+             * This is the fancy one.  It takes a single initializer list of
+             * any number of any mixed kinds of flags.  Chars are
+             * automatically interpreted as short flags, and strings are
+             * automatically interpreted as long flags:
+             *
+             *     args::Matcher{'a'}
+             *     args::Matcher{"foo"}
+             *     args::Matcher{'h', "help"}
+             *     args::Matcher{"foo", 'f', 'F', "FoO"}
+             */
+            Matcher(std::initializer_list<EitherFlag> in) :
+                Matcher(EitherFlag::GetShort(in), EitherFlag::GetLong(in)) {}
+
+            Matcher(Matcher &&other) : shortFlags(std::move(other.shortFlags)), longFlags(std::move(other.longFlags))
+            {}
+
+            ~Matcher() {}
+
+            /** (INTERNAL) Check if there is a match of a short flag
+             */
+            bool Match(const char flag) const
+            {
+                return shortFlags.find(flag) != shortFlags.end();
+            }
+
+            /** (INTERNAL) Check if there is a match of a long flag
+             */
+            bool Match(const std::string &flag) const
+            {
+                return longFlags.find(flag) != longFlags.end();
+            }
+
+            /** (INTERNAL) Check if there is a match of a flag
+             */
+            bool Match(const EitherFlag &flag) const
+            {
+                return flag.isShort ? Match(flag.shortFlag) : Match(flag.longFlag);
+            }
+
+            /** (INTERNAL) Get all flag strings as a vector, with the prefixes embedded
+             */
+            std::vector<EitherFlag> GetFlagStrings() const
+            {
+                std::vector<EitherFlag> flagStrings;
+                flagStrings.reserve(shortFlags.size() + longFlags.size());
+                for (const char flag: shortFlags)
+                {
+                    flagStrings.emplace_back(flag);
+                }
+                for (const std::string &flag: longFlags)
+                {
+                    flagStrings.emplace_back(flag);
+                }
+                return flagStrings;
+            }
+
+            /** (INTERNAL) Get long flag if it exists or any short flag
+             */
+            EitherFlag GetLongOrAny() const
+            {
+                if (!longFlags.empty())
+                {
+                    return *longFlags.begin();
+                }
+
+                if (!shortFlags.empty())
+                {
+                    return *shortFlags.begin();
+                }
+
+                // should be unreachable
+                return ' ';
+            }
+
+            /** (INTERNAL) Get short flag if it exists or any long flag
+             */
+            EitherFlag GetShortOrAny() const
+            {
+                if (!shortFlags.empty())
+                {
+                    return *shortFlags.begin();
+                }
+
+                if (!longFlags.empty())
+                {
+                    return *longFlags.begin();
+                }
+
+                // should be unreachable
+                return ' ';
+            }
+    };
+
+    /** Attributes for flags.
+     */
+    enum class Options
+    {
+        /** Default options.
+         */
+        None = 0x0,
+
+        /** Flag can't be passed multiple times.
+         */
+        Single = 0x01,
+
+        /** Flag can't be omitted.
+         */
+        Required = 0x02,
+
+        /** Flag is excluded from usage line.
+         */
+        HiddenFromUsage = 0x04,
+
+        /** Flag is excluded from options help.
+         */
+        HiddenFromDescription = 0x08,
+
+        /** Flag is global and can be used in any subcommand.
+         */
+        Global = 0x10,
+
+        /** Flag stops a parser.
+         */
+        KickOut = 0x20,
+
+        /** Flag is excluded from auto completion.
+         */
+        HiddenFromCompletion = 0x40,
+
+        /** Flag is excluded from options help and usage line
+         */
+        Hidden = HiddenFromUsage | HiddenFromDescription | HiddenFromCompletion,
+    };
+
+    inline Options operator | (Options lhs, Options rhs)
+    {
+        return static_cast<Options>(static_cast<int>(lhs) | static_cast<int>(rhs));
+    }
+
+    inline Options operator & (Options lhs, Options rhs)
+    {
+        return static_cast<Options>(static_cast<int>(lhs) & static_cast<int>(rhs));
+    }
+
+    class FlagBase;
+    class PositionalBase;
+    class Command;
+    class ArgumentParser;
+
+    /** A simple structure of parameters for easy user-modifyable help menus
+     */
+    struct HelpParams
+    {
+        /** The width of the help menu
+         */
+        unsigned int width = 80;
+        /** The indent of the program line
+         */
+        unsigned int progindent = 2;
+        /** The indent of the program trailing lines for long parameters
+         */
+        unsigned int progtailindent = 4;
+        /** The indent of the description and epilogs
+         */
+        unsigned int descriptionindent = 4;
+        /** The indent of the flags
+         */
+        unsigned int flagindent = 6;
+        /** The indent of the flag descriptions
+         */
+        unsigned int helpindent = 40;
+        /** The additional indent each group adds
+         */
+        unsigned int eachgroupindent = 2;
+
+        /** The minimum gutter between each flag and its help
+         */
+        unsigned int gutter = 1;
+
+        /** Show the terminator when both options and positional parameters are present
+         */
+        bool showTerminator = true;
+
+        /** Show the {OPTIONS} on the prog line when this is true
+         */
+        bool showProglineOptions = true;
+
+        /** Show the positionals on the prog line when this is true
+         */
+        bool showProglinePositionals = true;
+
+        /** The prefix for short flags
+         */
+        std::string shortPrefix;
+
+        /** The prefix for long flags
+         */
+        std::string longPrefix;
+
+        /** The separator for short flags
+         */
+        std::string shortSeparator;
+
+        /** The separator for long flags
+         */
+        std::string longSeparator;
+
+        /** The program name for help generation
+         */
+        std::string programName;
+
+        /** Show command's flags
+         */
+        bool showCommandChildren = false;
+
+        /** Show command's descriptions and epilog
+         */
+        bool showCommandFullHelp = false;
+
+        /** The postfix for progline when showProglineOptions is true and command has any flags
+         */
+        std::string proglineOptions = "{OPTIONS}";
+
+        /** The prefix for progline when command has any subcommands
+         */
+        std::string proglineCommand = "COMMAND";
+
+        /** The prefix for progline value
+         */
+        std::string proglineValueOpen = " <";
+
+        /** The postfix for progline value
+         */
+        std::string proglineValueClose = ">";
+
+        /** The prefix for progline required argument
+         */
+        std::string proglineRequiredOpen = "";
+
+        /** The postfix for progline required argument
+         */
+        std::string proglineRequiredClose = "";
+
+        /** The prefix for progline non-required argument
+         */
+        std::string proglineNonrequiredOpen = "[";
+
+        /** The postfix for progline non-required argument
+         */
+        std::string proglineNonrequiredClose = "]";
+
+        /** Show flags in program line
+         */
+        bool proglineShowFlags = false;
+
+        /** Use short flags in program lines when possible
+         */
+        bool proglinePreferShortFlags = false;
+
+        /** Program line prefix
+         */
+        std::string usageString;
+
+        /** String shown in help before flags descriptions
+         */
+        std::string optionsString = "OPTIONS:";
+
+        /** Display value name after all the long and short flags
+         */
+        bool useValueNameOnce = false;
+
+        /** Show value name
+         */
+        bool showValueName = true;
+
+        /** Add newline before flag description
+         */
+        bool addNewlineBeforeDescription = false;
+
+        /** The prefix for option value
+         */
+        std::string valueOpen = "[";
+
+        /** The postfix for option value
+         */
+        std::string valueClose = "]";
+
+        /** Add choices to argument description
+         */
+        bool addChoices = false;
+
+        /** The prefix for choices
+         */
+        std::string choiceString = "\nOne of: ";
+
+        /** Add default values to argument description
+         */
+        bool addDefault = false;
+
+        /** The prefix for default values
+         */
+        std::string defaultString = "\nDefault: ";
+    };
+
+    /** A number of arguments which can be consumed by an option.
+     *
+     * Represents a closed interval [min, max].
+     */
+    struct Nargs
+    {
+        const size_t min;
+        const size_t max;
+
+        Nargs(size_t min_, size_t max_) : min{min_}, max{max_}
+        {
+#ifndef ARGS_NOEXCEPT
+            if (max < min)
+            {
+                throw UsageError("Nargs: max > min");
+            }
+#endif
+        }
+
+        Nargs(size_t num_) : min{num_}, max{num_}
+        {
+        }
+
+        friend bool operator == (const Nargs &lhs, const Nargs &rhs)
+        {
+            return lhs.min == rhs.min && lhs.max == rhs.max;
+        }
+
+        friend bool operator != (const Nargs &lhs, const Nargs &rhs)
+        {
+            return !(lhs == rhs);
+        }
+    };
+
+    /** Base class for all match types
+     */
+    class Base
+    {
+        private:
+            Options options = {};
+
+        protected:
+            bool matched = false;
+            const std::string help;
+#ifdef ARGS_NOEXCEPT
+            /// Only for ARGS_NOEXCEPT
+            mutable Error error = Error::None;
+            mutable std::string errorMsg;
+#endif
+
+        public:
+            Base(const std::string &help_, Options options_ = {}) : options(options_), help(help_) {}
+            virtual ~Base() {}
+
+            Options GetOptions() const noexcept
+            {
+                return options;
+            }
+
+            bool IsRequired() const noexcept
+            {
+                return (GetOptions() & Options::Required) != Options::None;
+            }
+
+            virtual bool Matched() const noexcept
+            {
+                return matched;
+            }
+
+            virtual void Validate(const std::string &, const std::string &) const
+            {
+            }
+
+            operator bool() const noexcept
+            {
+                return Matched();
+            }
+
+            virtual std::vector<std::tuple<std::string, std::string, unsigned>> GetDescription(const HelpParams &, const unsigned indentLevel) const
+            {
+                std::tuple<std::string, std::string, unsigned> description;
+                std::get<1>(description) = help;
+                std::get<2>(description) = indentLevel;
+                return { std::move(description) };
+            }
+
+            virtual std::vector<Command*> GetCommands()
+            {
+                return {};
+            }
+
+            virtual bool IsGroup() const
+            {
+                return false;
+            }
+
+            virtual FlagBase *Match(const EitherFlag &)
+            {
+                return nullptr;
+            }
+
+            virtual PositionalBase *GetNextPositional()
+            {
+                return nullptr;
+            }
+
+            virtual std::vector<FlagBase*> GetAllFlags()
+            {
+                return {};
+            }
+
+            virtual bool HasFlag() const
+            {
+                return false;
+            }
+
+            virtual bool HasPositional() const
+            {
+                return false;
+            }
+
+            virtual bool HasCommand() const
+            {
+                return false;
+            }
+
+            virtual std::vector<std::string> GetProgramLine(const HelpParams &) const
+            {
+                return {};
+            }
+
+            /// Sets a kick-out value for building subparsers
+            void KickOut(bool kickout_) noexcept
+            {
+                if (kickout_)
+                {
+                    options = options | Options::KickOut;
+                }
+                else
+                {
+                    options = static_cast<Options>(static_cast<int>(options) & ~static_cast<int>(Options::KickOut));
+                }
+            }
+
+            /// Gets the kick-out value for building subparsers
+            bool KickOut() const noexcept
+            {
+                return (options & Options::KickOut) != Options::None;
+            }
+
+            virtual void Reset() noexcept
+            {
+                matched = false;
+#ifdef ARGS_NOEXCEPT
+                error = Error::None;
+                errorMsg.clear();
+#endif
+            }
+
+#ifdef ARGS_NOEXCEPT
+            /// Only for ARGS_NOEXCEPT
+            virtual Error GetError() const
+            {
+                return error;
+            }
+
+            /// Only for ARGS_NOEXCEPT
+            std::string GetErrorMsg() const
+            {
+                return errorMsg;
+            }
+#endif
+    };
+
+    /** Base class for all match types that have a name
+     */
+    class NamedBase : public Base
+    {
+        protected:
+            const std::string name;
+            bool kickout = false;
+            std::string defaultString;
+            bool defaultStringManual = false;
+            std::vector<std::string> choicesStrings;
+            bool choicesStringManual = false;
+
+            virtual std::string GetDefaultString(const HelpParams&) const { return {}; }
+
+            virtual std::vector<std::string> GetChoicesStrings(const HelpParams&) const { return {}; }
+
+            virtual std::string GetNameString(const HelpParams&) const { return Name(); }
+
+            void AddDescriptionPostfix(std::string &dest, const bool isManual, const std::string &manual, bool isGenerated, const std::string &generated, const std::string &str) const
+            {
+                if (isManual && !manual.empty())
+                {
+                    dest += str;
+                    dest += manual;
+                }
+                else if (!isManual && isGenerated && !generated.empty())
+                {
+                    dest += str;
+                    dest += generated;
+                }
+            }
+
+        public:
+            NamedBase(const std::string &name_, const std::string &help_, Options options_ = {}) : Base(help_, options_), name(name_) {}
+            virtual ~NamedBase() {}
+
+            /** Sets default value string that will be added to argument description.
+             *  Use empty string to disable it for this argument.
+             */
+            void HelpDefault(const std::string &str)
+            {
+                defaultStringManual = true;
+                defaultString = str;
+            }
+
+            /** Gets default value string that will be added to argument description.
+             */
+            std::string HelpDefault(const HelpParams &params) const
+            {
+                return defaultStringManual ? defaultString : GetDefaultString(params);
+            }
+
+            /** Sets choices strings that will be added to argument description.
+             *  Use empty vector to disable it for this argument.
+             */
+            void HelpChoices(const std::vector<std::string> &array)
+            {
+                choicesStringManual = true;
+                choicesStrings = array;
+            }
+
+            /** Gets choices strings that will be added to argument description.
+             */
+            std::vector<std::string> HelpChoices(const HelpParams &params) const
+            {
+                return choicesStringManual ? choicesStrings : GetChoicesStrings(params);
+            }
+
+            virtual std::vector<std::tuple<std::string, std::string, unsigned>> GetDescription(const HelpParams &params, const unsigned indentLevel) const override
+            {
+                std::tuple<std::string, std::string, unsigned> description;
+                std::get<0>(description) = GetNameString(params);
+                std::get<1>(description) = help;
+                std::get<2>(description) = indentLevel;
+
+                AddDescriptionPostfix(std::get<1>(description), choicesStringManual, detail::Join(choicesStrings, ", "), params.addChoices, detail::Join(GetChoicesStrings(params), ", "), params.choiceString);
+                AddDescriptionPostfix(std::get<1>(description), defaultStringManual, defaultString, params.addDefault, GetDefaultString(params), params.defaultString);
+
+                return { std::move(description) };
+            }
+
+            virtual std::string Name() const
+            {
+                return name;
+            }
+    };
+
+    namespace detail
+    {
+        template <typename T, typename = int>
+        struct IsConvertableToString : std::false_type {};
+
+        template <typename T>
+        struct IsConvertableToString<T, decltype(std::declval<std::ostringstream&>() << std::declval<T>(), int())> : std::true_type {};
+
+        template <typename T>
+        typename std::enable_if<IsConvertableToString<T>::value, std::string>::type
+        ToString(const T &value)
+        {
+            std::ostringstream s;
+            s << value;
+            return s.str();
+        }
+
+        template <typename T>
+        typename std::enable_if<!IsConvertableToString<T>::value, std::string>::type
+        ToString(const T &)
+        {
+            return {};
+        }
+
+        template <typename T>
+        std::vector<std::string> MapKeysToStrings(const T &map)
+        {
+            std::vector<std::string> res;
+            using K = typename std::decay<decltype(std::begin(map)->first)>::type;
+            if (IsConvertableToString<K>::value)
+            {
+                for (const auto &p : map)
+                {
+                    res.push_back(detail::ToString(p.first));
+                }
+
+                std::sort(res.begin(), res.end());
+            }
+            return res;
+        }
+    }
+
+    /** Base class for all flag options
+     */
+    class FlagBase : public NamedBase
+    {
+        protected:
+            const Matcher matcher;
+
+            virtual std::string GetNameString(const HelpParams &params) const override
+            {
+                const std::string postfix = !params.showValueName || NumberOfArguments() == 0 ? std::string() : Name();
+                std::string flags;
+                const auto flagStrings = matcher.GetFlagStrings();
+                const bool useValueNameOnce = flagStrings.size() == 1 ? false : params.useValueNameOnce;
+                for (auto it = flagStrings.begin(); it != flagStrings.end(); ++it)
+                {
+                    auto &flag = *it;
+                    if (it != flagStrings.begin())
+                    {
+                        flags += ", ";
+                    }
+
+                    flags += flag.isShort ? params.shortPrefix : params.longPrefix;
+                    flags += flag.str();
+
+                    if (!postfix.empty() && (!useValueNameOnce || it + 1 == flagStrings.end()))
+                    {
+                        flags += flag.isShort ? params.shortSeparator : params.longSeparator;
+                        flags += params.valueOpen + postfix + params.valueClose;
+                    }
+                }
+
+                return flags;
+            }
+
+        public:
+            FlagBase(const std::string &name_, const std::string &help_, Matcher &&matcher_, const bool extraError_ = false) : NamedBase(name_, help_, extraError_ ? Options::Single : Options()), matcher(std::move(matcher_)) {}
+
+            FlagBase(const std::string &name_, const std::string &help_, Matcher &&matcher_, Options options_) : NamedBase(name_, help_, options_), matcher(std::move(matcher_)) {}
+
+            virtual ~FlagBase() {}
+
+            virtual FlagBase *Match(const EitherFlag &flag) override
+            {
+                if (matcher.Match(flag))
+                {
+                    if ((GetOptions() & Options::Single) != Options::None && matched)
+                    {
+                        std::ostringstream problem;
+                        problem << "Flag '" << flag.str() << "' was passed multiple times, but is only allowed to be passed once";
+#ifdef ARGS_NOEXCEPT
+                        error = Error::Extra;
+                        errorMsg = problem.str();
+#else
+                        throw ExtraError(problem.str());
+#endif
+                    }
+                    matched = true;
+                    return this;
+                }
+                return nullptr;
+            }
+
+            virtual std::vector<FlagBase*> GetAllFlags() override
+            {
+                return { this };
+            }
+
+            const Matcher &GetMatcher() const
+            {
+                return matcher;
+            }
+
+            virtual void Validate(const std::string &shortPrefix, const std::string &longPrefix) const override
+            {
+                if (!Matched() && IsRequired())
+                {
+                        std::ostringstream problem;
+                        problem << "Flag '" << matcher.GetLongOrAny().str(shortPrefix, longPrefix) << "' is required";
+#ifdef ARGS_NOEXCEPT
+                        error = Error::Required;
+                        errorMsg = problem.str();
+#else
+                        throw RequiredError(problem.str());
+#endif
+                }
+            }
+
+            virtual std::vector<std::string> GetProgramLine(const HelpParams &params) const override
+            {
+                if (!params.proglineShowFlags)
+                {
+                    return {};
+                }
+
+                const std::string postfix = NumberOfArguments() == 0 ? std::string() : Name();
+                const EitherFlag flag = params.proglinePreferShortFlags ? matcher.GetShortOrAny() : matcher.GetLongOrAny();
+                std::string res = flag.str(params.shortPrefix, params.longPrefix);
+                if (!postfix.empty())
+                {
+                    res += params.proglineValueOpen + postfix + params.proglineValueClose;
+                }
+
+                return { IsRequired() ? params.proglineRequiredOpen + res + params.proglineRequiredClose
+                                      : params.proglineNonrequiredOpen + res + params.proglineNonrequiredClose };
+            }
+
+            virtual bool HasFlag() const override
+            {
+                return true;
+            }
+
+#ifdef ARGS_NOEXCEPT
+            /// Only for ARGS_NOEXCEPT
+            virtual Error GetError() const override
+            {
+                const auto nargs = NumberOfArguments();
+                if (nargs.min > nargs.max)
+                {
+                    return Error::Usage;
+                }
+
+                const auto matcherError = matcher.GetError();
+                if (matcherError != Error::None)
+                {
+                    return matcherError;
+                }
+
+                return error;
+            }
+#endif
+
+            /** Defines how many values can be consumed by this option.
+             *
+             * \return closed interval [min, max]
+             */
+            virtual Nargs NumberOfArguments() const noexcept = 0;
+
+            /** Parse values of this option.
+             *
+             * \param value Vector of values. It's size must be in NumberOfArguments() interval.
+             */
+            virtual void ParseValue(const std::vector<std::string> &value) = 0;
+    };
+
+    /** Base class for value-accepting flag options
+     */
+    class ValueFlagBase : public FlagBase
+    {
+        public:
+            ValueFlagBase(const std::string &name_, const std::string &help_, Matcher &&matcher_, const bool extraError_ = false) : FlagBase(name_, help_, std::move(matcher_), extraError_) {}
+            ValueFlagBase(const std::string &name_, const std::string &help_, Matcher &&matcher_, Options options_) : FlagBase(name_, help_, std::move(matcher_), options_) {}
+            virtual ~ValueFlagBase() {}
+
+            virtual Nargs NumberOfArguments() const noexcept override
+            {
+                return 1;
+            }
+    };
+
+    class CompletionFlag : public ValueFlagBase
+    {
+        public:
+            std::vector<std::string> reply;
+            size_t cword = 0;
+            std::string syntax;
+
+            template <typename GroupClass>
+            CompletionFlag(GroupClass &group_, Matcher &&matcher_): ValueFlagBase("completion", "completion flag", std::move(matcher_), Options::Hidden)
+            {
+                group_.AddCompletion(*this);
+            }
+
+            virtual ~CompletionFlag() {}
+
+            virtual Nargs NumberOfArguments() const noexcept override
+            {
+                return 2;
+            }
+
+            virtual void ParseValue(const std::vector<std::string> &value_) override
+            {
+                syntax = value_.at(0);
+                std::istringstream(value_.at(1)) >> cword;
+            }
+
+            /** Get the completion reply
+             */
+            std::string Get() noexcept
+            {
+                return detail::Join(reply, "\n");
+            }
+
+            virtual void Reset() noexcept override
+            {
+                ValueFlagBase::Reset();
+                cword = 0;
+                syntax.clear();
+                reply.clear();
+            }
+    };
+
+
+    /** Base class for positional options
+     */
+    class PositionalBase : public NamedBase
+    {
+        protected:
+            bool ready;
+
+        public:
+            PositionalBase(const std::string &name_, const std::string &help_, Options options_ = {}) : NamedBase(name_, help_, options_), ready(true) {}
+            virtual ~PositionalBase() {}
+
+            bool Ready()
+            {
+                return ready;
+            }
+
+            virtual void ParseValue(const std::string &value_) = 0;
+
+            virtual void Reset() noexcept override
+            {
+                matched = false;
+                ready = true;
+#ifdef ARGS_NOEXCEPT
+                error = Error::None;
+                errorMsg.clear();
+#endif
+            }
+
+            virtual PositionalBase *GetNextPositional() override
+            {
+                return Ready() ? this : nullptr;
+            }
+
+            virtual bool HasPositional() const override
+            {
+                return true;
+            }
+
+            virtual std::vector<std::string> GetProgramLine(const HelpParams &params) const override
+            {
+                return { IsRequired() ? params.proglineRequiredOpen + Name() + params.proglineRequiredClose
+                                      : params.proglineNonrequiredOpen + Name() + params.proglineNonrequiredClose };
+            }
+
+            virtual void Validate(const std::string &, const std::string &) const override
+            {
+                if (IsRequired() && !Matched())
+                {
+                    std::ostringstream problem;
+                    problem << "Option '" << Name() << "' is required";
+#ifdef ARGS_NOEXCEPT
+                    error = Error::Required;
+                    errorMsg = problem.str();
+#else
+                    throw RequiredError(problem.str());
+#endif
+                }
+            }
+    };
+
+    /** Class for all kinds of validating groups, including ArgumentParser
+     */
+    class Group : public Base
+    {
+        private:
+            std::vector<Base*> children;
+            std::function<bool(const Group &)> validator;
+
+        public:
+            /** Default validators
+             */
+            struct Validators
+            {
+                static bool Xor(const Group &group)
+                {
+                    return group.MatchedChildren() == 1;
+                }
+
+                static bool AtLeastOne(const Group &group)
+                {
+                    return group.MatchedChildren() >= 1;
+                }
+
+                static bool AtMostOne(const Group &group)
+                {
+                    return group.MatchedChildren() <= 1;
+                }
+
+                static bool All(const Group &group)
+                {
+                    return group.Children().size() == group.MatchedChildren();
+                }
+
+                static bool AllOrNone(const Group &group)
+                {
+                    return (All(group) || None(group));
+                }
+
+                static bool AllChildGroups(const Group &group)
+                {
+                    return std::none_of(std::begin(group.Children()), std::end(group.Children()), [](const Base* child) -> bool {
+                            return child->IsGroup() && !child->Matched();
+                            });
+                }
+
+                static bool DontCare(const Group &)
+                {
+                    return true;
+                }
+
+                static bool CareTooMuch(const Group &)
+                {
+                    return false;
+                }
+
+                static bool None(const Group &group)
+                {
+                    return group.MatchedChildren() == 0;
+                }
+            };
+            /// If help is empty, this group will not be printed in help output
+            Group(const std::string &help_ = std::string(), const std::function<bool(const Group &)> &validator_ = Validators::DontCare, Options options_ = {}) : Base(help_, options_), validator(validator_) {}
+            /// If help is empty, this group will not be printed in help output
+            Group(Group &group_, const std::string &help_ = std::string(), const std::function<bool(const Group &)> &validator_ = Validators::DontCare, Options options_ = {}) : Base(help_, options_), validator(validator_)
+            {
+                group_.Add(*this);
+            }
+            virtual ~Group() {}
+
+            /** Append a child to this Group.
+             */
+            void Add(Base &child)
+            {
+                children.emplace_back(&child);
+            }
+
+            /** Get all this group's children
+             */
+            const std::vector<Base *> &Children() const
+            {
+                return children;
+            }
+
+            /** Return the first FlagBase that matches flag, or nullptr
+             *
+             * \param flag The flag with prefixes stripped
+             * \return the first matching FlagBase pointer, or nullptr if there is no match
+             */
+            virtual FlagBase *Match(const EitherFlag &flag) override
+            {
+                for (Base *child: Children())
+                {
+                    if (FlagBase *match = child->Match(flag))
+                    {
+                        return match;
+                    }
+                }
+                return nullptr;
+            }
+
+            virtual std::vector<FlagBase*> GetAllFlags() override
+            {
+                std::vector<FlagBase*> res;
+                for (Base *child: Children())
+                {
+                    auto childRes = child->GetAllFlags();
+                    res.insert(res.end(), childRes.begin(), childRes.end());
+                }
+                return res;
+            }
+
+            virtual void Validate(const std::string &shortPrefix, const std::string &longPrefix) const override
+            {
+                for (Base *child: Children())
+                {
+                    child->Validate(shortPrefix, longPrefix);
+                }
+            }
+
+            /** Get the next ready positional, or nullptr if there is none
+             *
+             * \return the first ready PositionalBase pointer, or nullptr if there is no match
+             */
+            virtual PositionalBase *GetNextPositional() override
+            {
+                for (Base *child: Children())
+                {
+                    if (auto next = child->GetNextPositional())
+                    {
+                        return next;
+                    }
+                }
+                return nullptr;
+            }
+
+            /** Get whether this has any FlagBase children
+             *
+             * \return Whether or not there are any FlagBase children
+             */
+            virtual bool HasFlag() const override
+            {
+                return std::any_of(Children().begin(), Children().end(), [](Base *child) { return child->HasFlag(); });
+            }
+
+            /** Get whether this has any PositionalBase children
+             *
+             * \return Whether or not there are any PositionalBase children
+             */
+            virtual bool HasPositional() const override
+            {
+                return std::any_of(Children().begin(), Children().end(), [](Base *child) { return child->HasPositional(); });
+            }
+
+            /** Get whether this has any Command children
+             *
+             * \return Whether or not there are any Command children
+             */
+            virtual bool HasCommand() const override
+            {
+                return std::any_of(Children().begin(), Children().end(), [](Base *child) { return child->HasCommand(); });
+            }
+
+            /** Count the number of matched children this group has
+             */
+            std::vector<Base *>::size_type MatchedChildren() const
+            {
+                return std::count_if(std::begin(Children()), std::end(Children()), [](const Base *child){return child->Matched();});
+            }
+
+            /** Whether or not this group matches validation
+             */
+            virtual bool Matched() const noexcept override
+            {
+                return validator(*this);
+            }
+
+            /** Get validation
+             */
+            bool Get() const
+            {
+                return Matched();
+            }
+
+            /** Get all the child descriptions for help generation
+             */
+            virtual std::vector<std::tuple<std::string, std::string, unsigned>> GetDescription(const HelpParams &params, const unsigned int indent) const override
+            {
+                std::vector<std::tuple<std::string, std::string, unsigned int>> descriptions;
+
+                // Push that group description on the back if not empty
+                unsigned addindent = 0;
+                if (!help.empty())
+                {
+                    descriptions.emplace_back(help, "", indent);
+                    addindent = 1;
+                }
+
+                for (Base *child: Children())
+                {
+                    if ((child->GetOptions() & Options::HiddenFromDescription) != Options::None)
+                    {
+                        continue;
+                    }
+
+                    auto groupDescriptions = child->GetDescription(params, indent + addindent);
+                    descriptions.insert(
+                        std::end(descriptions),
+                        std::make_move_iterator(std::begin(groupDescriptions)),
+                        std::make_move_iterator(std::end(groupDescriptions)));
+                }
+                return descriptions;
+            }
+
+            /** Get the names of positional parameters
+             */
+            virtual std::vector<std::string> GetProgramLine(const HelpParams &params) const override
+            {
+                std::vector <std::string> names;
+                for (Base *child: Children())
+                {
+                    if ((child->GetOptions() & Options::HiddenFromUsage) != Options::None)
+                    {
+                        continue;
+                    }
+
+                    auto groupNames = child->GetProgramLine(params);
+                    names.insert(
+                        std::end(names),
+                        std::make_move_iterator(std::begin(groupNames)),
+                        std::make_move_iterator(std::end(groupNames)));
+                }
+                return names;
+            }
+
+            virtual std::vector<Command*> GetCommands() override
+            {
+                std::vector<Command*> res;
+                for (const auto &child : Children())
+                {
+                    auto subparsers = child->GetCommands();
+                    res.insert(std::end(res), std::begin(subparsers), std::end(subparsers));
+                }
+                return res;
+            }
+
+            virtual bool IsGroup() const override
+            {
+                return true;
+            }
+
+            virtual void Reset() noexcept override
+            {
+                Base::Reset();
+
+                for (auto &child: Children())
+                {
+                    child->Reset();
+                }
+#ifdef ARGS_NOEXCEPT
+                error = Error::None;
+                errorMsg.clear();
+#endif
+            }
+
+#ifdef ARGS_NOEXCEPT
+            /// Only for ARGS_NOEXCEPT
+            virtual Error GetError() const override
+            {
+                if (error != Error::None)
+                {
+                    return error;
+                }
+
+                auto it = std::find_if(Children().begin(), Children().end(), [](const Base *child){return child->GetError() != Error::None;});
+                if (it == Children().end())
+                {
+                    return Error::None;
+                } else
+                {
+                    return (*it)->GetError();
+                }
+            }
+#endif
+
+    };
+
+    /** Class for using global options in ArgumentParser.
+     */
+    class GlobalOptions : public Group
+    {
+        public:
+            GlobalOptions(Group &base, Base &options_) : Group(base, {}, Group::Validators::DontCare, Options::Global)
+            {
+                Add(options_);
+            }
+    };
+
+    /** Utility class for building subparsers with coroutines/callbacks.
+     *
+     * Brief example:
+     * \code
+     * Command command(argumentParser, "command", "my command", [](args::Subparser &s)
+     * {
+     *      // your command flags/positionals
+     *      s.Parse(); //required
+     *      //your command code
+     * });
+     * \endcode
+     *
+     * For ARGS_NOEXCEPT mode don't forget to check `s.GetError()` after `s.Parse()`
+     * and return if it isn't equals to args::Error::None.
+     *
+     * \sa Command
+     */
+    class Subparser : public Group
+    {
+        private:
+            std::vector<std::string> args;
+            std::vector<std::string> kicked;
+            ArgumentParser *parser = nullptr;
+            const HelpParams &helpParams;
+            const Command &command;
+            bool isParsed = false;
+
+        public:
+            Subparser(std::vector<std::string> args_, ArgumentParser &parser_, const Command &command_, const HelpParams &helpParams_)
+                : args(std::move(args_)), parser(&parser_), helpParams(helpParams_), command(command_)
+            {
+            }
+
+            Subparser(const Command &command_, const HelpParams &helpParams_) : helpParams(helpParams_), command(command_)
+            {
+            }
+
+            Subparser(const Subparser&) = delete;
+            Subparser(Subparser&&) = delete;
+            Subparser &operator = (const Subparser&) = delete;
+            Subparser &operator = (Subparser&&) = delete;
+
+            const Command &GetCommand()
+            {
+                return command;
+            }
+
+            /** (INTERNAL) Determines whether Parse was called or not.
+             */
+            bool IsParsed() const
+            {
+                return isParsed;
+            }
+
+            /** Continue parsing arguments for new command.
+             */
+            void Parse();
+
+            /** Returns a vector of kicked out arguments.
+             *
+             * \sa Base::KickOut
+             */
+            const std::vector<std::string> &KickedOut() const noexcept
+            {
+                return kicked;
+            }
+    };
+
+    /** Main class for building subparsers.
+     *
+     * /sa Subparser
+     */
+    class Command : public Group
+    {
+        private:
+            friend class Subparser;
+
+            std::string name;
+            std::string help;
+            std::string description;
+            std::string epilog;
+            std::string proglinePostfix;
+
+            std::function<void(Subparser&)> parserCoroutine;
+            bool commandIsRequired = true;
+            Command *selectedCommand = nullptr;
+
+            mutable std::vector<std::tuple<std::string, std::string, unsigned>> subparserDescription;
+            mutable std::vector<std::string> subparserProgramLine;
+            mutable bool subparserHasFlag = false;
+            mutable bool subparserHasPositional = false;
+            mutable bool subparserHasCommand = false;
+#ifdef ARGS_NOEXCEPT
+            mutable Error subparserError = Error::None;
+#endif
+            mutable Subparser *subparser = nullptr;
+
+        protected:
+
+            class RaiiSubparser
+            {
+                public:
+                    RaiiSubparser(ArgumentParser &parser_, std::vector<std::string> args_);
+                    RaiiSubparser(const Command &command_, const HelpParams &params_);
+
+                    ~RaiiSubparser()
+                    {
+                        command.subparser = oldSubparser;
+                    }
+
+                    Subparser &Parser()
+                    {
+                        return parser;
+                    }
+
+                private:
+                    const Command &command;
+                    Subparser parser;
+                    Subparser *oldSubparser;
+            };
+
+            Command() = default;
+
+            std::function<void(Subparser&)> &GetCoroutine()
+            {
+                return selectedCommand != nullptr ? selectedCommand->GetCoroutine() : parserCoroutine;
+            }
+
+            Command &SelectedCommand()
+            {
+                Command *res = this;
+                while (res->selectedCommand != nullptr)
+                {
+                    res = res->selectedCommand;
+                }
+
+                return *res;
+            }
+
+            const Command &SelectedCommand() const
+            {
+                const Command *res = this;
+                while (res->selectedCommand != nullptr)
+                {
+                    res = res->selectedCommand;
+                }
+
+                return *res;
+            }
+
+            void UpdateSubparserHelp(const HelpParams &params) const
+            {
+                if (parserCoroutine)
+                {
+                    RaiiSubparser coro(*this, params);
+#ifndef ARGS_NOEXCEPT
+                    try
+                    {
+                        parserCoroutine(coro.Parser());
+                    }
+                    catch (args::SubparserError&)
+                    {
+                    }
+#else
+                    parserCoroutine(coro.Parser());
+#endif
+                }
+            }
+
+        public:
+            Command(Group &base_, std::string name_, std::string help_, std::function<void(Subparser&)> coroutine_ = {})
+                : name(std::move(name_)), help(std::move(help_)), parserCoroutine(std::move(coroutine_))
+            {
+                base_.Add(*this);
+            }
+
+            /** The description that appears on the prog line after options
+             */
+            const std::string &ProglinePostfix() const
+            { return proglinePostfix; }
+
+            /** The description that appears on the prog line after options
+             */
+            void ProglinePostfix(const std::string &proglinePostfix_)
+            { this->proglinePostfix = proglinePostfix_; }
+
+            /** The description that appears above options
+             */
+            const std::string &Description() const
+            { return description; }
+            /** The description that appears above options
+             */
+
+            void Description(const std::string &description_)
+            { this->description = description_; }
+
+            /** The description that appears below options
+             */
+            const std::string &Epilog() const
+            { return epilog; }
+
+            /** The description that appears below options
+             */
+            void Epilog(const std::string &epilog_)
+            { this->epilog = epilog_; }
+
+            /** The name of command
+             */
+            const std::string &Name() const
+            { return name; }
+
+            /** The description of command
+             */
+            const std::string &Help() const
+            { return help; }
+
+            /** If value is true, parser will fail if no command was parsed.
+             *
+             * Default: true.
+             */
+            void RequireCommand(bool value)
+            { commandIsRequired = value; }
+
+            virtual bool IsGroup() const override
+            { return false; }
+
+            virtual bool Matched() const noexcept override
+            { return Base::Matched(); }
+
+            operator bool() const noexcept
+            { return Matched(); }
+
+            void Match() noexcept
+            { matched = true; }
+
+            void SelectCommand(Command *c) noexcept
+            {
+                selectedCommand = c;
+
+                if (c != nullptr)
+                {
+                    c->Match();
+                }
+            }
+
+            virtual FlagBase *Match(const EitherFlag &flag) override
+            {
+                if (selectedCommand != nullptr)
+                {
+                    if (auto *res = selectedCommand->Match(flag))
+                    {
+                        return res;
+                    }
+
+                    for (auto *child: Children())
+                    {
+                        if ((child->GetOptions() & Options::Global) != Options::None)
+                        {
+                            if (auto *res = child->Match(flag))
+                            {
+                                return res;
+                            }
+                        }
+                    }
+
+                    return nullptr;
+                }
+
+                if (subparser != nullptr)
+                {
+                    return subparser->Match(flag);
+                }
+
+                return Matched() ? Group::Match(flag) : nullptr;
+            }
+
+            virtual std::vector<FlagBase*> GetAllFlags() override
+            {
+                std::vector<FlagBase*> res;
+
+                if (!Matched())
+                {
+                    return res;
+                }
+
+                for (auto *child: Children())
+                {
+                    if (selectedCommand == nullptr || (child->GetOptions() & Options::Global) != Options::None)
+                    {
+                        auto childFlags = child->GetAllFlags();
+                        res.insert(res.end(), childFlags.begin(), childFlags.end());
+                    }
+                }
+
+                if (selectedCommand != nullptr)
+                {
+                    auto childFlags = selectedCommand->GetAllFlags();
+                    res.insert(res.end(), childFlags.begin(), childFlags.end());
+                }
+
+                if (subparser != nullptr)
+                {
+                    auto childFlags = subparser->GetAllFlags();
+                    res.insert(res.end(), childFlags.begin(), childFlags.end());
+                }
+
+                return res;
+            }
+
+            virtual PositionalBase *GetNextPositional() override
+            {
+                if (selectedCommand != nullptr)
+                {
+                    if (auto *res = selectedCommand->GetNextPositional())
+                    {
+                        return res;
+                    }
+
+                    for (auto *child: Children())
+                    {
+                        if ((child->GetOptions() & Options::Global) != Options::None)
+                        {
+                            if (auto *res = child->GetNextPositional())
+                            {
+                                return res;
+                            }
+                        }
+                    }
+
+                    return nullptr;
+                }
+
+                if (subparser != nullptr)
+                {
+                    return subparser->GetNextPositional();
+                }
+
+                return Matched() ? Group::GetNextPositional() : nullptr;
+            }
+
+            virtual bool HasFlag() const override
+            {
+                return subparserHasFlag || Group::HasFlag();
+            }
+
+            virtual bool HasPositional() const override
+            {
+                return subparserHasPositional || Group::HasPositional();
+            }
+
+            virtual bool HasCommand() const override
+            {
+                return true;
+            }
+
+            std::vector<std::string> GetCommandProgramLine(const HelpParams &params) const
+            {
+                UpdateSubparserHelp(params);
+
+                auto res = Group::GetProgramLine(params);
+                res.insert(res.end(), subparserProgramLine.begin(), subparserProgramLine.end());
+
+                if (!params.proglineCommand.empty() && (Group::HasCommand() || subparserHasCommand))
+                {
+                    res.insert(res.begin(), commandIsRequired ? params.proglineCommand : "[" + params.proglineCommand + "]");
+                }
+
+                if (!Name().empty())
+                {
+                    res.insert(res.begin(), Name());
+                }
+
+                if ((subparserHasFlag || Group::HasFlag()) && params.showProglineOptions && !params.proglineShowFlags)
+                {
+                    res.push_back(params.proglineOptions);
+                }
+
+                if (!ProglinePostfix().empty())
+                {
+                    std::string line;
+                    for (char c : ProglinePostfix())
+                    {
+                        if (isspace(c))
+                        {
+                            if (!line.empty())
+                            {
+                                res.push_back(line);
+                                line.clear();
+                            }
+
+                            if (c == '\n')
+                            {
+                                res.push_back("\n");
+                            }
+                        }
+                        else
+                        {
+                            line += c;
+                        }
+                    }
+
+                    if (!line.empty())
+                    {
+                        res.push_back(line);
+                    }
+                }
+
+                return res;
+            }
+
+            virtual std::vector<std::string> GetProgramLine(const HelpParams &params) const override
+            {
+                if (!Matched())
+                {
+                    return {};
+                }
+
+                return GetCommandProgramLine(params);
+            }
+
+            virtual std::vector<Command*> GetCommands() override
+            {
+                if (selectedCommand != nullptr)
+                {
+                    return selectedCommand->GetCommands();
+                }
+
+                if (Matched())
+                {
+                    return Group::GetCommands();
+                }
+
+                return { this };
+            }
+
+            virtual std::vector<std::tuple<std::string, std::string, unsigned>> GetDescription(const HelpParams &params, const unsigned int indent) const override
+            {
+                std::vector<std::tuple<std::string, std::string, unsigned>> descriptions;
+                unsigned addindent = 0;
+
+                UpdateSubparserHelp(params);
+
+                if (!Matched())
+                {
+                    if (params.showCommandFullHelp)
+                    {
+                        std::ostringstream s;
+                        bool empty = true;
+                        for (const auto &progline: GetCommandProgramLine(params))
+                        {
+                            if (!empty)
+                            {
+                                s << ' ';
+                            }
+                            else
+                            {
+                                empty = false;
+                            }
+
+                            s << progline;
+                        }
+
+                        descriptions.emplace_back(s.str(), "", indent);
+                    }
+                    else
+                    {
+                        descriptions.emplace_back(Name(), help, indent);
+                    }
+
+                    if (!params.showCommandChildren && !params.showCommandFullHelp)
+                    {
+                        return descriptions;
+                    }
+
+                    addindent = 1;
+                }
+
+                if (params.showCommandFullHelp && !Matched())
+                {
+                    descriptions.emplace_back("", "", indent + addindent);
+                    descriptions.emplace_back(Description().empty() ? Help() : Description(), "", indent + addindent);
+                    descriptions.emplace_back("", "", indent + addindent);
+                }
+
+                for (Base *child: Children())
+                {
+                    if ((child->GetOptions() & Options::HiddenFromDescription) != Options::None)
+                    {
+                        continue;
+                    }
+
+                    auto groupDescriptions = child->GetDescription(params, indent + addindent);
+                    descriptions.insert(
+                                        std::end(descriptions),
+                                        std::make_move_iterator(std::begin(groupDescriptions)),
+                                        std::make_move_iterator(std::end(groupDescriptions)));
+                }
+
+                for (auto childDescription: subparserDescription)
+                {
+                    std::get<2>(childDescription) += indent + addindent;
+                    descriptions.push_back(std::move(childDescription));
+                }
+
+                if (params.showCommandFullHelp && !Matched())
+                {
+                    descriptions.emplace_back("", "", indent + addindent);
+                    if (!Epilog().empty())
+                    {
+                        descriptions.emplace_back(Epilog(), "", indent + addindent);
+                        descriptions.emplace_back("", "", indent + addindent);
+                    }
+                }
+
+                return descriptions;
+            }
+
+            virtual void Validate(const std::string &shortprefix, const std::string &longprefix) const override
+            {
+                if (!Matched())
+                {
+                    return;
+                }
+
+                for (Base *child: Children())
+                {
+                    if (child->IsGroup() && !child->Matched())
+                    {
+                        std::ostringstream problem;
+                        problem << "Group validation failed somewhere!";
+#ifdef ARGS_NOEXCEPT
+                        error = Error::Validation;
+                        errorMsg = problem.str();
+#else
+                        throw ValidationError(problem.str());
+#endif
+                    }
+
+                    child->Validate(shortprefix, longprefix);
+                }
+
+                if (subparser != nullptr)
+                {
+                    subparser->Validate(shortprefix, longprefix);
+                }
+
+                if (selectedCommand == nullptr && commandIsRequired && (Group::HasCommand() || subparserHasCommand))
+                {
+                    std::ostringstream problem;
+                    problem << "Command is required";
+#ifdef ARGS_NOEXCEPT
+                    error = Error::Validation;
+                    errorMsg = problem.str();
+#else
+                    throw ValidationError(problem.str());
+#endif
+                }
+            }
+
+            virtual void Reset() noexcept override
+            {
+                Group::Reset();
+                selectedCommand = nullptr;
+                subparserProgramLine.clear();
+                subparserDescription.clear();
+                subparserHasFlag = false;
+                subparserHasPositional = false;
+                subparserHasCommand = false;
+#ifdef ARGS_NOEXCEPT
+                subparserError = Error::None;
+#endif
+            }
+
+#ifdef ARGS_NOEXCEPT
+            /// Only for ARGS_NOEXCEPT
+            virtual Error GetError() const override
+            {
+                if (!Matched())
+                {
+                    return Error::None;
+                }
+
+                if (error != Error::None)
+                {
+                    return error;
+                }
+
+                if (subparserError != Error::None)
+                {
+                    return subparserError;
+                }
+
+                return Group::GetError();
+            }
+#endif
+    };
+
+    /** The main user facing command line argument parser class
+     */
+    class ArgumentParser : public Command
+    {
+        friend class Subparser;
+
+        private:
+            std::string longprefix;
+            std::string shortprefix;
+
+            std::string longseparator;
+
+            std::string terminator;
+
+            bool allowJoinedShortValue = true;
+            bool allowJoinedLongValue = true;
+            bool allowSeparateShortValue = true;
+            bool allowSeparateLongValue = true;
+
+            CompletionFlag *completion = nullptr;
+            bool readCompletion = false;
+
+        protected:
+            enum class OptionType
+            {
+                LongFlag,
+                ShortFlag,
+                Positional
+            };
+
+            OptionType ParseOption(const std::string &s, bool allowEmpty = false)
+            {
+                if (s.find(longprefix) == 0 && (allowEmpty || s.length() > longprefix.length()))
+                {
+                    return OptionType::LongFlag;
+                }
+
+                if (s.find(shortprefix) == 0 && (allowEmpty || s.length() > shortprefix.length()))
+                {
+                    return OptionType::ShortFlag;
+                }
+
+                return OptionType::Positional;
+            }
+
+            template <typename It>
+            bool Complete(FlagBase &flag, It it, It end)
+            {
+                auto nextIt = it;
+                if (!readCompletion || (++nextIt != end))
+                {
+                    return false;
+                }
+
+                const auto &chunk = *it;
+                for (auto &choice : flag.HelpChoices(helpParams))
+                {
+                    AddCompletionReply(chunk, choice);
+                }
+
+#ifndef ARGS_NOEXCEPT
+                throw Completion(completion->Get());
+#else
+                return true;
+#endif
+            }
+
+            /** (INTERNAL) Parse flag's values
+             *
+             * \param arg The string to display in error message as a flag name
+             * \param[in, out] it The iterator to first value. It will point to the last value
+             * \param end The end iterator
+             * \param joinedArg Joined value (e.g. bar in --foo=bar)
+             * \param canDiscardJoined If true joined value can be parsed as flag not as a value (as in -abcd)
+             * \param[out] values The vector to store parsed arg's values
+             */
+            template <typename It>
+            std::string ParseArgsValues(FlagBase &flag, const std::string &arg, It &it, It end,
+                                        const bool allowSeparate, const bool allowJoined,
+                                        const bool hasJoined, const std::string &joinedArg,
+                                        const bool canDiscardJoined, std::vector<std::string> &values)
+            {
+                values.clear();
+
+                Nargs nargs = flag.NumberOfArguments();
+
+                if (hasJoined && !allowJoined && nargs.min != 0)
+                {
+                    return "Flag '" + arg + "' was passed a joined argument, but these are disallowed";
+                }
+
+                if (hasJoined)
+                {
+                    if (!canDiscardJoined || nargs.max != 0)
+                    {
+                        values.push_back(joinedArg);
+                    }
+                } else if (!allowSeparate)
+                {
+                    if (nargs.min != 0)
+                    {
+                        return "Flag '" + arg + "' was passed a separate argument, but these are disallowed";
+                    }
+                } else
+                {
+                    auto valueIt = it;
+                    ++valueIt;
+
+                    while (valueIt != end &&
+                           values.size() < nargs.max &&
+                           (nargs.min == nargs.max || ParseOption(*valueIt) == OptionType::Positional))
+                    {
+                        if (Complete(flag, valueIt, end))
+                        {
+                            it = end;
+                            return "";
+                        }
+
+                        values.push_back(*valueIt);
+                        ++it;
+                        ++valueIt;
+                    }
+                }
+
+                if (values.size() > nargs.max)
+                {
+                    return "Passed an argument into a non-argument flag: " + arg;
+                } else if (values.size() < nargs.min)
+                {
+                    if (nargs.min == 1 && nargs.max == 1)
+                    {
+                        return "Flag '" + arg + "' requires an argument but received none";
+                    } else if (nargs.min == 1)
+                    {
+                        return "Flag '" + arg + "' requires at least one argument but received none";
+                    } else if (nargs.min != nargs.max)
+                    {
+                        return "Flag '" + arg + "' requires at least " + std::to_string(nargs.min) +
+                               " arguments but received " + std::to_string(values.size());
+                    } else
+                    {
+                        return "Flag '" + arg + "' requires " + std::to_string(nargs.min) +
+                               " arguments but received " + std::to_string(values.size());
+                    }
+                }
+
+                return {};
+            }
+
+            template <typename It>
+            bool ParseLong(It &it, It end)
+            {
+                const auto &chunk = *it;
+                const auto argchunk = chunk.substr(longprefix.size());
+                // Try to separate it, in case of a separator:
+                const auto separator = longseparator.empty() ? argchunk.npos : argchunk.find(longseparator);
+                // If the separator is in the argument, separate it.
+                const auto arg = (separator != argchunk.npos ?
+                    std::string(argchunk, 0, separator)
+                    : argchunk);
+                const auto joined = (separator != argchunk.npos ?
+                    argchunk.substr(separator + longseparator.size())
+                    : std::string());
+
+                if (auto flag = Match(arg))
+                {
+                    std::vector<std::string> values;
+                    const std::string errorMessage = ParseArgsValues(*flag, arg, it, end, allowSeparateLongValue, allowJoinedLongValue,
+                                                                     separator != argchunk.npos, joined, false, values);
+                    if (!errorMessage.empty())
+                    {
+#ifndef ARGS_NOEXCEPT
+                        throw ParseError(errorMessage);
+#else
+                        error = Error::Parse;
+                        errorMsg = errorMessage;
+                        return false;
+#endif
+                    }
+
+                    if (!readCompletion)
+                    {
+                        flag->ParseValue(values);
+                    }
+
+                    if (flag->KickOut())
+                    {
+                        ++it;
+                        return false;
+                    }
+                } else
+                {
+                    const std::string errorMessage("Flag could not be matched: " + arg);
+#ifndef ARGS_NOEXCEPT
+                    throw ParseError(errorMessage);
+#else
+                    error = Error::Parse;
+                    errorMsg = errorMessage;
+                    return false;
+#endif
+                }
+
+                return true;
+            }
+
+            template <typename It>
+            bool ParseShort(It &it, It end)
+            {
+                const auto &chunk = *it;
+                const auto argchunk = chunk.substr(shortprefix.size());
+                for (auto argit = std::begin(argchunk); argit != std::end(argchunk); ++argit)
+                {
+                    const auto arg = *argit;
+
+                    if (auto flag = Match(arg))
+                    {
+                        const std::string value(argit + 1, std::end(argchunk));
+                        std::vector<std::string> values;
+                        const std::string errorMessage = ParseArgsValues(*flag, std::string(1, arg), it, end,
+                                                                         allowSeparateShortValue, allowJoinedShortValue,
+                                                                         !value.empty(), value, !value.empty(), values);
+
+                        if (!errorMessage.empty())
+                        {
+#ifndef ARGS_NOEXCEPT
+                            throw ParseError(errorMessage);
+#else
+                            error = Error::Parse;
+                            errorMsg = errorMessage;
+                            return false;
+#endif
+                        }
+
+                        if (!readCompletion)
+                        {
+                            flag->ParseValue(values);
+                        }
+
+                        if (flag->KickOut())
+                        {
+                            ++it;
+                            return false;
+                        }
+
+                        if (!values.empty())
+                        {
+                            break;
+                        }
+                    } else
+                    {
+                        const std::string errorMessage("Flag could not be matched: '" + std::string(1, arg) + "'");
+#ifndef ARGS_NOEXCEPT
+                        throw ParseError(errorMessage);
+#else
+                        error = Error::Parse;
+                        errorMsg = errorMessage;
+                        return false;
+#endif
+                    }
+                }
+
+                return true;
+            }
+
+            bool AddCompletionReply(const std::string &cur, const std::string &choice)
+            {
+                if (cur.empty() || choice.find(cur) == 0)
+                {
+                    if (completion->syntax == "bash" && ParseOption(choice) == OptionType::LongFlag && choice.find(longseparator) != std::string::npos)
+                    {
+                        completion->reply.push_back(choice.substr(choice.find(longseparator) + 1));
+                    } else
+                    {
+                        completion->reply.push_back(choice);
+                    }
+                    return true;
+                }
+
+                return false;
+            }
+
+            template <typename It>
+            bool Complete(It it, It end)
+            {
+                auto nextIt = it;
+                if (!readCompletion || (++nextIt != end))
+                {
+                    return false;
+                }
+
+                const auto &chunk = *it;
+                auto pos = GetNextPositional();
+                std::vector<Command *> commands = GetCommands();
+                const auto optionType = ParseOption(chunk, true);
+
+                if (!commands.empty() && (chunk.empty() || optionType == OptionType::Positional))
+                {
+                    for (auto &cmd : commands)
+                    {
+                        if ((cmd->GetOptions() & Options::HiddenFromCompletion) == Options::None)
+                        {
+                            AddCompletionReply(chunk, cmd->Name());
+                        }
+                    }
+                } else
+                {
+                    bool hasPositionalCompletion = true;
+
+                    if (!commands.empty())
+                    {
+                        for (auto &cmd : commands)
+                        {
+                            if ((cmd->GetOptions() & Options::HiddenFromCompletion) == Options::None)
+                            {
+                                AddCompletionReply(chunk, cmd->Name());
+                            }
+                        }
+                    } else if (pos)
+                    {
+                        if ((pos->GetOptions() & Options::HiddenFromCompletion) == Options::None)
+                        {
+                            auto choices = pos->HelpChoices(helpParams);
+                            hasPositionalCompletion = !choices.empty() || optionType != OptionType::Positional;
+                            for (auto &choice : choices)
+                            {
+                                AddCompletionReply(chunk, choice);
+                            }
+                        }
+                    }
+
+                    if (hasPositionalCompletion)
+                    {
+                        auto flags = GetAllFlags();
+                        for (auto flag : flags)
+                        {
+                            if ((flag->GetOptions() & Options::HiddenFromCompletion) != Options::None)
+                            {
+                                continue;
+                            }
+
+                            auto &matcher = flag->GetMatcher();
+                            if (!AddCompletionReply(chunk, matcher.GetShortOrAny().str(shortprefix, longprefix)))
+                            {
+                                for (auto &flagName : matcher.GetFlagStrings())
+                                {
+                                    if (AddCompletionReply(chunk, flagName.str(shortprefix, longprefix)))
+                                    {
+                                        break;
+                                    }
+                                }
+                            }
+                        }
+
+                        if (optionType == OptionType::LongFlag && allowJoinedLongValue)
+                        {
+                            const auto separator = longseparator.empty() ? chunk.npos : chunk.find(longseparator);
+                            if (separator != chunk.npos)
+                            {
+                                std::string arg(chunk, 0, separator);
+                                if (auto flag = this->Match(arg.substr(longprefix.size())))
+                                {
+                                    for (auto &choice : flag->HelpChoices(helpParams))
+                                    {
+                                        AddCompletionReply(chunk, arg + longseparator + choice);
+                                    }
+                                }
+                            }
+                        } else if (optionType == OptionType::ShortFlag && allowJoinedShortValue)
+                        {
+                            if (chunk.size() > shortprefix.size() + 1)
+                            {
+                                auto arg = chunk.at(shortprefix.size());
+                                //TODO: support -abcVALUE where a and b take no value
+                                if (auto flag = this->Match(arg))
+                                {
+                                    for (auto &choice : flag->HelpChoices(helpParams))
+                                    {
+                                        AddCompletionReply(chunk, shortprefix + arg + choice);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+
+#ifndef ARGS_NOEXCEPT
+                throw Completion(completion->Get());
+#else
+                return true;
+#endif
+            }
+
+            template <typename It>
+            It Parse(It begin, It end)
+            {
+                bool terminated = false;
+                std::vector<Command *> commands = GetCommands();
+
+                // Check all arg chunks
+                for (auto it = begin; it != end; ++it)
+                {
+                    if (Complete(it, end))
+                    {
+                        return end;
+                    }
+
+                    const auto &chunk = *it;
+
+                    if (!terminated && chunk == terminator)
+                    {
+                        terminated = true;
+                    } else if (!terminated && ParseOption(chunk) == OptionType::LongFlag)
+                    {
+                        if (!ParseLong(it, end))
+                        {
+                            return it;
+                        }
+                    } else if (!terminated && ParseOption(chunk) == OptionType::ShortFlag)
+                    {
+                        if (!ParseShort(it, end))
+                        {
+                            return it;
+                        }
+                    } else if (!terminated && !commands.empty())
+                    {
+                        auto itCommand = std::find_if(commands.begin(), commands.end(), [&chunk](Command *c) { return c->Name() == chunk; });
+                        if (itCommand == commands.end())
+                        {
+                            const std::string errorMessage("Unknown command: " + chunk);
+#ifndef ARGS_NOEXCEPT
+                            throw ParseError(errorMessage);
+#else
+                            error = Error::Parse;
+                            errorMsg = errorMessage;
+                            return it;
+#endif
+                        }
+
+                        SelectCommand(*itCommand);
+
+                        if (const auto &coroutine = GetCoroutine())
+                        {
+                            ++it;
+                            RaiiSubparser coro(*this, std::vector<std::string>(it, end));
+                            coroutine(coro.Parser());
+#ifdef ARGS_NOEXCEPT
+                            error = GetError();
+                            if (error != Error::None)
+                            {
+                                return end;
+                            }
+
+                            if (!coro.Parser().IsParsed())
+                            {
+                                error = Error::Usage;
+                                return end;
+                            }
+#else
+                            if (!coro.Parser().IsParsed())
+                            {
+                                throw UsageError("Subparser::Parse was not called");
+                            }
+#endif
+
+                            break;
+                        }
+
+                        commands = GetCommands();
+                    } else
+                    {
+                        auto pos = GetNextPositional();
+                        if (pos)
+                        {
+                            pos->ParseValue(chunk);
+
+                            if (pos->KickOut())
+                            {
+                                return ++it;
+                            }
+                        } else
+                        {
+                            const std::string errorMessage("Passed in argument, but no positional arguments were ready to receive it: " + chunk);
+#ifndef ARGS_NOEXCEPT
+                            throw ParseError(errorMessage);
+#else
+                            error = Error::Parse;
+                            errorMsg = errorMessage;
+                            return it;
+#endif
+                        }
+                    }
+
+                    if (!readCompletion && completion != nullptr && completion->Matched())
+                    {
+#ifdef ARGS_NOEXCEPT
+                        error = Error::Completion;
+#endif
+                        readCompletion = true;
+                        ++it;
+                        size_t argsLeft = std::distance(it, end);
+                        if (completion->cword == 0 || argsLeft <= 1 || completion->cword >= argsLeft)
+                        {
+#ifndef ARGS_NOEXCEPT
+                            throw Completion("");
+#endif
+                        }
+
+                        std::vector<std::string> curArgs(++it, end);
+                        curArgs.resize(completion->cword);
+
+                        if (completion->syntax == "bash")
+                        {
+                            // bash tokenizes --flag=value as --flag=value
+                            for (size_t idx = 0; idx < curArgs.size(); )
+                            {
+                                if (idx > 0 && curArgs[idx] == "=")
+                                {
+                                    curArgs[idx - 1] += "=";
+                                    if (idx + 1 < curArgs.size())
+                                    {
+                                        curArgs[idx - 1] += curArgs[idx + 1];
+                                        curArgs.erase(curArgs.begin() + idx, curArgs.begin() + idx + 2);
+                                    } else
+                                    {
+                                        curArgs.erase(curArgs.begin() + idx);
+                                    }
+                                } else
+                                {
+                                    ++idx;
+                                }
+                            }
+
+                        }
+#ifndef ARGS_NOEXCEPT
+                        try
+                        {
+                            Parse(curArgs.begin(), curArgs.end());
+                            throw Completion("");
+                        }
+                        catch (Completion &)
+                        {
+                            throw;
+                        }
+                        catch (args::Error&)
+                        {
+                            throw Completion("");
+                        }
+#else
+                        return Parse(curArgs.begin(), curArgs.end());
+#endif
+                    }
+                }
+
+                Validate(shortprefix, longprefix);
+                return end;
+            }
+
+        public:
+            HelpParams helpParams;
+
+            ArgumentParser(const std::string &description_, const std::string &epilog_ = std::string())
+            {
+                Description(description_);
+                Epilog(epilog_);
+                LongPrefix("--");
+                ShortPrefix("-");
+                LongSeparator("=");
+                Terminator("--");
+                SetArgumentSeparations(true, true, true, true);
+                matched = true;
+            }
+
+            void AddCompletion(CompletionFlag &completionFlag)
+            {
+                completion = &completionFlag;
+                Add(completionFlag);
+            }
+
+            /** The program name for help generation
+             */
+            const std::string &Prog() const
+            { return helpParams.programName; }
+            /** The program name for help generation
+             */
+            void Prog(const std::string &prog_)
+            { this->helpParams.programName = prog_; }
+
+            /** The prefix for long flags
+             */
+            const std::string &LongPrefix() const
+            { return longprefix; }
+            /** The prefix for long flags
+             */
+            void LongPrefix(const std::string &longprefix_)
+            {
+                this->longprefix = longprefix_;
+                this->helpParams.longPrefix = longprefix_;
+            }
+
+            /** The prefix for short flags
+             */
+            const std::string &ShortPrefix() const
+            { return shortprefix; }
+            /** The prefix for short flags
+             */
+            void ShortPrefix(const std::string &shortprefix_)
+            {
+                this->shortprefix = shortprefix_;
+                this->helpParams.shortPrefix = shortprefix_;
+            }
+
+            /** The separator for long flags
+             */
+            const std::string &LongSeparator() const
+            { return longseparator; }
+            /** The separator for long flags
+             */
+            void LongSeparator(const std::string &longseparator_)
+            {
+                if (longseparator_.empty())
+                {
+                    const std::string errorMessage("longseparator can not be set to empty");
+#ifdef ARGS_NOEXCEPT
+                    error = Error::Usage;
+                    errorMsg = errorMessage;
+#else
+                    throw UsageError(errorMessage);
+#endif
+                } else
+                {
+                    this->longseparator = longseparator_;
+                    this->helpParams.longSeparator = allowJoinedLongValue ? longseparator_ : " ";
+                }
+            }
+
+            /** The terminator that forcibly separates flags from positionals
+             */
+            const std::string &Terminator() const
+            { return terminator; }
+            /** The terminator that forcibly separates flags from positionals
+             */
+            void Terminator(const std::string &terminator_)
+            { this->terminator = terminator_; }
+
+            /** Get the current argument separation parameters.
+             *
+             * See SetArgumentSeparations for details on what each one means.
+             */
+            void GetArgumentSeparations(
+                bool &allowJoinedShortValue_,
+                bool &allowJoinedLongValue_,
+                bool &allowSeparateShortValue_,
+                bool &allowSeparateLongValue_) const
+            {
+                allowJoinedShortValue_ = this->allowJoinedShortValue;
+                allowJoinedLongValue_ = this->allowJoinedLongValue;
+                allowSeparateShortValue_ = this->allowSeparateShortValue;
+                allowSeparateLongValue_ = this->allowSeparateLongValue;
+            }
+
+            /** Change allowed option separation.
+             *
+             * \param allowJoinedShortValue_ Allow a short flag that accepts an argument to be passed its argument immediately next to it (ie. in the same argv field)
+             * \param allowJoinedLongValue_ Allow a long flag that accepts an argument to be passed its argument separated by the longseparator (ie. in the same argv field)
+             * \param allowSeparateShortValue_ Allow a short flag that accepts an argument to be passed its argument separated by whitespace (ie. in the next argv field)
+             * \param allowSeparateLongValue_ Allow a long flag that accepts an argument to be passed its argument separated by whitespace (ie. in the next argv field)
+             */
+            void SetArgumentSeparations(
+                const bool allowJoinedShortValue_,
+                const bool allowJoinedLongValue_,
+                const bool allowSeparateShortValue_,
+                const bool allowSeparateLongValue_)
+            {
+                this->allowJoinedShortValue = allowJoinedShortValue_;
+                this->allowJoinedLongValue = allowJoinedLongValue_;
+                this->allowSeparateShortValue = allowSeparateShortValue_;
+                this->allowSeparateLongValue = allowSeparateLongValue_;
+
+                this->helpParams.longSeparator = allowJoinedLongValue ? longseparator : " ";
+                this->helpParams.shortSeparator = allowJoinedShortValue ? "" : " ";
+            }
+
+            /** Pass the help menu into an ostream
+             */
+            void Help(std::ostream &help_) const
+            {
+                auto &command = SelectedCommand();
+                const auto &commandDescription = command.Description().empty() ? command.Help() : command.Description();
+                const auto description_text = Wrap(commandDescription, helpParams.width - helpParams.descriptionindent);
+                const auto epilog_text = Wrap(command.Epilog(), helpParams.width - helpParams.descriptionindent);
+
+                const bool hasoptions = command.HasFlag();
+                const bool hasarguments = command.HasPositional();
+
+                std::vector<std::string> prognameline;
+                prognameline.push_back(helpParams.usageString);
+                prognameline.push_back(Prog());
+                auto commandProgLine = command.GetProgramLine(helpParams);
+                prognameline.insert(prognameline.end(), commandProgLine.begin(), commandProgLine.end());
+
+                const auto proglines = Wrap(prognameline.begin(), prognameline.end(),
+                                            helpParams.width - (helpParams.progindent + helpParams.progtailindent),
+                                            helpParams.width - helpParams.progindent);
+                auto progit = std::begin(proglines);
+                if (progit != std::end(proglines))
+                {
+                    help_ << std::string(helpParams.progindent, ' ') << *progit << '\n';
+                    ++progit;
+                }
+                for (; progit != std::end(proglines); ++progit)
+                {
+                    help_ << std::string(helpParams.progtailindent, ' ') << *progit << '\n';
+                }
+
+                help_ << '\n';
+
+                if (!description_text.empty())
+                {
+                    for (const auto &line: description_text)
+                    {
+                        help_ << std::string(helpParams.descriptionindent, ' ') << line << "\n";
+                    }
+                    help_ << "\n";
+                }
+
+                bool lastDescriptionIsNewline = false;
+
+                if (!helpParams.optionsString.empty())
+                {
+                    help_ << std::string(helpParams.progindent, ' ') << helpParams.optionsString << "\n\n";
+                }
+
+                for (const auto &desc: command.GetDescription(helpParams, 0))
+                {
+                    lastDescriptionIsNewline = std::get<0>(desc).empty() && std::get<1>(desc).empty();
+                    const auto groupindent = std::get<2>(desc) * helpParams.eachgroupindent;
+                    const auto flags = Wrap(std::get<0>(desc), helpParams.width - (helpParams.flagindent + helpParams.helpindent + helpParams.gutter));
+                    const auto info = Wrap(std::get<1>(desc), helpParams.width - (helpParams.helpindent + groupindent));
+
+                    std::string::size_type flagssize = 0;
+                    for (auto flagsit = std::begin(flags); flagsit != std::end(flags); ++flagsit)
+                    {
+                        if (flagsit != std::begin(flags))
+                        {
+                            help_ << '\n';
+                        }
+                        help_ << std::string(groupindent + helpParams.flagindent, ' ') << *flagsit;
+                        flagssize = Glyphs(*flagsit);
+                    }
+
+                    auto infoit = std::begin(info);
+                    // groupindent is on both sides of this inequality, and therefore can be removed
+                    if ((helpParams.flagindent + flagssize + helpParams.gutter) > helpParams.helpindent || infoit == std::end(info) || helpParams.addNewlineBeforeDescription)
+                    {
+                        help_ << '\n';
+                    } else
+                    {
+                        // groupindent is on both sides of the minus sign, and therefore doesn't actually need to be in here
+                        help_ << std::string(helpParams.helpindent - (helpParams.flagindent + flagssize), ' ') << *infoit << '\n';
+                        ++infoit;
+                    }
+                    for (; infoit != std::end(info); ++infoit)
+                    {
+                        help_ << std::string(groupindent + helpParams.helpindent, ' ') << *infoit << '\n';
+                    }
+                }
+                if (hasoptions && hasarguments && helpParams.showTerminator)
+                {
+                    lastDescriptionIsNewline = false;
+                    for (const auto &item: Wrap(std::string("\"") + terminator + "\" can be used to terminate flag options and force all following arguments to be treated as positional options", helpParams.width - helpParams.flagindent))
+                    {
+                        help_ << std::string(helpParams.flagindent, ' ') << item << '\n';
+                    }
+                }
+
+                if (!lastDescriptionIsNewline)
+                {
+                    help_ << "\n";
+                }
+
+                for (const auto &line: epilog_text)
+                {
+                    help_ << std::string(helpParams.descriptionindent, ' ') << line << "\n";
+                }
+            }
+
+            /** Generate a help menu as a string.
+             *
+             * \return the help text as a single string
+             */
+            std::string Help() const
+            {
+                std::ostringstream help_;
+                Help(help_);
+                return help_.str();
+            }
+
+            virtual void Reset() noexcept override
+            {
+                Command::Reset();
+                matched = true;
+                readCompletion = false;
+            }
+
+            /** Parse all arguments.
+             *
+             * \param begin an iterator to the beginning of the argument list
+             * \param end an iterator to the past-the-end element of the argument list
+             * \return the iterator after the last parsed value.  Only useful for kick-out
+             */
+            template <typename It>
+            It ParseArgs(It begin, It end)
+            {
+                // Reset all Matched statuses and errors
+                Reset();
+#ifdef ARGS_NOEXCEPT
+                error = GetError();
+                if (error != Error::None)
+                {
+                    return end;
+                }
+#endif
+                return Parse(begin, end);
+            }
+
+            /** Parse all arguments.
+             *
+             * \param args an iterable of the arguments
+             * \return the iterator after the last parsed value.  Only useful for kick-out
+             */
+            template <typename T>
+            auto ParseArgs(const T &args) -> decltype(std::begin(args))
+            {
+                return ParseArgs(std::begin(args), std::end(args));
+            }
+
+            /** Convenience function to parse the CLI from argc and argv
+             *
+             * Just assigns the program name and vectorizes arguments for passing into ParseArgs()
+             *
+             * \return whether or not all arguments were parsed.  This works for detecting kick-out, but is generally useless as it can't do anything with it.
+             */
+            bool ParseCLI(const int argc, const char * const * argv)
+            {
+                if (Prog().empty())
+                {
+                    Prog(argv[0]);
+                }
+                const std::vector<std::string> args(argv + 1, argv + argc);
+                return ParseArgs(args) == std::end(args);
+            }
+            
+            template <typename T>
+            bool ParseCLI(const T &args)
+            {
+                return ParseArgs(args) == std::end(args);
+            }
+    };
+
+    inline Command::RaiiSubparser::RaiiSubparser(ArgumentParser &parser_, std::vector<std::string> args_)
+        : command(parser_.SelectedCommand()), parser(std::move(args_), parser_, command, parser_.helpParams), oldSubparser(command.subparser)
+    {
+        command.subparser = &parser;
+    }
+
+    inline Command::RaiiSubparser::RaiiSubparser(const Command &command_, const HelpParams &params_): command(command_), parser(command, params_), oldSubparser(command.subparser)
+    {
+        command.subparser = &parser;
+    }
+
+    inline void Subparser::Parse()
+    {
+        isParsed = true;
+        Reset();
+        command.subparserDescription = GetDescription(helpParams, 0);
+        command.subparserHasFlag = HasFlag();
+        command.subparserHasPositional = HasPositional();
+        command.subparserHasCommand = HasCommand();
+        command.subparserProgramLine = GetProgramLine(helpParams);
+        if (parser == nullptr)
+        {
+#ifndef ARGS_NOEXCEPT
+            throw args::SubparserError();
+#else
+            error = Error::Subparser;
+            return;
+#endif
+        }
+
+        auto it = parser->Parse(args.begin(), args.end());
+        command.Validate(parser->ShortPrefix(), parser->LongPrefix());
+        kicked.assign(it, args.end());
+
+#ifdef ARGS_NOEXCEPT
+        command.subparserError = GetError();
+#endif
+    }
+
+    inline std::ostream &operator<<(std::ostream &os, const ArgumentParser &parser)
+    {
+        parser.Help(os);
+        return os;
+    }
+
+    /** Boolean argument matcher
+     */
+    class Flag : public FlagBase
+    {
+        public:
+            Flag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, Options options_): FlagBase(name_, help_, std::move(matcher_), options_)
+            {
+                group_.Add(*this);
+            }
+
+            Flag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const bool extraError_ = false): Flag(group_, name_, help_, std::move(matcher_), extraError_ ? Options::Single : Options::None)
+            {
+            }
+
+            virtual ~Flag() {}
+
+            /** Get whether this was matched
+             */
+            bool Get() const
+            {
+                return Matched();
+            }
+
+            virtual Nargs NumberOfArguments() const noexcept override
+            {
+                return 0;
+            }
+
+            virtual void ParseValue(const std::vector<std::string>&) override
+            {
+            }
+    };
+
+    /** Help flag class
+     *
+     * Works like a regular flag, but throws an instance of Help when it is matched
+     */
+    class HelpFlag : public Flag
+    {
+        public:
+            HelpFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, Options options_ = {}): Flag(group_, name_, help_, std::move(matcher_), options_) {}
+
+            virtual ~HelpFlag() {}
+
+            virtual void ParseValue(const std::vector<std::string> &)
+            {
+#ifdef ARGS_NOEXCEPT
+                    error = Error::Help;
+                    errorMsg = Name();
+#else
+                    throw Help(Name());
+#endif
+            }
+
+            /** Get whether this was matched
+             */
+            bool Get() const noexcept
+            {
+                return Matched();
+            }
+    };
+
+    /** A flag class that simply counts the number of times it's matched
+     */
+    class CounterFlag : public Flag
+    {
+        private:
+            const int startcount;
+            int count;
+
+        public:
+            CounterFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const int startcount_ = 0, Options options_ = {}):
+                Flag(group_, name_, help_, std::move(matcher_), options_), startcount(startcount_), count(startcount_) {}
+
+            virtual ~CounterFlag() {}
+
+            virtual FlagBase *Match(const EitherFlag &arg) override
+            {
+                auto me = FlagBase::Match(arg);
+                if (me)
+                {
+                    ++count;
+                }
+                return me;
+            }
+
+            /** Get the count
+             */
+            int &Get() noexcept
+            {
+                return count;
+            }
+
+            virtual void Reset() noexcept override
+            {
+                FlagBase::Reset();
+                count = startcount;
+            }
+    };
+
+    /** A flag class that calls a function when it's matched
+     */
+    class ActionFlag : public FlagBase
+    {
+        private:
+            std::function<void(const std::vector<std::string> &)> action;
+            Nargs nargs;
+
+        public:
+            ActionFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, Nargs nargs_, std::function<void(const std::vector<std::string> &)> action_, Options options_ = {}):
+                FlagBase(name_, help_, std::move(matcher_), options_), action(std::move(action_)), nargs(nargs_)
+            {
+                group_.Add(*this);
+            }
+
+            ActionFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, std::function<void(const std::string &)> action_, Options options_ = {}):
+                FlagBase(name_, help_, std::move(matcher_), options_), nargs(1)
+            {
+                group_.Add(*this);
+                action = [action_](const std::vector<std::string> &a) { return action_(a.at(0)); };
+            }
+
+            ActionFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, std::function<void()> action_, Options options_ = {}):
+                FlagBase(name_, help_, std::move(matcher_), options_), nargs(0)
+            {
+                group_.Add(*this);
+                action = [action_](const std::vector<std::string> &) { return action_(); };
+            }
+
+            virtual Nargs NumberOfArguments() const noexcept override
+            { return nargs; }
+
+            virtual void ParseValue(const std::vector<std::string> &value) override
+            { action(value); }
+    };
+
+    /** A default Reader class for argument classes
+     *
+     * If destination type is assignable to std::string it uses an assignment to std::string.
+     * Otherwise ValueReader simply uses a std::istringstream to read into the destination type, and
+     * raises a ParseError if there are any characters left.
+     */
+    struct ValueReader
+    {
+        template <typename T>
+        typename std::enable_if<!std::is_assignable<T, std::string>::value, bool>::type
+        operator ()(const std::string &name, const std::string &value, T &destination)
+        {
+            std::istringstream ss(value);
+            ss >> destination >> std::ws;
+
+            if (ss.rdbuf()->in_avail() > 0)
+            {
+#ifdef ARGS_NOEXCEPT
+                (void)name;
+                return false;
+#else
+                std::ostringstream problem;
+                problem << "Argument '" << name << "' received invalid value type '" << value << "'";
+                throw ParseError(problem.str());
+#endif
+            }
+            return true;
+        }
+
+        template <typename T>
+        typename std::enable_if<std::is_assignable<T, std::string>::value, bool>::type
+        operator()(const std::string &, const std::string &value, T &destination)
+        {
+            destination = value;
+            return true;
+        }
+    };
+
+    /** An argument-accepting flag class
+     * 
+     * \tparam T the type to extract the argument as
+     * \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)
+     */
+    template <
+        typename T,
+        typename Reader = ValueReader>
+    class ValueFlag : public ValueFlagBase
+    {
+        protected:
+            T value;
+            T defaultValue;
+
+            virtual std::string GetDefaultString(const HelpParams&) const override
+            {
+                return detail::ToString(defaultValue);
+            }
+
+        private:
+            Reader reader;
+
+        public:
+
+            ValueFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const T &defaultValue_, Options options_): ValueFlagBase(name_, help_, std::move(matcher_), options_), value(defaultValue_), defaultValue(defaultValue_)
+            {
+                group_.Add(*this);
+            }
+
+            ValueFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const T &defaultValue_ = T(), const bool extraError_ = false): ValueFlag(group_, name_, help_, std::move(matcher_), defaultValue_, extraError_ ? Options::Single : Options::None)
+            {
+            }
+
+            ValueFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, Options options_): ValueFlag(group_, name_, help_, std::move(matcher_), T(), options_)
+            {
+            }
+
+            virtual ~ValueFlag() {}
+
+            virtual void ParseValue(const std::vector<std::string> &values_) override
+            {
+                const std::string &value_ = values_.at(0);
+
+#ifdef ARGS_NOEXCEPT
+                if (!reader(name, value_, this->value))
+                {
+                    error = Error::Parse;
+                }
+#else
+                reader(name, value_, this->value);
+#endif
+            }
+
+            virtual void Reset() noexcept override
+            {
+                ValueFlagBase::Reset();
+                value = defaultValue;
+            }
+
+            /** Get the value
+             */
+            T &Get() noexcept
+            {
+                return value;
+            }
+
+            /** Get the default value
+             */
+            const T &GetDefault() noexcept
+            {
+                return defaultValue;
+            }
+    };
+
+    /** An optional argument-accepting flag class
+     *
+     * \tparam T the type to extract the argument as
+     * \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)
+     */
+    template <
+        typename T,
+        typename Reader = ValueReader>
+    class ImplicitValueFlag : public ValueFlag<T, Reader>
+    {
+        protected:
+            T implicitValue;
+
+        public:
+
+            ImplicitValueFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const T &implicitValue_, const T &defaultValue_ = T(), Options options_ = {})
+                : ValueFlag<T, Reader>(group_, name_, help_, std::move(matcher_), defaultValue_, options_), implicitValue(implicitValue_)
+            {
+            }
+
+            ImplicitValueFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const T &defaultValue_ = T(), Options options_ = {})
+                : ValueFlag<T, Reader>(group_, name_, help_, std::move(matcher_), defaultValue_, options_), implicitValue(defaultValue_)
+            {
+            }
+
+            ImplicitValueFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, Options options_)
+                : ValueFlag<T, Reader>(group_, name_, help_, std::move(matcher_), {}, options_), implicitValue()
+            {
+            }
+
+            virtual ~ImplicitValueFlag() {}
+
+            virtual Nargs NumberOfArguments() const noexcept override
+            {
+                return {0, 1};
+            }
+
+            virtual void ParseValue(const std::vector<std::string> &value_) override
+            {
+                if (value_.empty())
+                {
+                    this->value = implicitValue;
+                } else
+                {
+                    ValueFlag<T, Reader>::ParseValue(value_);
+                }
+            }
+    };
+
+    /** A variadic arguments accepting flag class
+     *
+     * \tparam T the type to extract the argument as
+     * \tparam List the list type that houses the values
+     * \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)
+     */
+    template <
+        typename T,
+        template <typename...> class List = std::vector,
+        typename Reader = ValueReader>
+    class NargsValueFlag : public FlagBase
+    {
+        protected:
+
+            List<T> values;
+            const List<T> defaultValues;
+            Nargs nargs;
+            Reader reader;
+
+        public:
+
+            typedef List<T> Container;
+            typedef T value_type;
+            typedef typename Container::allocator_type allocator_type;
+            typedef typename Container::pointer pointer;
+            typedef typename Container::const_pointer const_pointer;
+            typedef T& reference;
+            typedef const T& const_reference;
+            typedef typename Container::size_type size_type;
+            typedef typename Container::difference_type difference_type;
+            typedef typename Container::iterator iterator;
+            typedef typename Container::const_iterator const_iterator;
+            typedef std::reverse_iterator<iterator> reverse_iterator;
+            typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+            NargsValueFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, Nargs nargs_, const List<T> &defaultValues_ = {}, Options options_ = {})
+                : FlagBase(name_, help_, std::move(matcher_), options_), values(defaultValues_), defaultValues(defaultValues_),nargs(nargs_)
+            {
+                group_.Add(*this);
+            }
+
+            virtual ~NargsValueFlag() {}
+
+            virtual Nargs NumberOfArguments() const noexcept override
+            {
+                return nargs;
+            }
+
+            virtual void ParseValue(const std::vector<std::string> &values_) override
+            {
+                values.clear();
+
+                for (const std::string &value : values_)
+                {
+                    T v;
+#ifdef ARGS_NOEXCEPT
+                    if (!reader(name, value, v))
+                    {
+                        error = Error::Parse;
+                    }
+#else
+                    reader(name, value, v);
+#endif
+                    values.insert(std::end(values), v);
+                }
+            }
+
+            List<T> &Get() noexcept
+            {
+                return values;
+            }
+
+            iterator begin() noexcept
+            {
+                return values.begin();
+            }
+
+            const_iterator begin() const noexcept
+            {
+                return values.begin();
+            }
+
+            const_iterator cbegin() const noexcept
+            {
+                return values.cbegin();
+            }
+
+            iterator end() noexcept
+            {
+                return values.end();
+            }
+
+            const_iterator end() const noexcept 
+            {
+                return values.end();
+            }
+
+            const_iterator cend() const noexcept
+            {
+                return values.cend();
+            }
+
+            virtual void Reset() noexcept override
+            {
+                FlagBase::Reset();
+                values = defaultValues;
+            }
+
+            virtual FlagBase *Match(const EitherFlag &arg) override
+            {
+                const bool wasMatched = Matched();
+                auto me = FlagBase::Match(arg);
+                if (me && !wasMatched)
+                {
+                    values.clear();
+                }
+                return me;
+            }
+    };
+
+    /** An argument-accepting flag class that pushes the found values into a list
+     * 
+     * \tparam T the type to extract the argument as
+     * \tparam List the list type that houses the values
+     * \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)
+     */
+    template <
+        typename T,
+        template <typename...> class List = std::vector,
+        typename Reader = ValueReader>
+    class ValueFlagList : public ValueFlagBase
+    {
+        private:
+            using Container = List<T>;
+            Container values;
+            const Container defaultValues;
+            Reader reader;
+
+        public:
+
+            typedef T value_type;
+            typedef typename Container::allocator_type allocator_type;
+            typedef typename Container::pointer pointer;
+            typedef typename Container::const_pointer const_pointer;
+            typedef T& reference;
+            typedef const T& const_reference;
+            typedef typename Container::size_type size_type;
+            typedef typename Container::difference_type difference_type;
+            typedef typename Container::iterator iterator;
+            typedef typename Container::const_iterator const_iterator;
+            typedef std::reverse_iterator<iterator> reverse_iterator;
+            typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+            ValueFlagList(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const Container &defaultValues_ = Container(), Options options_ = {}):
+                ValueFlagBase(name_, help_, std::move(matcher_), options_), values(defaultValues_), defaultValues(defaultValues_)
+            {
+                group_.Add(*this);
+            }
+
+            virtual ~ValueFlagList() {}
+
+            virtual void ParseValue(const std::vector<std::string> &values_) override
+            {
+                const std::string &value_ = values_.at(0);
+
+                T v;
+#ifdef ARGS_NOEXCEPT
+                if (!reader(name, value_, v))
+                {
+                    error = Error::Parse;
+                }
+#else
+                reader(name, value_, v);
+#endif
+                values.insert(std::end(values), v);
+            }
+
+            /** Get the values
+             */
+            Container &Get() noexcept
+            {
+                return values;
+            }
+
+            virtual std::string Name() const override
+            {
+                return name + std::string("...");
+            }
+
+            virtual void Reset() noexcept override
+            {
+                ValueFlagBase::Reset();
+                values = defaultValues;
+            }
+
+            virtual FlagBase *Match(const EitherFlag &arg) override
+            {
+                const bool wasMatched = Matched();
+                auto me = FlagBase::Match(arg);
+                if (me && !wasMatched)
+                {
+                    values.clear();
+                }
+                return me;
+            }
+
+            iterator begin() noexcept
+            {
+                return values.begin();
+            }
+
+            const_iterator begin() const noexcept
+            {
+                return values.begin();
+            }
+
+            const_iterator cbegin() const noexcept
+            {
+                return values.cbegin();
+            }
+
+            iterator end() noexcept
+            {
+                return values.end();
+            }
+
+            const_iterator end() const noexcept 
+            {
+                return values.end();
+            }
+
+            const_iterator cend() const noexcept
+            {
+                return values.cend();
+            }
+    };
+
+    /** A mapping value flag class
+     * 
+     * \tparam K the type to extract the argument as
+     * \tparam T the type to store the result as
+     * \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)
+     * \tparam Map The Map type.  Should operate like std::map or std::unordered_map
+     */
+    template <
+        typename K,
+        typename T,
+        typename Reader = ValueReader,
+        template <typename...> class Map = std::unordered_map>
+    class MapFlag : public ValueFlagBase
+    {
+        private:
+            const Map<K, T> map;
+            T value;
+            const T defaultValue;
+            Reader reader;
+
+        protected:
+            virtual std::vector<std::string> GetChoicesStrings(const HelpParams &) const override
+            {
+                return detail::MapKeysToStrings(map);
+            }
+
+        public:
+
+            MapFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const Map<K, T> &map_, const T &defaultValue_, Options options_): ValueFlagBase(name_, help_, std::move(matcher_), options_), map(map_), value(defaultValue_), defaultValue(defaultValue_)
+            {
+                group_.Add(*this);
+            }
+
+            MapFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const Map<K, T> &map_, const T &defaultValue_ = T(), const bool extraError_ = false): MapFlag(group_, name_, help_, std::move(matcher_), map_, defaultValue_, extraError_ ? Options::Single : Options::None)
+            {
+            }
+
+            MapFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const Map<K, T> &map_, Options options_): MapFlag(group_, name_, help_, std::move(matcher_), map_, T(), options_)
+            {
+            }
+
+            virtual ~MapFlag() {}
+
+            virtual void ParseValue(const std::vector<std::string> &values_) override
+            {
+                const std::string &value_ = values_.at(0);
+
+                K key;
+#ifdef ARGS_NOEXCEPT
+                if (!reader(name, value_, key))
+                {
+                    error = Error::Parse;
+                }
+#else
+                reader(name, value_, key);
+#endif
+                auto it = map.find(key);
+                if (it == std::end(map))
+                {
+                    std::ostringstream problem;
+                    problem << "Could not find key '" << key << "' in map for arg '" << name << "'";
+#ifdef ARGS_NOEXCEPT
+                    error = Error::Map;
+                    errorMsg = problem.str();
+#else
+                    throw MapError(problem.str());
+#endif
+                } else
+                {
+                    this->value = it->second;
+                }
+            }
+
+            /** Get the value
+             */
+            T &Get() noexcept
+            {
+                return value;
+            }
+
+            virtual void Reset() noexcept override
+            {
+                ValueFlagBase::Reset();
+                value = defaultValue;
+            }
+    };
+
+    /** A mapping value flag list class
+     * 
+     * \tparam K the type to extract the argument as
+     * \tparam T the type to store the result as
+     * \tparam List the list type that houses the values
+     * \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)
+     * \tparam Map The Map type.  Should operate like std::map or std::unordered_map
+     */
+    template <
+        typename K,
+        typename T,
+        template <typename...> class List = std::vector,
+        typename Reader = ValueReader,
+        template <typename...> class Map = std::unordered_map>
+    class MapFlagList : public ValueFlagBase
+    {
+        private:
+            using Container = List<T>;
+            const Map<K, T> map;
+            Container values;
+            const Container defaultValues;
+            Reader reader;
+
+        protected:
+            virtual std::vector<std::string> GetChoicesStrings(const HelpParams &) const override
+            {
+                return detail::MapKeysToStrings(map);
+            }
+
+        public:
+            typedef T value_type;
+            typedef typename Container::allocator_type allocator_type;
+            typedef typename Container::pointer pointer;
+            typedef typename Container::const_pointer const_pointer;
+            typedef T& reference;
+            typedef const T& const_reference;
+            typedef typename Container::size_type size_type;
+            typedef typename Container::difference_type difference_type;
+            typedef typename Container::iterator iterator;
+            typedef typename Container::const_iterator const_iterator;
+            typedef std::reverse_iterator<iterator> reverse_iterator;
+            typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+            MapFlagList(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const Map<K, T> &map_, const Container &defaultValues_ = Container()): ValueFlagBase(name_, help_, std::move(matcher_)), map(map_), values(defaultValues_), defaultValues(defaultValues_)
+            {
+                group_.Add(*this);
+            }
+
+            virtual ~MapFlagList() {}
+
+            virtual void ParseValue(const std::vector<std::string> &values_) override
+            {
+                const std::string &value = values_.at(0);
+
+                K key;
+#ifdef ARGS_NOEXCEPT
+                if (!reader(name, value, key))
+                {
+                    error = Error::Parse;
+                }
+#else
+                reader(name, value, key);
+#endif
+                auto it = map.find(key);
+                if (it == std::end(map))
+                {
+                    std::ostringstream problem;
+                    problem << "Could not find key '" << key << "' in map for arg '" << name << "'";
+#ifdef ARGS_NOEXCEPT
+                    error = Error::Map;
+                    errorMsg = problem.str();
+#else
+                    throw MapError(problem.str());
+#endif
+                } else
+                {
+                    this->values.emplace_back(it->second);
+                }
+            }
+
+            /** Get the value
+             */
+            Container &Get() noexcept
+            {
+                return values;
+            }
+
+            virtual std::string Name() const override
+            {
+                return name + std::string("...");
+            }
+
+            virtual void Reset() noexcept override
+            {
+                ValueFlagBase::Reset();
+                values = defaultValues;
+            }
+
+            virtual FlagBase *Match(const EitherFlag &arg) override
+            {
+                const bool wasMatched = Matched();
+                auto me = FlagBase::Match(arg);
+                if (me && !wasMatched)
+                {
+                    values.clear();
+                }
+                return me;
+            }
+
+            iterator begin() noexcept
+            {
+                return values.begin();
+            }
+
+            const_iterator begin() const noexcept
+            {
+                return values.begin();
+            }
+
+            const_iterator cbegin() const noexcept
+            {
+                return values.cbegin();
+            }
+
+            iterator end() noexcept
+            {
+                return values.end();
+            }
+
+            const_iterator end() const noexcept 
+            {
+                return values.end();
+            }
+
+            const_iterator cend() const noexcept
+            {
+                return values.cend();
+            }
+    };
+
+    /** A positional argument class
+     *
+     * \tparam T the type to extract the argument as
+     * \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)
+     */
+    template <
+        typename T,
+        typename Reader = ValueReader>
+    class Positional : public PositionalBase
+    {
+        private:
+            T value;
+            const T defaultValue;
+            Reader reader;
+        public:
+            Positional(Group &group_, const std::string &name_, const std::string &help_, const T &defaultValue_ = T(), Options options_ = {}): PositionalBase(name_, help_, options_), value(defaultValue_), defaultValue(defaultValue_)
+            {
+                group_.Add(*this);
+            }
+
+            Positional(Group &group_, const std::string &name_, const std::string &help_, Options options_): Positional(group_, name_, help_, T(), options_)
+            {
+            }
+
+            virtual ~Positional() {}
+
+            virtual void ParseValue(const std::string &value_) override
+            {
+#ifdef ARGS_NOEXCEPT
+                if (!reader(name, value_, this->value))
+                {
+                    error = Error::Parse;
+                }
+#else
+                reader(name, value_, this->value);
+#endif
+                ready = false;
+                matched = true;
+            }
+
+            /** Get the value
+             */
+            T &Get() noexcept
+            {
+                return value;
+            }
+
+            virtual void Reset() noexcept override
+            {
+                PositionalBase::Reset();
+                value = defaultValue;
+            }
+    };
+
+    /** A positional argument class that pushes the found values into a list
+     * 
+     * \tparam T the type to extract the argument as
+     * \tparam List the list type that houses the values
+     * \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)
+     */
+    template <
+        typename T,
+        template <typename...> class List = std::vector,
+        typename Reader = ValueReader>
+    class PositionalList : public PositionalBase
+    {
+        private:
+            using Container = List<T>;
+            Container values;
+            const Container defaultValues;
+            Reader reader;
+
+        public:
+            typedef T value_type;
+            typedef typename Container::allocator_type allocator_type;
+            typedef typename Container::pointer pointer;
+            typedef typename Container::const_pointer const_pointer;
+            typedef T& reference;
+            typedef const T& const_reference;
+            typedef typename Container::size_type size_type;
+            typedef typename Container::difference_type difference_type;
+            typedef typename Container::iterator iterator;
+            typedef typename Container::const_iterator const_iterator;
+            typedef std::reverse_iterator<iterator> reverse_iterator;
+            typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+            PositionalList(Group &group_, const std::string &name_, const std::string &help_, const Container &defaultValues_ = Container(), Options options_ = {}): PositionalBase(name_, help_, options_), values(defaultValues_), defaultValues(defaultValues_)
+            {
+                group_.Add(*this);
+            }
+
+            PositionalList(Group &group_, const std::string &name_, const std::string &help_, Options options_): PositionalList(group_, name_, help_, {}, options_)
+            {
+            }
+
+            virtual ~PositionalList() {}
+
+            virtual void ParseValue(const std::string &value_) override
+            {
+                T v;
+#ifdef ARGS_NOEXCEPT
+                if (!reader(name, value_, v))
+                {
+                    error = Error::Parse;
+                }
+#else
+                reader(name, value_, v);
+#endif
+                values.insert(std::end(values), v);
+                matched = true;
+            }
+
+            virtual std::string Name() const override
+            {
+                return name + std::string("...");
+            }
+
+            /** Get the values
+             */
+            Container &Get() noexcept
+            {
+                return values;
+            }
+
+            virtual void Reset() noexcept override
+            {
+                PositionalBase::Reset();
+                values = defaultValues;
+            }
+
+            virtual PositionalBase *GetNextPositional() override
+            {
+                const bool wasMatched = Matched();
+                auto me = PositionalBase::GetNextPositional();
+                if (me && !wasMatched)
+                {
+                    values.clear();
+                }
+                return me;
+            }
+
+            iterator begin() noexcept
+            {
+                return values.begin();
+            }
+
+            const_iterator begin() const noexcept
+            {
+                return values.begin();
+            }
+
+            const_iterator cbegin() const noexcept
+            {
+                return values.cbegin();
+            }
+
+            iterator end() noexcept
+            {
+                return values.end();
+            }
+
+            const_iterator end() const noexcept 
+            {
+                return values.end();
+            }
+
+            const_iterator cend() const noexcept
+            {
+                return values.cend();
+            }
+    };
+
+    /** A positional argument mapping class
+     * 
+     * \tparam K the type to extract the argument as
+     * \tparam T the type to store the result as
+     * \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)
+     * \tparam Map The Map type.  Should operate like std::map or std::unordered_map
+     */
+    template <
+        typename K,
+        typename T,
+        typename Reader = ValueReader,
+        template <typename...> class Map = std::unordered_map>
+    class MapPositional : public PositionalBase
+    {
+        private:
+            const Map<K, T> map;
+            T value;
+            const T defaultValue;
+            Reader reader;
+
+        protected:
+            virtual std::vector<std::string> GetChoicesStrings(const HelpParams &) const override
+            {
+                return detail::MapKeysToStrings(map);
+            }
+
+        public:
+
+            MapPositional(Group &group_, const std::string &name_, const std::string &help_, const Map<K, T> &map_, const T &defaultValue_ = T(), Options options_ = {}):
+                PositionalBase(name_, help_, options_), map(map_), value(defaultValue_), defaultValue(defaultValue_)
+            {
+                group_.Add(*this);
+            }
+
+            virtual ~MapPositional() {}
+
+            virtual void ParseValue(const std::string &value_) override
+            {
+                K key;
+#ifdef ARGS_NOEXCEPT
+                if (!reader(name, value_, key))
+                {
+                    error = Error::Parse;
+                }
+#else
+                reader(name, value_, key);
+#endif
+                auto it = map.find(key);
+                if (it == std::end(map))
+                {
+                    std::ostringstream problem;
+                    problem << "Could not find key '" << key << "' in map for arg '" << name << "'";
+#ifdef ARGS_NOEXCEPT
+                    error = Error::Map;
+                    errorMsg = problem.str();
+#else
+                    throw MapError(problem.str());
+#endif
+                } else
+                {
+                    this->value = it->second;
+                    ready = false;
+                    matched = true;
+                }
+            }
+
+            /** Get the value
+             */
+            T &Get() noexcept
+            {
+                return value;
+            }
+
+            virtual void Reset() noexcept override
+            {
+                PositionalBase::Reset();
+                value = defaultValue;
+            }
+    };
+
+    /** A positional argument mapping list class
+     * 
+     * \tparam K the type to extract the argument as
+     * \tparam T the type to store the result as
+     * \tparam List the list type that houses the values
+     * \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)
+     * \tparam Map The Map type.  Should operate like std::map or std::unordered_map
+     */
+    template <
+        typename K,
+        typename T,
+        template <typename...> class List = std::vector,
+        typename Reader = ValueReader,
+        template <typename...> class Map = std::unordered_map>
+    class MapPositionalList : public PositionalBase
+    {
+        private:
+            using Container = List<T>;
+
+            const Map<K, T> map;
+            Container values;
+            const Container defaultValues;
+            Reader reader;
+
+        protected:
+            virtual std::vector<std::string> GetChoicesStrings(const HelpParams &) const override
+            {
+                return detail::MapKeysToStrings(map);
+            }
+
+        public:
+            typedef T value_type;
+            typedef typename Container::allocator_type allocator_type;
+            typedef typename Container::pointer pointer;
+            typedef typename Container::const_pointer const_pointer;
+            typedef T& reference;
+            typedef const T& const_reference;
+            typedef typename Container::size_type size_type;
+            typedef typename Container::difference_type difference_type;
+            typedef typename Container::iterator iterator;
+            typedef typename Container::const_iterator const_iterator;
+            typedef std::reverse_iterator<iterator> reverse_iterator;
+            typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+            MapPositionalList(Group &group_, const std::string &name_, const std::string &help_, const Map<K, T> &map_, const Container &defaultValues_ = Container(), Options options_ = {}):
+                PositionalBase(name_, help_, options_), map(map_), values(defaultValues_), defaultValues(defaultValues_)
+            {
+                group_.Add(*this);
+            }
+
+            virtual ~MapPositionalList() {}
+
+            virtual void ParseValue(const std::string &value_) override
+            {
+                K key;
+#ifdef ARGS_NOEXCEPT
+                if (!reader(name, value_, key))
+                {
+                    error = Error::Parse;
+                }
+#else
+                reader(name, value_, key);
+#endif
+                auto it = map.find(key);
+                if (it == std::end(map))
+                {
+                    std::ostringstream problem;
+                    problem << "Could not find key '" << key << "' in map for arg '" << name << "'";
+#ifdef ARGS_NOEXCEPT
+                    error = Error::Map;
+                    errorMsg = problem.str();
+#else
+                    throw MapError(problem.str());
+#endif
+                } else
+                {
+                    this->values.emplace_back(it->second);
+                    matched = true;
+                }
+            }
+
+            /** Get the value
+             */
+            Container &Get() noexcept
+            {
+                return values;
+            }
+
+            virtual std::string Name() const override
+            {
+                return name + std::string("...");
+            }
+
+            virtual void Reset() noexcept override
+            {
+                PositionalBase::Reset();
+                values = defaultValues;
+            }
+
+            virtual PositionalBase *GetNextPositional() override
+            {
+                const bool wasMatched = Matched();
+                auto me = PositionalBase::GetNextPositional();
+                if (me && !wasMatched)
+                {
+                    values.clear();
+                }
+                return me;
+            }
+
+            iterator begin() noexcept
+            {
+                return values.begin();
+            }
+
+            const_iterator begin() const noexcept
+            {
+                return values.begin();
+            }
+
+            const_iterator cbegin() const noexcept
+            {
+                return values.cbegin();
+            }
+
+            iterator end() noexcept
+            {
+                return values.end();
+            }
+
+            const_iterator end() const noexcept 
+            {
+                return values.end();
+            }
+
+            const_iterator cend() const noexcept
+            {
+                return values.cend();
+            }
+    };
+}
+
+#endif
diff --git a/skia/utils/rive_mgr.cpp b/skia/utils/rive_mgr.cpp
new file mode 100644
index 0000000..3e8026f
--- /dev/null
+++ b/skia/utils/rive_mgr.cpp
@@ -0,0 +1,70 @@
+#include "rive_mgr.hpp"
+#include "rive/animation/linear_animation_instance.hpp"
+#include "rive/artboard.hpp"
+#include "rive/file.hpp"
+
+struct AutoClose {
+    FILE* m_File;
+
+    AutoClose(FILE* file) : m_File(file) {}
+    ~AutoClose() { this->close(); }
+
+    void close() {
+        if (m_File) {
+            fclose(m_File);
+            m_File = nullptr;
+        }
+    }
+};
+
+bool RiveMgr::load(const char filename[], const char artboard[], const char animation[]) {
+    m_File = nullptr;
+    m_Artboard = nullptr;
+    m_Animation = nullptr;
+
+    m_File = RiveMgr::loadFile(filename);
+    if (m_File) {
+        m_Artboard = m_File->artboardNamed(artboard);
+        if (m_Artboard) {
+            m_Animation = m_Artboard->animationNamed(animation);
+        }
+    }
+    return m_File != nullptr;
+}
+
+static void log(const char msg[], const char arg[] = nullptr) {
+    std::string err(msg);
+    if (arg) {
+        err = err + std::string(arg);
+    }
+    fprintf(stderr, "%s\n", err.c_str());
+}
+
+std::unique_ptr<rive::File> RiveMgr::loadFile(const char filename[]) {
+    AutoClose afc(fopen(filename, "rb"));
+    FILE* fp = afc.m_File;
+
+    if (fp == nullptr) {
+        log("Failed to open file ", filename);
+        return nullptr;
+    }
+
+    fseek(fp, 0, SEEK_END);
+    auto length = ftell(fp);
+    fseek(fp, 0, SEEK_SET);
+
+    std::vector<uint8_t> bytes(length);
+
+    if (fread(bytes.data(), 1, length, fp) != length) {
+        log("Failed to read file into bytes array ", filename);
+        return nullptr;
+    }
+
+    auto reader = rive::BinaryReader(bytes.data(), length);
+    auto file = rive::File::import(reader);
+
+    if (!file) {
+        log("Failed to read bytes into Rive file ", filename);
+    }
+    return file;
+}
diff --git a/skia/utils/rive_mgr.hpp b/skia/utils/rive_mgr.hpp
new file mode 100644
index 0000000..d3d351b
--- /dev/null
+++ b/skia/utils/rive_mgr.hpp
@@ -0,0 +1,27 @@
+#ifndef _RIVE_MGR_HPP_
+#define _RIVE_MGR_HPP_
+
+#include "rive/animation/animation.hpp"
+#include "rive/animation/linear_animation.hpp"
+#include "rive/artboard.hpp"
+#include "rive/file.hpp"
+#include <memory>
+
+class RiveMgr {
+    std::unique_ptr<rive::File> m_File;
+    std::unique_ptr<rive::ArtboardInstance> m_Artboard;
+    std::unique_ptr<rive::LinearAnimationInstance> m_Animation;
+
+public:
+    RiveMgr() {}
+
+    bool load(const char path[], const char artboard[], const char animation[]);
+
+    rive::File* file() const { return m_File.get(); }
+    rive::ArtboardInstance* artboard() const { return m_Artboard.get(); }
+    rive::LinearAnimationInstance* animation() const { return m_Animation.get(); }
+
+    static std::unique_ptr<rive::File> loadFile(const char filename[]);
+};
+
+#endif
