diff --git a/.clang-format b/.clang-format
index b98e24f..dd27708 100644
--- a/.clang-format
+++ b/.clang-format
@@ -1,97 +1,98 @@
 ---
-BasedOnStyle:  Google
-AccessModifierOffset: -1
+Language:        Cpp
+# BasedOnStyle:  LLVM
+AccessModifierOffset: -2
 AlignAfterOpenBracket: Align
 AlignConsecutiveAssignments: false
 AlignConsecutiveDeclarations: false
-AlignEscapedNewlinesLeft: true
+AlignEscapedNewlinesLeft: false
 AlignOperands:   true
 AlignTrailingComments: true
 AllowAllParametersOfDeclarationOnNextLine: true
 AllowShortBlocksOnASingleLine: false
 AllowShortCaseLabelsOnASingleLine: false
-AllowShortFunctionsOnASingleLine: All
-AllowShortIfStatementsOnASingleLine: true
-AllowShortLoopsOnASingleLine: true
+AllowShortFunctionsOnASingleLine: None
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
 AlwaysBreakAfterDefinitionReturnType: None
 AlwaysBreakAfterReturnType: None
-AlwaysBreakBeforeMultilineStrings: true
-AlwaysBreakTemplateDeclarations: true
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: false
 BinPackArguments: true
 BinPackParameters: true
 BraceWrapping:
-  AfterClass:      false
-  AfterControlStatement: false
-  AfterEnum:       false
-  AfterFunction:   false
-  AfterNamespace:  false
-  AfterObjCDeclaration: false
-  AfterStruct:     false
-  AfterUnion:      false
-  BeforeCatch:     false
-  BeforeElse:      false
+  AfterClass:      true
+  AfterControlStatement: true
+  AfterEnum:       true
+  AfterFunction:   true
+  AfterNamespace:  true
+  AfterObjCDeclaration: true
+  AfterStruct:     true
+  AfterUnion:      true
+  BeforeCatch:     true
+  BeforeElse:      true
   IndentBraces:    false
 BreakBeforeBinaryOperators: None
-BreakBeforeBraces: Attach
+BreakBeforeBraces: Custom
 BreakBeforeTernaryOperators: true
-BreakConstructorInitializersBeforeComma: false
+BreakConstructorInitializers: AfterColon
 ColumnLimit:     80
 CommentPragmas:  '^ IWYU pragma:'
-ConstructorInitializerAllOnOneLineOrOnePerLine: true
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
 ConstructorInitializerIndentWidth: 4
 ContinuationIndentWidth: 4
 Cpp11BracedListStyle: true
 DerivePointerAlignment: true
+PointerAlignment: Left
 DisableFormat:   false
 ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: true
 ForEachMacros:   [ foreach, Q_FOREACH, BOOST_FOREACH ]
+IncludeBlocks: Regroup
 IncludeCategories:
-  - Regex:           '^[<"](crow)'
-    Priority:        5
-  - Regex:           '^[<"](boost)'
-    Priority:        6
   - Regex:           '^[<"](gtest|gmock)'
-    Priority:        7
-  - Regex:           '^<.*\.h>'
+    Priority:        5
+  - Regex:           '^"config.h"'
+    Priority:        -1
+  - Regex:           '^".*\.hpp"'
     Priority:        1
-  - Regex:           '^<.*\.hpp>'
+  - Regex:           '^<.*\.h>'
     Priority:        2
   - Regex:           '^<.*'
     Priority:        3
   - Regex:           '.*'
     Priority:        4
 IndentCaseLabels: true
-IndentWidth:     2
-IndentWrappedFunctionNames: false
-KeepEmptyLinesAtTheStartOfBlocks: false
+IndentWidth:     4
+IndentWrappedFunctionNames: true
+KeepEmptyLinesAtTheStartOfBlocks: true
 MacroBlockBegin: ''
 MacroBlockEnd:   ''
 MaxEmptyLinesToKeep: 1
 NamespaceIndentation: None
 ObjCBlockIndentWidth: 2
 ObjCSpaceAfterProperty: false
-ObjCSpaceBeforeProtocolList: false
-PenaltyBreakBeforeFirstCallParameter: 1
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakBeforeFirstCallParameter: 19
 PenaltyBreakComment: 300
 PenaltyBreakFirstLessLess: 120
 PenaltyBreakString: 1000
 PenaltyExcessCharacter: 1000000
-PenaltyReturnTypeOnItsOwnLine: 200
-PointerAlignment: Left
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Right
 ReflowComments:  true
 SortIncludes:    true
 SpaceAfterCStyleCast: false
 SpaceBeforeAssignmentOperators: true
 SpaceBeforeParens: ControlStatements
 SpaceInEmptyParentheses: false
-SpacesBeforeTrailingComments: 2
+SpacesBeforeTrailingComments: 1
 SpacesInAngles:  false
 SpacesInContainerLiterals: true
 SpacesInCStyleCastParentheses: false
 SpacesInParentheses: false
 SpacesInSquareBrackets: false
-Standard:        Auto
-TabWidth:        8
+Standard:        Cpp11
+TabWidth:        4
 UseTab:          Never
 ...
-
diff --git a/crow/include/crow.h b/crow/include/crow.h
index edc0d7f..7e31cf3 100644
--- a/crow/include/crow.h
+++ b/crow/include/crow.h
@@ -1,4 +1,6 @@
 #pragma once
+#include "boost/beast/core.hpp"
+
 #include "crow/app.h"
 #include "crow/common.h"
 #include "crow/http_connection.h"
@@ -13,4 +15,3 @@
 #include "crow/timer_queue.h"
 #include "crow/utility.h"
 #include "crow/websocket.h"
-#include "boost/beast/core.hpp"
diff --git a/crow/include/crow/app.h b/crow/include/crow/app.h
index 78d99df..7051ec8 100644
--- a/crow/include/crow/app.h
+++ b/crow/include/crow/app.h
@@ -7,6 +7,7 @@
 #include <memory>
 #include <string>
 #include <utility>
+
 #include "crow/http_request.h"
 #include "crow/http_server.h"
 #include "crow/logging.h"
@@ -14,198 +15,236 @@
 #include "crow/routing.h"
 #include "crow/utility.h"
 
-#define BMCWEB_ROUTE(app, url) \
-  app.template route<crow::black_magic::get_parameter_tag(url)>(url)
+#define BMCWEB_ROUTE(app, url)                                                 \
+    app.template route<crow::black_magic::get_parameter_tag(url)>(url)
 
-namespace crow {
+namespace crow
+{
 #ifdef BMCWEB_ENABLE_SSL
 using ssl_context_t = boost::asio::ssl::context;
 #endif
-template <typename... Middlewares>
-class Crow {
- public:
-  using self_t = Crow;
-  using server_t = Server<Crow, SocketAdaptor, Middlewares...>;
+template <typename... Middlewares> class Crow
+{
+  public:
+    using self_t = Crow;
+    using server_t = Server<Crow, SocketAdaptor, Middlewares...>;
 #ifdef BMCWEB_ENABLE_SSL
-  using ssl_server_t = Server<Crow, SSLAdaptor, Middlewares...>;
+    using ssl_server_t = Server<Crow, SSLAdaptor, Middlewares...>;
 #endif
-  explicit Crow(std::shared_ptr<boost::asio::io_service> io =
-                    std::make_shared<boost::asio::io_service>())
-      : io(std::move(io)) {}
-  ~Crow() { this->stop(); }
-
-  template <typename Adaptor>
-  void handleUpgrade(const Request& req, Response& res, Adaptor&& adaptor) {
-    router.handleUpgrade(req, res, adaptor);
-  }
-
-  void handle(const Request& req, Response& res) { router.handle(req, res); }
-
-  DynamicRule& routeDynamic(std::string&& rule) {
-    return router.newRuleDynamic(rule);
-  }
-
-  template <uint64_t Tag>
-  auto route(std::string&& rule) -> typename std::result_of<
-      decltype (&Router::newRuleTagged<Tag>)(Router, std::string&&)>::type {
-    return router.newRuleTagged<Tag>(std::move(rule));
-  }
-
-  self_t& socket(int existing_socket) {
-    socketFd = existing_socket;
-    return *this;
-  }
-
-  self_t& port(std::uint16_t port) {
-    portUint = port;
-    return *this;
-  }
-
-  self_t& bindaddr(std::string bindaddr) {
-    bindaddrStr = bindaddr;
-    return *this;
-  }
-
-  void validate() { router.validate(); }
-
-  void run() {
-    validate();
-#ifdef BMCWEB_ENABLE_SSL
-    if (useSsl) {
-      if (-1 == socketFd) {
-        sslServer = std::move(std::make_unique<ssl_server_t>(
-            this, bindaddrStr, portUint, &middlewares, &sslContext, io));
-      } else {
-        sslServer = std::move(std::make_unique<ssl_server_t>(
-            this, socketFd, &middlewares, &sslContext, io));
-      }
-      sslServer->setTickFunction(tickInterval, tickFunction);
-      sslServer->run();
-    } else
-#endif
+    explicit Crow(std::shared_ptr<boost::asio::io_service> io =
+                      std::make_shared<boost::asio::io_service>()) :
+        io(std::move(io))
     {
-      if (-1 == socketFd) {
-        server = std::move(std::make_unique<server_t>(
-            this, bindaddrStr, portUint, &middlewares, nullptr, io));
-      } else {
-        server = std::move(std::make_unique<server_t>(
-            this, socketFd, &middlewares, nullptr, io));
-      }
-      server->setTickFunction(tickInterval, tickFunction);
-      server->run();
     }
-  }
+    ~Crow()
+    {
+        this->stop();
+    }
 
-  void stop() { io->stop(); }
+    template <typename Adaptor>
+    void handleUpgrade(const Request& req, Response& res, Adaptor&& adaptor)
+    {
+        router.handleUpgrade(req, res, adaptor);
+    }
 
-  void debugPrint() {
-    BMCWEB_LOG_DEBUG << "Routing:";
-    router.debugPrint();
-  }
+    void handle(const Request& req, Response& res)
+    {
+        router.handle(req, res);
+    }
 
-  std::vector<const std::string*> getRoutes() {
-    // TODO(ed) Should this be /?
-    const std::string root("");
-    return router.getRoutes(root);
-  }
-  std::vector<const std::string*> getRoutes(const std::string& parent) {
-    return router.getRoutes(parent);
-  }
+    DynamicRule& routeDynamic(std::string&& rule)
+    {
+        return router.newRuleDynamic(rule);
+    }
+
+    template <uint64_t Tag>
+    auto route(std::string&& rule) -> typename std::result_of<
+        decltype (&Router::newRuleTagged<Tag>)(Router, std::string&&)>::type
+    {
+        return router.newRuleTagged<Tag>(std::move(rule));
+    }
+
+    self_t& socket(int existing_socket)
+    {
+        socketFd = existing_socket;
+        return *this;
+    }
+
+    self_t& port(std::uint16_t port)
+    {
+        portUint = port;
+        return *this;
+    }
+
+    self_t& bindaddr(std::string bindaddr)
+    {
+        bindaddrStr = bindaddr;
+        return *this;
+    }
+
+    void validate()
+    {
+        router.validate();
+    }
+
+    void run()
+    {
+        validate();
+#ifdef BMCWEB_ENABLE_SSL
+        if (useSsl)
+        {
+            if (-1 == socketFd)
+            {
+                sslServer = std::move(std::make_unique<ssl_server_t>(
+                    this, bindaddrStr, portUint, &middlewares, &sslContext,
+                    io));
+            }
+            else
+            {
+                sslServer = std::move(std::make_unique<ssl_server_t>(
+                    this, socketFd, &middlewares, &sslContext, io));
+            }
+            sslServer->setTickFunction(tickInterval, tickFunction);
+            sslServer->run();
+        }
+        else
+#endif
+        {
+            if (-1 == socketFd)
+            {
+                server = std::move(std::make_unique<server_t>(
+                    this, bindaddrStr, portUint, &middlewares, nullptr, io));
+            }
+            else
+            {
+                server = std::move(std::make_unique<server_t>(
+                    this, socketFd, &middlewares, nullptr, io));
+            }
+            server->setTickFunction(tickInterval, tickFunction);
+            server->run();
+        }
+    }
+
+    void stop()
+    {
+        io->stop();
+    }
+
+    void debugPrint()
+    {
+        BMCWEB_LOG_DEBUG << "Routing:";
+        router.debugPrint();
+    }
+
+    std::vector<const std::string*> getRoutes()
+    {
+        // TODO(ed) Should this be /?
+        const std::string root("");
+        return router.getRoutes(root);
+    }
+    std::vector<const std::string*> getRoutes(const std::string& parent)
+    {
+        return router.getRoutes(parent);
+    }
 
 #ifdef BMCWEB_ENABLE_SSL
-  self_t& sslFile(const std::string& crt_filename,
-                  const std::string& key_filename) {
-    useSsl = true;
-    sslContext.set_verify_mode(boost::asio::ssl::verify_peer);
-    sslContext.use_certificate_file(crt_filename, ssl_context_t::pem);
-    sslContext.use_private_key_file(key_filename, ssl_context_t::pem);
-    sslContext.set_options(boost::asio::ssl::context::default_workarounds |
-                           boost::asio::ssl::context::no_sslv2 |
-                           boost::asio::ssl::context::no_sslv3);
-    return *this;
-  }
+    self_t& sslFile(const std::string& crt_filename,
+                    const std::string& key_filename)
+    {
+        useSsl = true;
+        sslContext.set_verify_mode(boost::asio::ssl::verify_peer);
+        sslContext.use_certificate_file(crt_filename, ssl_context_t::pem);
+        sslContext.use_private_key_file(key_filename, ssl_context_t::pem);
+        sslContext.set_options(boost::asio::ssl::context::default_workarounds |
+                               boost::asio::ssl::context::no_sslv2 |
+                               boost::asio::ssl::context::no_sslv3);
+        return *this;
+    }
 
-  self_t& sslFile(const std::string& pem_filename) {
-    useSsl = true;
-    sslContext.set_verify_mode(boost::asio::ssl::verify_peer);
-    sslContext.load_verify_file(pem_filename);
-    sslContext.set_options(boost::asio::ssl::context::default_workarounds |
-                           boost::asio::ssl::context::no_sslv2 |
-                           boost::asio::ssl::context::no_sslv3);
-    return *this;
-  }
+    self_t& sslFile(const std::string& pem_filename)
+    {
+        useSsl = true;
+        sslContext.set_verify_mode(boost::asio::ssl::verify_peer);
+        sslContext.load_verify_file(pem_filename);
+        sslContext.set_options(boost::asio::ssl::context::default_workarounds |
+                               boost::asio::ssl::context::no_sslv2 |
+                               boost::asio::ssl::context::no_sslv3);
+        return *this;
+    }
 
-  self_t& ssl(boost::asio::ssl::context&& ctx) {
-    useSsl = true;
-    sslContext = std::move(ctx);
-    return *this;
-  }
+    self_t& ssl(boost::asio::ssl::context&& ctx)
+    {
+        useSsl = true;
+        sslContext = std::move(ctx);
+        return *this;
+    }
 
-  bool useSsl{false};
-  ssl_context_t sslContext{boost::asio::ssl::context::sslv23};
+    bool useSsl{false};
+    ssl_context_t sslContext{boost::asio::ssl::context::sslv23};
 
 #else
-  template <typename T, typename... Remain>
-  self_t& ssl_file(T&&, Remain&&...) {
-    // We can't call .ssl() member function unless BMCWEB_ENABLE_SSL is defined.
-    static_assert(
-        // make static_assert dependent to T; always false
-        std::is_base_of<T, void>::value,
-        "Define BMCWEB_ENABLE_SSL to enable ssl support.");
-    return *this;
-  }
+    template <typename T, typename... Remain> self_t& ssl_file(T&&, Remain&&...)
+    {
+        // We can't call .ssl() member function unless BMCWEB_ENABLE_SSL is
+        // defined.
+        static_assert(
+            // make static_assert dependent to T; always false
+            std::is_base_of<T, void>::value,
+            "Define BMCWEB_ENABLE_SSL to enable ssl support.");
+        return *this;
+    }
 
-  template <typename T>
-  self_t& ssl(T&&) {
-    // We can't call .ssl() member function unless BMCWEB_ENABLE_SSL is defined.
-    static_assert(
-        // make static_assert dependent to T; always false
-        std::is_base_of<T, void>::value,
-        "Define BMCWEB_ENABLE_SSL to enable ssl support.");
-    return *this;
-  }
+    template <typename T> self_t& ssl(T&&)
+    {
+        // We can't call .ssl() member function unless BMCWEB_ENABLE_SSL is
+        // defined.
+        static_assert(
+            // make static_assert dependent to T; always false
+            std::is_base_of<T, void>::value,
+            "Define BMCWEB_ENABLE_SSL to enable ssl support.");
+        return *this;
+    }
 #endif
 
-  // middleware
-  using context_t = detail::Context<Middlewares...>;
-  template <typename T>
-  typename T::Context& getContext(const Request& req) {
-    static_assert(black_magic::Contains<T, Middlewares...>::value,
-                  "App doesn't have the specified middleware type.");
-    auto& ctx = *reinterpret_cast<context_t*>(req.middlewareContext);
-    return ctx.template get<T>();
-  }
+    // middleware
+    using context_t = detail::Context<Middlewares...>;
+    template <typename T> typename T::Context& getContext(const Request& req)
+    {
+        static_assert(black_magic::Contains<T, Middlewares...>::value,
+                      "App doesn't have the specified middleware type.");
+        auto& ctx = *reinterpret_cast<context_t*>(req.middlewareContext);
+        return ctx.template get<T>();
+    }
 
-  template <typename T>
-  T& getMiddleware() {
-    return utility::getElementByType<T, Middlewares...>(middlewares);
-  }
+    template <typename T> T& getMiddleware()
+    {
+        return utility::getElementByType<T, Middlewares...>(middlewares);
+    }
 
-  template <typename Duration, typename Func>
-  self_t& tick(Duration d, Func f) {
-    tickInterval = std::chrono::duration_cast<std::chrono::milliseconds>(d);
-    tickFunction = f;
-    return *this;
-  }
+    template <typename Duration, typename Func> self_t& tick(Duration d, Func f)
+    {
+        tickInterval = std::chrono::duration_cast<std::chrono::milliseconds>(d);
+        tickFunction = f;
+        return *this;
+    }
 
- private:
-  std::shared_ptr<asio::io_service> io;
-  uint16_t portUint = 80;
-  std::string bindaddrStr = "::";
-  int socketFd = -1;
-  Router router;
+  private:
+    std::shared_ptr<asio::io_service> io;
+    uint16_t portUint = 80;
+    std::string bindaddrStr = "::";
+    int socketFd = -1;
+    Router router;
 
-  std::chrono::milliseconds tickInterval{};
-  std::function<void()> tickFunction;
+    std::chrono::milliseconds tickInterval{};
+    std::function<void()> tickFunction;
 
-  std::tuple<Middlewares...> middlewares;
+    std::tuple<Middlewares...> middlewares;
 
 #ifdef BMCWEB_ENABLE_SSL
-  std::unique_ptr<ssl_server_t> sslServer;
+    std::unique_ptr<ssl_server_t> sslServer;
 #endif
-  std::unique_ptr<server_t> server;
+    std::unique_ptr<server_t> server;
 };
-template <typename... Middlewares>
-using App = Crow<Middlewares...>;
+template <typename... Middlewares> using App = Crow<Middlewares...>;
 using SimpleApp = Crow<>;
-}  // namespace crow
+} // namespace crow
diff --git a/crow/include/crow/common.h b/crow/include/crow/common.h
index e155da6..b3e424f 100644
--- a/crow/include/crow/common.h
+++ b/crow/include/crow/common.h
@@ -1,127 +1,140 @@
 #pragma once
 
+#include <boost/beast/http/verb.hpp>
 #include <iostream>
 #include <stdexcept>
 #include <string>
 #include <vector>
-#include "crow/utility.h"
-#include <boost/beast/http/verb.hpp>
 
-namespace crow {
-enum class HTTPMethod {
+#include "crow/utility.h"
+
+namespace crow
+{
+enum class HTTPMethod
+{
 #ifndef DELETE
-  DELETE = 0,
-  GET,
-  HEAD,
-  POST,
-  PUT,
-  CONNECT,
-  OPTIONS,
-  TRACE,
-  PATCH = 24,  // see http_parser_merged.h line 118 for why it is 24
+    DELETE = 0,
+    GET,
+    HEAD,
+    POST,
+    PUT,
+    CONNECT,
+    OPTIONS,
+    TRACE,
+    PATCH = 24, // see http_parser_merged.h line 118 for why it is 24
 #endif
 
-  Delete = 0,
-  Get,
-  Head,
-  Post,
-  Put,
-  Connect,
-  Options,
-  Trace,
-  Patch = 24,
+    Delete = 0,
+    Get,
+    Head,
+    Post,
+    Put,
+    Connect,
+    Options,
+    Trace,
+    Patch = 24,
 };
 
-inline std::string methodName(boost::beast::http::verb method) {
-  switch (method) {
-    case boost::beast::http::verb::delete_:
-      return "DELETE";
-    case boost::beast::http::verb::get:
-      return "GET";
-    case boost::beast::http::verb::head:
-      return "HEAD";
-    case boost::beast::http::verb::post:
-      return "POST";
-    case boost::beast::http::verb::put:
-      return "PUT";
-    case boost::beast::http::verb::connect:
-      return "CONNECT";
-    case boost::beast::http::verb::options:
-      return "OPTIONS";
-    case boost::beast::http::verb::trace:
-      return "TRACE";
-    case boost::beast::http::verb::patch:
-      return "PATCH";
-  }
-  return "invalid";
+inline std::string methodName(boost::beast::http::verb method)
+{
+    switch (method)
+    {
+        case boost::beast::http::verb::delete_:
+            return "DELETE";
+        case boost::beast::http::verb::get:
+            return "GET";
+        case boost::beast::http::verb::head:
+            return "HEAD";
+        case boost::beast::http::verb::post:
+            return "POST";
+        case boost::beast::http::verb::put:
+            return "PUT";
+        case boost::beast::http::verb::connect:
+            return "CONNECT";
+        case boost::beast::http::verb::options:
+            return "OPTIONS";
+        case boost::beast::http::verb::trace:
+            return "TRACE";
+        case boost::beast::http::verb::patch:
+            return "PATCH";
+    }
+    return "invalid";
 }
 
-enum class ParamType {
-  INT,
-  UINT,
-  DOUBLE,
-  STRING,
-  PATH,
+enum class ParamType
+{
+    INT,
+    UINT,
+    DOUBLE,
+    STRING,
+    PATH,
 
-  MAX
+    MAX
 };
 
-struct RoutingParams {
-  std::vector<int64_t> intParams;
-  std::vector<uint64_t> uintParams;
-  std::vector<double> doubleParams;
-  std::vector<std::string> stringParams;
+struct RoutingParams
+{
+    std::vector<int64_t> intParams;
+    std::vector<uint64_t> uintParams;
+    std::vector<double> doubleParams;
+    std::vector<std::string> stringParams;
 
-  void debugPrint() const {
-    std::cerr << "RoutingParams" << std::endl;
-    for (auto i : intParams) {
-      std::cerr << i << ", ";
+    void debugPrint() const
+    {
+        std::cerr << "RoutingParams" << std::endl;
+        for (auto i : intParams)
+        {
+            std::cerr << i << ", ";
+        }
+        std::cerr << std::endl;
+        for (auto i : uintParams)
+        {
+            std::cerr << i << ", ";
+        }
+        std::cerr << std::endl;
+        for (auto i : doubleParams)
+        {
+            std::cerr << i << ", ";
+        }
+        std::cerr << std::endl;
+        for (auto& i : stringParams)
+        {
+            std::cerr << i << ", ";
+        }
+        std::cerr << std::endl;
     }
-    std::cerr << std::endl;
-    for (auto i : uintParams) {
-      std::cerr << i << ", ";
-    }
-    std::cerr << std::endl;
-    for (auto i : doubleParams) {
-      std::cerr << i << ", ";
-    }
-    std::cerr << std::endl;
-    for (auto& i : stringParams) {
-      std::cerr << i << ", ";
-    }
-    std::cerr << std::endl;
-  }
 
-  template <typename T>
-  T get(unsigned) const;
+    template <typename T> T get(unsigned) const;
 };
 
-template <>
-inline int64_t RoutingParams::get<int64_t>(unsigned index) const {
-  return intParams[index];
+template <> inline int64_t RoutingParams::get<int64_t>(unsigned index) const
+{
+    return intParams[index];
+}
+
+template <> inline uint64_t RoutingParams::get<uint64_t>(unsigned index) const
+{
+    return uintParams[index];
+}
+
+template <> inline double RoutingParams::get<double>(unsigned index) const
+{
+    return doubleParams[index];
 }
 
 template <>
-inline uint64_t RoutingParams::get<uint64_t>(unsigned index) const {
-  return uintParams[index];
+inline std::string RoutingParams::get<std::string>(unsigned index) const
+{
+    return stringParams[index];
 }
 
-template <>
-inline double RoutingParams::get<double>(unsigned index) const {
-  return doubleParams[index];
-}
-
-template <>
-inline std::string RoutingParams::get<std::string>(unsigned index) const {
-  return stringParams[index];
-}
-
-}  // namespace crow
+} // namespace crow
 
 constexpr boost::beast::http::verb operator"" _method(const char* str,
-                                                      size_t /*len*/) {
-  using verb = boost::beast::http::verb;
-  // clang-format off
+                                                      size_t /*len*/)
+{
+    using verb = boost::beast::http::verb;
+    // clang-format off
   return
     crow::black_magic::isEquP(str, "GET", 3) ? verb::get :
     crow::black_magic::isEquP(str, "DELETE", 6) ? verb::delete_ :
@@ -134,5 +147,5 @@
     crow::black_magic::isEquP(str, "PATCH", 5) ? verb::patch :
     crow::black_magic::isEquP(str, "PURGE", 5) ? verb::purge :
     throw std::runtime_error("invalid http method");
-  // clang-format on
+    // clang-format on
 }
\ No newline at end of file
diff --git a/crow/include/crow/http_connection.h b/crow/include/crow/http_connection.h
index 5f2f719..6d62c85 100644
--- a/crow/include/crow/http_connection.h
+++ b/crow/include/crow/http_connection.h
@@ -1,249 +1,279 @@
 #pragma once
+#include "http_utility.hpp"
+
 #include <array>
 #include <atomic>
-#include <chrono>
-#include <regex>
-#include <vector>
-#include "http_utility.hpp"
-#include "crow/http_response.h"
-#include "crow/logging.h"
-#include "crow/middleware_context.h"
-#include "crow/socket_adaptors.h"
-#include "crow/timer_queue.h"
 #include <boost/algorithm/string.hpp>
 #include <boost/algorithm/string/predicate.hpp>
 #include <boost/asio.hpp>
 #include <boost/beast/core.hpp>
 #include <boost/beast/http.hpp>
 #include <boost/beast/websocket.hpp>
+#include <chrono>
+#include <regex>
+#include <vector>
+
+#include "crow/http_response.h"
+#include "crow/logging.h"
+#include "crow/middleware_context.h"
+#include "crow/socket_adaptors.h"
+#include "crow/timer_queue.h"
 
 #ifdef BMCWEB_ENABLE_SSL
 #include <boost/asio/ssl.hpp>
 #endif
 
-namespace crow {
+namespace crow
+{
 
-inline void escapeHtml(std::string& data) {
-  std::string buffer;
-  // less than 5% of characters should be larger, so reserve a buffer of the
-  // right size
-  buffer.reserve(data.size() * 1.05);
-  for (size_t pos = 0; pos != data.size(); ++pos) {
-    switch (data[pos]) {
-      case '&':
-        buffer.append("&amp;");
-        break;
-      case '\"':
-        buffer.append("&quot;");
-        break;
-      case '\'':
-        buffer.append("&apos;");
-        break;
-      case '<':
-        buffer.append("&lt;");
-        break;
-      case '>':
-        buffer.append("&gt;");
-        break;
-      default:
-        buffer.append(&data[pos], 1);
-        break;
+inline void escapeHtml(std::string& data)
+{
+    std::string buffer;
+    // less than 5% of characters should be larger, so reserve a buffer of the
+    // right size
+    buffer.reserve(data.size() * 1.05);
+    for (size_t pos = 0; pos != data.size(); ++pos)
+    {
+        switch (data[pos])
+        {
+            case '&':
+                buffer.append("&amp;");
+                break;
+            case '\"':
+                buffer.append("&quot;");
+                break;
+            case '\'':
+                buffer.append("&apos;");
+                break;
+            case '<':
+                buffer.append("&lt;");
+                break;
+            case '>':
+                buffer.append("&gt;");
+                break;
+            default:
+                buffer.append(&data[pos], 1);
+                break;
+        }
     }
-  }
-  data.swap(buffer);
+    data.swap(buffer);
 }
 
-inline void convertToLinks(std::string& s) {
-  const static std::regex r{
-      "(&quot;@odata\\.((id)|(Context))&quot;[ \\n]*:[ "
-      "\\n]*)(&quot;((?!&quot;).*)&quot;)"};
-  s = std::regex_replace(s, r, "$1<a href=\"$6\">$5</a>");
+inline void convertToLinks(std::string& s)
+{
+    const static std::regex r{"(&quot;@odata\\.((id)|(Context))&quot;[ \\n]*:[ "
+                              "\\n]*)(&quot;((?!&quot;).*)&quot;)"};
+    s = std::regex_replace(s, r, "$1<a href=\"$6\">$5</a>");
 }
 
-inline void prettyPrintJson(crow::Response& res) {
-  std::string value = res.jsonValue.dump(4);
-  escapeHtml(value);
-  convertToLinks(value);
-  res.body() =
-      "<html>\n"
-      "<head>\n"
-      "<title>Redfish API</title>\n"
-      "<link rel=\"stylesheet\" type=\"text/css\" "
-      "href=\"/styles/default.css\">\n"
-      "<script src=\"/highlight.pack.js\"></script>"
-      "<script>hljs.initHighlightingOnLoad();</script>"
-      "</head>\n"
-      "<body>\n"
-      "<div style=\"max-width: 576px;margin:0 auto;\">\n"
-      "<img src=\"/DMTF_Redfish_logo_2017.svg\" alt=\"redfish\" "
-      "height=\"406px\" "
-      "width=\"576px\">\n"
-      "<br>\n"
-      "<pre>\n"
-      "<code class=\"json\">" +
-      value +
-      "</code>\n"
-      "</pre>\n"
-      "</div>\n"
-      "</body>\n"
-      "</html>\n";
+inline void prettyPrintJson(crow::Response& res)
+{
+    std::string value = res.jsonValue.dump(4);
+    escapeHtml(value);
+    convertToLinks(value);
+    res.body() = "<html>\n"
+                 "<head>\n"
+                 "<title>Redfish API</title>\n"
+                 "<link rel=\"stylesheet\" type=\"text/css\" "
+                 "href=\"/styles/default.css\">\n"
+                 "<script src=\"/highlight.pack.js\"></script>"
+                 "<script>hljs.initHighlightingOnLoad();</script>"
+                 "</head>\n"
+                 "<body>\n"
+                 "<div style=\"max-width: 576px;margin:0 auto;\">\n"
+                 "<img src=\"/DMTF_Redfish_logo_2017.svg\" alt=\"redfish\" "
+                 "height=\"406px\" "
+                 "width=\"576px\">\n"
+                 "<br>\n"
+                 "<pre>\n"
+                 "<code class=\"json\">" +
+                 value +
+                 "</code>\n"
+                 "</pre>\n"
+                 "</div>\n"
+                 "</body>\n"
+                 "</html>\n";
 }
 
 using namespace boost;
 using tcp = asio::ip::tcp;
 
-namespace detail {
-template <typename MW>
-struct CheckBeforeHandleArity3Const {
-  template <typename T, void (T::*)(Request&, Response&, typename MW::Context&)
-                            const = &T::beforeHandle>
-  struct Get {};
+namespace detail
+{
+template <typename MW> struct CheckBeforeHandleArity3Const
+{
+    template <typename T,
+              void (T::*)(Request&, Response&, typename MW::Context&) const =
+                  &T::beforeHandle>
+    struct Get
+    {
+    };
 };
 
-template <typename MW>
-struct CheckBeforeHandleArity3 {
-  template <typename T, void (T::*)(Request&, Response&,
-                                    typename MW::Context&) = &T::beforeHandle>
-  struct Get {};
+template <typename MW> struct CheckBeforeHandleArity3
+{
+    template <typename T, void (T::*)(Request&, Response&,
+                                      typename MW::Context&) = &T::beforeHandle>
+    struct Get
+    {
+    };
 };
 
-template <typename MW>
-struct CheckAfterHandleArity3Const {
-  template <typename T, void (T::*)(Request&, Response&, typename MW::Context&)
-                            const = &T::afterHandle>
-  struct Get {};
+template <typename MW> struct CheckAfterHandleArity3Const
+{
+    template <typename T,
+              void (T::*)(Request&, Response&, typename MW::Context&) const =
+                  &T::afterHandle>
+    struct Get
+    {
+    };
 };
 
-template <typename MW>
-struct CheckAfterHandleArity3 {
-  template <typename T, void (T::*)(Request&, Response&,
-                                    typename MW::Context&) = &T::afterHandle>
-  struct Get {};
+template <typename MW> struct CheckAfterHandleArity3
+{
+    template <typename T, void (T::*)(Request&, Response&,
+                                      typename MW::Context&) = &T::afterHandle>
+    struct Get
+    {
+    };
 };
 
-template <typename T>
-struct IsBeforeHandleArity3Impl {
-  template <typename C>
-  static std::true_type f(
-      typename CheckBeforeHandleArity3Const<T>::template Get<C>*);
+template <typename T> struct IsBeforeHandleArity3Impl
+{
+    template <typename C>
+    static std::true_type
+        f(typename CheckBeforeHandleArity3Const<T>::template Get<C>*);
 
-  template <typename C>
-  static std::true_type f(
-      typename CheckBeforeHandleArity3<T>::template Get<C>*);
+    template <typename C>
+    static std::true_type
+        f(typename CheckBeforeHandleArity3<T>::template Get<C>*);
 
-  template <typename C>
-  static std::false_type f(...);
+    template <typename C> static std::false_type f(...);
 
- public:
-  static const bool value = decltype(f<T>(nullptr))::value;
+  public:
+    static const bool value = decltype(f<T>(nullptr))::value;
 };
 
-template <typename T>
-struct IsAfterHandleArity3Impl {
-  template <typename C>
-  static std::true_type f(
-      typename CheckAfterHandleArity3Const<T>::template Get<C>*);
+template <typename T> struct IsAfterHandleArity3Impl
+{
+    template <typename C>
+    static std::true_type
+        f(typename CheckAfterHandleArity3Const<T>::template Get<C>*);
 
-  template <typename C>
-  static std::true_type f(typename CheckAfterHandleArity3<T>::template Get<C>*);
+    template <typename C>
+    static std::true_type
+        f(typename CheckAfterHandleArity3<T>::template Get<C>*);
 
-  template <typename C>
-  static std::false_type f(...);
+    template <typename C> static std::false_type f(...);
 
- public:
-  static const bool value = decltype(f<T>(nullptr))::value;
+  public:
+    static const bool value = decltype(f<T>(nullptr))::value;
 };
 
 template <typename MW, typename Context, typename ParentContext>
 typename std::enable_if<!IsBeforeHandleArity3Impl<MW>::value>::type
-beforeHandlerCall(MW& mw, Request& req, Response& res, Context& ctx,
-                  ParentContext& /*parent_ctx*/) {
-  mw.beforeHandle(req, res, ctx.template get<MW>(), ctx);
+    beforeHandlerCall(MW& mw, Request& req, Response& res, Context& ctx,
+                      ParentContext& /*parent_ctx*/)
+{
+    mw.beforeHandle(req, res, ctx.template get<MW>(), ctx);
 }
 
 template <typename MW, typename Context, typename ParentContext>
 typename std::enable_if<IsBeforeHandleArity3Impl<MW>::value>::type
-beforeHandlerCall(MW& mw, Request& req, Response& res, Context& ctx,
-                  ParentContext& /*parent_ctx*/) {
-  mw.beforeHandle(req, res, ctx.template get<MW>());
+    beforeHandlerCall(MW& mw, Request& req, Response& res, Context& ctx,
+                      ParentContext& /*parent_ctx*/)
+{
+    mw.beforeHandle(req, res, ctx.template get<MW>());
 }
 
 template <typename MW, typename Context, typename ParentContext>
 typename std::enable_if<!IsAfterHandleArity3Impl<MW>::value>::type
-afterHandlerCall(MW& mw, Request& req, Response& res, Context& ctx,
-                 ParentContext& /*parent_ctx*/) {
-  mw.afterHandle(req, res, ctx.template get<MW>(), ctx);
+    afterHandlerCall(MW& mw, Request& req, Response& res, Context& ctx,
+                     ParentContext& /*parent_ctx*/)
+{
+    mw.afterHandle(req, res, ctx.template get<MW>(), ctx);
 }
 
 template <typename MW, typename Context, typename ParentContext>
 typename std::enable_if<IsAfterHandleArity3Impl<MW>::value>::type
-afterHandlerCall(MW& mw, Request& req, Response& res, Context& ctx,
-                 ParentContext& /*parent_ctx*/) {
-  mw.afterHandle(req, res, ctx.template get<MW>());
+    afterHandlerCall(MW& mw, Request& req, Response& res, Context& ctx,
+                     ParentContext& /*parent_ctx*/)
+{
+    mw.afterHandle(req, res, ctx.template get<MW>());
 }
 
 template <int N, typename Context, typename Container, typename CurrentMW,
           typename... Middlewares>
 bool middlewareCallHelper(Container& middlewares, Request& req, Response& res,
-                          Context& ctx) {
-  using parent_context_t = typename Context::template partial<N - 1>;
-  beforeHandlerCall<CurrentMW, Context, parent_context_t>(
-      std::get<N>(middlewares), req, res, ctx,
-      static_cast<parent_context_t&>(ctx));
-
-  if (res.isCompleted()) {
-    afterHandlerCall<CurrentMW, Context, parent_context_t>(
+                          Context& ctx)
+{
+    using parent_context_t = typename Context::template partial<N - 1>;
+    beforeHandlerCall<CurrentMW, Context, parent_context_t>(
         std::get<N>(middlewares), req, res, ctx,
         static_cast<parent_context_t&>(ctx));
-    return true;
-  }
 
-  if (middlewareCallHelper<N + 1, Context, Container, Middlewares...>(
-          middlewares, req, res, ctx)) {
-    afterHandlerCall<CurrentMW, Context, parent_context_t>(
-        std::get<N>(middlewares), req, res, ctx,
-        static_cast<parent_context_t&>(ctx));
-    return true;
-  }
+    if (res.isCompleted())
+    {
+        afterHandlerCall<CurrentMW, Context, parent_context_t>(
+            std::get<N>(middlewares), req, res, ctx,
+            static_cast<parent_context_t&>(ctx));
+        return true;
+    }
 
-  return false;
+    if (middlewareCallHelper<N + 1, Context, Container, Middlewares...>(
+            middlewares, req, res, ctx))
+    {
+        afterHandlerCall<CurrentMW, Context, parent_context_t>(
+            std::get<N>(middlewares), req, res, ctx,
+            static_cast<parent_context_t&>(ctx));
+        return true;
+    }
+
+    return false;
 }
 
 template <int N, typename Context, typename Container>
 bool middlewareCallHelper(Container& /*middlewares*/, Request& /*req*/,
-                          Response& /*res*/, Context& /*ctx*/) {
-  return false;
+                          Response& /*res*/, Context& /*ctx*/)
+{
+    return false;
 }
 
 template <int N, typename Context, typename Container>
-typename std::enable_if<(N < 0)>::type afterHandlersCallHelper(
-    Container& /*middlewares*/, Context& /*Context*/, Request& /*req*/,
-    Response& /*res*/) {}
-
-template <int N, typename Context, typename Container>
-typename std::enable_if<(N == 0)>::type afterHandlersCallHelper(
-    Container& middlewares, Context& ctx, Request& req, Response& res) {
-  using parent_context_t = typename Context::template partial<N - 1>;
-  using CurrentMW = typename std::tuple_element<
-      N, typename std::remove_reference<Container>::type>::type;
-  afterHandlerCall<CurrentMW, Context, parent_context_t>(
-      std::get<N>(middlewares), req, res, ctx,
-      static_cast<parent_context_t&>(ctx));
+typename std::enable_if<(N < 0)>::type
+    afterHandlersCallHelper(Container& /*middlewares*/, Context& /*Context*/,
+                            Request& /*req*/, Response& /*res*/)
+{
 }
 
 template <int N, typename Context, typename Container>
-typename std::enable_if<(N > 0)>::type afterHandlersCallHelper(
-    Container& middlewares, Context& ctx, Request& req, Response& res) {
-  using parent_context_t = typename Context::template partial<N - 1>;
-  using CurrentMW = typename std::tuple_element<
-      N, typename std::remove_reference<Container>::type>::type;
-  afterHandlerCall<CurrentMW, Context, parent_context_t>(
-      std::get<N>(middlewares), req, res, ctx,
-      static_cast<parent_context_t&>(ctx));
-  afterHandlersCallHelper<N - 1, Context, Container>(middlewares, ctx, req,
-                                                     res);
+typename std::enable_if<(N == 0)>::type
+    afterHandlersCallHelper(Container& middlewares, Context& ctx, Request& req,
+                            Response& res)
+{
+    using parent_context_t = typename Context::template partial<N - 1>;
+    using CurrentMW = typename std::tuple_element<
+        N, typename std::remove_reference<Container>::type>::type;
+    afterHandlerCall<CurrentMW, Context, parent_context_t>(
+        std::get<N>(middlewares), req, res, ctx,
+        static_cast<parent_context_t&>(ctx));
 }
-}  // namespace detail
+
+template <int N, typename Context, typename Container>
+typename std::enable_if<(N > 0)>::type
+    afterHandlersCallHelper(Container& middlewares, Context& ctx, Request& req,
+                            Response& res)
+{
+    using parent_context_t = typename Context::template partial<N - 1>;
+    using CurrentMW = typename std::tuple_element<
+        N, typename std::remove_reference<Container>::type>::type;
+    afterHandlerCall<CurrentMW, Context, parent_context_t>(
+        std::get<N>(middlewares), req, res, ctx,
+        static_cast<parent_context_t&>(ctx));
+    afterHandlersCallHelper<N - 1, Context, Container>(middlewares, ctx, req,
+                                                       res);
+}
+} // namespace detail
 
 #ifdef BMCWEB_ENABLE_DEBUG
 static std::atomic<int> connectionCount;
@@ -253,331 +283,382 @@
 constexpr unsigned int httpReqBodyLimit = 1024 * 1024 * 30;
 
 template <typename Adaptor, typename Handler, typename... Middlewares>
-class Connection {
- public:
-  Connection(boost::asio::io_service& ioService, Handler* handler,
-             const std::string& server_name,
-             std::tuple<Middlewares...>* middlewares,
-             std::function<std::string()>& get_cached_date_str_f,
-             detail::TimerQueue& timerQueue,
-             typename Adaptor::context* adaptorCtx)
-      : adaptor(ioService, adaptorCtx),
-        handler(handler),
-        serverName(server_name),
-        middlewares(middlewares),
-        getCachedDateStr(get_cached_date_str_f),
-        timerQueue(timerQueue) {
-    parser.emplace(std::piecewise_construct, std::make_tuple());
-    // Temporarily changed to 30MB; Need to modify uploading/authentication
-    // mechanism
-    parser->body_limit(httpReqBodyLimit);
-    req.emplace(parser->get());
+class Connection
+{
+  public:
+    Connection(boost::asio::io_service& ioService, Handler* handler,
+               const std::string& server_name,
+               std::tuple<Middlewares...>* middlewares,
+               std::function<std::string()>& get_cached_date_str_f,
+               detail::TimerQueue& timerQueue,
+               typename Adaptor::context* adaptorCtx) :
+        adaptor(ioService, adaptorCtx),
+        handler(handler), serverName(server_name), middlewares(middlewares),
+        getCachedDateStr(get_cached_date_str_f), timerQueue(timerQueue)
+    {
+        parser.emplace(std::piecewise_construct, std::make_tuple());
+        // Temporarily changed to 30MB; Need to modify uploading/authentication
+        // mechanism
+        parser->body_limit(httpReqBodyLimit);
+        req.emplace(parser->get());
 #ifdef BMCWEB_ENABLE_DEBUG
-    connectionCount++;
-    BMCWEB_LOG_DEBUG << this << " Connection open, total " << connectionCount;
+        connectionCount++;
+        BMCWEB_LOG_DEBUG << this << " Connection open, total "
+                         << connectionCount;
 #endif
-  }
+    }
 
-  ~Connection() {
-    res.completeRequestHandler = nullptr;
-    cancelDeadlineTimer();
+    ~Connection()
+    {
+        res.completeRequestHandler = nullptr;
+        cancelDeadlineTimer();
 #ifdef BMCWEB_ENABLE_DEBUG
-    connectionCount--;
-    BMCWEB_LOG_DEBUG << this << " Connection closed, total " << connectionCount;
+        connectionCount--;
+        BMCWEB_LOG_DEBUG << this << " Connection closed, total "
+                         << connectionCount;
 #endif
-  }
-
-  decltype(std::declval<Adaptor>().rawSocket()) & socket() {
-    return adaptor.rawSocket();
-  }
-
-  void start() {
-    adaptor.start([this](const boost::system::error_code& ec) {
-      if (!ec) {
-        startDeadline();
-
-        doReadHeaders();
-      } else {
-        checkDestroy();
-      }
-    });
-  }
-
-  void handle() {
-    cancelDeadlineTimer();
-    bool isInvalidRequest = false;
-    const boost::string_view connection =
-        req->getHeaderValue(boost::beast::http::field::connection);
-
-    // Check for HTTP version 1.1.
-    if (req->version() == 11) {
-      if (req->getHeaderValue(boost::beast::http::field::host).empty()) {
-        isInvalidRequest = true;
-        res = Response(boost::beast::http::status::bad_request);
-      }
     }
 
-    BMCWEB_LOG_INFO << "Request: " << adaptor.remoteEndpoint() << " " << this
-                    << " HTTP/" << req->version() / 10 << "."
-                    << req->version() % 10 << ' ' << req->methodString() << " "
-                    << req->target();
-
-    needToCallAfterHandlers = false;
-
-    if (!isInvalidRequest) {
-      res.completeRequestHandler = [] {};
-      res.isAliveHelper = [this]() -> bool { return adaptor.isOpen(); };
-
-      ctx = detail::Context<Middlewares...>();
-      req->middlewareContext = (void*)&ctx;
-      req->ioService = &adaptor.getIoService();
-      detail::middlewareCallHelper<0, decltype(ctx), decltype(*middlewares),
-                                   Middlewares...>(*middlewares, *req, res,
-                                                   ctx);
-
-      if (!res.completed) {
-        if (req->isUpgrade() &&
-            boost::iequals(
-                req->getHeaderValue(boost::beast::http::field::upgrade),
-                "websocket")) {
-          handler->handleUpgrade(*req, res, std::move(adaptor));
-          return;
-        }
-        res.completeRequestHandler = [this] { this->completeRequest(); };
-        needToCallAfterHandlers = true;
-        handler->handle(*req, res);
-        if (req->keepAlive()) {
-          res.addHeader("connection", "Keep-Alive");
-        }
-      } else {
-        completeRequest();
-      }
-    } else {
-      completeRequest();
-    }
-  }
-
-  void completeRequest() {
-    BMCWEB_LOG_INFO << "Response: " << this << ' ' << req->url << ' '
-                    << res.resultInt() << " keepalive=" << req->keepAlive();
-
-    if (needToCallAfterHandlers) {
-      needToCallAfterHandlers = false;
-
-      // call all afterHandler of middlewares
-      detail::afterHandlersCallHelper<((int)sizeof...(Middlewares) - 1),
-                                      decltype(ctx), decltype(*middlewares)>(
-          *middlewares, ctx, *req, res);
+    decltype(std::declval<Adaptor>().rawSocket())& socket()
+    {
+        return adaptor.rawSocket();
     }
 
-    // auto self = this->shared_from_this();
-    res.completeRequestHandler = nullptr;
+    void start()
+    {
+        adaptor.start([this](const boost::system::error_code& ec) {
+            if (!ec)
+            {
+                startDeadline();
 
-    if (!adaptor.isOpen()) {
-      // BMCWEB_LOG_DEBUG << this << " delete (socket is closed) " << isReading
-      // << ' ' << isWriting;
-      // delete this;
-      return;
-    }
-    if (res.body().empty() && !res.jsonValue.empty()) {
-      if (http_helpers::requestPrefersHtml(*req)) {
-        prettyPrintJson(res);
-      } else {
-        res.jsonMode();
-        res.body() = res.jsonValue.dump(2);
-      }
-    }
-
-    if (res.resultInt() >= 400 && res.body().empty()) {
-      res.body() = std::string(res.reason());
-    }
-    res.addHeader(boost::beast::http::field::server, serverName);
-    res.addHeader(boost::beast::http::field::date, getCachedDateStr());
-
-    res.keepAlive(req->keepAlive());
-
-    doWrite();
-  }
-
- private:
-  void doReadHeaders() {
-    // auto self = this->shared_from_this();
-    isReading = true;
-    BMCWEB_LOG_DEBUG << this << " doReadHeaders";
-
-    // Clean up any previous Connection.
-    boost::beast::http::async_read_header(
-        adaptor.socket(), buffer, *parser,
-        [this](const boost::system::error_code& ec,
-               std::size_t bytes_transferred) {
-          isReading = false;
-          BMCWEB_LOG_ERROR << this << " async_read_header " << bytes_transferred
-                           << " Bytes";
-          bool errorWhileReading = false;
-          if (ec) {
-            errorWhileReading = true;
-            BMCWEB_LOG_ERROR << this
-                             << " Error while reading: " << ec.message();
-          } else {
-            // if the adaptor isn't open anymore, and wasn't handed to a
-            // websocket, treat as an error
-            if (!adaptor.isOpen() && !req->isUpgrade()) {
-              errorWhileReading = true;
+                doReadHeaders();
             }
-          }
-
-          if (errorWhileReading) {
-            cancelDeadlineTimer();
-            adaptor.close();
-            BMCWEB_LOG_DEBUG << this << " from read(1)";
-            checkDestroy();
-            return;
-          }
-
-          // Compute the url parameters for the request
-          req->url = req->target();
-          std::size_t index = req->url.find("?");
-          if (index != boost::string_view::npos) {
-            req->url = req->url.substr(0, index - 1);
-          }
-          req->urlParams = QueryString(std::string(req->target()));
-          doRead();
-        });
-  }
-
-  void doRead() {
-    // auto self = this->shared_from_this();
-    isReading = true;
-    BMCWEB_LOG_DEBUG << this << " doRead";
-
-    boost::beast::http::async_read(
-        adaptor.socket(), buffer, *parser,
-        [this](const boost::system::error_code& ec,
-               std::size_t bytes_transferred) {
-          BMCWEB_LOG_ERROR << this << " async_read " << bytes_transferred
-                           << " Bytes";
-          isReading = false;
-
-          bool errorWhileReading = false;
-          if (ec) {
-            BMCWEB_LOG_ERROR << "Error while reading: " << ec.message();
-            errorWhileReading = true;
-          } else {
-            if (!adaptor.isOpen()) {
-              errorWhileReading = true;
+            else
+            {
+                checkDestroy();
             }
-          }
-          if (errorWhileReading) {
-            cancelDeadlineTimer();
-            adaptor.close();
-            BMCWEB_LOG_DEBUG << this << " from read(1)";
-            checkDestroy();
-            return;
-          }
-          handle();
         });
-  }
-
-  void doWrite() {
-    // auto self = this->shared_from_this();
-    isWriting = true;
-    BMCWEB_LOG_DEBUG << "Doing Write";
-    res.preparePayload();
-    serializer.emplace(*res.stringResponse);
-    boost::beast::http::async_write(
-        adaptor.socket(), *serializer,
-        [&](const boost::system::error_code& ec,
-            std::size_t bytes_transferred) {
-          isWriting = false;
-          BMCWEB_LOG_DEBUG << this << " Wrote " << bytes_transferred
-                           << " bytes";
-
-          if (ec) {
-            BMCWEB_LOG_DEBUG << this << " from write(2)";
-            checkDestroy();
-            return;
-          }
-          if (!req->keepAlive()) {
-            adaptor.close();
-            BMCWEB_LOG_DEBUG << this << " from write(1)";
-            checkDestroy();
-            return;
-          }
-
-          serializer.reset();
-          BMCWEB_LOG_DEBUG << this << " Clearing response";
-          res.clear();
-          parser.emplace(std::piecewise_construct, std::make_tuple());
-          parser->body_limit(httpReqBodyLimit);  // reset body limit for
-                                                 // newly created parser
-          buffer.consume(buffer.size());
-
-          req.emplace(parser->get());
-          doReadHeaders();
-        });
-  }
-
-  void checkDestroy() {
-    BMCWEB_LOG_DEBUG << this << " isReading " << isReading << " isWriting "
-                     << isWriting;
-    if (!isReading && !isWriting) {
-      BMCWEB_LOG_DEBUG << this << " delete (idle) ";
-      delete this;
     }
-  }
 
-  void cancelDeadlineTimer() {
-    BMCWEB_LOG_DEBUG << this << " timer cancelled: " << &timerQueue << ' '
-                     << timerCancelKey;
-    timerQueue.cancel(timerCancelKey);
-  }
+    void handle()
+    {
+        cancelDeadlineTimer();
+        bool isInvalidRequest = false;
+        const boost::string_view connection =
+            req->getHeaderValue(boost::beast::http::field::connection);
 
-  void startDeadline() {
-    cancelDeadlineTimer();
+        // Check for HTTP version 1.1.
+        if (req->version() == 11)
+        {
+            if (req->getHeaderValue(boost::beast::http::field::host).empty())
+            {
+                isInvalidRequest = true;
+                res = Response(boost::beast::http::status::bad_request);
+            }
+        }
 
-    timerCancelKey = timerQueue.add([this] {
-      if (!adaptor.isOpen()) {
-        return;
-      }
-      adaptor.close();
-    });
-    BMCWEB_LOG_DEBUG << this << " timer added: " << &timerQueue << ' '
-                     << timerCancelKey;
-  }
+        BMCWEB_LOG_INFO << "Request: " << adaptor.remoteEndpoint() << " "
+                        << this << " HTTP/" << req->version() / 10 << "."
+                        << req->version() % 10 << ' ' << req->methodString()
+                        << " " << req->target();
 
- private:
-  Adaptor adaptor;
-  Handler* handler;
+        needToCallAfterHandlers = false;
 
-  // Making this a boost::optional allows it to be efficiently destroyed and
-  // re-created on Connection reset
-  boost::optional<
-      boost::beast::http::request_parser<boost::beast::http::string_body>>
-      parser;
+        if (!isInvalidRequest)
+        {
+            res.completeRequestHandler = [] {};
+            res.isAliveHelper = [this]() -> bool { return adaptor.isOpen(); };
 
-  boost::beast::flat_buffer buffer{8192};
+            ctx = detail::Context<Middlewares...>();
+            req->middlewareContext = (void*)&ctx;
+            req->ioService = &adaptor.getIoService();
+            detail::middlewareCallHelper<
+                0, decltype(ctx), decltype(*middlewares), Middlewares...>(
+                *middlewares, *req, res, ctx);
 
-  boost::optional<
-      boost::beast::http::response_serializer<boost::beast::http::string_body>>
-      serializer;
+            if (!res.completed)
+            {
+                if (req->isUpgrade() &&
+                    boost::iequals(
+                        req->getHeaderValue(boost::beast::http::field::upgrade),
+                        "websocket"))
+                {
+                    handler->handleUpgrade(*req, res, std::move(adaptor));
+                    return;
+                }
+                res.completeRequestHandler = [this] {
+                    this->completeRequest();
+                };
+                needToCallAfterHandlers = true;
+                handler->handle(*req, res);
+                if (req->keepAlive())
+                {
+                    res.addHeader("connection", "Keep-Alive");
+                }
+            }
+            else
+            {
+                completeRequest();
+            }
+        }
+        else
+        {
+            completeRequest();
+        }
+    }
 
-  boost::optional<crow::Request> req;
-  crow::Response res;
+    void completeRequest()
+    {
+        BMCWEB_LOG_INFO << "Response: " << this << ' ' << req->url << ' '
+                        << res.resultInt() << " keepalive=" << req->keepAlive();
 
-  const std::string& serverName;
+        if (needToCallAfterHandlers)
+        {
+            needToCallAfterHandlers = false;
 
-  int timerCancelKey{-1};
+            // call all afterHandler of middlewares
+            detail::afterHandlersCallHelper<((int)sizeof...(Middlewares) - 1),
+                                            decltype(ctx),
+                                            decltype(*middlewares)>(
+                *middlewares, ctx, *req, res);
+        }
 
-  bool isReading{};
-  bool isWriting{};
-  bool needToCallAfterHandlers{};
-  bool needToStartReadAfterComplete{};
-  bool addKeepAlive{};
+        // auto self = this->shared_from_this();
+        res.completeRequestHandler = nullptr;
 
-  std::tuple<Middlewares...>* middlewares;
-  detail::Context<Middlewares...> ctx;
+        if (!adaptor.isOpen())
+        {
+            // BMCWEB_LOG_DEBUG << this << " delete (socket is closed) " <<
+            // isReading
+            // << ' ' << isWriting;
+            // delete this;
+            return;
+        }
+        if (res.body().empty() && !res.jsonValue.empty())
+        {
+            if (http_helpers::requestPrefersHtml(*req))
+            {
+                prettyPrintJson(res);
+            }
+            else
+            {
+                res.jsonMode();
+                res.body() = res.jsonValue.dump(2);
+            }
+        }
 
-  std::function<std::string()>& getCachedDateStr;
-  detail::TimerQueue& timerQueue;
-};  // namespace crow
-}  // namespace crow
+        if (res.resultInt() >= 400 && res.body().empty())
+        {
+            res.body() = std::string(res.reason());
+        }
+        res.addHeader(boost::beast::http::field::server, serverName);
+        res.addHeader(boost::beast::http::field::date, getCachedDateStr());
+
+        res.keepAlive(req->keepAlive());
+
+        doWrite();
+    }
+
+  private:
+    void doReadHeaders()
+    {
+        // auto self = this->shared_from_this();
+        isReading = true;
+        BMCWEB_LOG_DEBUG << this << " doReadHeaders";
+
+        // Clean up any previous Connection.
+        boost::beast::http::async_read_header(
+            adaptor.socket(), buffer, *parser,
+            [this](const boost::system::error_code& ec,
+                   std::size_t bytes_transferred) {
+                isReading = false;
+                BMCWEB_LOG_ERROR << this << " async_read_header "
+                                 << bytes_transferred << " Bytes";
+                bool errorWhileReading = false;
+                if (ec)
+                {
+                    errorWhileReading = true;
+                    BMCWEB_LOG_ERROR
+                        << this << " Error while reading: " << ec.message();
+                }
+                else
+                {
+                    // if the adaptor isn't open anymore, and wasn't handed to a
+                    // websocket, treat as an error
+                    if (!adaptor.isOpen() && !req->isUpgrade())
+                    {
+                        errorWhileReading = true;
+                    }
+                }
+
+                if (errorWhileReading)
+                {
+                    cancelDeadlineTimer();
+                    adaptor.close();
+                    BMCWEB_LOG_DEBUG << this << " from read(1)";
+                    checkDestroy();
+                    return;
+                }
+
+                // Compute the url parameters for the request
+                req->url = req->target();
+                std::size_t index = req->url.find("?");
+                if (index != boost::string_view::npos)
+                {
+                    req->url = req->url.substr(0, index - 1);
+                }
+                req->urlParams = QueryString(std::string(req->target()));
+                doRead();
+            });
+    }
+
+    void doRead()
+    {
+        // auto self = this->shared_from_this();
+        isReading = true;
+        BMCWEB_LOG_DEBUG << this << " doRead";
+
+        boost::beast::http::async_read(
+            adaptor.socket(), buffer, *parser,
+            [this](const boost::system::error_code& ec,
+                   std::size_t bytes_transferred) {
+                BMCWEB_LOG_ERROR << this << " async_read " << bytes_transferred
+                                 << " Bytes";
+                isReading = false;
+
+                bool errorWhileReading = false;
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR << "Error while reading: " << ec.message();
+                    errorWhileReading = true;
+                }
+                else
+                {
+                    if (!adaptor.isOpen())
+                    {
+                        errorWhileReading = true;
+                    }
+                }
+                if (errorWhileReading)
+                {
+                    cancelDeadlineTimer();
+                    adaptor.close();
+                    BMCWEB_LOG_DEBUG << this << " from read(1)";
+                    checkDestroy();
+                    return;
+                }
+                handle();
+            });
+    }
+
+    void doWrite()
+    {
+        // auto self = this->shared_from_this();
+        isWriting = true;
+        BMCWEB_LOG_DEBUG << "Doing Write";
+        res.preparePayload();
+        serializer.emplace(*res.stringResponse);
+        boost::beast::http::async_write(
+            adaptor.socket(), *serializer,
+            [&](const boost::system::error_code& ec,
+                std::size_t bytes_transferred) {
+                isWriting = false;
+                BMCWEB_LOG_DEBUG << this << " Wrote " << bytes_transferred
+                                 << " bytes";
+
+                if (ec)
+                {
+                    BMCWEB_LOG_DEBUG << this << " from write(2)";
+                    checkDestroy();
+                    return;
+                }
+                if (!req->keepAlive())
+                {
+                    adaptor.close();
+                    BMCWEB_LOG_DEBUG << this << " from write(1)";
+                    checkDestroy();
+                    return;
+                }
+
+                serializer.reset();
+                BMCWEB_LOG_DEBUG << this << " Clearing response";
+                res.clear();
+                parser.emplace(std::piecewise_construct, std::make_tuple());
+                parser->body_limit(httpReqBodyLimit); // reset body limit for
+                                                      // newly created parser
+                buffer.consume(buffer.size());
+
+                req.emplace(parser->get());
+                doReadHeaders();
+            });
+    }
+
+    void checkDestroy()
+    {
+        BMCWEB_LOG_DEBUG << this << " isReading " << isReading << " isWriting "
+                         << isWriting;
+        if (!isReading && !isWriting)
+        {
+            BMCWEB_LOG_DEBUG << this << " delete (idle) ";
+            delete this;
+        }
+    }
+
+    void cancelDeadlineTimer()
+    {
+        BMCWEB_LOG_DEBUG << this << " timer cancelled: " << &timerQueue << ' '
+                         << timerCancelKey;
+        timerQueue.cancel(timerCancelKey);
+    }
+
+    void startDeadline()
+    {
+        cancelDeadlineTimer();
+
+        timerCancelKey = timerQueue.add([this] {
+            if (!adaptor.isOpen())
+            {
+                return;
+            }
+            adaptor.close();
+        });
+        BMCWEB_LOG_DEBUG << this << " timer added: " << &timerQueue << ' '
+                         << timerCancelKey;
+    }
+
+  private:
+    Adaptor adaptor;
+    Handler* handler;
+
+    // Making this a boost::optional allows it to be efficiently destroyed and
+    // re-created on Connection reset
+    boost::optional<
+        boost::beast::http::request_parser<boost::beast::http::string_body>>
+        parser;
+
+    boost::beast::flat_buffer buffer{8192};
+
+    boost::optional<boost::beast::http::response_serializer<
+        boost::beast::http::string_body>>
+        serializer;
+
+    boost::optional<crow::Request> req;
+    crow::Response res;
+
+    const std::string& serverName;
+
+    int timerCancelKey{-1};
+
+    bool isReading{};
+    bool isWriting{};
+    bool needToCallAfterHandlers{};
+    bool needToStartReadAfterComplete{};
+    bool addKeepAlive{};
+
+    std::tuple<Middlewares...>* middlewares;
+    detail::Context<Middlewares...> ctx;
+
+    std::function<std::string()>& getCachedDateStr;
+    detail::TimerQueue& timerQueue;
+}; // namespace crow
+} // namespace crow
diff --git a/crow/include/crow/http_request.h b/crow/include/crow/http_request.h
index 7e95bc6..0e6dd12 100644
--- a/crow/include/crow/http_request.h
+++ b/crow/include/crow/http_request.h
@@ -7,42 +7,66 @@
 #include "crow/common.h"
 #include "crow/query_string.h"
 
-namespace crow {
+namespace crow
+{
 
-struct Request {
-  boost::string_view url{};
-  QueryString urlParams{};
-  bool isSecure{false};
+struct Request
+{
+    boost::string_view url{};
+    QueryString urlParams{};
+    bool isSecure{false};
 
-  const std::string& body;
+    const std::string& body;
 
-  void* middlewareContext{};
-  boost::asio::io_service* ioService{};
+    void* middlewareContext{};
+    boost::asio::io_service* ioService{};
 
-  Request(boost::beast::http::request<boost::beast::http::string_body>& req)
-      : req(req), body(req.body()) {}
+    Request(boost::beast::http::request<boost::beast::http::string_body>& req) :
+        req(req), body(req.body())
+    {
+    }
 
-  const boost::beast::http::verb method() const { return req.method(); }
+    const boost::beast::http::verb method() const
+    {
+        return req.method();
+    }
 
-  const boost::string_view getHeaderValue(boost::string_view key) const {
-    return req[key];
-  }
+    const boost::string_view getHeaderValue(boost::string_view key) const
+    {
+        return req[key];
+    }
 
-  const boost::string_view getHeaderValue(boost::beast::http::field key) const {
-    return req[key];
-  }
+    const boost::string_view getHeaderValue(boost::beast::http::field key) const
+    {
+        return req[key];
+    }
 
-  const boost::string_view methodString() const { return req.method_string(); }
+    const boost::string_view methodString() const
+    {
+        return req.method_string();
+    }
 
-  const boost::string_view target() const { return req.target(); }
+    const boost::string_view target() const
+    {
+        return req.target();
+    }
 
-  unsigned version() { return req.version(); }
+    unsigned version()
+    {
+        return req.version();
+    }
 
-  bool isUpgrade() { return boost::beast::websocket::is_upgrade(req); }
+    bool isUpgrade()
+    {
+        return boost::beast::websocket::is_upgrade(req);
+    }
 
-  bool keepAlive() { return req.keep_alive(); }
+    bool keepAlive()
+    {
+        return req.keep_alive();
+    }
 
-  boost::beast::http::request<boost::beast::http::string_body>& req;
+    boost::beast::http::request<boost::beast::http::string_body>& req;
 };
 
-}  // namespace crow
+} // namespace crow
diff --git a/crow/include/crow/http_response.h b/crow/include/crow/http_response.h
index 560eef4..d66bf47 100644
--- a/crow/include/crow/http_response.h
+++ b/crow/include/crow/http_response.h
@@ -1,121 +1,173 @@
 #pragma once
+#include "nlohmann/json.hpp"
+
+#include <boost/beast/http.hpp>
 #include <string>
 
-#include "nlohmann/json.hpp"
 #include "crow/http_request.h"
 #include "crow/logging.h"
-#include <boost/beast/http.hpp>
 
-namespace crow {
+namespace crow
+{
 
 template <typename Adaptor, typename Handler, typename... Middlewares>
 class Connection;
 
-struct Response {
-  template <typename Adaptor, typename Handler, typename... Middlewares>
-  friend class crow::Connection;
-  using response_type =
-      boost::beast::http::response<boost::beast::http::string_body>;
+struct Response
+{
+    template <typename Adaptor, typename Handler, typename... Middlewares>
+    friend class crow::Connection;
+    using response_type =
+        boost::beast::http::response<boost::beast::http::string_body>;
 
-  boost::optional<response_type> stringResponse;
+    boost::optional<response_type> stringResponse;
 
-  nlohmann::json jsonValue;
+    nlohmann::json jsonValue;
 
-  void addHeader(const boost::string_view key, const boost::string_view value) {
-    stringResponse->set(key, value);
-  }
-
-  void addHeader(boost::beast::http::field key, boost::string_view value) {
-    stringResponse->set(key, value);
-  }
-
-  Response() : stringResponse(response_type{}) {}
-
-  explicit Response(boost::beast::http::status code)
-      : stringResponse(response_type{}) {}
-
-  explicit Response(boost::string_view body_)
-      : stringResponse(response_type{}) {
-    stringResponse->body() = std::string(body_);
-  }
-
-  Response(boost::beast::http::status code, boost::string_view s)
-      : stringResponse(response_type{}) {
-    stringResponse->result(code);
-    stringResponse->body() = std::string(s);
-  }
-
-  Response(Response&& r) {
-    BMCWEB_LOG_DEBUG << "Moving response containers";
-    *this = std::move(r);
-  }
-
-  ~Response() { BMCWEB_LOG_DEBUG << this << " Destroying response"; }
-
-  Response& operator=(const Response& r) = delete;
-
-  Response& operator=(Response&& r) noexcept {
-    BMCWEB_LOG_DEBUG << "Moving response containers";
-    stringResponse = std::move(r.stringResponse);
-    r.stringResponse.emplace(response_type{});
-    jsonValue = std::move(r.jsonValue);
-    completed = r.completed;
-    return *this;
-  }
-
-  void result(boost::beast::http::status v) { stringResponse->result(v); }
-
-  boost::beast::http::status result() { return stringResponse->result(); }
-
-  unsigned resultInt() { return stringResponse->result_int(); }
-
-  boost::string_view reason() { return stringResponse->reason(); }
-
-  bool isCompleted() const noexcept { return completed; }
-
-  std::string& body() { return stringResponse->body(); }
-
-  void keepAlive(bool k) { stringResponse->keep_alive(k); }
-
-  void preparePayload() { stringResponse->prepare_payload(); };
-
-  void clear() {
-    BMCWEB_LOG_DEBUG << this << " Clearing response containers";
-    stringResponse.emplace(response_type{});
-    jsonValue.clear();
-    completed = false;
-  }
-
-  void write(boost::string_view body_part) {
-    stringResponse->body() += std::string(body_part);
-  }
-
-  void end() {
-    if (completed) {
-      BMCWEB_LOG_ERROR << "Response was ended twice";
-      return;
+    void addHeader(const boost::string_view key, const boost::string_view value)
+    {
+        stringResponse->set(key, value);
     }
-    completed = true;
-    BMCWEB_LOG_DEBUG << "calling completion handler";
-    if (completeRequestHandler) {
-      BMCWEB_LOG_DEBUG << "completion handler was valid";
-      completeRequestHandler();
+
+    void addHeader(boost::beast::http::field key, boost::string_view value)
+    {
+        stringResponse->set(key, value);
     }
-  }
 
-  void end(boost::string_view body_part) {
-    write(body_part);
-    end();
-  }
+    Response() : stringResponse(response_type{})
+    {
+    }
 
-  bool isAlive() { return isAliveHelper && isAliveHelper(); }
+    explicit Response(boost::beast::http::status code) :
+        stringResponse(response_type{})
+    {
+    }
 
- private:
-  bool completed{};
-  std::function<void()> completeRequestHandler;
-  std::function<bool()> isAliveHelper;
+    explicit Response(boost::string_view body_) :
+        stringResponse(response_type{})
+    {
+        stringResponse->body() = std::string(body_);
+    }
 
-  // In case of a JSON object, set the Content-Type header
-  void jsonMode() { addHeader("Content-Type", "application/json"); }
+    Response(boost::beast::http::status code, boost::string_view s) :
+        stringResponse(response_type{})
+    {
+        stringResponse->result(code);
+        stringResponse->body() = std::string(s);
+    }
+
+    Response(Response&& r)
+    {
+        BMCWEB_LOG_DEBUG << "Moving response containers";
+        *this = std::move(r);
+    }
+
+    ~Response()
+    {
+        BMCWEB_LOG_DEBUG << this << " Destroying response";
+    }
+
+    Response& operator=(const Response& r) = delete;
+
+    Response& operator=(Response&& r) noexcept
+    {
+        BMCWEB_LOG_DEBUG << "Moving response containers";
+        stringResponse = std::move(r.stringResponse);
+        r.stringResponse.emplace(response_type{});
+        jsonValue = std::move(r.jsonValue);
+        completed = r.completed;
+        return *this;
+    }
+
+    void result(boost::beast::http::status v)
+    {
+        stringResponse->result(v);
+    }
+
+    boost::beast::http::status result()
+    {
+        return stringResponse->result();
+    }
+
+    unsigned resultInt()
+    {
+        return stringResponse->result_int();
+    }
+
+    boost::string_view reason()
+    {
+        return stringResponse->reason();
+    }
+
+    bool isCompleted() const noexcept
+    {
+        return completed;
+    }
+
+    std::string& body()
+    {
+        return stringResponse->body();
+    }
+
+    void keepAlive(bool k)
+    {
+        stringResponse->keep_alive(k);
+    }
+
+    void preparePayload()
+    {
+        stringResponse->prepare_payload();
+    };
+
+    void clear()
+    {
+        BMCWEB_LOG_DEBUG << this << " Clearing response containers";
+        stringResponse.emplace(response_type{});
+        jsonValue.clear();
+        completed = false;
+    }
+
+    void write(boost::string_view body_part)
+    {
+        stringResponse->body() += std::string(body_part);
+    }
+
+    void end()
+    {
+        if (completed)
+        {
+            BMCWEB_LOG_ERROR << "Response was ended twice";
+            return;
+        }
+        completed = true;
+        BMCWEB_LOG_DEBUG << "calling completion handler";
+        if (completeRequestHandler)
+        {
+            BMCWEB_LOG_DEBUG << "completion handler was valid";
+            completeRequestHandler();
+        }
+    }
+
+    void end(boost::string_view body_part)
+    {
+        write(body_part);
+        end();
+    }
+
+    bool isAlive()
+    {
+        return isAliveHelper && isAliveHelper();
+    }
+
+  private:
+    bool completed{};
+    std::function<void()> completeRequestHandler;
+    std::function<bool()> isAliveHelper;
+
+    // In case of a JSON object, set the Content-Type header
+    void jsonMode()
+    {
+        addHeader("Content-Type", "application/json");
+    }
 };
-}  // namespace crow
+} // namespace crow
diff --git a/crow/include/crow/http_server.h b/crow/include/crow/http_server.h
index 96b85dc..173d0d1 100644
--- a/crow/include/crow/http_server.h
+++ b/crow/include/crow/http_server.h
@@ -1,183 +1,205 @@
 #pragma once
 
 #include <atomic>
+#include <boost/asio.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
 #include <chrono>
 #include <cstdint>
 #include <future>
 #include <memory>
 #include <utility>
 #include <vector>
+
 #include "crow/http_connection.h"
 #include "crow/logging.h"
 #include "crow/timer_queue.h"
-#include <boost/asio.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
 #ifdef BMCWEB_ENABLE_SSL
 #include <boost/asio/ssl.hpp>
 #endif
 
-namespace crow {
+namespace crow
+{
 using namespace boost;
 using tcp = asio::ip::tcp;
 
 template <typename Handler, typename Adaptor = SocketAdaptor,
           typename... Middlewares>
-class Server {
- public:
-  Server(Handler* handler, std::unique_ptr<tcp::acceptor>&& acceptor,
-         std::tuple<Middlewares...>* middlewares = nullptr,
-         typename Adaptor::context* adaptor_ctx = nullptr,
-         std::shared_ptr<boost::asio::io_service> io =
-             std::make_shared<boost::asio::io_service>())
-      : ioService(std::move(io)),
-        acceptor(std::move(acceptor)),
-        signals(*ioService, SIGINT, SIGTERM),
-        tickTimer(*ioService),
-        handler(handler),
-        middlewares(middlewares),
-        adaptorCtx(adaptor_ctx) {}
+class Server
+{
+  public:
+    Server(Handler* handler, std::unique_ptr<tcp::acceptor>&& acceptor,
+           std::tuple<Middlewares...>* middlewares = nullptr,
+           typename Adaptor::context* adaptor_ctx = nullptr,
+           std::shared_ptr<boost::asio::io_service> io =
+               std::make_shared<boost::asio::io_service>()) :
+        ioService(std::move(io)),
+        acceptor(std::move(acceptor)), signals(*ioService, SIGINT, SIGTERM),
+        tickTimer(*ioService), handler(handler), middlewares(middlewares),
+        adaptorCtx(adaptor_ctx)
+    {
+    }
 
-  Server(Handler* handler, const std::string& bindaddr, uint16_t port,
-         std::tuple<Middlewares...>* middlewares = nullptr,
-         typename Adaptor::context* adaptor_ctx = nullptr,
-         std::shared_ptr<boost::asio::io_service> io =
-             std::make_shared<boost::asio::io_service>())
-      : Server(handler,
+    Server(Handler* handler, const std::string& bindaddr, uint16_t port,
+           std::tuple<Middlewares...>* middlewares = nullptr,
+           typename Adaptor::context* adaptor_ctx = nullptr,
+           std::shared_ptr<boost::asio::io_service> io =
+               std::make_shared<boost::asio::io_service>()) :
+        Server(handler,
                std::make_unique<tcp::acceptor>(
                    *io,
                    tcp::endpoint(
                        boost::asio::ip::address::from_string(bindaddr), port)),
-               middlewares, adaptor_ctx, io) {}
-
-  Server(Handler* handler, int existing_socket,
-         std::tuple<Middlewares...>* middlewares = nullptr,
-         typename Adaptor::context* adaptor_ctx = nullptr,
-         std::shared_ptr<boost::asio::io_service> io =
-             std::make_shared<boost::asio::io_service>())
-      : Server(handler,
-               std::make_unique<tcp::acceptor>(*io, boost::asio::ip::tcp::v6(),
-                                               existing_socket),
-               middlewares, adaptor_ctx, io) {}
-
-  void setTickFunction(std::chrono::milliseconds d, std::function<void()> f) {
-    tickInterval = d;
-    tickFunction = f;
-  }
-
-  void onTick() {
-    tickFunction();
-    tickTimer.expires_from_now(
-        boost::posix_time::milliseconds(tickInterval.count()));
-    tickTimer.async_wait([this](const boost::system::error_code& ec) {
-      if (ec) {
-        return;
-      }
-      onTick();
-    });
-  }
-
-  void updateDateStr() {
-    auto lastTimeT = time(0);
-    tm myTm{};
-
-#ifdef _MSC_VER
-    gmtime_s(&my_tm, &last_time_t);
-#else
-    gmtime_r(&lastTimeT, &myTm);
-#endif
-    dateStr.resize(100);
-    size_t dateStrSz =
-        strftime(&dateStr[0], 99, "%a, %d %b %Y %H:%M:%S GMT", &myTm);
-    dateStr.resize(dateStrSz);
-  };
-
-  void run() {
-    updateDateStr();
-
-    getCachedDateStr = [this]() -> std::string {
-      static std::chrono::time_point<std::chrono::steady_clock> lastDateUpdate =
-          std::chrono::steady_clock::now();
-      if (std::chrono::steady_clock::now() - lastDateUpdate >=
-          std::chrono::seconds(10)) {
-        lastDateUpdate = std::chrono::steady_clock::now();
-        updateDateStr();
-      }
-      return this->dateStr;
-    };
-
-    boost::asio::deadline_timer timer(*ioService);
-    timer.expires_from_now(boost::posix_time::seconds(1));
-
-    std::function<void(const boost::system::error_code& ec)> handler;
-    handler = [&](const boost::system::error_code& ec) {
-      if (ec) {
-        return;
-      }
-      timerQueue.process();
-      timer.expires_from_now(boost::posix_time::seconds(1));
-      timer.async_wait(handler);
-    };
-    timer.async_wait(handler);
-
-    if (tickFunction && tickInterval.count() > 0) {
-      tickTimer.expires_from_now(
-          boost::posix_time::milliseconds(tickInterval.count()));
-      tickTimer.async_wait([this](const boost::system::error_code& ec) {
-        if (ec) {
-          return;
-        }
-        onTick();
-      });
+               middlewares, adaptor_ctx, io)
+    {
     }
 
-    BMCWEB_LOG_INFO << serverName << " server is running, local endpoint "
-                    << acceptor->local_endpoint();
+    Server(Handler* handler, int existing_socket,
+           std::tuple<Middlewares...>* middlewares = nullptr,
+           typename Adaptor::context* adaptor_ctx = nullptr,
+           std::shared_ptr<boost::asio::io_service> io =
+               std::make_shared<boost::asio::io_service>()) :
+        Server(handler,
+               std::make_unique<tcp::acceptor>(*io, boost::asio::ip::tcp::v6(),
+                                               existing_socket),
+               middlewares, adaptor_ctx, io)
+    {
+    }
 
-    signals.async_wait([&](const boost::system::error_code& /*error*/,
-                           int /*signal_number*/) { stop(); });
+    void setTickFunction(std::chrono::milliseconds d, std::function<void()> f)
+    {
+        tickInterval = d;
+        tickFunction = f;
+    }
 
-    doAccept();
-  }
+    void onTick()
+    {
+        tickFunction();
+        tickTimer.expires_from_now(
+            boost::posix_time::milliseconds(tickInterval.count()));
+        tickTimer.async_wait([this](const boost::system::error_code& ec) {
+            if (ec)
+            {
+                return;
+            }
+            onTick();
+        });
+    }
 
-  void stop() { ioService->stop(); }
+    void updateDateStr()
+    {
+        auto lastTimeT = time(0);
+        tm myTm{};
 
-  void doAccept() {
-    auto p = new Connection<Adaptor, Handler, Middlewares...>(
-        *ioService, handler, serverName, middlewares, getCachedDateStr,
-        timerQueue, adaptorCtx);
-    acceptor->async_accept(p->socket(),
-                           [this, p](boost::system::error_code ec) {
-                             if (!ec) {
-                               this->ioService->post([p] { p->start(); });
-                             } else {
-                               delete p;
-                             }
-                             doAccept();
-                           });
-  }
+#ifdef _MSC_VER
+        gmtime_s(&my_tm, &last_time_t);
+#else
+        gmtime_r(&lastTimeT, &myTm);
+#endif
+        dateStr.resize(100);
+        size_t dateStrSz =
+            strftime(&dateStr[0], 99, "%a, %d %b %Y %H:%M:%S GMT", &myTm);
+        dateStr.resize(dateStrSz);
+    };
 
- private:
-  std::shared_ptr<asio::io_service> ioService;
-  detail::TimerQueue timerQueue;
-  std::function<std::string()> getCachedDateStr;
-  std::unique_ptr<tcp::acceptor> acceptor;
-  boost::asio::signal_set signals;
-  boost::asio::deadline_timer tickTimer;
+    void run()
+    {
+        updateDateStr();
 
-  std::string dateStr;
+        getCachedDateStr = [this]() -> std::string {
+            static std::chrono::time_point<std::chrono::steady_clock>
+                lastDateUpdate = std::chrono::steady_clock::now();
+            if (std::chrono::steady_clock::now() - lastDateUpdate >=
+                std::chrono::seconds(10))
+            {
+                lastDateUpdate = std::chrono::steady_clock::now();
+                updateDateStr();
+            }
+            return this->dateStr;
+        };
 
-  Handler* handler;
-  std::string serverName = "iBMC";
+        boost::asio::deadline_timer timer(*ioService);
+        timer.expires_from_now(boost::posix_time::seconds(1));
 
-  std::chrono::milliseconds tickInterval{};
-  std::function<void()> tickFunction;
+        std::function<void(const boost::system::error_code& ec)> handler;
+        handler = [&](const boost::system::error_code& ec) {
+            if (ec)
+            {
+                return;
+            }
+            timerQueue.process();
+            timer.expires_from_now(boost::posix_time::seconds(1));
+            timer.async_wait(handler);
+        };
+        timer.async_wait(handler);
 
-  std::tuple<Middlewares...>* middlewares;
+        if (tickFunction && tickInterval.count() > 0)
+        {
+            tickTimer.expires_from_now(
+                boost::posix_time::milliseconds(tickInterval.count()));
+            tickTimer.async_wait([this](const boost::system::error_code& ec) {
+                if (ec)
+                {
+                    return;
+                }
+                onTick();
+            });
+        }
+
+        BMCWEB_LOG_INFO << serverName << " server is running, local endpoint "
+                        << acceptor->local_endpoint();
+
+        signals.async_wait([&](const boost::system::error_code& /*error*/,
+                               int /*signal_number*/) { stop(); });
+
+        doAccept();
+    }
+
+    void stop()
+    {
+        ioService->stop();
+    }
+
+    void doAccept()
+    {
+        auto p = new Connection<Adaptor, Handler, Middlewares...>(
+            *ioService, handler, serverName, middlewares, getCachedDateStr,
+            timerQueue, adaptorCtx);
+        acceptor->async_accept(
+            p->socket(), [this, p](boost::system::error_code ec) {
+                if (!ec)
+                {
+                    this->ioService->post([p] { p->start(); });
+                }
+                else
+                {
+                    delete p;
+                }
+                doAccept();
+            });
+    }
+
+  private:
+    std::shared_ptr<asio::io_service> ioService;
+    detail::TimerQueue timerQueue;
+    std::function<std::string()> getCachedDateStr;
+    std::unique_ptr<tcp::acceptor> acceptor;
+    boost::asio::signal_set signals;
+    boost::asio::deadline_timer tickTimer;
+
+    std::string dateStr;
+
+    Handler* handler;
+    std::string serverName = "iBMC";
+
+    std::chrono::milliseconds tickInterval{};
+    std::function<void()> tickFunction;
+
+    std::tuple<Middlewares...>* middlewares;
 
 #ifdef BMCWEB_ENABLE_SSL
-  bool useSsl{false};
-  boost::asio::ssl::context sslContext{boost::asio::ssl::context::sslv23};
+    bool useSsl{false};
+    boost::asio::ssl::context sslContext{boost::asio::ssl::context::sslv23};
 #endif
-  typename Adaptor::context* adaptorCtx;
-};  // namespace crow
-}  // namespace crow
+    typename Adaptor::context* adaptorCtx;
+}; // namespace crow
+} // namespace crow
diff --git a/crow/include/crow/logging.h b/crow/include/crow/logging.h
index 4a68df3..353a448 100644
--- a/crow/include/crow/logging.h
+++ b/crow/include/crow/logging.h
@@ -7,117 +7,139 @@
 #include <sstream>
 #include <string>
 
-namespace crow {
-enum class LogLevel {
+namespace crow
+{
+enum class LogLevel
+{
 #ifndef ERROR
-  DEBUG = 0,
-  INFO,
-  WARNING,
-  ERROR,
-  CRITICAL,
+    DEBUG = 0,
+    INFO,
+    WARNING,
+    ERROR,
+    CRITICAL,
 #endif
 
-  Debug = 0,
-  Info,
-  Warning,
-  Error,
-  Critical,
+    Debug = 0,
+    Info,
+    Warning,
+    Error,
+    Critical,
 };
 
-class ILogHandler {
- public:
-  virtual void log(std::string message, LogLevel level) = 0;
+class ILogHandler
+{
+  public:
+    virtual void log(std::string message, LogLevel level) = 0;
 };
 
-class CerrLogHandler : public ILogHandler {
- public:
-  void log(std::string message, LogLevel /*level*/) override {
-    std::cerr << message;
-  }
+class CerrLogHandler : public ILogHandler
+{
+  public:
+    void log(std::string message, LogLevel /*level*/) override
+    {
+        std::cerr << message;
+    }
 };
 
-class logger {
- private:
-  //
-  static std::string timestamp() {
-    char date[32];
-    time_t t = time(0);
+class logger
+{
+  private:
+    //
+    static std::string timestamp()
+    {
+        char date[32];
+        time_t t = time(0);
 
-    tm myTm{};
+        tm myTm{};
 
 #ifdef _MSC_VER
-    gmtime_s(&my_tm, &t);
+        gmtime_s(&my_tm, &t);
 #else
-    gmtime_r(&t, &myTm);
+        gmtime_r(&t, &myTm);
 #endif
 
-    size_t sz = strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", &myTm);
-    return std::string(date, date + sz);
-  }
-
- public:
-  logger(const std::string& prefix, LogLevel level) : level(level) {
-#ifdef BMCWEB_ENABLE_LOGGING
-    stringstream << "(" << timestamp() << ") [" << prefix << "] ";
-#endif
-  }
-  ~logger() {
-#ifdef BMCWEB_ENABLE_LOGGING
-    if (level >= get_current_log_level()) {
-      stringstream << std::endl;
-      getHandlerRef()->log(stringstream.str(), level);
+        size_t sz = strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", &myTm);
+        return std::string(date, date + sz);
     }
-#endif
-  }
 
-  //
-  template <typename T>
-  logger& operator<<(T const& value) {
+  public:
+    logger(const std::string& prefix, LogLevel level) : level(level)
+    {
 #ifdef BMCWEB_ENABLE_LOGGING
-    if (level >= get_current_log_level()) {
-      stringstream << value;
-    }
+        stringstream << "(" << timestamp() << ") [" << prefix << "] ";
 #endif
-    return *this;
-  }
+    }
+    ~logger()
+    {
+#ifdef BMCWEB_ENABLE_LOGGING
+        if (level >= get_current_log_level())
+        {
+            stringstream << std::endl;
+            getHandlerRef()->log(stringstream.str(), level);
+        }
+#endif
+    }
 
-  //
-  static void setLogLevel(LogLevel level) { getLogLevelRef() = level; }
+    //
+    template <typename T> logger& operator<<(T const& value)
+    {
+#ifdef BMCWEB_ENABLE_LOGGING
+        if (level >= get_current_log_level())
+        {
+            stringstream << value;
+        }
+#endif
+        return *this;
+    }
 
-  static void setHandler(ILogHandler* handler) { getHandlerRef() = handler; }
+    //
+    static void setLogLevel(LogLevel level)
+    {
+        getLogLevelRef() = level;
+    }
 
-  static LogLevel get_current_log_level() { return getLogLevelRef(); }
+    static void setHandler(ILogHandler* handler)
+    {
+        getHandlerRef() = handler;
+    }
 
- private:
-  //
-  static LogLevel& getLogLevelRef() {
-    static auto currentLevel = static_cast<LogLevel>(1);
-    return currentLevel;
-  }
-  static ILogHandler*& getHandlerRef() {
-    static CerrLogHandler defaultHandler;
-    static ILogHandler* currentHandler = &defaultHandler;
-    return currentHandler;
-  }
+    static LogLevel get_current_log_level()
+    {
+        return getLogLevelRef();
+    }
 
-  //
-  std::ostringstream stringstream;
-  LogLevel level;
+  private:
+    //
+    static LogLevel& getLogLevelRef()
+    {
+        static auto currentLevel = static_cast<LogLevel>(1);
+        return currentLevel;
+    }
+    static ILogHandler*& getHandlerRef()
+    {
+        static CerrLogHandler defaultHandler;
+        static ILogHandler* currentHandler = &defaultHandler;
+        return currentHandler;
+    }
+
+    //
+    std::ostringstream stringstream;
+    LogLevel level;
 };
-}  // namespace crow
+} // namespace crow
 
-#define BMCWEB_LOG_CRITICAL                                              \
-  if (crow::logger::get_current_log_level() <= crow::LogLevel::Critical) \
-  crow::logger("CRITICAL", crow::LogLevel::Critical)
-#define BMCWEB_LOG_ERROR                                              \
-  if (crow::logger::get_current_log_level() <= crow::LogLevel::Error) \
-  crow::logger("ERROR   ", crow::LogLevel::Error)
-#define BMCWEB_LOG_WARNING                                              \
-  if (crow::logger::get_current_log_level() <= crow::LogLevel::Warning) \
-  crow::logger("WARNING ", crow::LogLevel::Warning)
-#define BMCWEB_LOG_INFO                                              \
-  if (crow::logger::get_current_log_level() <= crow::LogLevel::Info) \
-  crow::logger("INFO    ", crow::LogLevel::Info)
-#define BMCWEB_LOG_DEBUG                                              \
-  if (crow::logger::get_current_log_level() <= crow::LogLevel::Debug) \
-  crow::logger("DEBUG   ", crow::LogLevel::Debug)
+#define BMCWEB_LOG_CRITICAL                                                    \
+    if (crow::logger::get_current_log_level() <= crow::LogLevel::Critical)     \
+    crow::logger("CRITICAL", crow::LogLevel::Critical)
+#define BMCWEB_LOG_ERROR                                                       \
+    if (crow::logger::get_current_log_level() <= crow::LogLevel::Error)        \
+    crow::logger("ERROR   ", crow::LogLevel::Error)
+#define BMCWEB_LOG_WARNING                                                     \
+    if (crow::logger::get_current_log_level() <= crow::LogLevel::Warning)      \
+    crow::logger("WARNING ", crow::LogLevel::Warning)
+#define BMCWEB_LOG_INFO                                                        \
+    if (crow::logger::get_current_log_level() <= crow::LogLevel::Info)         \
+    crow::logger("INFO    ", crow::LogLevel::Info)
+#define BMCWEB_LOG_DEBUG                                                       \
+    if (crow::logger::get_current_log_level() <= crow::LogLevel::Debug)        \
+    crow::logger("DEBUG   ", crow::LogLevel::Debug)
diff --git a/crow/include/crow/middleware_context.h b/crow/include/crow/middleware_context.h
index 03309f6..f109a44 100644
--- a/crow/include/crow/middleware_context.h
+++ b/crow/include/crow/middleware_context.h
@@ -4,30 +4,32 @@
 #include "crow/http_response.h"
 #include "crow/utility.h"
 
-namespace crow {
-namespace detail {
+namespace crow
+{
+namespace detail
+{
 template <typename... Middlewares>
 struct PartialContext
     : public black_magic::PopBack<Middlewares...>::template rebind<
           PartialContext>,
-      public black_magic::LastElementType<Middlewares...>::type::Context {
-  using parent_context = typename black_magic::PopBack<
-      Middlewares...>::template rebind<::crow::detail::PartialContext>;
-  template <int N>
-  using partial = typename std::conditional<
-      N == sizeof...(Middlewares) - 1, PartialContext,
-      typename parent_context::template partial<N>>::type;
+      public black_magic::LastElementType<Middlewares...>::type::Context
+{
+    using parent_context = typename black_magic::PopBack<
+        Middlewares...>::template rebind<::crow::detail::PartialContext>;
+    template <int N>
+    using partial = typename std::conditional<
+        N == sizeof...(Middlewares) - 1, PartialContext,
+        typename parent_context::template partial<N>>::type;
 
-  template <typename T>
-  typename T::Context& get() {
-    return static_cast<typename T::Context&>(*this);
-  }
+    template <typename T> typename T::Context& get()
+    {
+        return static_cast<typename T::Context&>(*this);
+    }
 };
 
-template <>
-struct PartialContext<> {
-  template <int>
-  using partial = PartialContext;
+template <> struct PartialContext<>
+{
+    template <int> using partial = PartialContext;
 };
 
 template <int N, typename Context, typename Container, typename CurrentMW,
@@ -39,25 +41,28 @@
 struct Context : private PartialContext<Middlewares...>
 // struct Context : private Middlewares::context... // simple but less type-safe
 {
-  template <int N, typename Context, typename Container>
-  friend typename std::enable_if<(N == 0)>::type afterHandlersCallHelper(
-      Container& middlewares, Context& ctx, Request& req, Response& res);
-  template <int N, typename Context, typename Container>
-  friend typename std::enable_if<(N > 0)>::type afterHandlersCallHelper(
-      Container& middlewares, Context& ctx, Request& req, Response& res);
+    template <int N, typename Context, typename Container>
+    friend typename std::enable_if<(N == 0)>::type
+        afterHandlersCallHelper(Container& middlewares, Context& ctx,
+                                Request& req, Response& res);
+    template <int N, typename Context, typename Container>
+    friend typename std::enable_if<(N > 0)>::type
+        afterHandlersCallHelper(Container& middlewares, Context& ctx,
+                                Request& req, Response& res);
 
-  template <int N, typename Context, typename Container, typename CurrentMW,
-            typename... Middlewares2>
-  friend bool middlewareCallHelper(Container& middlewares, Request& req,
-                                   Response& res, Context& ctx);
+    template <int N, typename Context, typename Container, typename CurrentMW,
+              typename... Middlewares2>
+    friend bool middlewareCallHelper(Container& middlewares, Request& req,
+                                     Response& res, Context& ctx);
 
-  template <typename T>
-  typename T::Context& get() {
-    return static_cast<typename T::Context&>(*this);
-  }
+    template <typename T> typename T::Context& get()
+    {
+        return static_cast<typename T::Context&>(*this);
+    }
 
-  template <int N>
-  using partial = typename PartialContext<Middlewares...>::template partial<N>;
+    template <int N>
+    using partial =
+        typename PartialContext<Middlewares...>::template partial<N>;
 };
-}  // namespace detail
-}  // namespace crow
+} // namespace detail
+} // namespace crow
diff --git a/crow/include/crow/query_string.h b/crow/include/crow/query_string.h
index 0606994..67e426a 100644
--- a/crow/include/crow/query_string.h
+++ b/crow/include/crow/query_string.h
@@ -6,7 +6,8 @@
 #include <string>
 #include <vector>
 
-namespace crow {
+namespace crow
+{
 // ----------------------------------------------------------------------------
 // qs_parse (modified)
 // https://github.com/bartgrantham/qs_parse
@@ -37,306 +38,376 @@
 #undef _qsSORTING
 
 // isxdigit _is_ available in <ctype.h>, but let's avoid another header instead
-#define BMCWEB_QS_ISHEX(x)                                      \
-  ((((x) >= '0' && (x) <= '9') || ((x) >= 'A' && (x) <= 'F') || \
-    ((x) >= 'a' && (x) <= 'f'))                                 \
-       ? 1                                                      \
-       : 0)
-#define BMCWEB_QS_HEX2DEC(x)                 \
-  (((x) >= '0' && (x) <= '9')                \
-       ? (x)-48                              \
-       : ((x) >= 'A' && (x) <= 'F') ? (x)-55 \
-                                    : ((x) >= 'a' && (x) <= 'f') ? (x)-87 : 0)
-#define BMCWEB_QS_ISQSCHR(x) \
-  ((((x) == '=') || ((x) == '#') || ((x) == '&') || ((x) == '\0')) ? 0 : 1)
+#define BMCWEB_QS_ISHEX(x)                                                     \
+    ((((x) >= '0' && (x) <= '9') || ((x) >= 'A' && (x) <= 'F') ||              \
+      ((x) >= 'a' && (x) <= 'f'))                                              \
+         ? 1                                                                   \
+         : 0)
+#define BMCWEB_QS_HEX2DEC(x)                                                   \
+    (((x) >= '0' && (x) <= '9')                                                \
+         ? (x)-48                                                              \
+         : ((x) >= 'A' && (x) <= 'F')                                          \
+               ? (x)-55                                                        \
+               : ((x) >= 'a' && (x) <= 'f') ? (x)-87 : 0)
+#define BMCWEB_QS_ISQSCHR(x)                                                   \
+    ((((x) == '=') || ((x) == '#') || ((x) == '&') || ((x) == '\0')) ? 0 : 1)
 
-inline int qsStrncmp(const char* s, const char* qs, size_t n) {
-  int i = 0;
-  unsigned char u1, u2, unyb, lnyb;
+inline int qsStrncmp(const char* s, const char* qs, size_t n)
+{
+    int i = 0;
+    unsigned char u1, u2, unyb, lnyb;
 
-  while (n-- > 0) {
-    u1 = static_cast<unsigned char>(*s++);
-    u2 = static_cast<unsigned char>(*qs++);
-
-    if (!BMCWEB_QS_ISQSCHR(u1)) {
-      u1 = '\0';
-    }
-    if (!BMCWEB_QS_ISQSCHR(u2)) {
-      u2 = '\0';
-    }
-
-    if (u1 == '+') {
-      u1 = ' ';
-    }
-    if (u1 == '%')  // easier/safer than scanf
+    while (n-- > 0)
     {
-      unyb = static_cast<unsigned char>(*s++);
-      lnyb = static_cast<unsigned char>(*s++);
-      if (BMCWEB_QS_ISHEX(unyb) && BMCWEB_QS_ISHEX(lnyb)) {
-        u1 = (BMCWEB_QS_HEX2DEC(unyb) * 16) + BMCWEB_QS_HEX2DEC(lnyb);
-      } else {
-        u1 = '\0';
-      }
-    }
+        u1 = static_cast<unsigned char>(*s++);
+        u2 = static_cast<unsigned char>(*qs++);
 
-    if (u2 == '+') {
-      u2 = ' ';
+        if (!BMCWEB_QS_ISQSCHR(u1))
+        {
+            u1 = '\0';
+        }
+        if (!BMCWEB_QS_ISQSCHR(u2))
+        {
+            u2 = '\0';
+        }
+
+        if (u1 == '+')
+        {
+            u1 = ' ';
+        }
+        if (u1 == '%') // easier/safer than scanf
+        {
+            unyb = static_cast<unsigned char>(*s++);
+            lnyb = static_cast<unsigned char>(*s++);
+            if (BMCWEB_QS_ISHEX(unyb) && BMCWEB_QS_ISHEX(lnyb))
+            {
+                u1 = (BMCWEB_QS_HEX2DEC(unyb) * 16) + BMCWEB_QS_HEX2DEC(lnyb);
+            }
+            else
+            {
+                u1 = '\0';
+            }
+        }
+
+        if (u2 == '+')
+        {
+            u2 = ' ';
+        }
+        if (u2 == '%') // easier/safer than scanf
+        {
+            unyb = static_cast<unsigned char>(*qs++);
+            lnyb = static_cast<unsigned char>(*qs++);
+            if (BMCWEB_QS_ISHEX(unyb) && BMCWEB_QS_ISHEX(lnyb))
+            {
+                u2 = (BMCWEB_QS_HEX2DEC(unyb) * 16) + BMCWEB_QS_HEX2DEC(lnyb);
+            }
+            else
+            {
+                u2 = '\0';
+            }
+        }
+
+        if (u1 != u2)
+        {
+            return u1 - u2;
+        }
+        if (u1 == '\0')
+        {
+            return 0;
+        }
+        i++;
     }
-    if (u2 == '%')  // easier/safer than scanf
+    if (BMCWEB_QS_ISQSCHR(*qs))
     {
-      unyb = static_cast<unsigned char>(*qs++);
-      lnyb = static_cast<unsigned char>(*qs++);
-      if (BMCWEB_QS_ISHEX(unyb) && BMCWEB_QS_ISHEX(lnyb)) {
-        u2 = (BMCWEB_QS_HEX2DEC(unyb) * 16) + BMCWEB_QS_HEX2DEC(lnyb);
-      } else {
-        u2 = '\0';
-      }
+        return -1;
     }
-
-    if (u1 != u2) {
-      return u1 - u2;
+    else
+    {
+        return 0;
     }
-    if (u1 == '\0') {
-      return 0;
-    }
-    i++;
-  }
-  if (BMCWEB_QS_ISQSCHR(*qs)) {
-    return -1;
-  } else {
-    return 0;
-  }
 }
 
-inline int qsParse(char* qs, char* qs_kv[], int qs_kv_size) {
-  int i, j;
-  char* substrPtr;
+inline int qsParse(char* qs, char* qs_kv[], int qs_kv_size)
+{
+    int i, j;
+    char* substrPtr;
 
-  for (i = 0; i < qs_kv_size; i++) {
-    qs_kv[i] = NULL;
-  }
-
-  // find the beginning of the k/v substrings or the fragment
-  substrPtr = qs + strcspn(qs, "?#");
-  if (substrPtr[0] != '\0') {
-    substrPtr++;
-  } else {
-    return 0;  // no query or fragment
-  }
-
-  i = 0;
-  while (i < qs_kv_size) {
-    qs_kv[i] = substrPtr;
-    j = strcspn(substrPtr, "&");
-    if (substrPtr[j] == '\0') {
-      break;
+    for (i = 0; i < qs_kv_size; i++)
+    {
+        qs_kv[i] = NULL;
     }
-    substrPtr += j + 1;
-    i++;
-  }
-  i++;  // x &'s -> means x iterations of this loop -> means *x+1* k/v pairs
 
-  // we only decode the values in place, the keys could have '='s in them
-  // which will hose our ability to distinguish keys from values later
-  for (j = 0; j < i; j++) {
-    substrPtr = qs_kv[j] + strcspn(qs_kv[j], "=&#");
-    if (substrPtr[0] == '&' ||
-        substrPtr[0] == '\0') {  // blank value: skip decoding
-      substrPtr[0] = '\0';
-    } else {
-      qsDecode(++substrPtr);
+    // find the beginning of the k/v substrings or the fragment
+    substrPtr = qs + strcspn(qs, "?#");
+    if (substrPtr[0] != '\0')
+    {
+        substrPtr++;
     }
-  }
+    else
+    {
+        return 0; // no query or fragment
+    }
+
+    i = 0;
+    while (i < qs_kv_size)
+    {
+        qs_kv[i] = substrPtr;
+        j = strcspn(substrPtr, "&");
+        if (substrPtr[j] == '\0')
+        {
+            break;
+        }
+        substrPtr += j + 1;
+        i++;
+    }
+    i++; // x &'s -> means x iterations of this loop -> means *x+1* k/v pairs
+
+    // we only decode the values in place, the keys could have '='s in them
+    // which will hose our ability to distinguish keys from values later
+    for (j = 0; j < i; j++)
+    {
+        substrPtr = qs_kv[j] + strcspn(qs_kv[j], "=&#");
+        if (substrPtr[0] == '&' || substrPtr[0] == '\0')
+        { // blank value: skip decoding
+            substrPtr[0] = '\0';
+        }
+        else
+        {
+            qsDecode(++substrPtr);
+        }
+    }
 
 #ifdef _qsSORTING
 // TODO: qsort qs_kv, using qs_strncmp() for the comparison
 #endif
 
-  return i;
+    return i;
 }
 
-inline int qsDecode(char* qs) {
-  int i = 0, j = 0;
+inline int qsDecode(char* qs)
+{
+    int i = 0, j = 0;
 
-  while (BMCWEB_QS_ISQSCHR(qs[j])) {
-    if (qs[j] == '+') {
-      qs[i] = ' ';
-    } else if (qs[j] == '%')  // easier/safer than scanf
+    while (BMCWEB_QS_ISQSCHR(qs[j]))
     {
-      if (!BMCWEB_QS_ISHEX(qs[j + 1]) || !BMCWEB_QS_ISHEX(qs[j + 2])) {
-        qs[i] = '\0';
-        return i;
-      }
-      qs[i] =
-          (BMCWEB_QS_HEX2DEC(qs[j + 1]) * 16) + BMCWEB_QS_HEX2DEC(qs[j + 2]);
-      j += 2;
-    } else {
-      qs[i] = qs[j];
+        if (qs[j] == '+')
+        {
+            qs[i] = ' ';
+        }
+        else if (qs[j] == '%') // easier/safer than scanf
+        {
+            if (!BMCWEB_QS_ISHEX(qs[j + 1]) || !BMCWEB_QS_ISHEX(qs[j + 2]))
+            {
+                qs[i] = '\0';
+                return i;
+            }
+            qs[i] = (BMCWEB_QS_HEX2DEC(qs[j + 1]) * 16) +
+                    BMCWEB_QS_HEX2DEC(qs[j + 2]);
+            j += 2;
+        }
+        else
+        {
+            qs[i] = qs[j];
+        }
+        i++;
+        j++;
     }
-    i++;
-    j++;
-  }
-  qs[i] = '\0';
+    qs[i] = '\0';
 
-  return i;
+    return i;
 }
 
 inline char* qsK2v(const char* key, char* const* qs_kv, int qs_kv_size,
-                   int nth = 0) {
-  int i;
-  size_t keyLen, skip;
+                   int nth = 0)
+{
+    int i;
+    size_t keyLen, skip;
 
-  keyLen = strlen(key);
+    keyLen = strlen(key);
 
 #ifdef _qsSORTING
 // TODO: binary search for key in the sorted qs_kv
-#else   // _qsSORTING
-  for (i = 0; i < qs_kv_size; i++) {
-    // we rely on the unambiguous '=' to find the value in our k/v pair
-    if (qsStrncmp(key, qs_kv[i], keyLen) == 0) {
-      skip = strcspn(qs_kv[i], "=");
-      if (qs_kv[i][skip] == '=') {
-        skip++;
-      }
-      // return (zero-char value) ? ptr to trailing '\0' : ptr to value
-      if (nth == 0) {
-        return qs_kv[i] + skip;
-      } else {
-        --nth;
-      }
+#else  // _qsSORTING
+    for (i = 0; i < qs_kv_size; i++)
+    {
+        // we rely on the unambiguous '=' to find the value in our k/v pair
+        if (qsStrncmp(key, qs_kv[i], keyLen) == 0)
+        {
+            skip = strcspn(qs_kv[i], "=");
+            if (qs_kv[i][skip] == '=')
+            {
+                skip++;
+            }
+            // return (zero-char value) ? ptr to trailing '\0' : ptr to value
+            if (nth == 0)
+            {
+                return qs_kv[i] + skip;
+            }
+            else
+            {
+                --nth;
+            }
+        }
     }
-  }
-#endif  // _qsSORTING
+#endif // _qsSORTING
 
-  return NULL;
+    return NULL;
 }
 
 inline char* qsScanvalue(const char* key, const char* qs, char* val,
-                         size_t val_len) {
-  size_t i, keyLen;
-  const char* tmp;
+                         size_t val_len)
+{
+    size_t i, keyLen;
+    const char* tmp;
 
-  // find the beginning of the k/v substrings
-  if ((tmp = strchr(qs, '?')) != NULL) {
-    qs = tmp + 1;
-  }
-
-  keyLen = strlen(key);
-  while (qs[0] != '#' && qs[0] != '\0') {
-    if (qsStrncmp(key, qs, keyLen) == 0) {
-      break;
+    // find the beginning of the k/v substrings
+    if ((tmp = strchr(qs, '?')) != NULL)
+    {
+        qs = tmp + 1;
     }
-    qs += strcspn(qs, "&") + 1;
-  }
 
-  if (qs[0] == '\0') {
-    return NULL;
-  }
-
-  qs += strcspn(qs, "=&#");
-  if (qs[0] == '=') {
-    qs++;
-    i = strcspn(qs, "&=#");
-    strncpy(val, qs, (val_len - 1) < (i + 1) ? (val_len - 1) : (i + 1));
-    qsDecode(val);
-  } else {
-    if (val_len > 0) {
-      val[0] = '\0';
+    keyLen = strlen(key);
+    while (qs[0] != '#' && qs[0] != '\0')
+    {
+        if (qsStrncmp(key, qs, keyLen) == 0)
+        {
+            break;
+        }
+        qs += strcspn(qs, "&") + 1;
     }
-  }
 
-  return val;
+    if (qs[0] == '\0')
+    {
+        return NULL;
+    }
+
+    qs += strcspn(qs, "=&#");
+    if (qs[0] == '=')
+    {
+        qs++;
+        i = strcspn(qs, "&=#");
+        strncpy(val, qs, (val_len - 1) < (i + 1) ? (val_len - 1) : (i + 1));
+        qsDecode(val);
+    }
+    else
+    {
+        if (val_len > 0)
+        {
+            val[0] = '\0';
+        }
+    }
+
+    return val;
 }
-}  // namespace crow
+} // namespace crow
 // ----------------------------------------------------------------------------
 
-namespace crow {
-class QueryString {
- public:
-  static const int maxKeyValuePairsCount = 256;
+namespace crow
+{
+class QueryString
+{
+  public:
+    static const int maxKeyValuePairsCount = 256;
 
-  QueryString() = default;
+    QueryString() = default;
 
-  QueryString(const QueryString& qs) : url(qs.url) {
-    for (auto p : qs.keyValuePairs) {
-      keyValuePairs.push_back(
-          const_cast<char*>(p - qs.url.c_str() + url.c_str()));
-    }
-  }
-
-  QueryString& operator=(const QueryString& qs) {
-    url = qs.url;
-    keyValuePairs.clear();
-    for (auto p : qs.keyValuePairs) {
-      keyValuePairs.push_back(
-          const_cast<char*>(p - qs.url.c_str() + url.c_str()));
-    }
-    return *this;
-  }
-
-  QueryString& operator=(QueryString&& qs) {
-    keyValuePairs = std::move(qs.keyValuePairs);
-    auto* oldData = const_cast<char*>(qs.url.c_str());
-    url = std::move(qs.url);
-    for (auto& p : keyValuePairs) {
-      p += const_cast<char*>(url.c_str()) - oldData;
-    }
-    return *this;
-  }
-
-  explicit QueryString(std::string url) : url(std::move(url)) {
-    if (url.empty()) {
-      return;
+    QueryString(const QueryString& qs) : url(qs.url)
+    {
+        for (auto p : qs.keyValuePairs)
+        {
+            keyValuePairs.push_back(
+                const_cast<char*>(p - qs.url.c_str() + url.c_str()));
+        }
     }
 
-    keyValuePairs.resize(maxKeyValuePairsCount);
-
-    int count = qsParse(&url[0], &keyValuePairs[0], maxKeyValuePairsCount);
-    keyValuePairs.resize(count);
-  }
-
-  void clear() {
-    keyValuePairs.clear();
-    url.clear();
-  }
-
-  friend std::ostream& operator<<(std::ostream& os, const QueryString& qs) {
-    os << "[ ";
-    for (size_t i = 0; i < qs.keyValuePairs.size(); ++i) {
-      if (i != 0u) {
-        os << ", ";
-      }
-      os << qs.keyValuePairs[i];
+    QueryString& operator=(const QueryString& qs)
+    {
+        url = qs.url;
+        keyValuePairs.clear();
+        for (auto p : qs.keyValuePairs)
+        {
+            keyValuePairs.push_back(
+                const_cast<char*>(p - qs.url.c_str() + url.c_str()));
+        }
+        return *this;
     }
-    os << " ]";
-    return os;
-  }
 
-  char* get(const std::string& name) const {
-    char* ret = qsK2v(name.c_str(), keyValuePairs.data(), keyValuePairs.size());
-    return ret;
-  }
-
-  std::vector<char*> getList(const std::string& name) const {
-    std::vector<char*> ret;
-    std::string plus = name + "[]";
-    char* element = nullptr;
-
-    int count = 0;
-    while (1) {
-      element = qsK2v(plus.c_str(), keyValuePairs.data(), keyValuePairs.size(),
-                      count++);
-      if (element == nullptr) {
-        break;
-      }
-      ret.push_back(element);
+    QueryString& operator=(QueryString&& qs)
+    {
+        keyValuePairs = std::move(qs.keyValuePairs);
+        auto* oldData = const_cast<char*>(qs.url.c_str());
+        url = std::move(qs.url);
+        for (auto& p : keyValuePairs)
+        {
+            p += const_cast<char*>(url.c_str()) - oldData;
+        }
+        return *this;
     }
-    return ret;
-  }
 
- private:
-  std::string url;
-  std::vector<char*> keyValuePairs;
+    explicit QueryString(std::string url) : url(std::move(url))
+    {
+        if (url.empty())
+        {
+            return;
+        }
+
+        keyValuePairs.resize(maxKeyValuePairsCount);
+
+        int count = qsParse(&url[0], &keyValuePairs[0], maxKeyValuePairsCount);
+        keyValuePairs.resize(count);
+    }
+
+    void clear()
+    {
+        keyValuePairs.clear();
+        url.clear();
+    }
+
+    friend std::ostream& operator<<(std::ostream& os, const QueryString& qs)
+    {
+        os << "[ ";
+        for (size_t i = 0; i < qs.keyValuePairs.size(); ++i)
+        {
+            if (i != 0u)
+            {
+                os << ", ";
+            }
+            os << qs.keyValuePairs[i];
+        }
+        os << " ]";
+        return os;
+    }
+
+    char* get(const std::string& name) const
+    {
+        char* ret =
+            qsK2v(name.c_str(), keyValuePairs.data(), keyValuePairs.size());
+        return ret;
+    }
+
+    std::vector<char*> getList(const std::string& name) const
+    {
+        std::vector<char*> ret;
+        std::string plus = name + "[]";
+        char* element = nullptr;
+
+        int count = 0;
+        while (1)
+        {
+            element = qsK2v(plus.c_str(), keyValuePairs.data(),
+                            keyValuePairs.size(), count++);
+            if (element == nullptr)
+            {
+                break;
+            }
+            ret.push_back(element);
+        }
+        return ret;
+    }
+
+  private:
+    std::string url;
+    std::vector<char*> keyValuePairs;
 };
 
-}  // namespace crow
+} // namespace crow
diff --git a/crow/include/crow/routing.h b/crow/include/crow/routing.h
index ddf307a..945f361 100644
--- a/crow/include/crow/routing.h
+++ b/crow/include/crow/routing.h
@@ -1,5 +1,8 @@
 #pragma once
 
+#include "boost/container/flat_map.hpp"
+
+#include <boost/lexical_cast.hpp>
 #include <cerrno>
 #include <cstdint>
 #include <cstdlib>
@@ -8,9 +11,6 @@
 #include <tuple>
 #include <utility>
 #include <vector>
-#include <boost/lexical_cast.hpp>
-
-#include "boost/container/flat_map.hpp"
 
 #include "crow/common.h"
 #include "crow/http_request.h"
@@ -19,969 +19,1174 @@
 #include "crow/utility.h"
 #include "crow/websocket.h"
 
-namespace crow {
-class BaseRule {
- public:
-  BaseRule(std::string rule) : rule(std::move(rule)) {}
+namespace crow
+{
+class BaseRule
+{
+  public:
+    BaseRule(std::string rule) : rule(std::move(rule))
+    {
+    }
 
-  virtual ~BaseRule() {}
+    virtual ~BaseRule()
+    {
+    }
 
-  virtual void validate() = 0;
-  std::unique_ptr<BaseRule> upgrade() {
-    if (ruleToUpgrade) return std::move(ruleToUpgrade);
-    return {};
-  }
+    virtual void validate() = 0;
+    std::unique_ptr<BaseRule> upgrade()
+    {
+        if (ruleToUpgrade)
+            return std::move(ruleToUpgrade);
+        return {};
+    }
 
-  virtual void handle(const Request&, Response&, const RoutingParams&) = 0;
-  virtual void handleUpgrade(const Request&, Response& res, SocketAdaptor&&) {
-    res = Response(boost::beast::http::status::not_found);
-    res.end();
-  }
+    virtual void handle(const Request&, Response&, const RoutingParams&) = 0;
+    virtual void handleUpgrade(const Request&, Response& res, SocketAdaptor&&)
+    {
+        res = Response(boost::beast::http::status::not_found);
+        res.end();
+    }
 #ifdef BMCWEB_ENABLE_SSL
-  virtual void handleUpgrade(const Request&, Response& res, SSLAdaptor&&) {
-    res = Response(boost::beast::http::status::not_found);
-    res.end();
-  }
+    virtual void handleUpgrade(const Request&, Response& res, SSLAdaptor&&)
+    {
+        res = Response(boost::beast::http::status::not_found);
+        res.end();
+    }
 #endif
 
-  uint32_t getMethods() { return methodsBitfield; }
+    uint32_t getMethods()
+    {
+        return methodsBitfield;
+    }
 
- protected:
-  uint32_t methodsBitfield{1 << (int)boost::beast::http::verb::get};
+  protected:
+    uint32_t methodsBitfield{1 << (int)boost::beast::http::verb::get};
 
-  std::string rule;
-  std::string nameStr;
+    std::string rule;
+    std::string nameStr;
 
-  std::unique_ptr<BaseRule> ruleToUpgrade;
+    std::unique_ptr<BaseRule> ruleToUpgrade;
 
-  friend class Router;
-  template <typename T>
-  friend struct RuleParameterTraits;
+    friend class Router;
+    template <typename T> friend struct RuleParameterTraits;
 };
 
-namespace detail {
-namespace routing_handler_call_helper {
-template <typename T, int Pos>
-struct CallPair {
-  using type = T;
-  static const int pos = Pos;
+namespace detail
+{
+namespace routing_handler_call_helper
+{
+template <typename T, int Pos> struct CallPair
+{
+    using type = T;
+    static const int pos = Pos;
 };
 
-template <typename H1>
-struct CallParams {
-  H1& handler;
-  const RoutingParams& params;
-  const Request& req;
-  Response& res;
+template <typename H1> struct CallParams
+{
+    H1& handler;
+    const RoutingParams& params;
+    const Request& req;
+    Response& res;
 };
 
 template <typename F, int NInt, int NUint, int NDouble, int NString,
           typename S1, typename S2>
-struct Call {};
+struct Call
+{
+};
 
 template <typename F, int NInt, int NUint, int NDouble, int NString,
           typename... Args1, typename... Args2>
 struct Call<F, NInt, NUint, NDouble, NString, black_magic::S<int64_t, Args1...>,
-            black_magic::S<Args2...>> {
-  void operator()(F cparams) {
-    using pushed = typename black_magic::S<Args2...>::template push_back<
-        CallPair<int64_t, NInt>>;
-    Call<F, NInt + 1, NUint, NDouble, NString, black_magic::S<Args1...>,
-         pushed>()(cparams);
-  }
+            black_magic::S<Args2...>>
+{
+    void operator()(F cparams)
+    {
+        using pushed = typename black_magic::S<Args2...>::template push_back<
+            CallPair<int64_t, NInt>>;
+        Call<F, NInt + 1, NUint, NDouble, NString, black_magic::S<Args1...>,
+             pushed>()(cparams);
+    }
 };
 
 template <typename F, int NInt, int NUint, int NDouble, int NString,
           typename... Args1, typename... Args2>
 struct Call<F, NInt, NUint, NDouble, NString,
-            black_magic::S<uint64_t, Args1...>, black_magic::S<Args2...>> {
-  void operator()(F cparams) {
-    using pushed = typename black_magic::S<Args2...>::template push_back<
-        CallPair<uint64_t, NUint>>;
-    Call<F, NInt, NUint + 1, NDouble, NString, black_magic::S<Args1...>,
-         pushed>()(cparams);
-  }
+            black_magic::S<uint64_t, Args1...>, black_magic::S<Args2...>>
+{
+    void operator()(F cparams)
+    {
+        using pushed = typename black_magic::S<Args2...>::template push_back<
+            CallPair<uint64_t, NUint>>;
+        Call<F, NInt, NUint + 1, NDouble, NString, black_magic::S<Args1...>,
+             pushed>()(cparams);
+    }
 };
 
 template <typename F, int NInt, int NUint, int NDouble, int NString,
           typename... Args1, typename... Args2>
 struct Call<F, NInt, NUint, NDouble, NString, black_magic::S<double, Args1...>,
-            black_magic::S<Args2...>> {
-  void operator()(F cparams) {
-    using pushed = typename black_magic::S<Args2...>::template push_back<
-        CallPair<double, NDouble>>;
-    Call<F, NInt, NUint, NDouble + 1, NString, black_magic::S<Args1...>,
-         pushed>()(cparams);
-  }
+            black_magic::S<Args2...>>
+{
+    void operator()(F cparams)
+    {
+        using pushed = typename black_magic::S<Args2...>::template push_back<
+            CallPair<double, NDouble>>;
+        Call<F, NInt, NUint, NDouble + 1, NString, black_magic::S<Args1...>,
+             pushed>()(cparams);
+    }
 };
 
 template <typename F, int NInt, int NUint, int NDouble, int NString,
           typename... Args1, typename... Args2>
 struct Call<F, NInt, NUint, NDouble, NString,
-            black_magic::S<std::string, Args1...>, black_magic::S<Args2...>> {
-  void operator()(F cparams) {
-    using pushed = typename black_magic::S<Args2...>::template push_back<
-        CallPair<std::string, NString>>;
-    Call<F, NInt, NUint, NDouble, NString + 1, black_magic::S<Args1...>,
-         pushed>()(cparams);
-  }
+            black_magic::S<std::string, Args1...>, black_magic::S<Args2...>>
+{
+    void operator()(F cparams)
+    {
+        using pushed = typename black_magic::S<Args2...>::template push_back<
+            CallPair<std::string, NString>>;
+        Call<F, NInt, NUint, NDouble, NString + 1, black_magic::S<Args1...>,
+             pushed>()(cparams);
+    }
 };
 
 template <typename F, int NInt, int NUint, int NDouble, int NString,
           typename... Args1>
 struct Call<F, NInt, NUint, NDouble, NString, black_magic::S<>,
-            black_magic::S<Args1...>> {
-  void operator()(F cparams) {
-    cparams.handler(
-        cparams.req, cparams.res,
-        cparams.params.template get<typename Args1::type>(Args1::pos)...);
-  }
+            black_magic::S<Args1...>>
+{
+    void operator()(F cparams)
+    {
+        cparams.handler(
+            cparams.req, cparams.res,
+            cparams.params.template get<typename Args1::type>(Args1::pos)...);
+    }
 };
 
-template <typename Func, typename... ArgsWrapped>
-struct Wrapped {
-  template <typename... Args>
-  void set(
-      Func f,
-      typename std::enable_if<
-          !std::is_same<
-              typename std::tuple_element<0, std::tuple<Args..., void>>::type,
-              const Request&>::value,
-          int>::type = 0) {
-    handler = (
+template <typename Func, typename... ArgsWrapped> struct Wrapped
+{
+    template <typename... Args>
+    void set(
+        Func f,
+        typename std::enable_if<
+            !std::is_same<
+                typename std::tuple_element<0, std::tuple<Args..., void>>::type,
+                const Request&>::value,
+            int>::type = 0)
+    {
+        handler = (
 #ifdef BMCWEB_CAN_USE_CPP14
-        [f = std::move(f)]
+            [f = std::move(f)]
 #else
-        [f]
+            [f]
 #endif
-        (const Request&, Response& res, Args... args) {
-          res = Response(f(args...));
-          res.end();
-        });
-  }
-
-  template <typename Req, typename... Args>
-  struct ReqHandlerWrapper {
-    ReqHandlerWrapper(Func f) : f(std::move(f)) {}
-
-    void operator()(const Request& req, Response& res, Args... args) {
-      res = Response(f(req, args...));
-      res.end();
+            (const Request&, Response& res, Args... args) {
+                res = Response(f(args...));
+                res.end();
+            });
     }
 
-    Func f;
-  };
+    template <typename Req, typename... Args> struct ReqHandlerWrapper
+    {
+        ReqHandlerWrapper(Func f) : f(std::move(f))
+        {
+        }
 
-  template <typename... Args>
-  void set(
-      Func f,
-      typename std::enable_if<
-          std::is_same<
-              typename std::tuple_element<0, std::tuple<Args..., void>>::type,
-              const Request&>::value &&
-              !std::is_same<typename std::tuple_element<
-                                1, std::tuple<Args..., void, void>>::type,
-                            Response&>::value,
-          int>::type = 0) {
-    handler = ReqHandlerWrapper<Args...>(std::move(f));
-    /*handler = (
-        [f = std::move(f)]
-        (const Request& req, Response& res, Args... args){
-             res = Response(f(req, args...));
-             res.end();
-        });*/
-  }
+        void operator()(const Request& req, Response& res, Args... args)
+        {
+            res = Response(f(req, args...));
+            res.end();
+        }
 
-  template <typename... Args>
-  void set(
-      Func f,
-      typename std::enable_if<
-          std::is_same<
-              typename std::tuple_element<0, std::tuple<Args..., void>>::type,
-              const Request&>::value &&
-              std::is_same<typename std::tuple_element<
-                               1, std::tuple<Args..., void, void>>::type,
-                           Response&>::value,
-          int>::type = 0) {
-    handler = std::move(f);
-  }
+        Func f;
+    };
 
-  template <typename... Args>
-  struct HandlerTypeHelper {
-    using type =
-        std::function<void(const crow::Request&, crow::Response&, Args...)>;
-    using args_type = black_magic::S<typename black_magic::promote_t<Args>...>;
-  };
+    template <typename... Args>
+    void set(
+        Func f,
+        typename std::enable_if<
+            std::is_same<
+                typename std::tuple_element<0, std::tuple<Args..., void>>::type,
+                const Request&>::value &&
+                !std::is_same<typename std::tuple_element<
+                                  1, std::tuple<Args..., void, void>>::type,
+                              Response&>::value,
+            int>::type = 0)
+    {
+        handler = ReqHandlerWrapper<Args...>(std::move(f));
+        /*handler = (
+            [f = std::move(f)]
+            (const Request& req, Response& res, Args... args){
+                 res = Response(f(req, args...));
+                 res.end();
+            });*/
+    }
 
-  template <typename... Args>
-  struct HandlerTypeHelper<const Request&, Args...> {
-    using type =
-        std::function<void(const crow::Request&, crow::Response&, Args...)>;
-    using args_type = black_magic::S<typename black_magic::promote_t<Args>...>;
-  };
+    template <typename... Args>
+    void set(
+        Func f,
+        typename std::enable_if<
+            std::is_same<
+                typename std::tuple_element<0, std::tuple<Args..., void>>::type,
+                const Request&>::value &&
+                std::is_same<typename std::tuple_element<
+                                 1, std::tuple<Args..., void, void>>::type,
+                             Response&>::value,
+            int>::type = 0)
+    {
+        handler = std::move(f);
+    }
 
-  template <typename... Args>
-  struct HandlerTypeHelper<const Request&, Response&, Args...> {
-    using type =
-        std::function<void(const crow::Request&, crow::Response&, Args...)>;
-    using args_type = black_magic::S<typename black_magic::promote_t<Args>...>;
-  };
+    template <typename... Args> struct HandlerTypeHelper
+    {
+        using type =
+            std::function<void(const crow::Request&, crow::Response&, Args...)>;
+        using args_type =
+            black_magic::S<typename black_magic::promote_t<Args>...>;
+    };
 
-  typename HandlerTypeHelper<ArgsWrapped...>::type handler;
+    template <typename... Args>
+    struct HandlerTypeHelper<const Request&, Args...>
+    {
+        using type =
+            std::function<void(const crow::Request&, crow::Response&, Args...)>;
+        using args_type =
+            black_magic::S<typename black_magic::promote_t<Args>...>;
+    };
 
-  void operator()(const Request& req, Response& res,
-                  const RoutingParams& params) {
-    detail::routing_handler_call_helper::Call<
-        detail::routing_handler_call_helper::CallParams<decltype(handler)>, 0,
-        0, 0, 0, typename HandlerTypeHelper<ArgsWrapped...>::args_type,
-        black_magic::S<>>()(
-        detail::routing_handler_call_helper::CallParams<decltype(handler)>{
-            handler, params, req, res});
-  }
+    template <typename... Args>
+    struct HandlerTypeHelper<const Request&, Response&, Args...>
+    {
+        using type =
+            std::function<void(const crow::Request&, crow::Response&, Args...)>;
+        using args_type =
+            black_magic::S<typename black_magic::promote_t<Args>...>;
+    };
+
+    typename HandlerTypeHelper<ArgsWrapped...>::type handler;
+
+    void operator()(const Request& req, Response& res,
+                    const RoutingParams& params)
+    {
+        detail::routing_handler_call_helper::Call<
+            detail::routing_handler_call_helper::CallParams<decltype(handler)>,
+            0, 0, 0, 0, typename HandlerTypeHelper<ArgsWrapped...>::args_type,
+            black_magic::S<>>()(
+            detail::routing_handler_call_helper::CallParams<decltype(handler)>{
+                handler, params, req, res});
+    }
 };
-}  // namespace routing_handler_call_helper
-}  // namespace detail
+} // namespace routing_handler_call_helper
+} // namespace detail
 
-class WebSocketRule : public BaseRule {
-  using self_t = WebSocketRule;
+class WebSocketRule : public BaseRule
+{
+    using self_t = WebSocketRule;
 
- public:
-  WebSocketRule(std::string rule) : BaseRule(std::move(rule)) {}
+  public:
+    WebSocketRule(std::string rule) : BaseRule(std::move(rule))
+    {
+    }
 
-  void validate() override {}
+    void validate() override
+    {
+    }
 
-  void handle(const Request&, Response& res, const RoutingParams&) override {
-    res = Response(boost::beast::http::status::not_found);
-    res.end();
-  }
+    void handle(const Request&, Response& res, const RoutingParams&) override
+    {
+        res = Response(boost::beast::http::status::not_found);
+        res.end();
+    }
 
-  void handleUpgrade(const Request& req, Response&,
-                     SocketAdaptor&& adaptor) override {
-    new crow::websocket::ConnectionImpl<SocketAdaptor>(
-        req, std::move(adaptor), openHandler, messageHandler, closeHandler,
-        errorHandler);
-  }
-#ifdef BMCWEB_ENABLE_SSL
-  void handleUpgrade(const Request& req, Response&,
-                     SSLAdaptor&& adaptor) override {
-    std::shared_ptr<crow::websocket::ConnectionImpl<SSLAdaptor>> myConnection =
-        std::make_shared<crow::websocket::ConnectionImpl<SSLAdaptor>>(
+    void handleUpgrade(const Request& req, Response&,
+                       SocketAdaptor&& adaptor) override
+    {
+        new crow::websocket::ConnectionImpl<SocketAdaptor>(
             req, std::move(adaptor), openHandler, messageHandler, closeHandler,
             errorHandler);
-    myConnection->start();
-  }
+    }
+#ifdef BMCWEB_ENABLE_SSL
+    void handleUpgrade(const Request& req, Response&,
+                       SSLAdaptor&& adaptor) override
+    {
+        std::shared_ptr<crow::websocket::ConnectionImpl<SSLAdaptor>>
+            myConnection =
+                std::make_shared<crow::websocket::ConnectionImpl<SSLAdaptor>>(
+                    req, std::move(adaptor), openHandler, messageHandler,
+                    closeHandler, errorHandler);
+        myConnection->start();
+    }
 #endif
 
-  template <typename Func>
-  self_t& onopen(Func f) {
-    openHandler = f;
-    return *this;
-  }
+    template <typename Func> self_t& onopen(Func f)
+    {
+        openHandler = f;
+        return *this;
+    }
 
-  template <typename Func>
-  self_t& onmessage(Func f) {
-    messageHandler = f;
-    return *this;
-  }
+    template <typename Func> self_t& onmessage(Func f)
+    {
+        messageHandler = f;
+        return *this;
+    }
 
-  template <typename Func>
-  self_t& onclose(Func f) {
-    closeHandler = f;
-    return *this;
-  }
+    template <typename Func> self_t& onclose(Func f)
+    {
+        closeHandler = f;
+        return *this;
+    }
 
-  template <typename Func>
-  self_t& onerror(Func f) {
-    errorHandler = f;
-    return *this;
-  }
+    template <typename Func> self_t& onerror(Func f)
+    {
+        errorHandler = f;
+        return *this;
+    }
 
- protected:
-  std::function<void(crow::websocket::Connection&)> openHandler;
-  std::function<void(crow::websocket::Connection&, const std::string&, bool)>
-      messageHandler;
-  std::function<void(crow::websocket::Connection&, const std::string&)>
-      closeHandler;
-  std::function<void(crow::websocket::Connection&)> errorHandler;
+  protected:
+    std::function<void(crow::websocket::Connection&)> openHandler;
+    std::function<void(crow::websocket::Connection&, const std::string&, bool)>
+        messageHandler;
+    std::function<void(crow::websocket::Connection&, const std::string&)>
+        closeHandler;
+    std::function<void(crow::websocket::Connection&)> errorHandler;
 };
 
-template <typename T>
-struct RuleParameterTraits {
-  using self_t = T;
-  WebSocketRule& websocket() {
-    auto p = new WebSocketRule(((self_t*)this)->rule);
-    ((self_t*)this)->ruleToUpgrade.reset(p);
-    return *p;
-  }
+template <typename T> struct RuleParameterTraits
+{
+    using self_t = T;
+    WebSocketRule& websocket()
+    {
+        auto p = new WebSocketRule(((self_t*)this)->rule);
+        ((self_t*)this)->ruleToUpgrade.reset(p);
+        return *p;
+    }
 
-  self_t& name(std::string name) noexcept {
-    ((self_t*)this)->nameStr = std::move(name);
-    return (self_t&)*this;
-  }
+    self_t& name(std::string name) noexcept
+    {
+        ((self_t*)this)->nameStr = std::move(name);
+        return (self_t&)*this;
+    }
 
-  self_t& methods(boost::beast::http::verb method) {
-    ((self_t*)this)->methodsBitfield = 1 << (int)method;
-    return (self_t&)*this;
-  }
+    self_t& methods(boost::beast::http::verb method)
+    {
+        ((self_t*)this)->methodsBitfield = 1 << (int)method;
+        return (self_t&)*this;
+    }
 
-  template <typename... MethodArgs>
-  self_t& methods(boost::beast::http::verb method, MethodArgs... args_method) {
-    methods(args_method...);
-    ((self_t*)this)->methodsBitfield |= 1 << (int)method;
-    return (self_t&)*this;
-  }
+    template <typename... MethodArgs>
+    self_t& methods(boost::beast::http::verb method, MethodArgs... args_method)
+    {
+        methods(args_method...);
+        ((self_t*)this)->methodsBitfield |= 1 << (int)method;
+        return (self_t&)*this;
+    }
 };
 
-class DynamicRule : public BaseRule, public RuleParameterTraits<DynamicRule> {
- public:
-  DynamicRule(std::string rule) : BaseRule(std::move(rule)) {}
-
-  void validate() override {
-    if (!erasedHandler) {
-      throw std::runtime_error(nameStr + (!nameStr.empty() ? ": " : "") +
-                               "no handler for url " + rule);
+class DynamicRule : public BaseRule, public RuleParameterTraits<DynamicRule>
+{
+  public:
+    DynamicRule(std::string rule) : BaseRule(std::move(rule))
+    {
     }
-  }
 
-  void handle(const Request& req, Response& res,
-              const RoutingParams& params) override {
-    erasedHandler(req, res, params);
-  }
-
-  template <typename Func>
-  void operator()(Func f) {
-    using function_t = utility::function_traits<Func>;
-
-    erasedHandler =
-        wrap(std::move(f), black_magic::gen_seq<function_t::arity>());
-  }
-
-  // enable_if Arg1 == request && Arg2 == Response
-  // enable_if Arg1 == request && Arg2 != resposne
-  // enable_if Arg1 != request
-
-  template <typename Func, unsigned... Indices>
-
-  std::function<void(const Request&, Response&, const RoutingParams&)> wrap(
-      Func f, black_magic::Seq<Indices...>) {
-    using function_t = utility::function_traits<Func>;
-
-    if (!black_magic::isParameterTagCompatible(
-            black_magic::getParameterTagRuntime(rule.c_str()),
-            black_magic::compute_parameter_tag_from_args_list<
-                typename function_t::template arg<Indices>...>::value)) {
-      throw std::runtime_error(
-          "routeDynamic: Handler type is mismatched with URL parameters: " +
-          rule);
+    void validate() override
+    {
+        if (!erasedHandler)
+        {
+            throw std::runtime_error(nameStr + (!nameStr.empty() ? ": " : "") +
+                                     "no handler for url " + rule);
+        }
     }
-    auto ret = detail::routing_handler_call_helper::Wrapped<
-        Func, typename function_t::template arg<Indices>...>();
-    ret.template set<typename function_t::template arg<Indices>...>(
-        std::move(f));
-    return ret;
-  }
 
-  template <typename Func>
-  void operator()(std::string name, Func&& f) {
-    nameStr = std::move(name);
-    (*this).template operator()<Func>(std::forward(f));
-  }
+    void handle(const Request& req, Response& res,
+                const RoutingParams& params) override
+    {
+        erasedHandler(req, res, params);
+    }
 
- private:
-  std::function<void(const Request&, Response&, const RoutingParams&)>
-      erasedHandler;
+    template <typename Func> void operator()(Func f)
+    {
+        using function_t = utility::function_traits<Func>;
+
+        erasedHandler =
+            wrap(std::move(f), black_magic::gen_seq<function_t::arity>());
+    }
+
+    // enable_if Arg1 == request && Arg2 == Response
+    // enable_if Arg1 == request && Arg2 != resposne
+    // enable_if Arg1 != request
+
+    template <typename Func, unsigned... Indices>
+
+    std::function<void(const Request&, Response&, const RoutingParams&)>
+        wrap(Func f, black_magic::Seq<Indices...>)
+    {
+        using function_t = utility::function_traits<Func>;
+
+        if (!black_magic::isParameterTagCompatible(
+                black_magic::getParameterTagRuntime(rule.c_str()),
+                black_magic::compute_parameter_tag_from_args_list<
+                    typename function_t::template arg<Indices>...>::value))
+        {
+            throw std::runtime_error("routeDynamic: Handler type is mismatched "
+                                     "with URL parameters: " +
+                                     rule);
+        }
+        auto ret = detail::routing_handler_call_helper::Wrapped<
+            Func, typename function_t::template arg<Indices>...>();
+        ret.template set<typename function_t::template arg<Indices>...>(
+            std::move(f));
+        return ret;
+    }
+
+    template <typename Func> void operator()(std::string name, Func&& f)
+    {
+        nameStr = std::move(name);
+        (*this).template operator()<Func>(std::forward(f));
+    }
+
+  private:
+    std::function<void(const Request&, Response&, const RoutingParams&)>
+        erasedHandler;
 };
 
 template <typename... Args>
 class TaggedRule : public BaseRule,
-                   public RuleParameterTraits<TaggedRule<Args...>> {
- public:
-  using self_t = TaggedRule<Args...>;
+                   public RuleParameterTraits<TaggedRule<Args...>>
+{
+  public:
+    using self_t = TaggedRule<Args...>;
 
-  TaggedRule(std::string rule) : BaseRule(std::move(rule)) {}
-
-  void validate() override {
-    if (!handler) {
-      throw std::runtime_error(nameStr + (!nameStr.empty() ? ": " : "") +
-                               "no handler for url " + rule);
+    TaggedRule(std::string rule) : BaseRule(std::move(rule))
+    {
     }
-  }
 
-  template <typename Func>
-  typename std::enable_if<
-      black_magic::CallHelper<Func, black_magic::S<Args...>>::value, void>::type
-  operator()(Func&& f) {
-    static_assert(
-        black_magic::CallHelper<Func, black_magic::S<Args...>>::value ||
+    void validate() override
+    {
+        if (!handler)
+        {
+            throw std::runtime_error(nameStr + (!nameStr.empty() ? ": " : "") +
+                                     "no handler for url " + rule);
+        }
+    }
+
+    template <typename Func>
+    typename std::enable_if<
+        black_magic::CallHelper<Func, black_magic::S<Args...>>::value,
+        void>::type
+        operator()(Func&& f)
+    {
+        static_assert(
+            black_magic::CallHelper<Func, black_magic::S<Args...>>::value ||
+                black_magic::CallHelper<
+                    Func, black_magic::S<crow::Request, Args...>>::value,
+            "Handler type is mismatched with URL parameters");
+        static_assert(
+            !std::is_same<void, decltype(f(std::declval<Args>()...))>::value,
+            "Handler function cannot have void return type; valid return "
+            "types: "
+            "string, int, crow::resposne, nlohmann::json");
+
+        handler = [f = std::move(f)](const Request&, Response& res,
+                                     Args... args) {
+            res = Response(f(args...));
+            res.end();
+        };
+    }
+
+    template <typename Func>
+    typename std::enable_if<
+        !black_magic::CallHelper<Func, black_magic::S<Args...>>::value &&
             black_magic::CallHelper<
                 Func, black_magic::S<crow::Request, Args...>>::value,
-        "Handler type is mismatched with URL parameters");
-    static_assert(
-        !std::is_same<void, decltype(f(std::declval<Args>()...))>::value,
-        "Handler function cannot have void return type; valid return types: "
-        "string, int, crow::resposne, nlohmann::json");
+        void>::type
+        operator()(Func&& f)
+    {
+        static_assert(
+            black_magic::CallHelper<Func, black_magic::S<Args...>>::value ||
+                black_magic::CallHelper<
+                    Func, black_magic::S<crow::Request, Args...>>::value,
+            "Handler type is mismatched with URL parameters");
+        static_assert(
+            !std::is_same<void, decltype(f(std::declval<crow::Request>(),
+                                           std::declval<Args>()...))>::value,
+            "Handler function cannot have void return type; valid return "
+            "types: "
+            "string, int, crow::resposne,nlohmann::json");
 
-    handler = [f = std::move(f)](const Request&, Response& res, Args... args) {
-      res = Response(f(args...));
-      res.end();
-    };
-  }
+        handler = [f = std::move(f)](const crow::Request& req,
+                                     crow::Response& res, Args... args) {
+            res = Response(f(req, args...));
+            res.end();
+        };
+    }
 
-  template <typename Func>
-  typename std::enable_if<
-      !black_magic::CallHelper<Func, black_magic::S<Args...>>::value &&
-          black_magic::CallHelper<
-              Func, black_magic::S<crow::Request, Args...>>::value,
-      void>::type
-  operator()(Func&& f) {
-    static_assert(
-        black_magic::CallHelper<Func, black_magic::S<Args...>>::value ||
-            black_magic::CallHelper<
+    template <typename Func>
+    typename std::enable_if<
+        !black_magic::CallHelper<Func, black_magic::S<Args...>>::value &&
+            !black_magic::CallHelper<
                 Func, black_magic::S<crow::Request, Args...>>::value,
-        "Handler type is mismatched with URL parameters");
-    static_assert(
-        !std::is_same<void, decltype(f(std::declval<crow::Request>(),
-                                       std::declval<Args>()...))>::value,
-        "Handler function cannot have void return type; valid return types: "
-        "string, int, crow::resposne,nlohmann::json");
+        void>::type
+        operator()(Func&& f)
+    {
+        static_assert(
+            black_magic::CallHelper<Func, black_magic::S<Args...>>::value ||
+                black_magic::CallHelper<
+                    Func, black_magic::S<crow::Request, Args...>>::value ||
+                black_magic::CallHelper<
+                    Func, black_magic::S<crow::Request, crow::Response&,
+                                         Args...>>::value,
+            "Handler type is mismatched with URL parameters");
+        static_assert(
+            std::is_same<void, decltype(f(std::declval<crow::Request>(),
+                                          std::declval<crow::Response&>(),
+                                          std::declval<Args>()...))>::value,
+            "Handler function with response argument should have void return "
+            "type");
 
-    handler = [f = std::move(f)](const crow::Request& req, crow::Response& res,
-                                 Args... args) {
-      res = Response(f(req, args...));
-      res.end();
-    };
-  }
+        handler = std::move(f);
+    }
 
-  template <typename Func>
-  typename std::enable_if<
-      !black_magic::CallHelper<Func, black_magic::S<Args...>>::value &&
-          !black_magic::CallHelper<
-              Func, black_magic::S<crow::Request, Args...>>::value,
-      void>::type
-  operator()(Func&& f) {
-    static_assert(
-        black_magic::CallHelper<Func, black_magic::S<Args...>>::value ||
-            black_magic::CallHelper<
-                Func, black_magic::S<crow::Request, Args...>>::value ||
-            black_magic::CallHelper<
-                Func,
-                black_magic::S<crow::Request, crow::Response&, Args...>>::value,
-        "Handler type is mismatched with URL parameters");
-    static_assert(
-        std::is_same<void, decltype(f(std::declval<crow::Request>(),
-                                      std::declval<crow::Response&>(),
-                                      std::declval<Args>()...))>::value,
-        "Handler function with response argument should have void return type");
+    template <typename Func> void operator()(std::string name, Func&& f)
+    {
+        nameStr = std::move(name);
+        (*this).template operator()<Func>(std::forward(f));
+    }
 
-    handler = std::move(f);
-  }
+    void handle(const Request& req, Response& res,
+                const RoutingParams& params) override
+    {
+        detail::routing_handler_call_helper::Call<
+            detail::routing_handler_call_helper::CallParams<decltype(handler)>,
+            0, 0, 0, 0, black_magic::S<Args...>, black_magic::S<>>()(
+            detail::routing_handler_call_helper::CallParams<decltype(handler)>{
+                handler, params, req, res});
+    }
 
-  template <typename Func>
-  void operator()(std::string name, Func&& f) {
-    nameStr = std::move(name);
-    (*this).template operator()<Func>(std::forward(f));
-  }
-
-  void handle(const Request& req, Response& res,
-              const RoutingParams& params) override {
-    detail::routing_handler_call_helper::Call<
-        detail::routing_handler_call_helper::CallParams<decltype(handler)>, 0,
-        0, 0, 0, black_magic::S<Args...>, black_magic::S<>>()(
-        detail::routing_handler_call_helper::CallParams<decltype(handler)>{
-            handler, params, req, res});
-  }
-
- private:
-  std::function<void(const crow::Request&, crow::Response&, Args...)> handler;
+  private:
+    std::function<void(const crow::Request&, crow::Response&, Args...)> handler;
 };
 
 const int ruleSpecialRedirectSlash = 1;
 
-class Trie {
- public:
-  struct Node {
-    unsigned ruleIndex{};
-    std::array<unsigned, (int)ParamType::MAX> paramChildrens{};
-    boost::container::flat_map<std::string, unsigned> children;
+class Trie
+{
+  public:
+    struct Node
+    {
+        unsigned ruleIndex{};
+        std::array<unsigned, (int)ParamType::MAX> paramChildrens{};
+        boost::container::flat_map<std::string, unsigned> children;
 
-    bool isSimpleNode() const {
-      return !ruleIndex &&
-             std::all_of(std::begin(paramChildrens), std::end(paramChildrens),
-                         [](unsigned x) { return !x; });
-    }
-  };
-
-  Trie() : nodes(1) {}
-
- private:
-  void optimizeNode(Node* node) {
-    for (auto x : node->paramChildrens) {
-      if (!x) continue;
-      Node* child = &nodes[x];
-      optimizeNode(child);
-    }
-    if (node->children.empty()) return;
-    bool mergeWithChild = true;
-    for (auto& kv : node->children) {
-      Node* child = &nodes[kv.second];
-      if (!child->isSimpleNode()) {
-        mergeWithChild = false;
-        break;
-      }
-    }
-    if (mergeWithChild) {
-      decltype(node->children) merged;
-      for (auto& kv : node->children) {
-        Node* child = &nodes[kv.second];
-        for (auto& childKv : child->children) {
-          merged[kv.first + childKv.first] = childKv.second;
+        bool isSimpleNode() const
+        {
+            return !ruleIndex && std::all_of(std::begin(paramChildrens),
+                                             std::end(paramChildrens),
+                                             [](unsigned x) { return !x; });
         }
-      }
-      node->children = std::move(merged);
-      optimizeNode(node);
-    } else {
-      for (auto& kv : node->children) {
-        Node* child = &nodes[kv.second];
-        optimizeNode(child);
-      }
-    }
-  }
-
-  void optimize() { optimizeNode(head()); }
-
- public:
-  void validate() {
-    if (!head()->isSimpleNode())
-      throw std::runtime_error("Internal error: Trie header should be simple!");
-    optimize();
-  }
-
-  void findRouteIndexes(const std::string& req_url,
-                        std::vector<unsigned>& route_indexes,
-                        const Node* node = nullptr, unsigned pos = 0) {
-    if (node == nullptr) {
-      node = head();
-    }
-    for (auto& kv : node->children) {
-      const std::string& fragment = kv.first;
-      const Node* child = &nodes[kv.second];
-      if (pos >= req_url.size()) {
-        if (child->ruleIndex != 0 && fragment != "/") {
-          route_indexes.push_back(child->ruleIndex);
-        }
-        findRouteIndexes(req_url, route_indexes, child, pos + fragment.size());
-      } else {
-        if (req_url.compare(pos, fragment.size(), fragment) == 0) {
-          findRouteIndexes(req_url, route_indexes, child,
-                           pos + fragment.size());
-        }
-      }
-    }
-  }
-
-  std::pair<unsigned, RoutingParams> find(
-      const boost::string_view req_url, const Node* node = nullptr,
-      unsigned pos = 0, RoutingParams* params = nullptr) const {
-    RoutingParams empty;
-    if (params == nullptr) params = &empty;
-
-    unsigned found{};
-    RoutingParams matchParams;
-
-    if (node == nullptr) node = head();
-    if (pos == req_url.size()) return {node->ruleIndex, *params};
-
-    auto updateFound = [&found,
-                        &matchParams](std::pair<unsigned, RoutingParams>& ret) {
-      if (ret.first && (!found || found > ret.first)) {
-        found = ret.first;
-        matchParams = std::move(ret.second);
-      }
     };
 
-    if (node->paramChildrens[(int)ParamType::INT]) {
-      char c = req_url[pos];
-      if ((c >= '0' && c <= '9') || c == '+' || c == '-') {
-        char* eptr;
-        errno = 0;
-        long long int value = std::strtoll(req_url.data() + pos, &eptr, 10);
-        if (errno != ERANGE && eptr != req_url.data() + pos) {
-          params->intParams.push_back(value);
-          auto ret =
-              find(req_url, &nodes[node->paramChildrens[(int)ParamType::INT]],
-                   eptr - req_url.data(), params);
-          updateFound(ret);
-          params->intParams.pop_back();
+    Trie() : nodes(1)
+    {
+    }
+
+  private:
+    void optimizeNode(Node* node)
+    {
+        for (auto x : node->paramChildrens)
+        {
+            if (!x)
+                continue;
+            Node* child = &nodes[x];
+            optimizeNode(child);
         }
-      }
-    }
-
-    if (node->paramChildrens[(int)ParamType::UINT]) {
-      char c = req_url[pos];
-      if ((c >= '0' && c <= '9') || c == '+') {
-        char* eptr;
-        errno = 0;
-        unsigned long long int value =
-            std::strtoull(req_url.data() + pos, &eptr, 10);
-        if (errno != ERANGE && eptr != req_url.data() + pos) {
-          params->uintParams.push_back(value);
-          auto ret =
-              find(req_url, &nodes[node->paramChildrens[(int)ParamType::UINT]],
-                   eptr - req_url.data(), params);
-          updateFound(ret);
-          params->uintParams.pop_back();
-        }
-      }
-    }
-
-    if (node->paramChildrens[(int)ParamType::DOUBLE]) {
-      char c = req_url[pos];
-      if ((c >= '0' && c <= '9') || c == '+' || c == '-' || c == '.') {
-        char* eptr;
-        errno = 0;
-        double value = std::strtod(req_url.data() + pos, &eptr);
-        if (errno != ERANGE && eptr != req_url.data() + pos) {
-          params->doubleParams.push_back(value);
-          auto ret = find(req_url,
-                          &nodes[node->paramChildrens[(int)ParamType::DOUBLE]],
-                          eptr - req_url.data(), params);
-          updateFound(ret);
-          params->doubleParams.pop_back();
-        }
-      }
-    }
-
-    if (node->paramChildrens[(int)ParamType::STRING]) {
-      size_t epos = pos;
-      for (; epos < req_url.size(); epos++) {
-        if (req_url[epos] == '/') break;
-      }
-
-      if (epos != pos) {
-        params->stringParams.emplace_back(req_url.substr(pos, epos - pos));
-        auto ret =
-            find(req_url, &nodes[node->paramChildrens[(int)ParamType::STRING]],
-                 epos, params);
-        updateFound(ret);
-        params->stringParams.pop_back();
-      }
-    }
-
-    if (node->paramChildrens[(int)ParamType::PATH]) {
-      size_t epos = req_url.size();
-
-      if (epos != pos) {
-        params->stringParams.emplace_back(req_url.substr(pos, epos - pos));
-        auto ret =
-            find(req_url, &nodes[node->paramChildrens[(int)ParamType::PATH]],
-                 epos, params);
-        updateFound(ret);
-        params->stringParams.pop_back();
-      }
-    }
-
-    for (auto& kv : node->children) {
-      const std::string& fragment = kv.first;
-      const Node* child = &nodes[kv.second];
-
-      if (req_url.compare(pos, fragment.size(), fragment) == 0) {
-        auto ret = find(req_url, child, pos + fragment.size(), params);
-        updateFound(ret);
-      }
-    }
-
-    return {found, matchParams};
-  }
-
-  void add(const std::string& url, unsigned ruleIndex) {
-    unsigned idx{0};
-
-    for (unsigned i = 0; i < url.size(); i++) {
-      char c = url[i];
-      if (c == '<') {
-        static struct ParamTraits {
-          ParamType type;
-          std::string name;
-        } paramTraits[] = {
-            {ParamType::INT, "<int>"},      {ParamType::UINT, "<uint>"},
-            {ParamType::DOUBLE, "<float>"}, {ParamType::DOUBLE, "<double>"},
-            {ParamType::STRING, "<str>"},   {ParamType::STRING, "<string>"},
-            {ParamType::PATH, "<path>"},
-        };
-
-        for (auto& x : paramTraits) {
-          if (url.compare(i, x.name.size(), x.name) == 0) {
-            if (!nodes[idx].paramChildrens[(int)x.type]) {
-              auto newNodeIdx = newNode();
-              nodes[idx].paramChildrens[(int)x.type] = newNodeIdx;
+        if (node->children.empty())
+            return;
+        bool mergeWithChild = true;
+        for (auto& kv : node->children)
+        {
+            Node* child = &nodes[kv.second];
+            if (!child->isSimpleNode())
+            {
+                mergeWithChild = false;
+                break;
             }
-            idx = nodes[idx].paramChildrens[(int)x.type];
-            i += x.name.size();
-            break;
-          }
+        }
+        if (mergeWithChild)
+        {
+            decltype(node->children) merged;
+            for (auto& kv : node->children)
+            {
+                Node* child = &nodes[kv.second];
+                for (auto& childKv : child->children)
+                {
+                    merged[kv.first + childKv.first] = childKv.second;
+                }
+            }
+            node->children = std::move(merged);
+            optimizeNode(node);
+        }
+        else
+        {
+            for (auto& kv : node->children)
+            {
+                Node* child = &nodes[kv.second];
+                optimizeNode(child);
+            }
+        }
+    }
+
+    void optimize()
+    {
+        optimizeNode(head());
+    }
+
+  public:
+    void validate()
+    {
+        if (!head()->isSimpleNode())
+            throw std::runtime_error(
+                "Internal error: Trie header should be simple!");
+        optimize();
+    }
+
+    void findRouteIndexes(const std::string& req_url,
+                          std::vector<unsigned>& route_indexes,
+                          const Node* node = nullptr, unsigned pos = 0)
+    {
+        if (node == nullptr)
+        {
+            node = head();
+        }
+        for (auto& kv : node->children)
+        {
+            const std::string& fragment = kv.first;
+            const Node* child = &nodes[kv.second];
+            if (pos >= req_url.size())
+            {
+                if (child->ruleIndex != 0 && fragment != "/")
+                {
+                    route_indexes.push_back(child->ruleIndex);
+                }
+                findRouteIndexes(req_url, route_indexes, child,
+                                 pos + fragment.size());
+            }
+            else
+            {
+                if (req_url.compare(pos, fragment.size(), fragment) == 0)
+                {
+                    findRouteIndexes(req_url, route_indexes, child,
+                                     pos + fragment.size());
+                }
+            }
+        }
+    }
+
+    std::pair<unsigned, RoutingParams>
+        find(const boost::string_view req_url, const Node* node = nullptr,
+             unsigned pos = 0, RoutingParams* params = nullptr) const
+    {
+        RoutingParams empty;
+        if (params == nullptr)
+            params = &empty;
+
+        unsigned found{};
+        RoutingParams matchParams;
+
+        if (node == nullptr)
+            node = head();
+        if (pos == req_url.size())
+            return {node->ruleIndex, *params};
+
+        auto updateFound =
+            [&found, &matchParams](std::pair<unsigned, RoutingParams>& ret) {
+                if (ret.first && (!found || found > ret.first))
+                {
+                    found = ret.first;
+                    matchParams = std::move(ret.second);
+                }
+            };
+
+        if (node->paramChildrens[(int)ParamType::INT])
+        {
+            char c = req_url[pos];
+            if ((c >= '0' && c <= '9') || c == '+' || c == '-')
+            {
+                char* eptr;
+                errno = 0;
+                long long int value =
+                    std::strtoll(req_url.data() + pos, &eptr, 10);
+                if (errno != ERANGE && eptr != req_url.data() + pos)
+                {
+                    params->intParams.push_back(value);
+                    auto ret =
+                        find(req_url,
+                             &nodes[node->paramChildrens[(int)ParamType::INT]],
+                             eptr - req_url.data(), params);
+                    updateFound(ret);
+                    params->intParams.pop_back();
+                }
+            }
         }
 
-        i--;
-      } else {
-        std::string piece(&c, 1);
-        if (!nodes[idx].children.count(piece)) {
-          auto newNodeIdx = newNode();
-          nodes[idx].children.emplace(piece, newNodeIdx);
-        }
-        idx = nodes[idx].children[piece];
-      }
-    }
-    if (nodes[idx].ruleIndex)
-      throw std::runtime_error("handler already exists for " + url);
-    nodes[idx].ruleIndex = ruleIndex;
-  }
-
- private:
-  void debugNodePrint(Node* n, int level) {
-    for (int i = 0; i < (int)ParamType::MAX; i++) {
-      if (n->paramChildrens[i]) {
-        BMCWEB_LOG_DEBUG << std::string(
-            2 * level, ' ') /*<< "("<<n->paramChildrens[i]<<") "*/;
-        switch ((ParamType)i) {
-          case ParamType::INT:
-            BMCWEB_LOG_DEBUG << "<int>";
-            break;
-          case ParamType::UINT:
-            BMCWEB_LOG_DEBUG << "<uint>";
-            break;
-          case ParamType::DOUBLE:
-            BMCWEB_LOG_DEBUG << "<float>";
-            break;
-          case ParamType::STRING:
-            BMCWEB_LOG_DEBUG << "<str>";
-            break;
-          case ParamType::PATH:
-            BMCWEB_LOG_DEBUG << "<path>";
-            break;
-          default:
-            BMCWEB_LOG_DEBUG << "<ERROR>";
-            break;
+        if (node->paramChildrens[(int)ParamType::UINT])
+        {
+            char c = req_url[pos];
+            if ((c >= '0' && c <= '9') || c == '+')
+            {
+                char* eptr;
+                errno = 0;
+                unsigned long long int value =
+                    std::strtoull(req_url.data() + pos, &eptr, 10);
+                if (errno != ERANGE && eptr != req_url.data() + pos)
+                {
+                    params->uintParams.push_back(value);
+                    auto ret =
+                        find(req_url,
+                             &nodes[node->paramChildrens[(int)ParamType::UINT]],
+                             eptr - req_url.data(), params);
+                    updateFound(ret);
+                    params->uintParams.pop_back();
+                }
+            }
         }
 
-        debugNodePrint(&nodes[n->paramChildrens[i]], level + 1);
-      }
+        if (node->paramChildrens[(int)ParamType::DOUBLE])
+        {
+            char c = req_url[pos];
+            if ((c >= '0' && c <= '9') || c == '+' || c == '-' || c == '.')
+            {
+                char* eptr;
+                errno = 0;
+                double value = std::strtod(req_url.data() + pos, &eptr);
+                if (errno != ERANGE && eptr != req_url.data() + pos)
+                {
+                    params->doubleParams.push_back(value);
+                    auto ret = find(
+                        req_url,
+                        &nodes[node->paramChildrens[(int)ParamType::DOUBLE]],
+                        eptr - req_url.data(), params);
+                    updateFound(ret);
+                    params->doubleParams.pop_back();
+                }
+            }
+        }
+
+        if (node->paramChildrens[(int)ParamType::STRING])
+        {
+            size_t epos = pos;
+            for (; epos < req_url.size(); epos++)
+            {
+                if (req_url[epos] == '/')
+                    break;
+            }
+
+            if (epos != pos)
+            {
+                params->stringParams.emplace_back(
+                    req_url.substr(pos, epos - pos));
+                auto ret =
+                    find(req_url,
+                         &nodes[node->paramChildrens[(int)ParamType::STRING]],
+                         epos, params);
+                updateFound(ret);
+                params->stringParams.pop_back();
+            }
+        }
+
+        if (node->paramChildrens[(int)ParamType::PATH])
+        {
+            size_t epos = req_url.size();
+
+            if (epos != pos)
+            {
+                params->stringParams.emplace_back(
+                    req_url.substr(pos, epos - pos));
+                auto ret = find(
+                    req_url, &nodes[node->paramChildrens[(int)ParamType::PATH]],
+                    epos, params);
+                updateFound(ret);
+                params->stringParams.pop_back();
+            }
+        }
+
+        for (auto& kv : node->children)
+        {
+            const std::string& fragment = kv.first;
+            const Node* child = &nodes[kv.second];
+
+            if (req_url.compare(pos, fragment.size(), fragment) == 0)
+            {
+                auto ret = find(req_url, child, pos + fragment.size(), params);
+                updateFound(ret);
+            }
+        }
+
+        return {found, matchParams};
     }
-    for (auto& kv : n->children) {
-      BMCWEB_LOG_DEBUG << std::string(2 * level,
-                                      ' ') /*<< "(" << kv.second << ") "*/
-                       << kv.first;
-      debugNodePrint(&nodes[kv.second], level + 1);
+
+    void add(const std::string& url, unsigned ruleIndex)
+    {
+        unsigned idx{0};
+
+        for (unsigned i = 0; i < url.size(); i++)
+        {
+            char c = url[i];
+            if (c == '<')
+            {
+                static struct ParamTraits
+                {
+                    ParamType type;
+                    std::string name;
+                } paramTraits[] = {
+                    {ParamType::INT, "<int>"},
+                    {ParamType::UINT, "<uint>"},
+                    {ParamType::DOUBLE, "<float>"},
+                    {ParamType::DOUBLE, "<double>"},
+                    {ParamType::STRING, "<str>"},
+                    {ParamType::STRING, "<string>"},
+                    {ParamType::PATH, "<path>"},
+                };
+
+                for (auto& x : paramTraits)
+                {
+                    if (url.compare(i, x.name.size(), x.name) == 0)
+                    {
+                        if (!nodes[idx].paramChildrens[(int)x.type])
+                        {
+                            auto newNodeIdx = newNode();
+                            nodes[idx].paramChildrens[(int)x.type] = newNodeIdx;
+                        }
+                        idx = nodes[idx].paramChildrens[(int)x.type];
+                        i += x.name.size();
+                        break;
+                    }
+                }
+
+                i--;
+            }
+            else
+            {
+                std::string piece(&c, 1);
+                if (!nodes[idx].children.count(piece))
+                {
+                    auto newNodeIdx = newNode();
+                    nodes[idx].children.emplace(piece, newNodeIdx);
+                }
+                idx = nodes[idx].children[piece];
+            }
+        }
+        if (nodes[idx].ruleIndex)
+            throw std::runtime_error("handler already exists for " + url);
+        nodes[idx].ruleIndex = ruleIndex;
     }
-  }
 
- public:
-  void debugPrint() { debugNodePrint(head(), 0); }
+  private:
+    void debugNodePrint(Node* n, int level)
+    {
+        for (int i = 0; i < (int)ParamType::MAX; i++)
+        {
+            if (n->paramChildrens[i])
+            {
+                BMCWEB_LOG_DEBUG << std::string(
+                    2 * level, ' ') /*<< "("<<n->paramChildrens[i]<<") "*/;
+                switch ((ParamType)i)
+                {
+                    case ParamType::INT:
+                        BMCWEB_LOG_DEBUG << "<int>";
+                        break;
+                    case ParamType::UINT:
+                        BMCWEB_LOG_DEBUG << "<uint>";
+                        break;
+                    case ParamType::DOUBLE:
+                        BMCWEB_LOG_DEBUG << "<float>";
+                        break;
+                    case ParamType::STRING:
+                        BMCWEB_LOG_DEBUG << "<str>";
+                        break;
+                    case ParamType::PATH:
+                        BMCWEB_LOG_DEBUG << "<path>";
+                        break;
+                    default:
+                        BMCWEB_LOG_DEBUG << "<ERROR>";
+                        break;
+                }
 
- private:
-  const Node* head() const { return &nodes.front(); }
+                debugNodePrint(&nodes[n->paramChildrens[i]], level + 1);
+            }
+        }
+        for (auto& kv : n->children)
+        {
+            BMCWEB_LOG_DEBUG
+                << std::string(2 * level, ' ') /*<< "(" << kv.second << ") "*/
+                << kv.first;
+            debugNodePrint(&nodes[kv.second], level + 1);
+        }
+    }
 
-  Node* head() { return &nodes.front(); }
+  public:
+    void debugPrint()
+    {
+        debugNodePrint(head(), 0);
+    }
 
-  unsigned newNode() {
-    nodes.resize(nodes.size() + 1);
-    return nodes.size() - 1;
-  }
+  private:
+    const Node* head() const
+    {
+        return &nodes.front();
+    }
 
-  std::vector<Node> nodes;
+    Node* head()
+    {
+        return &nodes.front();
+    }
+
+    unsigned newNode()
+    {
+        nodes.resize(nodes.size() + 1);
+        return nodes.size() - 1;
+    }
+
+    std::vector<Node> nodes;
 };
 
-class Router {
- public:
-  Router() : rules(2) {}
-
-  DynamicRule& newRuleDynamic(const std::string& rule) {
-    std::unique_ptr<DynamicRule> ruleObject =
-        std::make_unique<DynamicRule>(rule);
-    DynamicRule* ptr = ruleObject.get();
-    internalAddRuleObject(rule, std::move(ruleObject));
-
-    return *ptr;
-  }
-
-  template <uint64_t N>
-  typename black_magic::Arguments<N>::type::template rebind<TaggedRule>&
-  newRuleTagged(const std::string& rule) {
-    using RuleT =
-        typename black_magic::Arguments<N>::type::template rebind<TaggedRule>;
-    std::unique_ptr<RuleT> ruleObject = std::make_unique<RuleT>(rule);
-    RuleT* ptr = ruleObject.get();
-
-    internalAddRuleObject(rule, std::move(ruleObject));
-
-    return *ptr;
-  }
-
-  void internalAddRuleObject(const std::string& rule,
-                             std::unique_ptr<BaseRule> ruleObject) {
-    rules.emplace_back(std::move(ruleObject));
-    trie.add(rule, rules.size() - 1);
-
-    // directory case:
-    //   request to `/about' url matches `/about/' rule
-    if (rule.size() > 2 && rule.back() == '/') {
-      trie.add(rule.substr(0, rule.size() - 1), rules.size() - 1);
-    }
-  }
-
-  void validate() {
-    trie.validate();
-    for (auto& rule : rules) {
-      if (rule) {
-        auto upgraded = rule->upgrade();
-        if (upgraded) rule = std::move(upgraded);
-        rule->validate();
-      }
-    }
-  }
-
-  template <typename Adaptor>
-  void handleUpgrade(const Request& req, Response& res, Adaptor&& adaptor) {
-    auto found = trie.find(req.url);
-    unsigned ruleIndex = found.first;
-    if (!ruleIndex) {
-      BMCWEB_LOG_DEBUG << "Cannot match rules " << req.url;
-      res = Response(boost::beast::http::status::not_found);
-      res.end();
-      return;
+class Router
+{
+  public:
+    Router() : rules(2)
+    {
     }
 
-    if (ruleIndex >= rules.size())
-      throw std::runtime_error("Trie internal structure corrupted!");
+    DynamicRule& newRuleDynamic(const std::string& rule)
+    {
+        std::unique_ptr<DynamicRule> ruleObject =
+            std::make_unique<DynamicRule>(rule);
+        DynamicRule* ptr = ruleObject.get();
+        internalAddRuleObject(rule, std::move(ruleObject));
 
-    if (ruleIndex == ruleSpecialRedirectSlash) {
-      BMCWEB_LOG_INFO << "Redirecting to a url with trailing slash: "
-                      << req.url;
-      res = Response(boost::beast::http::status::moved_permanently);
-
-      // TODO absolute url building
-      if (req.getHeaderValue("Host").empty()) {
-        res.addHeader("Location", std::string(req.url) + "/");
-      } else {
-        res.addHeader(
-            "Location",
-            req.isSecure ? "https://"
-                         : "http://" + std::string(req.getHeaderValue("Host")) +
-                               std::string(req.url) + "/");
-      }
-      res.end();
-      return;
+        return *ptr;
     }
 
-    if ((rules[ruleIndex]->getMethods() & (1 << (uint32_t)req.method())) == 0) {
-      BMCWEB_LOG_DEBUG << "Rule found but method mismatch: " << req.url
-                       << " with " << req.methodString() << "("
-                       << (uint32_t)req.method() << ") / "
-                       << rules[ruleIndex]->getMethods();
-      res = Response(boost::beast::http::status::not_found);
-      res.end();
-      return;
+    template <uint64_t N>
+    typename black_magic::Arguments<N>::type::template rebind<TaggedRule>&
+        newRuleTagged(const std::string& rule)
+    {
+        using RuleT = typename black_magic::Arguments<N>::type::template rebind<
+            TaggedRule>;
+        std::unique_ptr<RuleT> ruleObject = std::make_unique<RuleT>(rule);
+        RuleT* ptr = ruleObject.get();
+
+        internalAddRuleObject(rule, std::move(ruleObject));
+
+        return *ptr;
     }
 
-    BMCWEB_LOG_DEBUG << "Matched rule (upgrade) '" << rules[ruleIndex]->rule
-                     << "' " << (uint32_t)req.method() << " / "
-                     << rules[ruleIndex]->getMethods();
+    void internalAddRuleObject(const std::string& rule,
+                               std::unique_ptr<BaseRule> ruleObject)
+    {
+        rules.emplace_back(std::move(ruleObject));
+        trie.add(rule, rules.size() - 1);
 
-    // any uncaught exceptions become 500s
-    try {
-      rules[ruleIndex]->handleUpgrade(req, res, std::move(adaptor));
-    } catch (std::exception& e) {
-      BMCWEB_LOG_ERROR << "An uncaught exception occurred: " << e.what();
-      res = Response(boost::beast::http::status::internal_server_error);
-      res.end();
-      return;
-    } catch (...) {
-      BMCWEB_LOG_ERROR
-          << "An uncaught exception occurred. The type was unknown "
-             "so no information was available.";
-      res = Response(boost::beast::http::status::internal_server_error);
-      res.end();
-      return;
-    }
-  }
-
-  void handle(const Request& req, Response& res) {
-    auto found = trie.find(req.url);
-
-    unsigned ruleIndex = found.first;
-
-    if (!ruleIndex) {
-      BMCWEB_LOG_DEBUG << "Cannot match rules " << req.url;
-      res.result(boost::beast::http::status::not_found);
-      res.end();
-      return;
+        // directory case:
+        //   request to `/about' url matches `/about/' rule
+        if (rule.size() > 2 && rule.back() == '/')
+        {
+            trie.add(rule.substr(0, rule.size() - 1), rules.size() - 1);
+        }
     }
 
-    if (ruleIndex >= rules.size())
-      throw std::runtime_error("Trie internal structure corrupted!");
-
-    if (ruleIndex == ruleSpecialRedirectSlash) {
-      BMCWEB_LOG_INFO << "Redirecting to a url with trailing slash: "
-                      << req.url;
-      res = Response(boost::beast::http::status::moved_permanently);
-
-      // TODO absolute url building
-      if (req.getHeaderValue("Host").empty()) {
-        res.addHeader("Location", std::string(req.url) + "/");
-      } else {
-        res.addHeader("Location", (req.isSecure ? "https://" : "http://") +
-                                      std::string(req.getHeaderValue("Host")) +
-                                      std::string(req.url) + "/");
-      }
-      res.end();
-      return;
+    void validate()
+    {
+        trie.validate();
+        for (auto& rule : rules)
+        {
+            if (rule)
+            {
+                auto upgraded = rule->upgrade();
+                if (upgraded)
+                    rule = std::move(upgraded);
+                rule->validate();
+            }
+        }
     }
 
-    if ((rules[ruleIndex]->getMethods() & (1 << (uint32_t)req.method())) == 0) {
-      BMCWEB_LOG_DEBUG << "Rule found but method mismatch: " << req.url
-                       << " with " << req.methodString() << "("
-                       << (uint32_t)req.method() << ") / "
-                       << rules[ruleIndex]->getMethods();
-      res = Response(boost::beast::http::status::not_found);
-      res.end();
-      return;
+    template <typename Adaptor>
+    void handleUpgrade(const Request& req, Response& res, Adaptor&& adaptor)
+    {
+        auto found = trie.find(req.url);
+        unsigned ruleIndex = found.first;
+        if (!ruleIndex)
+        {
+            BMCWEB_LOG_DEBUG << "Cannot match rules " << req.url;
+            res = Response(boost::beast::http::status::not_found);
+            res.end();
+            return;
+        }
+
+        if (ruleIndex >= rules.size())
+            throw std::runtime_error("Trie internal structure corrupted!");
+
+        if (ruleIndex == ruleSpecialRedirectSlash)
+        {
+            BMCWEB_LOG_INFO << "Redirecting to a url with trailing slash: "
+                            << req.url;
+            res = Response(boost::beast::http::status::moved_permanently);
+
+            // TODO absolute url building
+            if (req.getHeaderValue("Host").empty())
+            {
+                res.addHeader("Location", std::string(req.url) + "/");
+            }
+            else
+            {
+                res.addHeader(
+                    "Location",
+                    req.isSecure
+                        ? "https://"
+                        : "http://" + std::string(req.getHeaderValue("Host")) +
+                              std::string(req.url) + "/");
+            }
+            res.end();
+            return;
+        }
+
+        if ((rules[ruleIndex]->getMethods() & (1 << (uint32_t)req.method())) ==
+            0)
+        {
+            BMCWEB_LOG_DEBUG << "Rule found but method mismatch: " << req.url
+                             << " with " << req.methodString() << "("
+                             << (uint32_t)req.method() << ") / "
+                             << rules[ruleIndex]->getMethods();
+            res = Response(boost::beast::http::status::not_found);
+            res.end();
+            return;
+        }
+
+        BMCWEB_LOG_DEBUG << "Matched rule (upgrade) '" << rules[ruleIndex]->rule
+                         << "' " << (uint32_t)req.method() << " / "
+                         << rules[ruleIndex]->getMethods();
+
+        // any uncaught exceptions become 500s
+        try
+        {
+            rules[ruleIndex]->handleUpgrade(req, res, std::move(adaptor));
+        }
+        catch (std::exception& e)
+        {
+            BMCWEB_LOG_ERROR << "An uncaught exception occurred: " << e.what();
+            res = Response(boost::beast::http::status::internal_server_error);
+            res.end();
+            return;
+        }
+        catch (...)
+        {
+            BMCWEB_LOG_ERROR
+                << "An uncaught exception occurred. The type was unknown "
+                   "so no information was available.";
+            res = Response(boost::beast::http::status::internal_server_error);
+            res.end();
+            return;
+        }
     }
 
-    BMCWEB_LOG_DEBUG << "Matched rule '" << rules[ruleIndex]->rule << "' "
-                     << (uint32_t)req.method() << " / "
-                     << rules[ruleIndex]->getMethods();
+    void handle(const Request& req, Response& res)
+    {
+        auto found = trie.find(req.url);
 
-    // any uncaught exceptions become 500s
-    try {
-      rules[ruleIndex]->handle(req, res, found.second);
-    } catch (std::exception& e) {
-      BMCWEB_LOG_ERROR << "An uncaught exception occurred: " << e.what();
-      res = Response(boost::beast::http::status::internal_server_error);
-      res.end();
-      return;
-    } catch (...) {
-      BMCWEB_LOG_ERROR
-          << "An uncaught exception occurred. The type was unknown "
-             "so no information was available.";
-      res = Response(boost::beast::http::status::internal_server_error);
-      res.end();
-      return;
+        unsigned ruleIndex = found.first;
+
+        if (!ruleIndex)
+        {
+            BMCWEB_LOG_DEBUG << "Cannot match rules " << req.url;
+            res.result(boost::beast::http::status::not_found);
+            res.end();
+            return;
+        }
+
+        if (ruleIndex >= rules.size())
+            throw std::runtime_error("Trie internal structure corrupted!");
+
+        if (ruleIndex == ruleSpecialRedirectSlash)
+        {
+            BMCWEB_LOG_INFO << "Redirecting to a url with trailing slash: "
+                            << req.url;
+            res = Response(boost::beast::http::status::moved_permanently);
+
+            // TODO absolute url building
+            if (req.getHeaderValue("Host").empty())
+            {
+                res.addHeader("Location", std::string(req.url) + "/");
+            }
+            else
+            {
+                res.addHeader("Location",
+                              (req.isSecure ? "https://" : "http://") +
+                                  std::string(req.getHeaderValue("Host")) +
+                                  std::string(req.url) + "/");
+            }
+            res.end();
+            return;
+        }
+
+        if ((rules[ruleIndex]->getMethods() & (1 << (uint32_t)req.method())) ==
+            0)
+        {
+            BMCWEB_LOG_DEBUG << "Rule found but method mismatch: " << req.url
+                             << " with " << req.methodString() << "("
+                             << (uint32_t)req.method() << ") / "
+                             << rules[ruleIndex]->getMethods();
+            res = Response(boost::beast::http::status::not_found);
+            res.end();
+            return;
+        }
+
+        BMCWEB_LOG_DEBUG << "Matched rule '" << rules[ruleIndex]->rule << "' "
+                         << (uint32_t)req.method() << " / "
+                         << rules[ruleIndex]->getMethods();
+
+        // any uncaught exceptions become 500s
+        try
+        {
+            rules[ruleIndex]->handle(req, res, found.second);
+        }
+        catch (std::exception& e)
+        {
+            BMCWEB_LOG_ERROR << "An uncaught exception occurred: " << e.what();
+            res = Response(boost::beast::http::status::internal_server_error);
+            res.end();
+            return;
+        }
+        catch (...)
+        {
+            BMCWEB_LOG_ERROR
+                << "An uncaught exception occurred. The type was unknown "
+                   "so no information was available.";
+            res = Response(boost::beast::http::status::internal_server_error);
+            res.end();
+            return;
+        }
     }
-  }
 
-  void debugPrint() { trie.debugPrint(); }
-
-  std::vector<const std::string*> getRoutes(const std::string& parent) {
-    std::vector<unsigned> x;
-    std::vector<const std::string*> ret;
-    trie.findRouteIndexes(parent, x);
-    for (unsigned index : x) {
-      ret.push_back(&rules[index]->rule);
+    void debugPrint()
+    {
+        trie.debugPrint();
     }
-    return ret;
-  }
 
- private:
-  std::vector<std::unique_ptr<BaseRule>> rules;
-  Trie trie;
+    std::vector<const std::string*> getRoutes(const std::string& parent)
+    {
+        std::vector<unsigned> x;
+        std::vector<const std::string*> ret;
+        trie.findRouteIndexes(parent, x);
+        for (unsigned index : x)
+        {
+            ret.push_back(&rules[index]->rule);
+        }
+        return ret;
+    }
+
+  private:
+    std::vector<std::unique_ptr<BaseRule>> rules;
+    Trie trie;
 };
-}  // namespace crow
+} // namespace crow
diff --git a/crow/include/crow/socket_adaptors.h b/crow/include/crow/socket_adaptors.h
index 1d43ca2..a47697f 100644
--- a/crow/include/crow/socket_adaptors.h
+++ b/crow/include/crow/socket_adaptors.h
@@ -1,144 +1,200 @@
 #pragma once
-#include "crow/logging.h"
-
 #include <boost/asio.hpp>
 #include <boost/lexical_cast.hpp>
 
+#include "crow/logging.h"
+
 #ifdef BMCWEB_ENABLE_SSL
 #include <boost/asio/ssl.hpp>
 #endif
-namespace crow {
+namespace crow
+{
 using namespace boost;
 using tcp = asio::ip::tcp;
 
-struct SocketAdaptor {
-  using streamType = tcp::socket;
-  using secure = std::false_type;
-  using context = void;
-  SocketAdaptor(boost::asio::io_service& ioService, context* /*unused*/)
-      : socketCls(ioService) {}
-
-  boost::asio::io_service& getIoService() { return socketCls.get_io_service(); }
-
-  tcp::socket& rawSocket() { return socketCls; }
-
-  tcp::socket& socket() { return socketCls; }
-
-  std::string remoteEndpoint() {
-    boost::system::error_code ec;
-    tcp::endpoint ep = socketCls.remote_endpoint(ec);
-    if (ec) {
-      return "";
+struct SocketAdaptor
+{
+    using streamType = tcp::socket;
+    using secure = std::false_type;
+    using context = void;
+    SocketAdaptor(boost::asio::io_service& ioService, context* /*unused*/) :
+        socketCls(ioService)
+    {
     }
-    return boost::lexical_cast<std::string>(ep);
-  }
 
-  bool isOpen() { return socketCls.is_open(); }
+    boost::asio::io_service& getIoService()
+    {
+        return socketCls.get_io_service();
+    }
 
-  void close() { socketCls.close(); }
+    tcp::socket& rawSocket()
+    {
+        return socketCls;
+    }
 
-  template <typename F>
-  void start(F f) {
-    boost::system::error_code ec;
-    f(ec);
-  }
+    tcp::socket& socket()
+    {
+        return socketCls;
+    }
 
-  tcp::socket socketCls;
+    std::string remoteEndpoint()
+    {
+        boost::system::error_code ec;
+        tcp::endpoint ep = socketCls.remote_endpoint(ec);
+        if (ec)
+        {
+            return "";
+        }
+        return boost::lexical_cast<std::string>(ep);
+    }
+
+    bool isOpen()
+    {
+        return socketCls.is_open();
+    }
+
+    void close()
+    {
+        socketCls.close();
+    }
+
+    template <typename F> void start(F f)
+    {
+        boost::system::error_code ec;
+        f(ec);
+    }
+
+    tcp::socket socketCls;
 };
 
-struct TestSocketAdaptor {
-  using secure = std::false_type;
-  using context = void;
-  TestSocketAdaptor(boost::asio::io_service& ioService, context* /*unused*/)
-      : socketCls(ioService) {}
+struct TestSocketAdaptor
+{
+    using secure = std::false_type;
+    using context = void;
+    TestSocketAdaptor(boost::asio::io_service& ioService, context* /*unused*/) :
+        socketCls(ioService)
+    {
+    }
 
-  boost::asio::io_service& getIoService() { return socketCls.get_io_service(); }
+    boost::asio::io_service& getIoService()
+    {
+        return socketCls.get_io_service();
+    }
 
-  tcp::socket& rawSocket() { return socketCls; }
+    tcp::socket& rawSocket()
+    {
+        return socketCls;
+    }
 
-  tcp::socket& socket() { return socketCls; }
+    tcp::socket& socket()
+    {
+        return socketCls;
+    }
 
-  std::string remoteEndpoint() { return "Testhost"; }
+    std::string remoteEndpoint()
+    {
+        return "Testhost";
+    }
 
-  bool isOpen() { return socketCls.is_open(); }
+    bool isOpen()
+    {
+        return socketCls.is_open();
+    }
 
-  void close() { socketCls.close(); }
+    void close()
+    {
+        socketCls.close();
+    }
 
-  template <typename F>
-  void start(F f) {
-    f(boost::system::error_code());
-  }
+    template <typename F> void start(F f)
+    {
+        f(boost::system::error_code());
+    }
 
-  tcp::socket socketCls;
+    tcp::socket socketCls;
 };
 
 #ifdef BMCWEB_ENABLE_SSL
-struct SSLAdaptor {
-  using streamType = boost::asio::ssl::stream<tcp::socket>;
-  using secure = std::true_type;
-  using context = boost::asio::ssl::context;
-  using ssl_socket_t = boost::asio::ssl::stream<tcp::socket>;
-  SSLAdaptor(boost::asio::io_service& ioService, context* ctx)
-      : sslSocket(new ssl_socket_t(ioService, *ctx)) {}
-
-  boost::asio::ssl::stream<tcp::socket>& socket() { return *sslSocket; }
-
-  tcp::socket::lowest_layer_type& rawSocket() {
-    return sslSocket->lowest_layer();
-  }
-
-  std::string remoteEndpoint() {
-    boost::system::error_code ec;
-    tcp::endpoint ep = rawSocket().remote_endpoint(ec);
-    if (ec) {
-      return "";
+struct SSLAdaptor
+{
+    using streamType = boost::asio::ssl::stream<tcp::socket>;
+    using secure = std::true_type;
+    using context = boost::asio::ssl::context;
+    using ssl_socket_t = boost::asio::ssl::stream<tcp::socket>;
+    SSLAdaptor(boost::asio::io_service& ioService, context* ctx) :
+        sslSocket(new ssl_socket_t(ioService, *ctx))
+    {
     }
-    return boost::lexical_cast<std::string>(ep);
-  }
 
-  bool isOpen() {
-    /*TODO(ed) this is a bit of a cheat.
-     There are cases  when running a websocket where sslSocket might have
-    std::move() called on it (to transfer ownership to websocket::Connection)
-    and be empty.  This (and the check on close()) is a cheat to do something
-    sane in this scenario. the correct fix would likely involve changing the
-    http parser to return a specific code meaning "has been upgraded" so that
-    the doRead function knows not to try to close the Connection which would
-    fail, because the adapter is gone.  As is, doRead believes the parse
-    failed, because isOpen now returns False (which could also mean the client
-    disconnected during parse)
-    UPdate: The parser does in fact have an "isUpgrade" method that is
-    intended for exactly this purpose.  Todo is now to make doRead obey the
-    flag appropriately so this code can be changed back.
-    */
-    if (sslSocket != nullptr) {
-      return sslSocket->lowest_layer().is_open();
+    boost::asio::ssl::stream<tcp::socket>& socket()
+    {
+        return *sslSocket;
     }
-    return false;
-  }
 
-  void close() {
-    if (sslSocket == nullptr) {
-      return;
+    tcp::socket::lowest_layer_type& rawSocket()
+    {
+        return sslSocket->lowest_layer();
     }
-    boost::system::error_code ec;
 
-    // Shut it down
-    this->sslSocket->lowest_layer().close();
-  }
+    std::string remoteEndpoint()
+    {
+        boost::system::error_code ec;
+        tcp::endpoint ep = rawSocket().remote_endpoint(ec);
+        if (ec)
+        {
+            return "";
+        }
+        return boost::lexical_cast<std::string>(ep);
+    }
 
-  boost::asio::io_service& getIoService() {
-    return rawSocket().get_io_service();
-  }
+    bool isOpen()
+    {
+        /*TODO(ed) this is a bit of a cheat.
+         There are cases  when running a websocket where sslSocket might have
+        std::move() called on it (to transfer ownership to
+        websocket::Connection) and be empty.  This (and the check on close()) is
+        a cheat to do something sane in this scenario. the correct fix would
+        likely involve changing the http parser to return a specific code
+        meaning "has been upgraded" so that the doRead function knows not to try
+        to close the Connection which would fail, because the adapter is gone.
+        As is, doRead believes the parse failed, because isOpen now returns
+        False (which could also mean the client disconnected during parse)
+        UPdate: The parser does in fact have an "isUpgrade" method that is
+        intended for exactly this purpose.  Todo is now to make doRead obey the
+        flag appropriately so this code can be changed back.
+        */
+        if (sslSocket != nullptr)
+        {
+            return sslSocket->lowest_layer().is_open();
+        }
+        return false;
+    }
 
-  template <typename F>
-  void start(F f) {
-    sslSocket->async_handshake(
-        boost::asio::ssl::stream_base::server,
-        [f](const boost::system::error_code& ec) { f(ec); });
-  }
+    void close()
+    {
+        if (sslSocket == nullptr)
+        {
+            return;
+        }
+        boost::system::error_code ec;
 
-  std::unique_ptr<boost::asio::ssl::stream<tcp::socket>> sslSocket;
+        // Shut it down
+        this->sslSocket->lowest_layer().close();
+    }
+
+    boost::asio::io_service& getIoService()
+    {
+        return rawSocket().get_io_service();
+    }
+
+    template <typename F> void start(F f)
+    {
+        sslSocket->async_handshake(
+            boost::asio::ssl::stream_base::server,
+            [f](const boost::system::error_code& ec) { f(ec); });
+    }
+
+    std::unique_ptr<boost::asio::ssl::stream<tcp::socket>> sslSocket;
 };
 #endif
-}  // namespace crow
+} // namespace crow
diff --git a/crow/include/crow/timer_queue.h b/crow/include/crow/timer_queue.h
index f5bb467..bf1e084 100644
--- a/crow/include/crow/timer_queue.h
+++ b/crow/include/crow/timer_queue.h
@@ -1,63 +1,78 @@
 #pragma once
 
-#include <chrono>
-#include <functional>
-#include "crow/logging.h"
 #include <boost/circular_buffer.hpp>
 #include <boost/circular_buffer/space_optimized.hpp>
+#include <chrono>
+#include <functional>
 
-namespace crow {
-namespace detail {
+#include "crow/logging.h"
+
+namespace crow
+{
+namespace detail
+{
 // fast timer queue for fixed tick value.
-class TimerQueue {
- public:
-  TimerQueue() { dq.set_capacity(100); }
-
-  void cancel(int k) {
-    unsigned int index = static_cast<unsigned int>(k - step);
-    if (index < dq.size()) {
-      dq[index].second = nullptr;
+class TimerQueue
+{
+  public:
+    TimerQueue()
+    {
+        dq.set_capacity(100);
     }
-  }
 
-  int add(std::function<void()> f) {
-    dq.push_back(
-        std::make_pair(std::chrono::steady_clock::now(), std::move(f)));
-    int ret = step + dq.size() - 1;
-
-    BMCWEB_LOG_DEBUG << "timer add inside: " << this << ' ' << ret;
-    return ret;
-  }
-
-  void process() {
-    auto now = std::chrono::steady_clock::now();
-    while (!dq.empty()) {
-      auto& x = dq.front();
-      if (now - x.first < std::chrono::seconds(5)) {
-        break;
-      }
-      if (x.second) {
-        BMCWEB_LOG_DEBUG << "timer call: " << this << ' ' << step;
-        // we know that timer handlers are very simple currenty; call here
-        x.second();
-      }
-      dq.pop_front();
-      step++;
+    void cancel(int k)
+    {
+        unsigned int index = static_cast<unsigned int>(k - step);
+        if (index < dq.size())
+        {
+            dq[index].second = nullptr;
+        }
     }
-  }
 
- private:
-  using storage_type =
-      std::pair<std::chrono::time_point<std::chrono::steady_clock>,
-                std::function<void()>>;
+    int add(std::function<void()> f)
+    {
+        dq.push_back(
+            std::make_pair(std::chrono::steady_clock::now(), std::move(f)));
+        int ret = step + dq.size() - 1;
 
-  boost::circular_buffer_space_optimized<storage_type,
-                                         std::allocator<storage_type>>
-      dq{};
+        BMCWEB_LOG_DEBUG << "timer add inside: " << this << ' ' << ret;
+        return ret;
+    }
 
-  // boost::circular_buffer<storage_type> dq{20};
-  // std::deque<storage_type> dq{};
-  int step{};
+    void process()
+    {
+        auto now = std::chrono::steady_clock::now();
+        while (!dq.empty())
+        {
+            auto& x = dq.front();
+            if (now - x.first < std::chrono::seconds(5))
+            {
+                break;
+            }
+            if (x.second)
+            {
+                BMCWEB_LOG_DEBUG << "timer call: " << this << ' ' << step;
+                // we know that timer handlers are very simple currenty; call
+                // here
+                x.second();
+            }
+            dq.pop_front();
+            step++;
+        }
+    }
+
+  private:
+    using storage_type =
+        std::pair<std::chrono::time_point<std::chrono::steady_clock>,
+                  std::function<void()>>;
+
+    boost::circular_buffer_space_optimized<storage_type,
+                                           std::allocator<storage_type>>
+        dq{};
+
+    // boost::circular_buffer<storage_type> dq{20};
+    // std::deque<storage_type> dq{};
+    int step{};
 };
-}  // namespace detail
-}  // namespace crow
+} // namespace detail
+} // namespace crow
diff --git a/crow/include/crow/utility.h b/crow/include/crow/utility.h
index d2557b0..9d34e71 100644
--- a/crow/include/crow/utility.h
+++ b/crow/include/crow/utility.h
@@ -1,105 +1,136 @@
 #pragma once
 
+#include "nlohmann/json.hpp"
+
+#include <boost/utility/string_view.hpp>
 #include <cstdint>
 #include <cstring>
 #include <functional>
 #include <stdexcept>
 #include <string>
 #include <tuple>
-#include "nlohmann/json.hpp"
-#include <boost/utility/string_view.hpp>
 
-namespace crow {
-namespace black_magic {
-struct OutOfRange {
-  OutOfRange(unsigned /*pos*/, unsigned /*length*/) {}
+namespace crow
+{
+namespace black_magic
+{
+struct OutOfRange
+{
+    OutOfRange(unsigned /*pos*/, unsigned /*length*/)
+    {
+    }
 };
-constexpr unsigned requiresInRange(unsigned i, unsigned len) {
-  return i >= len ? throw OutOfRange(i, len) : i;
+constexpr unsigned requiresInRange(unsigned i, unsigned len)
+{
+    return i >= len ? throw OutOfRange(i, len) : i;
 }
 
-class ConstStr {
-  const char* const beginPtr;
-  unsigned sizeUint;
+class ConstStr
+{
+    const char* const beginPtr;
+    unsigned sizeUint;
 
- public:
-  template <unsigned N>
-  constexpr ConstStr(const char (&arr)[N]) : beginPtr(arr), sizeUint(N - 1) {
-    static_assert(N >= 1, "not a string literal");
-  }
-  constexpr char operator[](unsigned i) const {
-    return requiresInRange(i, sizeUint), beginPtr[i];
-  }
+  public:
+    template <unsigned N>
+    constexpr ConstStr(const char (&arr)[N]) : beginPtr(arr), sizeUint(N - 1)
+    {
+        static_assert(N >= 1, "not a string literal");
+    }
+    constexpr char operator[](unsigned i) const
+    {
+        return requiresInRange(i, sizeUint), beginPtr[i];
+    }
 
-  constexpr operator const char*() const { return beginPtr; }
+    constexpr operator const char*() const
+    {
+        return beginPtr;
+    }
 
-  constexpr const char* begin() const { return beginPtr; }
-  constexpr const char* end() const { return beginPtr + sizeUint; }
+    constexpr const char* begin() const
+    {
+        return beginPtr;
+    }
+    constexpr const char* end() const
+    {
+        return beginPtr + sizeUint;
+    }
 
-  constexpr unsigned size() const { return sizeUint; }
+    constexpr unsigned size() const
+    {
+        return sizeUint;
+    }
 };
 
-constexpr unsigned findClosingTag(ConstStr s, unsigned p) {
-  return s[p] == '>' ? p : findClosingTag(s, p + 1);
+constexpr unsigned findClosingTag(ConstStr s, unsigned p)
+{
+    return s[p] == '>' ? p : findClosingTag(s, p + 1);
 }
 
-constexpr bool isValid(ConstStr s, unsigned i = 0, int f = 0) {
-  return i == s.size()
-             ? f == 0
-             : f < 0 || f >= 2
-                   ? false
-                   : s[i] == '<' ? isValid(s, i + 1, f + 1)
-                                 : s[i] == '>' ? isValid(s, i + 1, f - 1)
-                                               : isValid(s, i + 1, f);
+constexpr bool isValid(ConstStr s, unsigned i = 0, int f = 0)
+{
+    return i == s.size()
+               ? f == 0
+               : f < 0 || f >= 2
+                     ? false
+                     : s[i] == '<' ? isValid(s, i + 1, f + 1)
+                                   : s[i] == '>' ? isValid(s, i + 1, f - 1)
+                                                 : isValid(s, i + 1, f);
 }
 
-constexpr bool isEquP(const char* a, const char* b, unsigned n) {
-  return *a == 0 && *b == 0 && n == 0
-             ? true
-             : (*a == 0 || *b == 0)
-                   ? false
-                   : n == 0 ? true
-                            : *a != *b ? false : isEquP(a + 1, b + 1, n - 1);
+constexpr bool isEquP(const char* a, const char* b, unsigned n)
+{
+    return *a == 0 && *b == 0 && n == 0
+               ? true
+               : (*a == 0 || *b == 0)
+                     ? false
+                     : n == 0 ? true
+                              : *a != *b ? false : isEquP(a + 1, b + 1, n - 1);
 }
 
 constexpr bool isEquN(ConstStr a, unsigned ai, ConstStr b, unsigned bi,
-                      unsigned n) {
-  return ai + n > a.size() || bi + n > b.size()
-             ? false
-             : n == 0 ? true
-                      : a[ai] != b[bi] ? false
-                                       : isEquN(a, ai + 1, b, bi + 1, n - 1);
+                      unsigned n)
+{
+    return ai + n > a.size() || bi + n > b.size()
+               ? false
+               : n == 0 ? true
+                        : a[ai] != b[bi] ? false
+                                         : isEquN(a, ai + 1, b, bi + 1, n - 1);
 }
 
-constexpr bool isInt(ConstStr s, unsigned i) {
-  return isEquN(s, i, "<int>", 0, 5);
+constexpr bool isInt(ConstStr s, unsigned i)
+{
+    return isEquN(s, i, "<int>", 0, 5);
 }
 
-constexpr bool isUint(ConstStr s, unsigned i) {
-  return isEquN(s, i, "<uint>", 0, 6);
+constexpr bool isUint(ConstStr s, unsigned i)
+{
+    return isEquN(s, i, "<uint>", 0, 6);
 }
 
-constexpr bool isFloat(ConstStr s, unsigned i) {
-  return isEquN(s, i, "<float>", 0, 7) || isEquN(s, i, "<double>", 0, 8);
+constexpr bool isFloat(ConstStr s, unsigned i)
+{
+    return isEquN(s, i, "<float>", 0, 7) || isEquN(s, i, "<double>", 0, 8);
 }
 
-constexpr bool isStr(ConstStr s, unsigned i) {
-  return isEquN(s, i, "<str>", 0, 5) || isEquN(s, i, "<string>", 0, 8);
+constexpr bool isStr(ConstStr s, unsigned i)
+{
+    return isEquN(s, i, "<str>", 0, 5) || isEquN(s, i, "<string>", 0, 8);
 }
 
-constexpr bool isPath(ConstStr s, unsigned i) {
-  return isEquN(s, i, "<path>", 0, 6);
+constexpr bool isPath(ConstStr s, unsigned i)
+{
+    return isEquN(s, i, "<path>", 0, 6);
 }
 
-template <typename T>
-struct parameter_tag {
-  static const int value = 0;
+template <typename T> struct parameter_tag
+{
+    static const int value = 0;
 };
-#define BMCWEB_INTERNAL_PARAMETER_TAG(t, i) \
-  template <>                               \
-  struct parameter_tag<t> {                 \
-    static const int value = i;             \
-  }
+#define BMCWEB_INTERNAL_PARAMETER_TAG(t, i)                                    \
+    template <> struct parameter_tag<t>                                        \
+    {                                                                          \
+        static const int value = i;                                            \
+    }
 BMCWEB_INTERNAL_PARAMETER_TAG(int, 1);
 BMCWEB_INTERNAL_PARAMETER_TAG(char, 1);
 BMCWEB_INTERNAL_PARAMETER_TAG(short, 1);
@@ -113,279 +144,290 @@
 BMCWEB_INTERNAL_PARAMETER_TAG(double, 3);
 BMCWEB_INTERNAL_PARAMETER_TAG(std::string, 4);
 #undef BMCWEB_INTERNAL_PARAMETER_TAG
-template <typename... Args>
-struct compute_parameter_tag_from_args_list;
+template <typename... Args> struct compute_parameter_tag_from_args_list;
 
-template <>
-struct compute_parameter_tag_from_args_list<> {
-  static const int value = 0;
+template <> struct compute_parameter_tag_from_args_list<>
+{
+    static const int value = 0;
 };
 
 template <typename Arg, typename... Args>
-struct compute_parameter_tag_from_args_list<Arg, Args...> {
-  static const int subValue =
-      compute_parameter_tag_from_args_list<Args...>::value;
-  static const int value =
-      parameter_tag<typename std::decay<Arg>::type>::value
-          ? subValue * 6 + parameter_tag<typename std::decay<Arg>::type>::value
-          : subValue;
+struct compute_parameter_tag_from_args_list<Arg, Args...>
+{
+    static const int subValue =
+        compute_parameter_tag_from_args_list<Args...>::value;
+    static const int value =
+        parameter_tag<typename std::decay<Arg>::type>::value
+            ? subValue * 6 +
+                  parameter_tag<typename std::decay<Arg>::type>::value
+            : subValue;
 };
 
-static inline bool isParameterTagCompatible(uint64_t a, uint64_t b) {
-  if (a == 0) {
-    return b == 0;
-  }
-  if (b == 0) {
-    return a == 0;
-  }
-  int sa = a % 6;
-  int sb = a % 6;
-  if (sa == 5) {
-    sa = 4;
-  }
-  if (sb == 5) {
-    sb = 4;
-  }
-  if (sa != sb) {
-    return false;
-  }
-  return isParameterTagCompatible(a / 6, b / 6);
+static inline bool isParameterTagCompatible(uint64_t a, uint64_t b)
+{
+    if (a == 0)
+    {
+        return b == 0;
+    }
+    if (b == 0)
+    {
+        return a == 0;
+    }
+    int sa = a % 6;
+    int sb = a % 6;
+    if (sa == 5)
+    {
+        sa = 4;
+    }
+    if (sb == 5)
+    {
+        sb = 4;
+    }
+    if (sa != sb)
+    {
+        return false;
+    }
+    return isParameterTagCompatible(a / 6, b / 6);
 }
 
-static inline unsigned findClosingTagRuntime(const char* s, unsigned p) {
-  return s[p] == 0 ? throw std::runtime_error("unmatched tag <")
-                   : s[p] == '>' ? p : findClosingTagRuntime(s, p + 1);
+static inline unsigned findClosingTagRuntime(const char* s, unsigned p)
+{
+    return s[p] == 0 ? throw std::runtime_error("unmatched tag <")
+                     : s[p] == '>' ? p : findClosingTagRuntime(s, p + 1);
 }
 
-static inline uint64_t getParameterTagRuntime(const char* s, unsigned p = 0) {
-  return s[p] == 0
-             ? 0
-             : s[p] == '<'
-                   ? (std::strncmp(s + p, "<int>", 5) == 0
-                          ? getParameterTagRuntime(
-                                s, findClosingTagRuntime(s, p)) *
-                                    6 +
-                                1
-                          : std::strncmp(s + p, "<uint>", 6) == 0
-                                ? getParameterTagRuntime(
-                                      s, findClosingTagRuntime(s, p)) *
-                                          6 +
-                                      2
-                                : (std::strncmp(s + p, "<float>", 7) == 0 ||
-                                   std::strncmp(s + p, "<double>", 8) == 0)
-                                      ? getParameterTagRuntime(
-                                            s, findClosingTagRuntime(s, p)) *
-                                                6 +
-                                            3
-                                      : (std::strncmp(s + p, "<str>", 5) == 0 ||
-                                         std::strncmp(s + p, "<string>", 8) ==
-                                             0)
-                                            ? getParameterTagRuntime(
-                                                  s,
-                                                  findClosingTagRuntime(s, p)) *
-                                                      6 +
-                                                  4
-                                            : std::strncmp(s + p, "<path>",
-                                                           6) == 0
-                                                  ? getParameterTagRuntime(
-                                                        s,
-                                                        findClosingTagRuntime(
-                                                            s, p)) *
-                                                            6 +
-                                                        5
-                                                  : throw std::runtime_error(
-                                                        "invalid parameter "
-                                                        "type"))
-                   : getParameterTagRuntime(s, p + 1);
+static inline uint64_t getParameterTagRuntime(const char* s, unsigned p = 0)
+{
+    return s[p] == 0
+               ? 0
+               : s[p] == '<'
+                     ? (std::strncmp(s + p, "<int>", 5) == 0
+                            ? getParameterTagRuntime(
+                                  s, findClosingTagRuntime(s, p)) *
+                                      6 +
+                                  1
+                            : std::strncmp(s + p, "<uint>", 6) == 0
+                                  ? getParameterTagRuntime(
+                                        s, findClosingTagRuntime(s, p)) *
+                                            6 +
+                                        2
+                                  : (std::strncmp(s + p, "<float>", 7) == 0 ||
+                                     std::strncmp(s + p, "<double>", 8) == 0)
+                                        ? getParameterTagRuntime(
+                                              s, findClosingTagRuntime(s, p)) *
+                                                  6 +
+                                              3
+                                        : (std::strncmp(s + p, "<str>", 5) ==
+                                               0 ||
+                                           std::strncmp(s + p, "<string>", 8) ==
+                                               0)
+                                              ? getParameterTagRuntime(
+                                                    s, findClosingTagRuntime(
+                                                           s, p)) *
+                                                        6 +
+                                                    4
+                                              : std::strncmp(s + p, "<path>",
+                                                             6) == 0
+                                                    ? getParameterTagRuntime(
+                                                          s,
+                                                          findClosingTagRuntime(
+                                                              s, p)) *
+                                                              6 +
+                                                          5
+                                                    : throw std::runtime_error(
+                                                          "invalid parameter "
+                                                          "type"))
+                     : getParameterTagRuntime(s, p + 1);
 }
 
-constexpr uint64_t get_parameter_tag(ConstStr s, unsigned p = 0) {
-  return p == s.size()
-             ? 0
-             : s[p] == '<'
-                   ? (isInt(s, p)
-                          ? get_parameter_tag(s, findClosingTag(s, p)) * 6 + 1
-                          : isUint(s, p)
-                                ? get_parameter_tag(s, findClosingTag(s, p)) *
-                                          6 +
-                                      2
-                                : isFloat(s, p)
-                                      ? get_parameter_tag(
-                                            s, findClosingTag(s, p)) *
-                                                6 +
-                                            3
-                                      : isStr(s, p)
-                                            ? get_parameter_tag(
-                                                  s, findClosingTag(s, p)) *
-                                                      6 +
-                                                  4
-                                            : isPath(s, p)
-                                                  ? get_parameter_tag(
-                                                        s,
-                                                        findClosingTag(s, p)) *
-                                                            6 +
-                                                        5
-                                                  : throw std::runtime_error(
-                                                        "invalid parameter "
-                                                        "type"))
-                   : get_parameter_tag(s, p + 1);
+constexpr uint64_t get_parameter_tag(ConstStr s, unsigned p = 0)
+{
+    return p == s.size()
+               ? 0
+               : s[p] == '<'
+                     ? (isInt(s, p)
+                            ? get_parameter_tag(s, findClosingTag(s, p)) * 6 + 1
+                            : isUint(s, p)
+                                  ? get_parameter_tag(s, findClosingTag(s, p)) *
+                                            6 +
+                                        2
+                                  : isFloat(s, p)
+                                        ? get_parameter_tag(
+                                              s, findClosingTag(s, p)) *
+                                                  6 +
+                                              3
+                                        : isStr(s, p)
+                                              ? get_parameter_tag(
+                                                    s, findClosingTag(s, p)) *
+                                                        6 +
+                                                    4
+                                              : isPath(s, p)
+                                                    ? get_parameter_tag(
+                                                          s, findClosingTag(
+                                                                 s, p)) *
+                                                              6 +
+                                                          5
+                                                    : throw std::runtime_error(
+                                                          "invalid parameter "
+                                                          "type"))
+                     : get_parameter_tag(s, p + 1);
 }
 
-template <typename... T>
-struct S {
-  template <typename U>
-  using push = S<U, T...>;
-  template <typename U>
-  using push_back = S<T..., U>;
-  template <template <typename... Args> class U>
-  using rebind = U<T...>;
+template <typename... T> struct S
+{
+    template <typename U> using push = S<U, T...>;
+    template <typename U> using push_back = S<T..., U>;
+    template <template <typename... Args> class U> using rebind = U<T...>;
 };
-template <typename F, typename Set>
-struct CallHelper;
-template <typename F, typename... Args>
-struct CallHelper<F, S<Args...>> {
-  template <typename F1, typename... Args1,
-            typename = decltype(std::declval<F1>()(std::declval<Args1>()...))>
-  static char __test(int);
+template <typename F, typename Set> struct CallHelper;
+template <typename F, typename... Args> struct CallHelper<F, S<Args...>>
+{
+    template <typename F1, typename... Args1,
+              typename = decltype(std::declval<F1>()(std::declval<Args1>()...))>
+    static char __test(int);
 
-  template <typename...>
-  static int __test(...);
+    template <typename...> static int __test(...);
 
-  static constexpr bool value = sizeof(__test<F, Args...>(0)) == sizeof(char);
+    static constexpr bool value = sizeof(__test<F, Args...>(0)) == sizeof(char);
 };
 
-template <int N>
-struct SingleTagToType {};
-
-template <>
-struct SingleTagToType<1> {
-  using type = int64_t;
+template <int N> struct SingleTagToType
+{
 };
 
-template <>
-struct SingleTagToType<2> {
-  using type = uint64_t;
+template <> struct SingleTagToType<1>
+{
+    using type = int64_t;
 };
 
-template <>
-struct SingleTagToType<3> {
-  using type = double;
+template <> struct SingleTagToType<2>
+{
+    using type = uint64_t;
 };
 
-template <>
-struct SingleTagToType<4> {
-  using type = std::string;
+template <> struct SingleTagToType<3>
+{
+    using type = double;
 };
 
-template <>
-struct SingleTagToType<5> {
-  using type = std::string;
+template <> struct SingleTagToType<4>
+{
+    using type = std::string;
 };
 
-template <uint64_t Tag>
-struct Arguments {
-  using subarguments = typename Arguments<Tag / 6>::type;
-  using type = typename subarguments::template push<
-      typename SingleTagToType<Tag % 6>::type>;
+template <> struct SingleTagToType<5>
+{
+    using type = std::string;
 };
 
-template <>
-struct Arguments<0> {
-  using type = S<>;
+template <uint64_t Tag> struct Arguments
+{
+    using subarguments = typename Arguments<Tag / 6>::type;
+    using type = typename subarguments::template push<
+        typename SingleTagToType<Tag % 6>::type>;
 };
 
-template <typename... T>
-struct LastElementType {
-  using type =
-      typename std::tuple_element<sizeof...(T) - 1, std::tuple<T...>>::type;
+template <> struct Arguments<0>
+{
+    using type = S<>;
 };
 
-template <>
-struct LastElementType<> {};
+template <typename... T> struct LastElementType
+{
+    using type =
+        typename std::tuple_element<sizeof...(T) - 1, std::tuple<T...>>::type;
+};
+
+template <> struct LastElementType<>
+{
+};
 
 // from
 // http://stackoverflow.com/questions/13072359/c11-compile-time-array-with-logarithmic-evaluation-depth
-template <class T>
-using Invoke = typename T::type;
+template <class T> using Invoke = typename T::type;
 
-template <unsigned...>
-struct Seq {
-  using type = Seq;
+template <unsigned...> struct Seq
+{
+    using type = Seq;
 };
 
-template <class S1, class S2>
-struct concat;
+template <class S1, class S2> struct concat;
 
 template <unsigned... I1, unsigned... I2>
-struct concat<Seq<I1...>, Seq<I2...>> : Seq<I1..., (sizeof...(I1) + I2)...> {};
+struct concat<Seq<I1...>, Seq<I2...>> : Seq<I1..., (sizeof...(I1) + I2)...>
+{
+};
 
-template <class S1, class S2>
-using Concat = Invoke<concat<S1, S2>>;
+template <class S1, class S2> using Concat = Invoke<concat<S1, S2>>;
 
-template <unsigned N>
-struct gen_seq;
-template <unsigned N>
-using GenSeq = Invoke<gen_seq<N>>;
+template <unsigned N> struct gen_seq;
+template <unsigned N> using GenSeq = Invoke<gen_seq<N>>;
 
-template <unsigned N>
-struct gen_seq : Concat<GenSeq<N / 2>, GenSeq<N - N / 2>> {};
+template <unsigned N> struct gen_seq : Concat<GenSeq<N / 2>, GenSeq<N - N / 2>>
+{
+};
 
-template <>
-struct gen_seq<0> : Seq<> {};
-template <>
-struct gen_seq<1> : Seq<0> {};
+template <> struct gen_seq<0> : Seq<>
+{
+};
+template <> struct gen_seq<1> : Seq<0>
+{
+};
 
-template <typename Seq, typename Tuple>
-struct PopBackHelper;
+template <typename Seq, typename Tuple> struct PopBackHelper;
 
-template <unsigned... N, typename Tuple>
-struct PopBackHelper<Seq<N...>, Tuple> {
-  template <template <typename... Args> class U>
-  using rebind = U<typename std::tuple_element<N, Tuple>::type...>;
+template <unsigned... N, typename Tuple> struct PopBackHelper<Seq<N...>, Tuple>
+{
+    template <template <typename... Args> class U>
+    using rebind = U<typename std::tuple_element<N, Tuple>::type...>;
 };
 
 template <typename... T>
-struct PopBack  //: public PopBackHelper<typename
-                // gen_seq<sizeof...(T)-1>::type, std::tuple<T...>>
+struct PopBack //: public PopBackHelper<typename
+               // gen_seq<sizeof...(T)-1>::type, std::tuple<T...>>
 {
-  template <template <typename... Args> class U>
-  using rebind =
-      typename PopBackHelper<typename gen_seq<sizeof...(T) - 1>::type,
-                             std::tuple<T...>>::template rebind<U>;
+    template <template <typename... Args> class U>
+    using rebind =
+        typename PopBackHelper<typename gen_seq<sizeof...(T) - 1>::type,
+                               std::tuple<T...>>::template rebind<U>;
 };
 
-template <>
-struct PopBack<> {
-  template <template <typename... Args> class U>
-  using rebind = U<>;
+template <> struct PopBack<>
+{
+    template <template <typename... Args> class U> using rebind = U<>;
 };
 
 // from
 // http://stackoverflow.com/questions/2118541/check-if-c0x-parameter-pack-contains-a-type
-template <typename Tp, typename... List>
-struct Contains : std::true_type {};
+template <typename Tp, typename... List> struct Contains : std::true_type
+{
+};
 
 template <typename Tp, typename Head, typename... Rest>
 struct Contains<Tp, Head, Rest...>
     : std::conditional<std::is_same<Tp, Head>::value, std::true_type,
-                       Contains<Tp, Rest...>>::type {};
-
-template <typename Tp>
-struct Contains<Tp> : std::false_type {};
-
-template <typename T>
-struct EmptyContext {};
-
-template <typename T>
-struct promote {
-  using type = T;
+                       Contains<Tp, Rest...>>::type
+{
 };
 
-#define BMCWEB_INTERNAL_PROMOTE_TYPE(t1, t2) \
-  template <>                                \
-  struct promote<t1> {                       \
-    using type = t2;                         \
-  }
+template <typename Tp> struct Contains<Tp> : std::false_type
+{
+};
+
+template <typename T> struct EmptyContext
+{
+};
+
+template <typename T> struct promote
+{
+    using type = T;
+};
+
+#define BMCWEB_INTERNAL_PROMOTE_TYPE(t1, t2)                                   \
+    template <> struct promote<t1>                                             \
+    {                                                                          \
+        using type = t2;                                                       \
+    }
 
 BMCWEB_INTERNAL_PROMOTE_TYPE(char, int64_t);
 BMCWEB_INTERNAL_PROMOTE_TYPE(short, int64_t);
@@ -400,204 +442,229 @@
 BMCWEB_INTERNAL_PROMOTE_TYPE(float, double);
 #undef BMCWEB_INTERNAL_PROMOTE_TYPE
 
-template <typename T>
-using promote_t = typename promote<T>::type;
+template <typename T> using promote_t = typename promote<T>::type;
 
-}  // namespace black_magic
+} // namespace black_magic
 
-namespace detail {
+namespace detail
+{
 
 template <class T, std::size_t N, class... Args>
-struct GetIndexOfElementFromTupleByTypeImpl {
-  static constexpr auto value = N;
+struct GetIndexOfElementFromTupleByTypeImpl
+{
+    static constexpr auto value = N;
 };
 
 template <class T, std::size_t N, class... Args>
-struct GetIndexOfElementFromTupleByTypeImpl<T, N, T, Args...> {
-  static constexpr auto value = N;
+struct GetIndexOfElementFromTupleByTypeImpl<T, N, T, Args...>
+{
+    static constexpr auto value = N;
 };
 
 template <class T, std::size_t N, class U, class... Args>
-struct GetIndexOfElementFromTupleByTypeImpl<T, N, U, Args...> {
-  static constexpr auto value =
-      GetIndexOfElementFromTupleByTypeImpl<T, N + 1, Args...>::value;
+struct GetIndexOfElementFromTupleByTypeImpl<T, N, U, Args...>
+{
+    static constexpr auto value =
+        GetIndexOfElementFromTupleByTypeImpl<T, N + 1, Args...>::value;
 };
 
-}  // namespace detail
+} // namespace detail
 
-namespace utility {
-template <class T, class... Args>
-T& getElementByType(std::tuple<Args...>& t) {
-  return std::get<
-      detail::GetIndexOfElementFromTupleByTypeImpl<T, 0, Args...>::value>(t);
+namespace utility
+{
+template <class T, class... Args> T& getElementByType(std::tuple<Args...>& t)
+{
+    return std::get<
+        detail::GetIndexOfElementFromTupleByTypeImpl<T, 0, Args...>::value>(t);
 }
 
-template <typename T>
-struct function_traits;
+template <typename T> struct function_traits;
 
 template <typename T>
-struct function_traits : public function_traits<decltype(&T::operator())> {
-  using parent_t = function_traits<decltype(&T::operator())>;
-  static const size_t arity = parent_t::arity;
-  using result_type = typename parent_t::result_type;
-  template <size_t i>
-  using arg = typename parent_t::template arg<i>;
+struct function_traits : public function_traits<decltype(&T::operator())>
+{
+    using parent_t = function_traits<decltype(&T::operator())>;
+    static const size_t arity = parent_t::arity;
+    using result_type = typename parent_t::result_type;
+    template <size_t i> using arg = typename parent_t::template arg<i>;
 };
 
 template <typename ClassType, typename r, typename... Args>
-struct function_traits<r (ClassType::*)(Args...) const> {
-  static const size_t arity = sizeof...(Args);
+struct function_traits<r (ClassType::*)(Args...) const>
+{
+    static const size_t arity = sizeof...(Args);
 
-  using result_type = r;
+    using result_type = r;
 
-  template <size_t i>
-  using arg = typename std::tuple_element<i, std::tuple<Args...>>::type;
+    template <size_t i>
+    using arg = typename std::tuple_element<i, std::tuple<Args...>>::type;
 };
 
 template <typename ClassType, typename r, typename... Args>
-struct function_traits<r (ClassType::*)(Args...)> {
-  static const size_t arity = sizeof...(Args);
+struct function_traits<r (ClassType::*)(Args...)>
+{
+    static const size_t arity = sizeof...(Args);
 
-  using result_type = r;
+    using result_type = r;
 
-  template <size_t i>
-  using arg = typename std::tuple_element<i, std::tuple<Args...>>::type;
+    template <size_t i>
+    using arg = typename std::tuple_element<i, std::tuple<Args...>>::type;
 };
 
 template <typename r, typename... Args>
-struct function_traits<std::function<r(Args...)>> {
-  static const size_t arity = sizeof...(Args);
+struct function_traits<std::function<r(Args...)>>
+{
+    static const size_t arity = sizeof...(Args);
 
-  using result_type = r;
+    using result_type = r;
 
-  template <size_t i>
-  using arg = typename std::tuple_element<i, std::tuple<Args...>>::type;
+    template <size_t i>
+    using arg = typename std::tuple_element<i, std::tuple<Args...>>::type;
 };
 
 inline static std::string base64encode(
     const char* data, size_t size,
     const char* key =
-        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/") {
-  std::string ret;
-  ret.resize((size + 2) / 3 * 4);
-  auto it = ret.begin();
-  while (size >= 3) {
-    *it++ = key[(((unsigned char)*data) & 0xFC) >> 2];
-    unsigned char h = (((unsigned char)*data++) & 0x03) << 4;
-    *it++ = key[h | ((((unsigned char)*data) & 0xF0) >> 4)];
-    h = (((unsigned char)*data++) & 0x0F) << 2;
-    *it++ = key[h | ((((unsigned char)*data) & 0xC0) >> 6)];
-    *it++ = key[((unsigned char)*data++) & 0x3F];
+        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")
+{
+    std::string ret;
+    ret.resize((size + 2) / 3 * 4);
+    auto it = ret.begin();
+    while (size >= 3)
+    {
+        *it++ = key[(((unsigned char)*data) & 0xFC) >> 2];
+        unsigned char h = (((unsigned char)*data++) & 0x03) << 4;
+        *it++ = key[h | ((((unsigned char)*data) & 0xF0) >> 4)];
+        h = (((unsigned char)*data++) & 0x0F) << 2;
+        *it++ = key[h | ((((unsigned char)*data) & 0xC0) >> 6)];
+        *it++ = key[((unsigned char)*data++) & 0x3F];
 
-    size -= 3;
-  }
-  if (size == 1) {
-    *it++ = key[(((unsigned char)*data) & 0xFC) >> 2];
-    unsigned char h = (((unsigned char)*data++) & 0x03) << 4;
-    *it++ = key[h];
-    *it++ = '=';
-    *it++ = '=';
-  } else if (size == 2) {
-    *it++ = key[(((unsigned char)*data) & 0xFC) >> 2];
-    unsigned char h = (((unsigned char)*data++) & 0x03) << 4;
-    *it++ = key[h | ((((unsigned char)*data) & 0xF0) >> 4)];
-    h = (((unsigned char)*data++) & 0x0F) << 2;
-    *it++ = key[h];
-    *it++ = '=';
-  }
-  return ret;
+        size -= 3;
+    }
+    if (size == 1)
+    {
+        *it++ = key[(((unsigned char)*data) & 0xFC) >> 2];
+        unsigned char h = (((unsigned char)*data++) & 0x03) << 4;
+        *it++ = key[h];
+        *it++ = '=';
+        *it++ = '=';
+    }
+    else if (size == 2)
+    {
+        *it++ = key[(((unsigned char)*data) & 0xFC) >> 2];
+        unsigned char h = (((unsigned char)*data++) & 0x03) << 4;
+        *it++ = key[h | ((((unsigned char)*data) & 0xF0) >> 4)];
+        h = (((unsigned char)*data++) & 0x0F) << 2;
+        *it++ = key[h];
+        *it++ = '=';
+    }
+    return ret;
 }
 
-inline static std::string base64encodeUrlsafe(const char* data, size_t size) {
-  return base64encode(
-      data, size,
-      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_");
+inline static std::string base64encodeUrlsafe(const char* data, size_t size)
+{
+    return base64encode(
+        data, size,
+        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_");
 }
 
 // TODO this is temporary and should be deleted once base64 is refactored out of
 // crow
-inline bool base64Decode(const boost::string_view input, std::string& output) {
-  static const char nop = -1;
-  // See note on encoding_data[] in above function
-  static const char decodingData[] = {
-      nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
-      nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
-      nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, 62,  nop,
-      nop, nop, 63,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  nop, nop,
-      nop, nop, nop, nop, nop, 0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
-      10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,
-      25,  nop, nop, nop, nop, nop, nop, 26,  27,  28,  29,  30,  31,  32,  33,
-      34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
-      49,  50,  51,  nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
-      nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
-      nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
-      nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
-      nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
-      nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
-      nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
-      nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
-      nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
-      nop};
+inline bool base64Decode(const boost::string_view input, std::string& output)
+{
+    static const char nop = -1;
+    // See note on encoding_data[] in above function
+    static const char decodingData[] = {
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, 62,  nop, nop, nop, 63,  52,  53,  54,  55,  56,  57,  58,  59,
+        60,  61,  nop, nop, nop, nop, nop, nop, nop, 0,   1,   2,   3,   4,
+        5,   6,   7,   8,   9,   10,  11,  12,  13,  14,  15,  16,  17,  18,
+        19,  20,  21,  22,  23,  24,  25,  nop, nop, nop, nop, nop, nop, 26,
+        27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,
+        41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop};
 
-  size_t inputLength = input.size();
+    size_t inputLength = input.size();
 
-  // allocate space for output string
-  output.clear();
-  output.reserve(((inputLength + 2) / 3) * 4);
+    // allocate space for output string
+    output.clear();
+    output.reserve(((inputLength + 2) / 3) * 4);
 
-  // for each 4-bytes sequence from the input, extract 4 6-bits sequences by
-  // droping first two bits
-  // and regenerate into 3 8-bits sequences
+    // for each 4-bytes sequence from the input, extract 4 6-bits sequences by
+    // droping first two bits
+    // and regenerate into 3 8-bits sequences
 
-  for (size_t i = 0; i < inputLength; i++) {
-    char base64code0;
-    char base64code1;
-    char base64code2 = 0;  // initialized to 0 to suppress warnings
-    char base64code3;
+    for (size_t i = 0; i < inputLength; i++)
+    {
+        char base64code0;
+        char base64code1;
+        char base64code2 = 0; // initialized to 0 to suppress warnings
+        char base64code3;
 
-    base64code0 = decodingData[static_cast<int>(input[i])];  // NOLINT
-    if (base64code0 == nop) {  // non base64 character
-      return false;
-    }
-    if (!(++i < inputLength)) {  // we need at least two input bytes for first
-                                 // byte output
-      return false;
-    }
-    base64code1 = decodingData[static_cast<int>(input[i])];  // NOLINT
-    if (base64code1 == nop) {  // non base64 character
-      return false;
-    }
-    output +=
-        static_cast<char>((base64code0 << 2) | ((base64code1 >> 4) & 0x3));
+        base64code0 = decodingData[static_cast<int>(input[i])]; // NOLINT
+        if (base64code0 == nop)
+        { // non base64 character
+            return false;
+        }
+        if (!(++i < inputLength))
+        { // we need at least two input bytes for first
+          // byte output
+            return false;
+        }
+        base64code1 = decodingData[static_cast<int>(input[i])]; // NOLINT
+        if (base64code1 == nop)
+        { // non base64 character
+            return false;
+        }
+        output +=
+            static_cast<char>((base64code0 << 2) | ((base64code1 >> 4) & 0x3));
 
-    if (++i < inputLength) {
-      char c = input[i];
-      if (c == '=') {  // padding , end of input
-        return (base64code1 & 0x0f) == 0;
-      }
-      base64code2 = decodingData[static_cast<int>(input[i])];  // NOLINT
-      if (base64code2 == nop) {  // non base64 character
-        return false;
-      }
-      output += static_cast<char>(((base64code1 << 4) & 0xf0) |
-                                  ((base64code2 >> 2) & 0x0f));
+        if (++i < inputLength)
+        {
+            char c = input[i];
+            if (c == '=')
+            { // padding , end of input
+                return (base64code1 & 0x0f) == 0;
+            }
+            base64code2 = decodingData[static_cast<int>(input[i])]; // NOLINT
+            if (base64code2 == nop)
+            { // non base64 character
+                return false;
+            }
+            output += static_cast<char>(((base64code1 << 4) & 0xf0) |
+                                        ((base64code2 >> 2) & 0x0f));
+        }
+
+        if (++i < inputLength)
+        {
+            char c = input[i];
+            if (c == '=')
+            { // padding , end of input
+                return (base64code2 & 0x03) == 0;
+            }
+            base64code3 = decodingData[static_cast<int>(input[i])]; // NOLINT
+            if (base64code3 == nop)
+            { // non base64 character
+                return false;
+            }
+            output +=
+                static_cast<char>((((base64code2 << 6) & 0xc0) | base64code3));
+        }
     }
 
-    if (++i < inputLength) {
-      char c = input[i];
-      if (c == '=') {  // padding , end of input
-        return (base64code2 & 0x03) == 0;
-      }
-      base64code3 = decodingData[static_cast<int>(input[i])];  // NOLINT
-      if (base64code3 == nop) {  // non base64 character
-        return false;
-      }
-      output += static_cast<char>((((base64code2 << 6) & 0xc0) | base64code3));
-    }
-  }
-
-  return true;
+    return true;
 }
 
-}  // namespace utility
-}  // namespace crow
+} // namespace utility
+} // namespace crow
diff --git a/crow/include/crow/websocket.h b/crow/include/crow/websocket.h
index 82c6db8..f345223 100644
--- a/crow/include/crow/websocket.h
+++ b/crow/include/crow/websocket.h
@@ -1,206 +1,240 @@
 #pragma once
 #include <array>
-#include <functional>
-#include "crow/http_request.h"
-#include "crow/socket_adaptors.h"
 #include <boost/algorithm/string/predicate.hpp>
 #include <boost/beast/websocket.hpp>
+#include <functional>
+
+#include "crow/http_request.h"
+#include "crow/socket_adaptors.h"
 
 #ifdef BMCWEB_ENABLE_SSL
 #include <boost/beast/websocket/ssl.hpp>
 #endif
 
-namespace crow {
-namespace websocket {
-struct Connection : std::enable_shared_from_this<Connection> {
- public:
-  explicit Connection(const crow::Request& req)
-      : req(req), userdataPtr(nullptr){};
+namespace crow
+{
+namespace websocket
+{
+struct Connection : std::enable_shared_from_this<Connection>
+{
+  public:
+    explicit Connection(const crow::Request& req) :
+        req(req), userdataPtr(nullptr){};
 
-  virtual void sendBinary(const boost::beast::string_view msg) = 0;
-  virtual void sendBinary(std::string&& msg) = 0;
-  virtual void sendText(const boost::beast::string_view msg) = 0;
-  virtual void sendText(std::string&& msg) = 0;
-  virtual void close(const boost::beast::string_view msg = "quit") = 0;
-  virtual boost::asio::io_service& getIoService() = 0;
-  virtual ~Connection() = default;
+    virtual void sendBinary(const boost::beast::string_view msg) = 0;
+    virtual void sendBinary(std::string&& msg) = 0;
+    virtual void sendText(const boost::beast::string_view msg) = 0;
+    virtual void sendText(std::string&& msg) = 0;
+    virtual void close(const boost::beast::string_view msg = "quit") = 0;
+    virtual boost::asio::io_service& getIoService() = 0;
+    virtual ~Connection() = default;
 
-  void userdata(void* u) { userdataPtr = u; }
-  void* userdata() { return userdataPtr; }
+    void userdata(void* u)
+    {
+        userdataPtr = u;
+    }
+    void* userdata()
+    {
+        return userdataPtr;
+    }
 
-  crow::Request req;
+    crow::Request req;
 
- private:
-  void* userdataPtr;
+  private:
+    void* userdataPtr;
 };
 
-template <typename Adaptor>
-class ConnectionImpl : public Connection {
- public:
-  ConnectionImpl(
-      const crow::Request& req, Adaptor&& adaptorIn,
-      std::function<void(Connection&)> open_handler,
-      std::function<void(Connection&, const std::string&, bool)>
-          message_handler,
-      std::function<void(Connection&, const std::string&)> close_handler,
-      std::function<void(Connection&)> error_handler)
-      : adaptor(std::move(adaptorIn)),
-        ws(adaptor.socket()),
-        Connection(req),
+template <typename Adaptor> class ConnectionImpl : public Connection
+{
+  public:
+    ConnectionImpl(
+        const crow::Request& req, Adaptor&& adaptorIn,
+        std::function<void(Connection&)> open_handler,
+        std::function<void(Connection&, const std::string&, bool)>
+            message_handler,
+        std::function<void(Connection&, const std::string&)> close_handler,
+        std::function<void(Connection&)> error_handler) :
+        adaptor(std::move(adaptorIn)),
+        ws(adaptor.socket()), Connection(req),
         openHandler(std::move(open_handler)),
         messageHandler(std::move(message_handler)),
         closeHandler(std::move(close_handler)),
-        errorHandler(std::move(error_handler)) {
-    BMCWEB_LOG_DEBUG << "Creating new connection " << this;
-  }
-
-  boost::asio::io_service& getIoService() override {
-    return adaptor.getIoService();
-  }
-
-  void start() {
-    BMCWEB_LOG_DEBUG << "starting connection " << this;
-
-    boost::string_view protocol =
-        req.getHeaderValue(boost::beast::http::field::sec_websocket_protocol);
-
-    // Perform the websocket upgrade
-    ws.async_accept_ex(
-        req.req,
-        [protocol{std::string(protocol)}](
-            boost::beast::websocket::response_type & m) {
-          if (!protocol.empty()) {
-            m.insert(boost::beast::http::field::sec_websocket_protocol,
-                     protocol);
-          }
-        },
-        [ this, self(shared_from_this()) ](boost::system::error_code ec) {
-          if (ec) {
-            BMCWEB_LOG_ERROR << "Error in ws.async_accept " << ec;
-            return;
-          }
-          acceptDone();
-        });
-  }
-
-  void sendBinary(const boost::beast::string_view msg) override {
-    ws.binary(true);
-    outBuffer.emplace_back(msg);
-    doWrite();
-  }
-
-  void sendBinary(std::string&& msg) override {
-    ws.binary(true);
-    outBuffer.emplace_back(std::move(msg));
-    doWrite();
-  }
-
-  void sendText(const boost::beast::string_view msg) override {
-    ws.text(true);
-    outBuffer.emplace_back(msg);
-    doWrite();
-  }
-
-  void sendText(std::string&& msg) override {
-    ws.text(true);
-    outBuffer.emplace_back(std::move(msg));
-    doWrite();
-  }
-
-  void close(const boost::beast::string_view msg) override {
-    ws.async_close(
-        boost::beast::websocket::close_code::normal,
-        [ this, self(shared_from_this()) ](boost::system::error_code ec) {
-          if (ec) {
-            BMCWEB_LOG_ERROR << "Error closing websocket " << ec;
-            return;
-          }
-          adaptor.close();
-        });
-  }
-
-  void acceptDone() {
-    BMCWEB_LOG_DEBUG << "Websocket accepted connection";
-
-    if (openHandler) {
-      openHandler(*this);
-    }
-    doRead();
-  }
-
-  void doRead() {
-    ws.async_read(
-        inBuffer, [ this, self(shared_from_this()) ](
-                      boost::beast::error_code ec, std::size_t bytes_read) {
-          if (ec) {
-            if (ec != boost::beast::websocket::error::closed) {
-              BMCWEB_LOG_ERROR << "doRead error " << ec;
-            }
-            if (closeHandler) {
-              boost::beast::string_view reason = ws.reason().reason;
-              closeHandler(*this, std::string(reason));
-            }
-            return;
-          }
-          if (messageHandler) {
-            // TODO(Ed) There must be a more direct way to do this conversion,
-            // but I can't find it at the moment.  It should get optimized away
-            boost::asio::const_buffer cb =
-                boost::beast::buffers_front(inBuffer.data());
-            boost::beast::string_view message(
-                reinterpret_cast<char const*>(cb.data()), cb.size());
-            messageHandler(*this, std::string(message), ws.got_text());
-          }
-          doRead();
-        });
-  }
-
-  void doWrite() {
-    // If we're already doing a write, ignore the request, it will be picked up
-    // when the current write is complete
-    if (doingWrite) {
-      return;
+        errorHandler(std::move(error_handler))
+    {
+        BMCWEB_LOG_DEBUG << "Creating new connection " << this;
     }
 
-    if (outBuffer.empty()) {
-      // Done for now
-      return;
+    boost::asio::io_service& getIoService() override
+    {
+        return adaptor.getIoService();
     }
-    doingWrite = true;
-    ws.async_write(boost::asio::buffer(outBuffer.front()),
-                   [ this, self(shared_from_this()) ](
-                       boost::beast::error_code ec, std::size_t bytes_written) {
-                     doingWrite = false;
-                     outBuffer.erase(outBuffer.begin());
-                     if (ec == boost::beast::websocket::error::closed) {
-                       // Do nothing here.  doRead handler will call the
-                       // closeHandler.
-                       close("Write error");
-                       return;
-                     }
-                     if (ec) {
-                       BMCWEB_LOG_ERROR << "Error in ws.async_write " << ec;
-                       return;
-                     }
-                     doWrite();
-                   });
-  }
 
- private:
-  Adaptor adaptor;
+    void start()
+    {
+        BMCWEB_LOG_DEBUG << "starting connection " << this;
 
-  boost::beast::websocket::stream<
-      std::add_lvalue_reference_t<typename Adaptor::streamType>>
-      ws;
+        boost::string_view protocol = req.getHeaderValue(
+            boost::beast::http::field::sec_websocket_protocol);
 
-  boost::beast::flat_static_buffer<4096> inBuffer;
-  std::vector<std::string> outBuffer;
-  bool doingWrite = false;
+        // Perform the websocket upgrade
+        ws.async_accept_ex(
+            req.req,
+            [protocol{std::string(protocol)}](
+                boost::beast::websocket::response_type& m) {
+                if (!protocol.empty())
+                {
+                    m.insert(boost::beast::http::field::sec_websocket_protocol,
+                             protocol);
+                }
+            },
+            [this, self(shared_from_this())](boost::system::error_code ec) {
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR << "Error in ws.async_accept " << ec;
+                    return;
+                }
+                acceptDone();
+            });
+    }
 
-  std::function<void(Connection&)> openHandler;
-  std::function<void(Connection&, const std::string&, bool)> messageHandler;
-  std::function<void(Connection&, const std::string&)> closeHandler;
-  std::function<void(Connection&)> errorHandler;
+    void sendBinary(const boost::beast::string_view msg) override
+    {
+        ws.binary(true);
+        outBuffer.emplace_back(msg);
+        doWrite();
+    }
+
+    void sendBinary(std::string&& msg) override
+    {
+        ws.binary(true);
+        outBuffer.emplace_back(std::move(msg));
+        doWrite();
+    }
+
+    void sendText(const boost::beast::string_view msg) override
+    {
+        ws.text(true);
+        outBuffer.emplace_back(msg);
+        doWrite();
+    }
+
+    void sendText(std::string&& msg) override
+    {
+        ws.text(true);
+        outBuffer.emplace_back(std::move(msg));
+        doWrite();
+    }
+
+    void close(const boost::beast::string_view msg) override
+    {
+        ws.async_close(
+            boost::beast::websocket::close_code::normal,
+            [this, self(shared_from_this())](boost::system::error_code ec) {
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR << "Error closing websocket " << ec;
+                    return;
+                }
+                adaptor.close();
+            });
+    }
+
+    void acceptDone()
+    {
+        BMCWEB_LOG_DEBUG << "Websocket accepted connection";
+
+        if (openHandler)
+        {
+            openHandler(*this);
+        }
+        doRead();
+    }
+
+    void doRead()
+    {
+        ws.async_read(
+            inBuffer, [this, self(shared_from_this())](
+                          boost::beast::error_code ec, std::size_t bytes_read) {
+                if (ec)
+                {
+                    if (ec != boost::beast::websocket::error::closed)
+                    {
+                        BMCWEB_LOG_ERROR << "doRead error " << ec;
+                    }
+                    if (closeHandler)
+                    {
+                        boost::beast::string_view reason = ws.reason().reason;
+                        closeHandler(*this, std::string(reason));
+                    }
+                    return;
+                }
+                if (messageHandler)
+                {
+                    // TODO(Ed) There must be a more direct way to do this
+                    // conversion, but I can't find it at the moment.  It should
+                    // get optimized away
+                    boost::asio::const_buffer cb =
+                        boost::beast::buffers_front(inBuffer.data());
+                    boost::beast::string_view message(
+                        reinterpret_cast<char const*>(cb.data()), cb.size());
+                    messageHandler(*this, std::string(message), ws.got_text());
+                }
+                doRead();
+            });
+    }
+
+    void doWrite()
+    {
+        // If we're already doing a write, ignore the request, it will be picked
+        // up when the current write is complete
+        if (doingWrite)
+        {
+            return;
+        }
+
+        if (outBuffer.empty())
+        {
+            // Done for now
+            return;
+        }
+        doingWrite = true;
+        ws.async_write(
+            boost::asio::buffer(outBuffer.front()),
+            [this, self(shared_from_this())](boost::beast::error_code ec,
+                                             std::size_t bytes_written) {
+                doingWrite = false;
+                outBuffer.erase(outBuffer.begin());
+                if (ec == boost::beast::websocket::error::closed)
+                {
+                    // Do nothing here.  doRead handler will call the
+                    // closeHandler.
+                    close("Write error");
+                    return;
+                }
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR << "Error in ws.async_write " << ec;
+                    return;
+                }
+                doWrite();
+            });
+    }
+
+  private:
+    Adaptor adaptor;
+
+    boost::beast::websocket::stream<
+        std::add_lvalue_reference_t<typename Adaptor::streamType>>
+        ws;
+
+    boost::beast::flat_static_buffer<4096> inBuffer;
+    std::vector<std::string> outBuffer;
+    bool doingWrite = false;
+
+    std::function<void(Connection&)> openHandler;
+    std::function<void(Connection&, const std::string&, bool)> messageHandler;
+    std::function<void(Connection&, const std::string&)> closeHandler;
+    std::function<void(Connection&)> errorHandler;
 };
-}  // namespace websocket
-}  // namespace crow
+} // namespace websocket
+} // namespace crow
diff --git a/include/ast_jpeg_decoder.hpp b/include/ast_jpeg_decoder.hpp
index e6e0f08..e8bdddb 100644
--- a/include/ast_jpeg_decoder.hpp
+++ b/include/ast_jpeg_decoder.hpp
@@ -1,345 +1,390 @@
 #pragma once
 
 #include <aspeed/JTABLES.H>
-#include <ast_video_types.hpp>
+
 #include <array>
+#include <ast_video_types.hpp>
 #include <cassert>
 #include <cstdint>
 #include <cstring>
 #include <iostream>
 #include <vector>
 
-namespace ast_video {
+namespace ast_video
+{
 
-struct ColorCache {
-  ColorCache()
-      : color{0x008080, 0xFF8080, 0x808080, 0xC08080}, index{0, 1, 2, 3} {}
+struct ColorCache
+{
+    ColorCache() :
+        color{0x008080, 0xFF8080, 0x808080, 0xC08080}, index{0, 1, 2, 3}
+    {
+    }
 
-  unsigned long color[4];
-  unsigned char index[4];
-  unsigned char bitMapBits{};
+    unsigned long color[4];
+    unsigned char index[4];
+    unsigned char bitMapBits{};
 };
 
-struct RGB {
-  unsigned char b;
-  unsigned char g;
-  unsigned char r;
-  unsigned char reserved;
+struct RGB
+{
+    unsigned char b;
+    unsigned char g;
+    unsigned char r;
+    unsigned char reserved;
 };
 
-enum class JpgBlock {
-  JPEG_NO_SKIP_CODE = 0x00,
-  JPEG_SKIP_CODE = 0x08,
+enum class JpgBlock
+{
+    JPEG_NO_SKIP_CODE = 0x00,
+    JPEG_SKIP_CODE = 0x08,
 
-  JPEG_PASS2_CODE = 0x02,
-  JPEG_SKIP_PASS2_CODE = 0x0A,
+    JPEG_PASS2_CODE = 0x02,
+    JPEG_SKIP_PASS2_CODE = 0x0A,
 
-  LOW_JPEG_NO_SKIP_CODE = 0x04,
-  LOW_JPEG_SKIP_CODE = 0x0C,
+    LOW_JPEG_NO_SKIP_CODE = 0x04,
+    LOW_JPEG_SKIP_CODE = 0x0C,
 
-  VQ_NO_SKIP_1_COLOR_CODE = 0x05,
-  VQ_SKIP_1_COLOR_CODE = 0x0D,
+    VQ_NO_SKIP_1_COLOR_CODE = 0x05,
+    VQ_SKIP_1_COLOR_CODE = 0x0D,
 
-  VQ_NO_SKIP_2_COLOR_CODE = 0x06,
-  VQ_SKIP_2_COLOR_CODE = 0x0E,
+    VQ_NO_SKIP_2_COLOR_CODE = 0x06,
+    VQ_SKIP_2_COLOR_CODE = 0x0E,
 
-  VQ_NO_SKIP_4_COLOR_CODE = 0x07,
-  VQ_SKIP_4_COLOR_CODE = 0x0F,
+    VQ_NO_SKIP_4_COLOR_CODE = 0x07,
+    VQ_SKIP_4_COLOR_CODE = 0x0F,
 
-  FRAME_END_CODE = 0x09,
+    FRAME_END_CODE = 0x09,
 
 };
 
-class AstJpegDecoder {
- public:
-  AstJpegDecoder() {
-    // TODO(ed) figure out how to init this in the constructor
-    yuvBuffer.resize(1920 * 1200);
-    outBuffer.resize(1920 * 1200);
-    for (auto &r : outBuffer) {
-      r.r = 0x00;
-      r.g = 0x00;
-      r.b = 0x00;
-      r.reserved = 0xAA;
+class AstJpegDecoder
+{
+  public:
+    AstJpegDecoder()
+    {
+        // TODO(ed) figure out how to init this in the constructor
+        yuvBuffer.resize(1920 * 1200);
+        outBuffer.resize(1920 * 1200);
+        for (auto &r : outBuffer)
+        {
+            r.r = 0x00;
+            r.g = 0x00;
+            r.b = 0x00;
+            r.reserved = 0xAA;
+        }
+
+        int qfactor = 16;
+
+        scalefactor = qfactor;
+        scalefactoruv = qfactor;
+        advancescalefactor = 16;
+        advancescalefactoruv = 16;
+        initJpgTable();
     }
 
-    int qfactor = 16;
+    void loadQuantTable(std::array<long, 64> &quant_table)
+    {
+        float scalefactorF[8] = {1.0f,         1.387039845f, 1.306562965f,
+                                 1.175875602f, 1.0f,         0.785694958f,
+                                 0.541196100f, 0.275899379f};
+        uint8_t j, row, col;
+        std::array<uint8_t, 64> tempQT{};
 
-    scalefactor = qfactor;
-    scalefactoruv = qfactor;
-    advancescalefactor = 16;
-    advancescalefactoruv = 16;
-    initJpgTable();
-  }
+        // Load quantization coefficients from JPG file, scale them for DCT and
+        // reorder
+        // from zig-zag order
+        switch (ySelector)
+        {
+            case 0:
+                stdLuminanceQt = tbl000Y;
+                break;
+            case 1:
+                stdLuminanceQt = tbl014Y;
+                break;
+            case 2:
+                stdLuminanceQt = tbl029Y;
+                break;
+            case 3:
+                stdLuminanceQt = tbl043Y;
+                break;
+            case 4:
+                stdLuminanceQt = tbl057Y;
+                break;
+            case 5:
+                stdLuminanceQt = tbl071Y;
+                break;
+            case 6:
+                stdLuminanceQt = tbl086Y;
+                break;
+            case 7:
+                stdLuminanceQt = tbl100Y;
+                break;
+        }
+        setQuantTable(stdLuminanceQt, static_cast<uint8_t>(scalefactor),
+                      tempQT);
 
-  void loadQuantTable(std::array<long, 64> &quant_table) {
-    float scalefactorF[8] = {1.0f, 1.387039845f, 1.306562965f, 1.175875602f,
-                             1.0f, 0.785694958f, 0.541196100f, 0.275899379f};
-    uint8_t j, row, col;
-    std::array<uint8_t, 64> tempQT{};
-
-    // Load quantization coefficients from JPG file, scale them for DCT and
-    // reorder
-    // from zig-zag order
-    switch (ySelector) {
-      case 0:
-        stdLuminanceQt = tbl000Y;
-        break;
-      case 1:
-        stdLuminanceQt = tbl014Y;
-        break;
-      case 2:
-        stdLuminanceQt = tbl029Y;
-        break;
-      case 3:
-        stdLuminanceQt = tbl043Y;
-        break;
-      case 4:
-        stdLuminanceQt = tbl057Y;
-        break;
-      case 5:
-        stdLuminanceQt = tbl071Y;
-        break;
-      case 6:
-        stdLuminanceQt = tbl086Y;
-        break;
-      case 7:
-        stdLuminanceQt = tbl100Y;
-        break;
+        for (j = 0; j <= 63; j++)
+        {
+            quant_table[j] = tempQT[zigzag[j]];
+        }
+        j = 0;
+        for (row = 0; row <= 7; row++)
+        {
+            for (col = 0; col <= 7; col++)
+            {
+                quant_table[j] = static_cast<long>(
+                    (quant_table[j] * scalefactorF[row] * scalefactorF[col]) *
+                    65536);
+                j++;
+            }
+        }
+        bytePos += 64;
     }
-    setQuantTable(stdLuminanceQt, static_cast<uint8_t>(scalefactor), tempQT);
 
-    for (j = 0; j <= 63; j++) {
-      quant_table[j] = tempQT[zigzag[j]];
-    }
-    j = 0;
-    for (row = 0; row <= 7; row++) {
-      for (col = 0; col <= 7; col++) {
-        quant_table[j] = static_cast<long>(
-            (quant_table[j] * scalefactorF[row] * scalefactorF[col]) * 65536);
-        j++;
-      }
-    }
-    bytePos += 64;
-  }
+    void loadQuantTableCb(std::array<long, 64> &quant_table)
+    {
+        float scalefactor[8] = {1.0f, 1.387039845f, 1.306562965f, 1.175875602f,
+                                1.0f, 0.785694958f, 0.541196100f, 0.275899379f};
+        uint8_t j, row, col;
+        std::array<uint8_t, 64> tempQT{};
 
-  void loadQuantTableCb(std::array<long, 64> &quant_table) {
-    float scalefactor[8] = {1.0f, 1.387039845f, 1.306562965f, 1.175875602f,
-                            1.0f, 0.785694958f, 0.541196100f, 0.275899379f};
-    uint8_t j, row, col;
-    std::array<uint8_t, 64> tempQT{};
+        // Load quantization coefficients from JPG file, scale them for DCT and
+        // reorder from zig-zag order
+        if (mapping == 0)
+        {
+            switch (uvSelector)
+            {
+                case 0:
+                    stdChrominanceQt = tbl000Y;
+                    break;
+                case 1:
+                    stdChrominanceQt = tbl014Y;
+                    break;
+                case 2:
+                    stdChrominanceQt = tbl029Y;
+                    break;
+                case 3:
+                    stdChrominanceQt = tbl043Y;
+                    break;
+                case 4:
+                    stdChrominanceQt = tbl057Y;
+                    break;
+                case 5:
+                    stdChrominanceQt = tbl071Y;
+                    break;
+                case 6:
+                    stdChrominanceQt = tbl086Y;
+                    break;
+                case 7:
+                    stdChrominanceQt = tbl100Y;
+                    break;
+            }
+        }
+        else
+        {
+            switch (uvSelector)
+            {
+                case 0:
+                    stdChrominanceQt = tbl000Uv;
+                    break;
+                case 1:
+                    stdChrominanceQt = tbl014Uv;
+                    break;
+                case 2:
+                    stdChrominanceQt = tbl029Uv;
+                    break;
+                case 3:
+                    stdChrominanceQt = tbl043Uv;
+                    break;
+                case 4:
+                    stdChrominanceQt = tbl057Uv;
+                    break;
+                case 5:
+                    stdChrominanceQt = tbl071Uv;
+                    break;
+                case 6:
+                    stdChrominanceQt = tbl086Uv;
+                    break;
+                case 7:
+                    stdChrominanceQt = tbl100Uv;
+                    break;
+            }
+        }
+        setQuantTable(stdChrominanceQt, static_cast<uint8_t>(scalefactoruv),
+                      tempQT);
 
-    // Load quantization coefficients from JPG file, scale them for DCT and
-    // reorder from zig-zag order
-    if (mapping == 0) {
-      switch (uvSelector) {
-        case 0:
-          stdChrominanceQt = tbl000Y;
-          break;
-        case 1:
-          stdChrominanceQt = tbl014Y;
-          break;
-        case 2:
-          stdChrominanceQt = tbl029Y;
-          break;
-        case 3:
-          stdChrominanceQt = tbl043Y;
-          break;
-        case 4:
-          stdChrominanceQt = tbl057Y;
-          break;
-        case 5:
-          stdChrominanceQt = tbl071Y;
-          break;
-        case 6:
-          stdChrominanceQt = tbl086Y;
-          break;
-        case 7:
-          stdChrominanceQt = tbl100Y;
-          break;
-      }
-    } else {
-      switch (uvSelector) {
-        case 0:
-          stdChrominanceQt = tbl000Uv;
-          break;
-        case 1:
-          stdChrominanceQt = tbl014Uv;
-          break;
-        case 2:
-          stdChrominanceQt = tbl029Uv;
-          break;
-        case 3:
-          stdChrominanceQt = tbl043Uv;
-          break;
-        case 4:
-          stdChrominanceQt = tbl057Uv;
-          break;
-        case 5:
-          stdChrominanceQt = tbl071Uv;
-          break;
-        case 6:
-          stdChrominanceQt = tbl086Uv;
-          break;
-        case 7:
-          stdChrominanceQt = tbl100Uv;
-          break;
-      }
+        for (j = 0; j <= 63; j++)
+        {
+            quant_table[j] = tempQT[zigzag[j]];
+        }
+        j = 0;
+        for (row = 0; row <= 7; row++)
+        {
+            for (col = 0; col <= 7; col++)
+            {
+                quant_table[j] = static_cast<long>(
+                    (quant_table[j] * scalefactor[row] * scalefactor[col]) *
+                    65536);
+                j++;
+            }
+        }
+        bytePos += 64;
     }
-    setQuantTable(stdChrominanceQt, static_cast<uint8_t>(scalefactoruv),
-                  tempQT);
+    //  Note: Added for Dual_JPEG
+    void loadAdvanceQuantTable(std::array<long, 64> &quant_table)
+    {
+        float scalefactor[8] = {1.0f, 1.387039845f, 1.306562965f, 1.175875602f,
+                                1.0f, 0.785694958f, 0.541196100f, 0.275899379f};
+        uint8_t j, row, col;
+        std::array<uint8_t, 64> tempQT{};
 
-    for (j = 0; j <= 63; j++) {
-      quant_table[j] = tempQT[zigzag[j]];
-    }
-    j = 0;
-    for (row = 0; row <= 7; row++) {
-      for (col = 0; col <= 7; col++) {
-        quant_table[j] = static_cast<long>(
-            (quant_table[j] * scalefactor[row] * scalefactor[col]) * 65536);
-        j++;
-      }
-    }
-    bytePos += 64;
-  }
-  //  Note: Added for Dual_JPEG
-  void loadAdvanceQuantTable(std::array<long, 64> &quant_table) {
-    float scalefactor[8] = {1.0f, 1.387039845f, 1.306562965f, 1.175875602f,
-                            1.0f, 0.785694958f, 0.541196100f, 0.275899379f};
-    uint8_t j, row, col;
-    std::array<uint8_t, 64> tempQT{};
+        // Load quantization coefficients from JPG file, scale them for DCT and
+        // reorder
+        // from zig-zag order
+        switch (advanceSelector)
+        {
+            case 0:
+                stdLuminanceQt = tbl000Y;
+                break;
+            case 1:
+                stdLuminanceQt = tbl014Y;
+                break;
+            case 2:
+                stdLuminanceQt = tbl029Y;
+                break;
+            case 3:
+                stdLuminanceQt = tbl043Y;
+                break;
+            case 4:
+                stdLuminanceQt = tbl057Y;
+                break;
+            case 5:
+                stdLuminanceQt = tbl071Y;
+                break;
+            case 6:
+                stdLuminanceQt = tbl086Y;
+                break;
+            case 7:
+                stdLuminanceQt = tbl100Y;
+                break;
+        }
+        //  Note: pass ADVANCE SCALE FACTOR to sub-function in Dual-JPEG
+        setQuantTable(stdLuminanceQt, static_cast<uint8_t>(advancescalefactor),
+                      tempQT);
 
-    // Load quantization coefficients from JPG file, scale them for DCT and
-    // reorder
-    // from zig-zag order
-    switch (advanceSelector) {
-      case 0:
-        stdLuminanceQt = tbl000Y;
-        break;
-      case 1:
-        stdLuminanceQt = tbl014Y;
-        break;
-      case 2:
-        stdLuminanceQt = tbl029Y;
-        break;
-      case 3:
-        stdLuminanceQt = tbl043Y;
-        break;
-      case 4:
-        stdLuminanceQt = tbl057Y;
-        break;
-      case 5:
-        stdLuminanceQt = tbl071Y;
-        break;
-      case 6:
-        stdLuminanceQt = tbl086Y;
-        break;
-      case 7:
-        stdLuminanceQt = tbl100Y;
-        break;
+        for (j = 0; j <= 63; j++)
+        {
+            quant_table[j] = tempQT[zigzag[j]];
+        }
+        j = 0;
+        for (row = 0; row <= 7; row++)
+        {
+            for (col = 0; col <= 7; col++)
+            {
+                quant_table[j] = static_cast<long>(
+                    (quant_table[j] * scalefactor[row] * scalefactor[col]) *
+                    65536);
+                j++;
+            }
+        }
+        bytePos += 64;
     }
-    //  Note: pass ADVANCE SCALE FACTOR to sub-function in Dual-JPEG
-    setQuantTable(stdLuminanceQt, static_cast<uint8_t>(advancescalefactor),
-                  tempQT);
 
-    for (j = 0; j <= 63; j++) {
-      quant_table[j] = tempQT[zigzag[j]];
-    }
-    j = 0;
-    for (row = 0; row <= 7; row++) {
-      for (col = 0; col <= 7; col++) {
-        quant_table[j] = static_cast<long>(
-            (quant_table[j] * scalefactor[row] * scalefactor[col]) * 65536);
-        j++;
-      }
-    }
-    bytePos += 64;
-  }
+    //  Note: Added for Dual-JPEG
+    void loadAdvanceQuantTableCb(std::array<long, 64> &quant_table)
+    {
+        float scalefactor[8] = {1.0f, 1.387039845f, 1.306562965f, 1.175875602f,
+                                1.0f, 0.785694958f, 0.541196100f, 0.275899379f};
+        uint8_t j, row, col;
+        std::array<uint8_t, 64> tempQT{};
 
-  //  Note: Added for Dual-JPEG
-  void loadAdvanceQuantTableCb(std::array<long, 64> &quant_table) {
-    float scalefactor[8] = {1.0f, 1.387039845f, 1.306562965f, 1.175875602f,
-                            1.0f, 0.785694958f, 0.541196100f, 0.275899379f};
-    uint8_t j, row, col;
-    std::array<uint8_t, 64> tempQT{};
+        // Load quantization coefficients from JPG file, scale them for DCT and
+        // reorder
+        // from zig-zag order
+        if (mapping == 1)
+        {
+            switch (advanceSelector)
+            {
+                case 0:
+                    stdChrominanceQt = tbl000Y;
+                    break;
+                case 1:
+                    stdChrominanceQt = tbl014Y;
+                    break;
+                case 2:
+                    stdChrominanceQt = tbl029Y;
+                    break;
+                case 3:
+                    stdChrominanceQt = tbl043Y;
+                    break;
+                case 4:
+                    stdChrominanceQt = tbl057Y;
+                    break;
+                case 5:
+                    stdChrominanceQt = tbl071Y;
+                    break;
+                case 6:
+                    stdChrominanceQt = tbl086Y;
+                    break;
+                case 7:
+                    stdChrominanceQt = tbl100Y;
+                    break;
+            }
+        }
+        else
+        {
+            switch (advanceSelector)
+            {
+                case 0:
+                    stdChrominanceQt = tbl000Uv;
+                    break;
+                case 1:
+                    stdChrominanceQt = tbl014Uv;
+                    break;
+                case 2:
+                    stdChrominanceQt = tbl029Uv;
+                    break;
+                case 3:
+                    stdChrominanceQt = tbl043Uv;
+                    break;
+                case 4:
+                    stdChrominanceQt = tbl057Uv;
+                    break;
+                case 5:
+                    stdChrominanceQt = tbl071Uv;
+                    break;
+                case 6:
+                    stdChrominanceQt = tbl086Uv;
+                    break;
+                case 7:
+                    stdChrominanceQt = tbl100Uv;
+                    break;
+            }
+        }
+        //  Note: pass ADVANCE SCALE FACTOR to sub-function in Dual-JPEG
+        setQuantTable(stdChrominanceQt,
+                      static_cast<uint8_t>(advancescalefactoruv), tempQT);
 
-    // Load quantization coefficients from JPG file, scale them for DCT and
-    // reorder
-    // from zig-zag order
-    if (mapping == 1) {
-      switch (advanceSelector) {
-        case 0:
-          stdChrominanceQt = tbl000Y;
-          break;
-        case 1:
-          stdChrominanceQt = tbl014Y;
-          break;
-        case 2:
-          stdChrominanceQt = tbl029Y;
-          break;
-        case 3:
-          stdChrominanceQt = tbl043Y;
-          break;
-        case 4:
-          stdChrominanceQt = tbl057Y;
-          break;
-        case 5:
-          stdChrominanceQt = tbl071Y;
-          break;
-        case 6:
-          stdChrominanceQt = tbl086Y;
-          break;
-        case 7:
-          stdChrominanceQt = tbl100Y;
-          break;
-      }
-    } else {
-      switch (advanceSelector) {
-        case 0:
-          stdChrominanceQt = tbl000Uv;
-          break;
-        case 1:
-          stdChrominanceQt = tbl014Uv;
-          break;
-        case 2:
-          stdChrominanceQt = tbl029Uv;
-          break;
-        case 3:
-          stdChrominanceQt = tbl043Uv;
-          break;
-        case 4:
-          stdChrominanceQt = tbl057Uv;
-          break;
-        case 5:
-          stdChrominanceQt = tbl071Uv;
-          break;
-        case 6:
-          stdChrominanceQt = tbl086Uv;
-          break;
-        case 7:
-          stdChrominanceQt = tbl100Uv;
-          break;
-      }
+        for (j = 0; j <= 63; j++)
+        {
+            quant_table[j] = tempQT[zigzag[j]];
+        }
+        j = 0;
+        for (row = 0; row <= 7; row++)
+        {
+            for (col = 0; col <= 7; col++)
+            {
+                quant_table[j] = static_cast<long>(
+                    (quant_table[j] * scalefactor[row] * scalefactor[col]) *
+                    65536);
+                j++;
+            }
+        }
+        bytePos += 64;
     }
-    //  Note: pass ADVANCE SCALE FACTOR to sub-function in Dual-JPEG
-    setQuantTable(stdChrominanceQt, static_cast<uint8_t>(advancescalefactoruv),
-                  tempQT);
 
-    for (j = 0; j <= 63; j++) {
-      quant_table[j] = tempQT[zigzag[j]];
-    }
-    j = 0;
-    for (row = 0; row <= 7; row++) {
-      for (col = 0; col <= 7; col++) {
-        quant_table[j] = static_cast<long>(
-            (quant_table[j] * scalefactor[row] * scalefactor[col]) * 65536);
-        j++;
-      }
-    }
-    bytePos += 64;
-  }
-
-  void idctTransform(short *coef, uint8_t *data, uint8_t nBlock) {
+    void idctTransform(short *coef, uint8_t *data, uint8_t nBlock)
+    {
 #define FIX_1_082392200 ((int)277) /* FIX(1.082392200) */
 #define FIX_1_414213562 ((int)362) /* FIX(1.414213562) */
 #define FIX_1_847759065 ((int)473) /* FIX(1.847759065) */
@@ -347,108 +392,111 @@
 
 #define MULTIPLY(var, cons) ((int)((var) * (cons)) >> 8)
 
-    int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
-    int tmp10, tmp11, tmp12, tmp13;
-    int z5, z10, z11, z12, z13;
-    int workspace[64]; /* buffers data between passes */
+        int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+        int tmp10, tmp11, tmp12, tmp13;
+        int z5, z10, z11, z12, z13;
+        int workspace[64]; /* buffers data between passes */
 
-    short *inptr = coef;
-    long *quantptr;
-    int *wsptr = workspace;
-    unsigned char *outptr;
-    unsigned char *rLimit = rlimitTable + 128;
-    int ctr, dcval, dctsize = 8;
+        short *inptr = coef;
+        long *quantptr;
+        int *wsptr = workspace;
+        unsigned char *outptr;
+        unsigned char *rLimit = rlimitTable + 128;
+        int ctr, dcval, dctsize = 8;
 
-    quantptr = &qt[nBlock][0];
+        quantptr = &qt[nBlock][0];
 
-    // Pass 1: process columns from input (inptr), store into work array(wsptr)
+        // Pass 1: process columns from input (inptr), store into work
+        // array(wsptr)
 
-    for (ctr = 8; ctr > 0; ctr--) {
-      /* Due to quantization, we will usually find that many of the input
-       * coefficients are zero, especially the AC terms.  We can exploit this
-       * by short-circuiting the IDCT calculation for any column in which all
-       * the AC terms are zero.  In that case each output is equal to the
-       * DC coefficient (with scale factor as needed).
-       * With typical images and quantization tables, half or more of the
-       * column DCT calculations can be simplified this way.
-       */
+        for (ctr = 8; ctr > 0; ctr--)
+        {
+            /* Due to quantization, we will usually find that many of the input
+             * coefficients are zero, especially the AC terms.  We can exploit
+             * this by short-circuiting the IDCT calculation for any column in
+             * which all the AC terms are zero.  In that case each output is
+             * equal to the DC coefficient (with scale factor as needed). With
+             * typical images and quantization tables, half or more of the
+             * column DCT calculations can be simplified this way.
+             */
 
-      if ((inptr[dctsize * 1] | inptr[dctsize * 2] | inptr[dctsize * 3] |
-           inptr[dctsize * 4] | inptr[dctsize * 5] | inptr[dctsize * 6] |
-           inptr[dctsize * 7]) == 0) {
-        /* AC terms all zero */
-        dcval = static_cast<int>((inptr[dctsize * 0] * quantptr[dctsize * 0]) >>
-                                 16);
+            if ((inptr[dctsize * 1] | inptr[dctsize * 2] | inptr[dctsize * 3] |
+                 inptr[dctsize * 4] | inptr[dctsize * 5] | inptr[dctsize * 6] |
+                 inptr[dctsize * 7]) == 0)
+            {
+                /* AC terms all zero */
+                dcval = static_cast<int>(
+                    (inptr[dctsize * 0] * quantptr[dctsize * 0]) >> 16);
 
-        wsptr[dctsize * 0] = dcval;
-        wsptr[dctsize * 1] = dcval;
-        wsptr[dctsize * 2] = dcval;
-        wsptr[dctsize * 3] = dcval;
-        wsptr[dctsize * 4] = dcval;
-        wsptr[dctsize * 5] = dcval;
-        wsptr[dctsize * 6] = dcval;
-        wsptr[dctsize * 7] = dcval;
+                wsptr[dctsize * 0] = dcval;
+                wsptr[dctsize * 1] = dcval;
+                wsptr[dctsize * 2] = dcval;
+                wsptr[dctsize * 3] = dcval;
+                wsptr[dctsize * 4] = dcval;
+                wsptr[dctsize * 5] = dcval;
+                wsptr[dctsize * 6] = dcval;
+                wsptr[dctsize * 7] = dcval;
 
-        inptr++; /* advance pointers to next column */
-        quantptr++;
-        wsptr++;
-        continue;
-      }
+                inptr++; /* advance pointers to next column */
+                quantptr++;
+                wsptr++;
+                continue;
+            }
 
-      /* Even part */
+            /* Even part */
 
-      tmp0 = (inptr[dctsize * 0] * quantptr[dctsize * 0]) >> 16;
-      tmp1 = (inptr[dctsize * 2] * quantptr[dctsize * 2]) >> 16;
-      tmp2 = (inptr[dctsize * 4] * quantptr[dctsize * 4]) >> 16;
-      tmp3 = (inptr[dctsize * 6] * quantptr[dctsize * 6]) >> 16;
+            tmp0 = (inptr[dctsize * 0] * quantptr[dctsize * 0]) >> 16;
+            tmp1 = (inptr[dctsize * 2] * quantptr[dctsize * 2]) >> 16;
+            tmp2 = (inptr[dctsize * 4] * quantptr[dctsize * 4]) >> 16;
+            tmp3 = (inptr[dctsize * 6] * quantptr[dctsize * 6]) >> 16;
 
-      tmp10 = tmp0 + tmp2; /* phase 3 */
-      tmp11 = tmp0 - tmp2;
+            tmp10 = tmp0 + tmp2; /* phase 3 */
+            tmp11 = tmp0 - tmp2;
 
-      tmp13 = tmp1 + tmp3;                                    /* phases 5-3 */
-      tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */
+            tmp13 = tmp1 + tmp3; /* phases 5-3 */
+            tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */
 
-      tmp0 = tmp10 + tmp13; /* phase 2 */
-      tmp3 = tmp10 - tmp13;
-      tmp1 = tmp11 + tmp12;
-      tmp2 = tmp11 - tmp12;
+            tmp0 = tmp10 + tmp13; /* phase 2 */
+            tmp3 = tmp10 - tmp13;
+            tmp1 = tmp11 + tmp12;
+            tmp2 = tmp11 - tmp12;
 
-      /* Odd part */
+            /* Odd part */
 
-      tmp4 = (inptr[dctsize * 1] * quantptr[dctsize * 1]) >> 16;
-      tmp5 = (inptr[dctsize * 3] * quantptr[dctsize * 3]) >> 16;
-      tmp6 = (inptr[dctsize * 5] * quantptr[dctsize * 5]) >> 16;
-      tmp7 = (inptr[dctsize * 7] * quantptr[dctsize * 7]) >> 16;
+            tmp4 = (inptr[dctsize * 1] * quantptr[dctsize * 1]) >> 16;
+            tmp5 = (inptr[dctsize * 3] * quantptr[dctsize * 3]) >> 16;
+            tmp6 = (inptr[dctsize * 5] * quantptr[dctsize * 5]) >> 16;
+            tmp7 = (inptr[dctsize * 7] * quantptr[dctsize * 7]) >> 16;
 
-      z13 = tmp6 + tmp5; /* phase 6 */
-      z10 = tmp6 - tmp5;
-      z11 = tmp4 + tmp7;
-      z12 = tmp4 - tmp7;
+            z13 = tmp6 + tmp5; /* phase 6 */
+            z10 = tmp6 - tmp5;
+            z11 = tmp4 + tmp7;
+            z12 = tmp4 - tmp7;
 
-      tmp7 = z11 + z13;                             /* phase 5 */
-      tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
+            tmp7 = z11 + z13;                             /* phase 5 */
+            tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
 
-      z5 = MULTIPLY(z10 + z12, FIX_1_847759065);    /* 2*c2 */
-      tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5;  /* 2*(c2-c6) */
-      tmp12 = MULTIPLY(z10, -FIX_2_613125930) + z5; /* -2*(c2+c6) */
+            z5 = MULTIPLY(z10 + z12, FIX_1_847759065);    /* 2*c2 */
+            tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5;  /* 2*(c2-c6) */
+            tmp12 = MULTIPLY(z10, -FIX_2_613125930) + z5; /* -2*(c2+c6) */
 
-      tmp6 = tmp12 - tmp7; /* phase 2 */
-      tmp5 = tmp11 - tmp6;
-      tmp4 = tmp10 + tmp5;
+            tmp6 = tmp12 - tmp7; /* phase 2 */
+            tmp5 = tmp11 - tmp6;
+            tmp4 = tmp10 + tmp5;
 
-      wsptr[dctsize * 0] = (tmp0 + tmp7);
-      wsptr[dctsize * 7] = (tmp0 - tmp7);
-      wsptr[dctsize * 1] = (tmp1 + tmp6);
-      wsptr[dctsize * 6] = (tmp1 - tmp6);
-      wsptr[dctsize * 2] = (tmp2 + tmp5);
-      wsptr[dctsize * 5] = (tmp2 - tmp5);
-      wsptr[dctsize * 4] = (tmp3 + tmp4);
-      wsptr[dctsize * 3] = (tmp3 - tmp4);
+            wsptr[dctsize * 0] = (tmp0 + tmp7);
+            wsptr[dctsize * 7] = (tmp0 - tmp7);
+            wsptr[dctsize * 1] = (tmp1 + tmp6);
+            wsptr[dctsize * 6] = (tmp1 - tmp6);
+            wsptr[dctsize * 2] = (tmp2 + tmp5);
+            wsptr[dctsize * 5] = (tmp2 - tmp5);
+            wsptr[dctsize * 4] = (tmp3 + tmp4);
+            wsptr[dctsize * 3] = (tmp3 - tmp4);
 
-      inptr++; /* advance pointers to next column */
-      quantptr++;
-      wsptr++;
-    }
+            inptr++; /* advance pointers to next column */
+            quantptr++;
+            wsptr++;
+        }
 
 /* Pass 2: process rows from work array, store into output array. */
 /* Note that we must descale the results by a factor of 8 == 2**3, */
@@ -458,897 +506,1042 @@
 #define PASS1_BITS 0
 #define IDESCALE(x, n) ((int)((x) >> (n)))
 
-    wsptr = workspace;
-    for (ctr = 0; ctr < dctsize; ctr++) {
-      outptr = data + ctr * 8;
+        wsptr = workspace;
+        for (ctr = 0; ctr < dctsize; ctr++)
+        {
+            outptr = data + ctr * 8;
 
-      /* Rows of zeroes can be exploited in the same way as we did with columns.
-       * However, the column calculation has created many nonzero AC terms, so
-       * the simplification applies less often (typically 5% to 10% of the
-       * time). On machines with very fast multiplication, it's possible that
-       * the test takes more time than it's worth.  In that case this section
-       * may be commented out.
-       */
-      /* Even part */
+            /* Rows of zeroes can be exploited in the same way as we did with
+             * columns. However, the column calculation has created many nonzero
+             * AC terms, so the simplification applies less often (typically 5%
+             * to 10% of the time). On machines with very fast multiplication,
+             * it's possible that the test takes more time than it's worth.  In
+             * that case this section may be commented out.
+             */
+            /* Even part */
 
-      tmp10 = (wsptr[0] + wsptr[4]);
-      tmp11 = (wsptr[0] - wsptr[4]);
+            tmp10 = (wsptr[0] + wsptr[4]);
+            tmp11 = (wsptr[0] - wsptr[4]);
 
-      tmp13 = (wsptr[2] + wsptr[6]);
-      tmp12 = MULTIPLY((int)wsptr[2] - (int)wsptr[6], FIX_1_414213562) - tmp13;
+            tmp13 = (wsptr[2] + wsptr[6]);
+            tmp12 = MULTIPLY((int)wsptr[2] - (int)wsptr[6], FIX_1_414213562) -
+                    tmp13;
 
-      tmp0 = tmp10 + tmp13;
-      tmp3 = tmp10 - tmp13;
-      tmp1 = tmp11 + tmp12;
-      tmp2 = tmp11 - tmp12;
+            tmp0 = tmp10 + tmp13;
+            tmp3 = tmp10 - tmp13;
+            tmp1 = tmp11 + tmp12;
+            tmp2 = tmp11 - tmp12;
 
-      /* Odd part */
+            /* Odd part */
 
-      z13 = wsptr[5] + wsptr[3];
-      z10 = wsptr[5] - wsptr[3];
-      z11 = wsptr[1] + wsptr[7];
-      z12 = wsptr[1] - wsptr[7];
+            z13 = wsptr[5] + wsptr[3];
+            z10 = wsptr[5] - wsptr[3];
+            z11 = wsptr[1] + wsptr[7];
+            z12 = wsptr[1] - wsptr[7];
 
-      tmp7 = z11 + z13;                             /* phase 5 */
-      tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
+            tmp7 = z11 + z13;                             /* phase 5 */
+            tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
 
-      z5 = MULTIPLY(z10 + z12, FIX_1_847759065);    /* 2*c2 */
-      tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5;  /* 2*(c2-c6) */
-      tmp12 = MULTIPLY(z10, -FIX_2_613125930) + z5; /* -2*(c2+c6) */
+            z5 = MULTIPLY(z10 + z12, FIX_1_847759065);    /* 2*c2 */
+            tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5;  /* 2*(c2-c6) */
+            tmp12 = MULTIPLY(z10, -FIX_2_613125930) + z5; /* -2*(c2+c6) */
 
-      tmp6 = tmp12 - tmp7; /* phase 2 */
-      tmp5 = tmp11 - tmp6;
-      tmp4 = tmp10 + tmp5;
+            tmp6 = tmp12 - tmp7; /* phase 2 */
+            tmp5 = tmp11 - tmp6;
+            tmp4 = tmp10 + tmp5;
 
-      /* Final output stage: scale down by a factor of 8 and range-limit */
+            /* Final output stage: scale down by a factor of 8 and range-limit
+             */
 
-      outptr[0] = rLimit[IDESCALE((tmp0 + tmp7), (PASS1_BITS + 3)) & 1023L];
-      outptr[7] = rLimit[IDESCALE((tmp0 - tmp7), (PASS1_BITS + 3)) & 1023L];
-      outptr[1] = rLimit[IDESCALE((tmp1 + tmp6), (PASS1_BITS + 3)) & 1023L];
-      outptr[6] = rLimit[IDESCALE((tmp1 - tmp6), (PASS1_BITS + 3)) & 1023L];
-      outptr[2] = rLimit[IDESCALE((tmp2 + tmp5), (PASS1_BITS + 3)) & 1023L];
-      outptr[5] = rLimit[IDESCALE((tmp2 - tmp5), (PASS1_BITS + 3)) & 1023L];
-      outptr[4] = rLimit[IDESCALE((tmp3 + tmp4), (PASS1_BITS + 3)) & 1023L];
-      outptr[3] = rLimit[IDESCALE((tmp3 - tmp4), (PASS1_BITS + 3)) & 1023L];
+            outptr[0] =
+                rLimit[IDESCALE((tmp0 + tmp7), (PASS1_BITS + 3)) & 1023L];
+            outptr[7] =
+                rLimit[IDESCALE((tmp0 - tmp7), (PASS1_BITS + 3)) & 1023L];
+            outptr[1] =
+                rLimit[IDESCALE((tmp1 + tmp6), (PASS1_BITS + 3)) & 1023L];
+            outptr[6] =
+                rLimit[IDESCALE((tmp1 - tmp6), (PASS1_BITS + 3)) & 1023L];
+            outptr[2] =
+                rLimit[IDESCALE((tmp2 + tmp5), (PASS1_BITS + 3)) & 1023L];
+            outptr[5] =
+                rLimit[IDESCALE((tmp2 - tmp5), (PASS1_BITS + 3)) & 1023L];
+            outptr[4] =
+                rLimit[IDESCALE((tmp3 + tmp4), (PASS1_BITS + 3)) & 1023L];
+            outptr[3] =
+                rLimit[IDESCALE((tmp3 - tmp4), (PASS1_BITS + 3)) & 1023L];
 
-      wsptr += dctsize; /* advance pointer to next row */
+            wsptr += dctsize; /* advance pointer to next row */
+        }
     }
-  }
-  void yuvToRgb(
-      int txb, int tyb,
-      unsigned char
-          *pYCbCr,       // in, Y: 256 or 64 bytes; Cb: 64 bytes; Cr: 64 bytes
-      struct RGB *pYUV,  // in, Y: 256 or 64 bytes; Cb: 64 bytes; Cr: 64 bytes
-      unsigned char
-          *pBgr  // out, BGR format, 16*16*3 = 768 bytes; or 8*8*3=192 bytes
-  ) {
-    int i, j, pos, m, n;
-    unsigned char cb, cr, *py, *pcb, *pcr, *py420[4];
-    int y;
-    struct RGB *pByte;
-    int nBlocksInMcu = 6;
-    unsigned int pixelX, pixelY;
+    void yuvToRgb(
+        int txb, int tyb,
+        unsigned char
+            *pYCbCr,      // in, Y: 256 or 64 bytes; Cb: 64 bytes; Cr: 64 bytes
+        struct RGB *pYUV, // in, Y: 256 or 64 bytes; Cb: 64 bytes; Cr: 64 bytes
+        unsigned char
+            *pBgr // out, BGR format, 16*16*3 = 768 bytes; or 8*8*3=192 bytes
+    )
+    {
+        int i, j, pos, m, n;
+        unsigned char cb, cr, *py, *pcb, *pcr, *py420[4];
+        int y;
+        struct RGB *pByte;
+        int nBlocksInMcu = 6;
+        unsigned int pixelX, pixelY;
 
-    pByte = reinterpret_cast<struct RGB *>(pBgr);
-    if (yuvmode == YuvMode::YUV444) {
-      py = pYCbCr;
-      pcb = pYCbCr + 64;
-      pcr = pcb + 64;
+        pByte = reinterpret_cast<struct RGB *>(pBgr);
+        if (yuvmode == YuvMode::YUV444)
+        {
+            py = pYCbCr;
+            pcb = pYCbCr + 64;
+            pcr = pcb + 64;
 
-      pixelX = txb * 8;
-      pixelY = tyb * 8;
-      pos = (pixelY * width) + pixelX;
+            pixelX = txb * 8;
+            pixelY = tyb * 8;
+            pos = (pixelY * width) + pixelX;
 
-      for (j = 0; j < 8; j++) {
-        for (i = 0; i < 8; i++) {
-          m = ((j << 3) + i);
-          y = py[m];
-          cb = pcb[m];
-          cr = pcr[m];
-          n = pos + i;
-          // For 2Pass. Save the YUV value
-          pYUV[n].b = cb;
-          pYUV[n].g = y;
-          pYUV[n].r = cr;
-          pByte[n].b = rlimitTable[mY[y] + mCbToB[cb]];
-          pByte[n].g = rlimitTable[mY[y] + mCbToG[cb] + mCrToG[cr]];
-          pByte[n].r = rlimitTable[mY[y] + mCrToR[cr]];
+            for (j = 0; j < 8; j++)
+            {
+                for (i = 0; i < 8; i++)
+                {
+                    m = ((j << 3) + i);
+                    y = py[m];
+                    cb = pcb[m];
+                    cr = pcr[m];
+                    n = pos + i;
+                    // For 2Pass. Save the YUV value
+                    pYUV[n].b = cb;
+                    pYUV[n].g = y;
+                    pYUV[n].r = cr;
+                    pByte[n].b = rlimitTable[mY[y] + mCbToB[cb]];
+                    pByte[n].g = rlimitTable[mY[y] + mCbToG[cb] + mCrToG[cr]];
+                    pByte[n].r = rlimitTable[mY[y] + mCrToR[cr]];
+                }
+                pos += width;
+            }
         }
-        pos += width;
-      }
-    } else {
-      for (i = 0; i < nBlocksInMcu - 2; i++) {
-        py420[i] = pYCbCr + i * 64;
-      }
-      pcb = pYCbCr + (nBlocksInMcu - 2) * 64;
-      pcr = pcb + 64;
+        else
+        {
+            for (i = 0; i < nBlocksInMcu - 2; i++)
+            {
+                py420[i] = pYCbCr + i * 64;
+            }
+            pcb = pYCbCr + (nBlocksInMcu - 2) * 64;
+            pcr = pcb + 64;
 
-      pixelX = txb * 16;
-      pixelY = tyb * 16;
-      pos = (pixelY * width) + pixelX;
+            pixelX = txb * 16;
+            pixelY = tyb * 16;
+            pos = (pixelY * width) + pixelX;
 
-      for (j = 0; j < 16; j++) {
-        for (i = 0; i < 16; i++) {
-          //	block number is ((j/8) * 2 + i/8)={0, 1, 2, 3}
-          y = *(py420[(j >> 3) * 2 + (i >> 3)]++);
-          m = ((j >> 1) << 3) + (i >> 1);
-          cb = pcb[m];
-          cr = pcr[m];
-          n = pos + i;
-          pByte[n].b = rlimitTable[mY[y] + mCbToB[cb]];
-          pByte[n].g = rlimitTable[mY[y] + mCbToG[cb] + mCrToG[cr]];
-          pByte[n].r = rlimitTable[mY[y] + mCrToR[cr]];
+            for (j = 0; j < 16; j++)
+            {
+                for (i = 0; i < 16; i++)
+                {
+                    //	block number is ((j/8) * 2 + i/8)={0, 1, 2, 3}
+                    y = *(py420[(j >> 3) * 2 + (i >> 3)]++);
+                    m = ((j >> 1) << 3) + (i >> 1);
+                    cb = pcb[m];
+                    cr = pcr[m];
+                    n = pos + i;
+                    pByte[n].b = rlimitTable[mY[y] + mCbToB[cb]];
+                    pByte[n].g = rlimitTable[mY[y] + mCbToG[cb] + mCrToG[cr]];
+                    pByte[n].r = rlimitTable[mY[y] + mCrToR[cr]];
+                }
+                pos += width;
+            }
         }
-        pos += width;
-      }
     }
-  }
-  void yuvToBuffer(
-      int txb, int tyb,
-      unsigned char
-          *pYCbCr,  // in, Y: 256 or 64 bytes; Cb: 64 bytes; Cr: 64 bytes
-      struct RGB
-          *pYUV,  // out, BGR format, 16*16*3 = 768 bytes; or 8*8*3=192 bytes
-      unsigned char
-          *pBgr  // out, BGR format, 16*16*3 = 768 bytes; or 8*8*3=192 bytes
-  ) {
-    int i, j, pos, m, n;
-    unsigned char cb, cr, *py, *pcb, *pcr, *py420[4];
-    int y;
-    struct RGB *pByte;
-    int nBlocksInMcu = 6;
-    unsigned int pixelX, pixelY;
+    void yuvToBuffer(
+        int txb, int tyb,
+        unsigned char
+            *pYCbCr, // in, Y: 256 or 64 bytes; Cb: 64 bytes; Cr: 64 bytes
+        struct RGB
+            *pYUV, // out, BGR format, 16*16*3 = 768 bytes; or 8*8*3=192 bytes
+        unsigned char
+            *pBgr // out, BGR format, 16*16*3 = 768 bytes; or 8*8*3=192 bytes
+    )
+    {
+        int i, j, pos, m, n;
+        unsigned char cb, cr, *py, *pcb, *pcr, *py420[4];
+        int y;
+        struct RGB *pByte;
+        int nBlocksInMcu = 6;
+        unsigned int pixelX, pixelY;
 
-    pByte = reinterpret_cast<struct RGB *>(pBgr);
-    if (yuvmode == YuvMode::YUV444) {
-      py = pYCbCr;
-      pcb = pYCbCr + 64;
-      pcr = pcb + 64;
+        pByte = reinterpret_cast<struct RGB *>(pBgr);
+        if (yuvmode == YuvMode::YUV444)
+        {
+            py = pYCbCr;
+            pcb = pYCbCr + 64;
+            pcr = pcb + 64;
 
-      pixelX = txb * 8;
-      pixelY = tyb * 8;
-      pos = (pixelY * width) + pixelX;
+            pixelX = txb * 8;
+            pixelY = tyb * 8;
+            pos = (pixelY * width) + pixelX;
 
-      for (j = 0; j < 8; j++) {
-        for (i = 0; i < 8; i++) {
-          m = ((j << 3) + i);
-          n = pos + i;
-          y = pYUV[n].g + (py[m] - 128);
-          cb = pYUV[n].b + (pcb[m] - 128);
-          cr = pYUV[n].r + (pcr[m] - 128);
-          pYUV[n].b = cb;
-          pYUV[n].g = y;
-          pYUV[n].r = cr;
-          pByte[n].b = rlimitTable[mY[y] + mCbToB[cb]];
-          pByte[n].g = rlimitTable[mY[y] + mCbToG[cb] + mCrToG[cr]];
-          pByte[n].r = rlimitTable[mY[y] + mCrToR[cr]];
+            for (j = 0; j < 8; j++)
+            {
+                for (i = 0; i < 8; i++)
+                {
+                    m = ((j << 3) + i);
+                    n = pos + i;
+                    y = pYUV[n].g + (py[m] - 128);
+                    cb = pYUV[n].b + (pcb[m] - 128);
+                    cr = pYUV[n].r + (pcr[m] - 128);
+                    pYUV[n].b = cb;
+                    pYUV[n].g = y;
+                    pYUV[n].r = cr;
+                    pByte[n].b = rlimitTable[mY[y] + mCbToB[cb]];
+                    pByte[n].g = rlimitTable[mY[y] + mCbToG[cb] + mCrToG[cr]];
+                    pByte[n].r = rlimitTable[mY[y] + mCrToR[cr]];
+                }
+                pos += width;
+            }
         }
-        pos += width;
-      }
-    } else {
-      for (i = 0; i < nBlocksInMcu - 2; i++) {
-        py420[i] = pYCbCr + i * 64;
-      }
-      pcb = pYCbCr + (nBlocksInMcu - 2) * 64;
-      pcr = pcb + 64;
+        else
+        {
+            for (i = 0; i < nBlocksInMcu - 2; i++)
+            {
+                py420[i] = pYCbCr + i * 64;
+            }
+            pcb = pYCbCr + (nBlocksInMcu - 2) * 64;
+            pcr = pcb + 64;
 
-      pixelX = txb * 16;
-      pixelY = tyb * 16;
-      pos = (pixelY * width) + pixelX;
+            pixelX = txb * 16;
+            pixelY = tyb * 16;
+            pos = (pixelY * width) + pixelX;
 
-      for (j = 0; j < 16; j++) {
-        for (i = 0; i < 16; i++) {
-          //	block number is ((j/8) * 2 + i/8)={0, 1, 2, 3}
-          y = *(py420[(j >> 3) * 2 + (i >> 3)]++);
-          m = ((j >> 1) << 3) + (i >> 1);
-          cb = pcb[m];
-          cr = pcr[m];
-          n = pos + i;
-          pByte[n].b = rlimitTable[mY[y] + mCbToB[cb]];
-          pByte[n].g = rlimitTable[mY[y] + mCbToG[cb] + mCrToG[cr]];
-          pByte[n].r = rlimitTable[mY[y] + mCrToR[cr]];
+            for (j = 0; j < 16; j++)
+            {
+                for (i = 0; i < 16; i++)
+                {
+                    //	block number is ((j/8) * 2 + i/8)={0, 1, 2, 3}
+                    y = *(py420[(j >> 3) * 2 + (i >> 3)]++);
+                    m = ((j >> 1) << 3) + (i >> 1);
+                    cb = pcb[m];
+                    cr = pcr[m];
+                    n = pos + i;
+                    pByte[n].b = rlimitTable[mY[y] + mCbToB[cb]];
+                    pByte[n].g = rlimitTable[mY[y] + mCbToG[cb] + mCrToG[cr]];
+                    pByte[n].r = rlimitTable[mY[y] + mCrToR[cr]];
+                }
+                pos += width;
+            }
         }
-        pos += width;
-      }
     }
-  }
-  void decompress(int txb, int tyb, char *outBuf, uint8_t QT_TableSelection) {
-    unsigned char *ptr;
-    unsigned char byTileYuv[768] = {};
+    void decompress(int txb, int tyb, char *outBuf, uint8_t QT_TableSelection)
+    {
+        unsigned char *ptr;
+        unsigned char byTileYuv[768] = {};
 
-    memset(dctCoeff, 0, 384 * 2);
-    ptr = byTileYuv;
-    processHuffmanDataUnit(ydcNr, yacNr, &dcy, 0);
-    idctTransform(dctCoeff, ptr, QT_TableSelection);
-    ptr += 64;
+        memset(dctCoeff, 0, 384 * 2);
+        ptr = byTileYuv;
+        processHuffmanDataUnit(ydcNr, yacNr, &dcy, 0);
+        idctTransform(dctCoeff, ptr, QT_TableSelection);
+        ptr += 64;
 
-    if (yuvmode == YuvMode::YUV420) {
-      processHuffmanDataUnit(ydcNr, yacNr, &dcy, 64);
-      idctTransform(dctCoeff + 64, ptr, QT_TableSelection);
-      ptr += 64;
+        if (yuvmode == YuvMode::YUV420)
+        {
+            processHuffmanDataUnit(ydcNr, yacNr, &dcy, 64);
+            idctTransform(dctCoeff + 64, ptr, QT_TableSelection);
+            ptr += 64;
 
-      processHuffmanDataUnit(ydcNr, yacNr, &dcy, 128);
-      idctTransform(dctCoeff + 128, ptr, QT_TableSelection);
-      ptr += 64;
+            processHuffmanDataUnit(ydcNr, yacNr, &dcy, 128);
+            idctTransform(dctCoeff + 128, ptr, QT_TableSelection);
+            ptr += 64;
 
-      processHuffmanDataUnit(ydcNr, yacNr, &dcy, 192);
-      idctTransform(dctCoeff + 192, ptr, QT_TableSelection);
-      ptr += 64;
+            processHuffmanDataUnit(ydcNr, yacNr, &dcy, 192);
+            idctTransform(dctCoeff + 192, ptr, QT_TableSelection);
+            ptr += 64;
 
-      processHuffmanDataUnit(cbDcNr, cbAcNr, &dcCb, 256);
-      idctTransform(dctCoeff + 256, ptr, QT_TableSelection + 1);
-      ptr += 64;
+            processHuffmanDataUnit(cbDcNr, cbAcNr, &dcCb, 256);
+            idctTransform(dctCoeff + 256, ptr, QT_TableSelection + 1);
+            ptr += 64;
 
-      processHuffmanDataUnit(crDcNr, crAcNr, &dcCr, 320);
-      idctTransform(dctCoeff + 320, ptr, QT_TableSelection + 1);
-    } else {
-      processHuffmanDataUnit(cbDcNr, cbAcNr, &dcCb, 64);
-      idctTransform(dctCoeff + 64, ptr, QT_TableSelection + 1);
-      ptr += 64;
+            processHuffmanDataUnit(crDcNr, crAcNr, &dcCr, 320);
+            idctTransform(dctCoeff + 320, ptr, QT_TableSelection + 1);
+        }
+        else
+        {
+            processHuffmanDataUnit(cbDcNr, cbAcNr, &dcCb, 64);
+            idctTransform(dctCoeff + 64, ptr, QT_TableSelection + 1);
+            ptr += 64;
 
-      processHuffmanDataUnit(crDcNr, crAcNr, &dcCr, 128);
-      idctTransform(dctCoeff + 128, ptr, QT_TableSelection + 1);
+            processHuffmanDataUnit(crDcNr, crAcNr, &dcCr, 128);
+            idctTransform(dctCoeff + 128, ptr, QT_TableSelection + 1);
+        }
+
+        //    yuvToRgb (txb, tyb, byTileYuv, (unsigned char *)outBuf);
+        //  yuvBuffer for YUV record
+        yuvToRgb(txb, tyb, byTileYuv, yuvBuffer.data(),
+                 reinterpret_cast<unsigned char *>(outBuf));
     }
 
-    //    yuvToRgb (txb, tyb, byTileYuv, (unsigned char *)outBuf);
-    //  yuvBuffer for YUV record
-    yuvToRgb(txb, tyb, byTileYuv, yuvBuffer.data(),
-             reinterpret_cast<unsigned char *>(outBuf));
-  }
+    void decompress2Pass(int txb, int tyb, char *outBuf,
+                         uint8_t QT_TableSelection)
+    {
+        unsigned char *ptr;
+        unsigned char byTileYuv[768];
+        memset(dctCoeff, 0, 384 * 2);
 
-  void decompress2Pass(int txb, int tyb, char *outBuf,
-                       uint8_t QT_TableSelection) {
-    unsigned char *ptr;
-    unsigned char byTileYuv[768];
-    memset(dctCoeff, 0, 384 * 2);
+        ptr = byTileYuv;
+        processHuffmanDataUnit(ydcNr, yacNr, &dcy, 0);
+        idctTransform(dctCoeff, ptr, QT_TableSelection);
+        ptr += 64;
 
-    ptr = byTileYuv;
-    processHuffmanDataUnit(ydcNr, yacNr, &dcy, 0);
-    idctTransform(dctCoeff, ptr, QT_TableSelection);
-    ptr += 64;
+        processHuffmanDataUnit(cbDcNr, cbAcNr, &dcCb, 64);
+        idctTransform(dctCoeff + 64, ptr, QT_TableSelection + 1);
+        ptr += 64;
 
-    processHuffmanDataUnit(cbDcNr, cbAcNr, &dcCb, 64);
-    idctTransform(dctCoeff + 64, ptr, QT_TableSelection + 1);
-    ptr += 64;
+        processHuffmanDataUnit(crDcNr, crAcNr, &dcCr, 128);
+        idctTransform(dctCoeff + 128, ptr, QT_TableSelection + 1);
 
-    processHuffmanDataUnit(crDcNr, crAcNr, &dcCr, 128);
-    idctTransform(dctCoeff + 128, ptr, QT_TableSelection + 1);
-
-    yuvToBuffer(txb, tyb, byTileYuv, yuvBuffer.data(),
-                reinterpret_cast<unsigned char *>(outBuf));
-    //    yuvToRgb (txb, tyb, byTileYuv, (unsigned char *)outBuf);
-  }
-
-  void vqDecompress(int txb, int tyb, char *outBuf, uint8_t QT_TableSelection,
-                    struct ColorCache *VQ) {
-    unsigned char *ptr, i;
-    unsigned char byTileYuv[192];
-    int data;
-
-    ptr = byTileYuv;
-    if (VQ->bitMapBits == 0) {
-      for (i = 0; i < 64; i++) {
-        ptr[0] = (VQ->color[VQ->index[0]] & 0xFF0000) >> 16;
-        ptr[64] = (VQ->color[VQ->index[0]] & 0x00FF00) >> 8;
-        ptr[128] = VQ->color[VQ->index[0]] & 0x0000FF;
-        ptr += 1;
-      }
-    } else {
-      for (i = 0; i < 64; i++) {
-        data = static_cast<int>(lookKbits(VQ->bitMapBits));
-        ptr[0] = (VQ->color[VQ->index[data]] & 0xFF0000) >> 16;
-        ptr[64] = (VQ->color[VQ->index[data]] & 0x00FF00) >> 8;
-        ptr[128] = VQ->color[VQ->index[data]] & 0x0000FF;
-        ptr += 1;
-        skipKbits(VQ->bitMapBits);
-      }
+        yuvToBuffer(txb, tyb, byTileYuv, yuvBuffer.data(),
+                    reinterpret_cast<unsigned char *>(outBuf));
+        //    yuvToRgb (txb, tyb, byTileYuv, (unsigned char *)outBuf);
     }
-    //    yuvToRgb (txb, tyb, byTileYuv, (unsigned char *)outBuf);
-    yuvToRgb(txb, tyb, byTileYuv, yuvBuffer.data(),
-             reinterpret_cast<unsigned char *>(outBuf));
-  }
 
-  void moveBlockIndex() {
-    if (yuvmode == YuvMode::YUV444) {
-      txb++;
-      if (txb >= static_cast<int>(width / 8)) {
-        tyb++;
-        if (tyb >= static_cast<int>(height / 8)) {
-          tyb = 0;
+    void vqDecompress(int txb, int tyb, char *outBuf, uint8_t QT_TableSelection,
+                      struct ColorCache *VQ)
+    {
+        unsigned char *ptr, i;
+        unsigned char byTileYuv[192];
+        int data;
+
+        ptr = byTileYuv;
+        if (VQ->bitMapBits == 0)
+        {
+            for (i = 0; i < 64; i++)
+            {
+                ptr[0] = (VQ->color[VQ->index[0]] & 0xFF0000) >> 16;
+                ptr[64] = (VQ->color[VQ->index[0]] & 0x00FF00) >> 8;
+                ptr[128] = VQ->color[VQ->index[0]] & 0x0000FF;
+                ptr += 1;
+            }
         }
-        txb = 0;
-      }
-    } else {
-      txb++;
-      if (txb >= static_cast<int>(width / 16)) {
-        tyb++;
-        if (tyb >= static_cast<int>(height / 16)) {
-          tyb = 0;
+        else
+        {
+            for (i = 0; i < 64; i++)
+            {
+                data = static_cast<int>(lookKbits(VQ->bitMapBits));
+                ptr[0] = (VQ->color[VQ->index[data]] & 0xFF0000) >> 16;
+                ptr[64] = (VQ->color[VQ->index[data]] & 0x00FF00) >> 8;
+                ptr[128] = VQ->color[VQ->index[data]] & 0x0000FF;
+                ptr += 1;
+                skipKbits(VQ->bitMapBits);
+            }
         }
-        txb = 0;
-      }
+        //    yuvToRgb (txb, tyb, byTileYuv, (unsigned char *)outBuf);
+        yuvToRgb(txb, tyb, byTileYuv, yuvBuffer.data(),
+                 reinterpret_cast<unsigned char *>(outBuf));
     }
-  }
 
-  void initColorTable() {
-    int i, x;
-    int nScale = 1L << 16;  // equal to power(2,16)
-    int nHalf = nScale >> 1;
+    void moveBlockIndex()
+    {
+        if (yuvmode == YuvMode::YUV444)
+        {
+            txb++;
+            if (txb >= static_cast<int>(width / 8))
+            {
+                tyb++;
+                if (tyb >= static_cast<int>(height / 8))
+                {
+                    tyb = 0;
+                }
+                txb = 0;
+            }
+        }
+        else
+        {
+            txb++;
+            if (txb >= static_cast<int>(width / 16))
+            {
+                tyb++;
+                if (tyb >= static_cast<int>(height / 16))
+                {
+                    tyb = 0;
+                }
+                txb = 0;
+            }
+        }
+    }
+
+    void initColorTable()
+    {
+        int i, x;
+        int nScale = 1L << 16; // equal to power(2,16)
+        int nHalf = nScale >> 1;
 
 #define FIX(x) ((int)((x)*nScale + 0.5))
 
-    /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
-    /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
-    /* Cr=>r value is nearest int to 1.597656 * x */
-    /* Cb=>b value is nearest int to 2.015625 * x */
-    /* Cr=>g value is scaled-up -0.8125 * x */
-    /* Cb=>g value is scaled-up -0.390625 * x */
-    for (i = 0, x = -128; i < 256; i++, x++) {
-      mCrToR[i] = (FIX(1.597656) * x + nHalf) >> 16;
-      mCbToB[i] = (FIX(2.015625) * x + nHalf) >> 16;
-      mCrToG[i] = (-FIX(0.8125) * x + nHalf) >> 16;
-      mCbToG[i] = (-FIX(0.390625) * x + nHalf) >> 16;
-    }
-    for (i = 0, x = -16; i < 256; i++, x++) {
-      mY[i] = (FIX(1.164) * x + nHalf) >> 16;
-    }
-    // For color Text Enchance Y Re-map. Recommend to disable in default
-    /*
-            for (i = 0; i < (VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate);
-       i++) {
-                    temp = (double)i /
-       VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate;
-                    temp1 = 1.0 / VideoEngineInfo->INFData.Gamma1Parameter;
-                    mY[i] =
-       (BYTE)(VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate * pow (temp,
-       temp1));
-                    if (mY[i] > 255) mY[i] = 255;
-            }
-            for (i = (VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate); i < 256;
-       i++) {
-                    mY[i] =
-       (BYTE)((VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate) + (256 -
-       VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate) * ( pow((double)((i -
-       VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate) / (256 -
-       (VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate))), (1.0 /
-       VideoEngineInfo->INFData.Gamma2Parameter)) ));
-                    if (mY[i] > 255) mY[i] = 255;
-            }
-    */
-  }
-  void loadHuffmanTable(HuffmanTable *HT, const unsigned char *nrcode,
-                        const unsigned char *value,
-                        const unsigned short int *Huff_code) {
-    unsigned char k, j, i;
-    unsigned int code, codeIndex;
-
-    for (j = 1; j <= 16; j++) {
-      HT->length[j] = nrcode[j];
-    }
-    for (i = 0, k = 1; k <= 16; k++) {
-      for (j = 0; j < HT->length[k]; j++) {
-        HT->v[wordHiLo(k, j)] = value[i];
-        i++;
-      }
-    }
-
-    code = 0;
-    for (k = 1; k <= 16; k++) {
-      HT->minorCode[k] = static_cast<unsigned short int>(code);
-      for (j = 1; j <= HT->length[k]; j++) {
-        code++;
-      }
-      HT->majorCode[k] = static_cast<unsigned short int>(code - 1);
-      code *= 2;
-      if (HT->length[k] == 0) {
-        HT->minorCode[k] = 0xFFFF;
-        HT->majorCode[k] = 0;
-      }
-    }
-
-    HT->len[0] = 2;
-    i = 2;
-
-    for (codeIndex = 1; codeIndex < 65535; codeIndex++) {
-      if (codeIndex < Huff_code[i]) {
-        HT->len[codeIndex] = static_cast<unsigned char>(Huff_code[i + 1]);
-      } else {
-        i = i + 2;
-        HT->len[codeIndex] = static_cast<unsigned char>(Huff_code[i + 1]);
-      }
-    }
-  }
-  void initJpgTable() {
-    initColorTable();
-    prepareRangeLimitTable();
-    loadHuffmanTable(&htdc[0], stdDcLuminanceNrcodes, stdDcLuminanceValues,
-                     dcLuminanceHuffmancode);
-    loadHuffmanTable(&htac[0], stdAcLuminanceNrcodes, stdAcLuminanceValues,
-                     acLuminanceHuffmancode);
-    loadHuffmanTable(&htdc[1], stdDcChrominanceNrcodes, stdDcChrominanceValues,
-                     dcChrominanceHuffmancode);
-    loadHuffmanTable(&htac[1], stdAcChrominanceNrcodes, stdAcChrominanceValues,
-                     acChrominanceHuffmancode);
-  }
-
-  void prepareRangeLimitTable()
-  /* Allocate and fill in the sample_range_limit table */
-  {
-    int j;
-    rlimitTable = reinterpret_cast<unsigned char *>(malloc(5 * 256L + 128));
-    /* First segment of "simple" table: limit[x] = 0 for x < 0 */
-    memset((void *)rlimitTable, 0, 256);
-    rlimitTable += 256; /* allow negative subscripts of simple table */
-    /* Main part of "simple" table: limit[x] = x */
-    for (j = 0; j < 256; j++) {
-      rlimitTable[j] = j;
-    }
-    /* End of simple table, rest of first half of post-IDCT table */
-    for (j = 256; j < 640; j++) {
-      rlimitTable[j] = 255;
-    }
-
-    /* Second half of post-IDCT table */
-    memset((void *)(rlimitTable + 640), 0, 384);
-    for (j = 0; j < 128; j++) {
-      rlimitTable[j + 1024] = j;
-    }
-  }
-
-  inline unsigned short int wordHiLo(uint8_t byte_high, uint8_t byte_low) {
-    return (byte_high << 8) + byte_low;
-  }
-
-  // river
-  void processHuffmanDataUnit(uint8_t DC_nr, uint8_t AC_nr,
-                              signed short int *previous_DC,
-                              unsigned short int position) {
-    uint8_t nr = 0;
-    uint8_t k;
-    unsigned short int tmpHcode;
-    uint8_t sizeVal, count0;
-    unsigned short int *minCode;
-    uint8_t *huffValues;
-    uint8_t byteTemp;
-
-    minCode = htdc[DC_nr].minorCode;
-    //   maj_code=htdc[DC_nr].majorCode;
-    huffValues = htdc[DC_nr].v;
-
-    // DC
-    k = htdc[DC_nr].len[static_cast<unsigned short int>(codebuf >> 16)];
-    // river
-    //	 tmp_Hcode=lookKbits(k);
-    tmpHcode = static_cast<unsigned short int>(codebuf >> (32 - k));
-    skipKbits(k);
-    sizeVal =
-        huffValues[wordHiLo(k, static_cast<uint8_t>(tmpHcode - minCode[k]))];
-    if (sizeVal == 0) {
-      dctCoeff[position + 0] = *previous_DC;
-    } else {
-      dctCoeff[position + 0] = *previous_DC + getKbits(sizeVal);
-      *previous_DC = dctCoeff[position + 0];
-    }
-
-    // Second, AC coefficient decoding
-    minCode = htac[AC_nr].minorCode;
-    //   maj_code=htac[AC_nr].majorCode;
-    huffValues = htac[AC_nr].v;
-
-    nr = 1;  // AC coefficient
-    do {
-      k = htac[AC_nr].len[static_cast<unsigned short int>(codebuf >> 16)];
-      tmpHcode = static_cast<unsigned short int>(codebuf >> (32 - k));
-      skipKbits(k);
-
-      byteTemp =
-          huffValues[wordHiLo(k, static_cast<uint8_t>(tmpHcode - minCode[k]))];
-      sizeVal = byteTemp & 0xF;
-      count0 = byteTemp >> 4;
-      if (sizeVal == 0) {
-        if (count0 != 0xF) {
-          break;
+        /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
+        /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
+        /* Cr=>r value is nearest int to 1.597656 * x */
+        /* Cb=>b value is nearest int to 2.015625 * x */
+        /* Cr=>g value is scaled-up -0.8125 * x */
+        /* Cb=>g value is scaled-up -0.390625 * x */
+        for (i = 0, x = -128; i < 256; i++, x++)
+        {
+            mCrToR[i] = (FIX(1.597656) * x + nHalf) >> 16;
+            mCbToB[i] = (FIX(2.015625) * x + nHalf) >> 16;
+            mCrToG[i] = (-FIX(0.8125) * x + nHalf) >> 16;
+            mCbToG[i] = (-FIX(0.390625) * x + nHalf) >> 16;
         }
-        nr += 16;
-      } else {
-        nr += count0;  // skip count_0 zeroes
-        dctCoeff[position + dezigzag[nr++]] = getKbits(sizeVal);
-      }
-    } while (nr < 64);
-  }
-
-  unsigned short int lookKbits(uint8_t k) {
-    unsigned short int revcode;
-
-    revcode = static_cast<unsigned short int>(codebuf >> (32 - k));
-
-    return (revcode);
-  }
-
-  void skipKbits(uint8_t k) {
-    unsigned long readbuf;
-
-    if ((newbits - k) <= 0) {
-      readbuf = buffer[bufferIndex];
-      bufferIndex++;
-      codebuf =
-          (codebuf << k) | ((newbuf | (readbuf >> (newbits))) >> (32 - k));
-      newbuf = readbuf << (k - newbits);
-      newbits = 32 + newbits - k;
-    } else {
-      codebuf = (codebuf << k) | (newbuf >> (32 - k));
-      newbuf = newbuf << k;
-      newbits -= k;
+        for (i = 0, x = -16; i < 256; i++, x++)
+        {
+            mY[i] = (FIX(1.164) * x + nHalf) >> 16;
+        }
+        // For color Text Enchance Y Re-map. Recommend to disable in default
+        /*
+                for (i = 0; i <
+           (VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate); i++) { temp =
+           (double)i / VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate; temp1
+           = 1.0 / VideoEngineInfo->INFData.Gamma1Parameter; mY[i] =
+           (BYTE)(VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate * pow (temp,
+           temp1));
+                        if (mY[i] > 255) mY[i] = 255;
+                }
+                for (i = (VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate); i <
+           256; i++) { mY[i] =
+           (BYTE)((VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate) + (256 -
+           VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate) * ( pow((double)((i
+           - VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate) / (256 -
+           (VideoEngineInfo->INFData.Gamma1_Gamma2_Seperate))), (1.0 /
+           VideoEngineInfo->INFData.Gamma2Parameter)) ));
+                        if (mY[i] > 255) mY[i] = 255;
+                }
+        */
     }
-  }
+    void loadHuffmanTable(HuffmanTable *HT, const unsigned char *nrcode,
+                          const unsigned char *value,
+                          const unsigned short int *Huff_code)
+    {
+        unsigned char k, j, i;
+        unsigned int code, codeIndex;
 
-  signed short int getKbits(uint8_t k) {
-    signed short int signedWordvalue;
+        for (j = 1; j <= 16; j++)
+        {
+            HT->length[j] = nrcode[j];
+        }
+        for (i = 0, k = 1; k <= 16; k++)
+        {
+            for (j = 0; j < HT->length[k]; j++)
+            {
+                HT->v[wordHiLo(k, j)] = value[i];
+                i++;
+            }
+        }
+
+        code = 0;
+        for (k = 1; k <= 16; k++)
+        {
+            HT->minorCode[k] = static_cast<unsigned short int>(code);
+            for (j = 1; j <= HT->length[k]; j++)
+            {
+                code++;
+            }
+            HT->majorCode[k] = static_cast<unsigned short int>(code - 1);
+            code *= 2;
+            if (HT->length[k] == 0)
+            {
+                HT->minorCode[k] = 0xFFFF;
+                HT->majorCode[k] = 0;
+            }
+        }
+
+        HT->len[0] = 2;
+        i = 2;
+
+        for (codeIndex = 1; codeIndex < 65535; codeIndex++)
+        {
+            if (codeIndex < Huff_code[i])
+            {
+                HT->len[codeIndex] =
+                    static_cast<unsigned char>(Huff_code[i + 1]);
+            }
+            else
+            {
+                i = i + 2;
+                HT->len[codeIndex] =
+                    static_cast<unsigned char>(Huff_code[i + 1]);
+            }
+        }
+    }
+    void initJpgTable()
+    {
+        initColorTable();
+        prepareRangeLimitTable();
+        loadHuffmanTable(&htdc[0], stdDcLuminanceNrcodes, stdDcLuminanceValues,
+                         dcLuminanceHuffmancode);
+        loadHuffmanTable(&htac[0], stdAcLuminanceNrcodes, stdAcLuminanceValues,
+                         acLuminanceHuffmancode);
+        loadHuffmanTable(&htdc[1], stdDcChrominanceNrcodes,
+                         stdDcChrominanceValues, dcChrominanceHuffmancode);
+        loadHuffmanTable(&htac[1], stdAcChrominanceNrcodes,
+                         stdAcChrominanceValues, acChrominanceHuffmancode);
+    }
+
+    void prepareRangeLimitTable()
+    /* Allocate and fill in the sample_range_limit table */
+    {
+        int j;
+        rlimitTable = reinterpret_cast<unsigned char *>(malloc(5 * 256L + 128));
+        /* First segment of "simple" table: limit[x] = 0 for x < 0 */
+        memset((void *)rlimitTable, 0, 256);
+        rlimitTable += 256; /* allow negative subscripts of simple table */
+        /* Main part of "simple" table: limit[x] = x */
+        for (j = 0; j < 256; j++)
+        {
+            rlimitTable[j] = j;
+        }
+        /* End of simple table, rest of first half of post-IDCT table */
+        for (j = 256; j < 640; j++)
+        {
+            rlimitTable[j] = 255;
+        }
+
+        /* Second half of post-IDCT table */
+        memset((void *)(rlimitTable + 640), 0, 384);
+        for (j = 0; j < 128; j++)
+        {
+            rlimitTable[j + 1024] = j;
+        }
+    }
+
+    inline unsigned short int wordHiLo(uint8_t byte_high, uint8_t byte_low)
+    {
+        return (byte_high << 8) + byte_low;
+    }
 
     // river
-    // signed_wordvalue=lookKbits(k);
-    signedWordvalue = static_cast<unsigned short int>(codebuf >> (32 - k));
-    if (((1L << (k - 1)) & signedWordvalue) == 0) {
-      // neg_pow2 was previously defined as the below.  It seemed silly to keep
-      // a table of values around for something
-      // THat's relatively easy to compute, so it was replaced with the
-      // appropriate math
-      // signed_wordvalue = signed_wordvalue - (0xFFFF >> (16 - k));
-      std::array<signed short int, 17> negPow2 = {
-          0,    -1,   -3,    -7,    -15,   -31,   -63,    -127,
-          -255, -511, -1023, -2047, -4095, -8191, -16383, -32767};
+    void processHuffmanDataUnit(uint8_t DC_nr, uint8_t AC_nr,
+                                signed short int *previous_DC,
+                                unsigned short int position)
+    {
+        uint8_t nr = 0;
+        uint8_t k;
+        unsigned short int tmpHcode;
+        uint8_t sizeVal, count0;
+        unsigned short int *minCode;
+        uint8_t *huffValues;
+        uint8_t byteTemp;
 
-      signedWordvalue = signedWordvalue + negPow2[k];
-    }
-    skipKbits(k);
-    return signedWordvalue;
-  }
-  int initJpgDecoding() {
-    bytePos = 0;
-    loadQuantTable(qt[0]);
-    loadQuantTableCb(qt[1]);
-    //  Note: Added for Dual-JPEG
-    loadAdvanceQuantTable(qt[2]);
-    loadAdvanceQuantTableCb(qt[3]);
-    return 1;
-  }
+        minCode = htdc[DC_nr].minorCode;
+        //   maj_code=htdc[DC_nr].majorCode;
+        huffValues = htdc[DC_nr].v;
 
-  void setQuantTable(const uint8_t *basic_table, uint8_t scale_factor,
-                     std::array<uint8_t, 64> &newtable)
-  // Set quantization table and zigzag reorder it
-  {
-    uint8_t i;
-    long temp;
-    for (i = 0; i < 64; i++) {
-      temp = (static_cast<long>(basic_table[i] * 16) / scale_factor);
-      /* limit the values to the valid range */
-      if (temp <= 0L) {
-        temp = 1L;
-      }
-      if (temp > 255L) {
-        temp = 255L; /* limit to baseline range if requested */
-      }
-      newtable[zigzag[i]] = static_cast<uint8_t>(temp);
-    }
-  }
-
-  void updatereadbuf(uint32_t *codebuf, uint32_t *newbuf, int walks,
-                     int *newbits, std::vector<uint32_t> &buffer) {
-    unsigned long readbuf;
-
-    if ((*newbits - walks) <= 0) {
-      readbuf = buffer[bufferIndex];
-      bufferIndex++;
-      *codebuf = (*codebuf << walks) |
-                 ((*newbuf | (readbuf >> (*newbits))) >> (32 - walks));
-      *newbuf = readbuf << (walks - *newbits);
-      *newbits = 32 + *newbits - walks;
-    } else {
-      *codebuf = (*codebuf << walks) | (*newbuf >> (32 - walks));
-      *newbuf = *newbuf << walks;
-      *newbits -= walks;
-    }
-  }
-
-  uint32_t decode(std::vector<uint32_t> &bufferVector, unsigned long width,
-                  unsigned long height, YuvMode yuvmode_in, int ySelector,
-                  int uvSelector) {
-    ColorCache decodeColor;
-    if (width != userWidth || height != userHeight || yuvmode_in != yuvmode ||
-        ySelector != ySelector || uvSelector != uvSelector) {
-      yuvmode = yuvmode_in;
-      ySelector = ySelector;    // 0-7
-      uvSelector = uvSelector;  // 0-7
-      userHeight = height;
-      userWidth = width;
-      width = width;
-      height = height;
-
-      // TODO(ed) Magic number section.  Document appropriately
-      advanceSelector = 0;  // 0-7
-      mapping = 0;          // 0 or 1
-
-      if (yuvmode == YuvMode::YUV420) {
-        if ((width % 16) != 0u) {
-          width = width + 16 - (width % 16);
+        // DC
+        k = htdc[DC_nr].len[static_cast<unsigned short int>(codebuf >> 16)];
+        // river
+        //	 tmp_Hcode=lookKbits(k);
+        tmpHcode = static_cast<unsigned short int>(codebuf >> (32 - k));
+        skipKbits(k);
+        sizeVal = huffValues[wordHiLo(
+            k, static_cast<uint8_t>(tmpHcode - minCode[k]))];
+        if (sizeVal == 0)
+        {
+            dctCoeff[position + 0] = *previous_DC;
         }
-        if ((height % 16) != 0u) {
-          height = height + 16 - (height % 16);
+        else
+        {
+            dctCoeff[position + 0] = *previous_DC + getKbits(sizeVal);
+            *previous_DC = dctCoeff[position + 0];
         }
-      } else {
-        if ((width % 8) != 0u) {
-          width = width + 8 - (width % 8);
-        }
-        if ((height % 8) != 0u) {
-          height = height + 8 - (height % 8);
-        }
-      }
 
-      initJpgDecoding();
+        // Second, AC coefficient decoding
+        minCode = htac[AC_nr].minorCode;
+        //   maj_code=htac[AC_nr].majorCode;
+        huffValues = htac[AC_nr].v;
+
+        nr = 1; // AC coefficient
+        do
+        {
+            k = htac[AC_nr].len[static_cast<unsigned short int>(codebuf >> 16)];
+            tmpHcode = static_cast<unsigned short int>(codebuf >> (32 - k));
+            skipKbits(k);
+
+            byteTemp = huffValues[wordHiLo(
+                k, static_cast<uint8_t>(tmpHcode - minCode[k]))];
+            sizeVal = byteTemp & 0xF;
+            count0 = byteTemp >> 4;
+            if (sizeVal == 0)
+            {
+                if (count0 != 0xF)
+                {
+                    break;
+                }
+                nr += 16;
+            }
+            else
+            {
+                nr += count0; // skip count_0 zeroes
+                dctCoeff[position + dezigzag[nr++]] = getKbits(sizeVal);
+            }
+        } while (nr < 64);
     }
-    // TODO(ed) cleanup cruft
-    buffer = bufferVector.data();
 
-    codebuf = bufferVector[0];
-    newbuf = bufferVector[1];
-    bufferIndex = 2;
+    unsigned short int lookKbits(uint8_t k)
+    {
+        unsigned short int revcode;
 
-    txb = tyb = 0;
-    newbits = 32;
-    dcy = dcCb = dcCr = 0;
+        revcode = static_cast<unsigned short int>(codebuf >> (32 - k));
 
-    static const uint32_t vqHeaderMask = 0x01;
-    static const uint32_t vqNoUpdateHeader = 0x00;
-    static const uint32_t vqUpdateHeader = 0x01;
-    static const int vqNoUpdateLength = 0x03;
-    static const int vqUpdateLength = 0x1B;
-    static const uint32_t vqIndexMask = 0x03;
-    static const uint32_t vqColorMask = 0xFFFFFF;
+        return (revcode);
+    }
 
-    static const int blockAsT2100StartLength = 0x04;
-    static const int blockAsT2100SkipLength = 20;  // S:1 H:3 X:8 Y:8
+    void skipKbits(uint8_t k)
+    {
+        unsigned long readbuf;
 
-    do {
-      auto blockHeader = static_cast<JpgBlock>((codebuf >> 28) & 0xFF);
-      switch (blockHeader) {
-        case JpgBlock::JPEG_NO_SKIP_CODE:
-          updatereadbuf(&codebuf, &newbuf, blockAsT2100StartLength, &newbits,
-                        bufferVector);
-          decompress(txb, tyb, reinterpret_cast<char *>(outBuffer.data()), 0);
-          break;
-        case JpgBlock::FRAME_END_CODE:
-          return 0;
-          break;
-        case JpgBlock::JPEG_SKIP_CODE:
+        if ((newbits - k) <= 0)
+        {
+            readbuf = buffer[bufferIndex];
+            bufferIndex++;
+            codebuf = (codebuf << k) |
+                      ((newbuf | (readbuf >> (newbits))) >> (32 - k));
+            newbuf = readbuf << (k - newbits);
+            newbits = 32 + newbits - k;
+        }
+        else
+        {
+            codebuf = (codebuf << k) | (newbuf >> (32 - k));
+            newbuf = newbuf << k;
+            newbits -= k;
+        }
+    }
 
-          txb = (codebuf & 0x0FF00000) >> 20;
-          tyb = (codebuf & 0x0FF000) >> 12;
+    signed short int getKbits(uint8_t k)
+    {
+        signed short int signedWordvalue;
 
-          updatereadbuf(&codebuf, &newbuf, blockAsT2100SkipLength, &newbits,
-                        bufferVector);
-          decompress(txb, tyb, reinterpret_cast<char *>(outBuffer.data()), 0);
-          break;
-        case JpgBlock::VQ_NO_SKIP_1_COLOR_CODE:
-          updatereadbuf(&codebuf, &newbuf, blockAsT2100StartLength, &newbits,
-                        bufferVector);
-          decodeColor.bitMapBits = 0;
+        // river
+        // signed_wordvalue=lookKbits(k);
+        signedWordvalue = static_cast<unsigned short int>(codebuf >> (32 - k));
+        if (((1L << (k - 1)) & signedWordvalue) == 0)
+        {
+            // neg_pow2 was previously defined as the below.  It seemed silly to
+            // keep a table of values around for something THat's relatively
+            // easy to compute, so it was replaced with the appropriate math
+            // signed_wordvalue = signed_wordvalue - (0xFFFF >> (16 - k));
+            std::array<signed short int, 17> negPow2 = {
+                0,    -1,   -3,    -7,    -15,   -31,   -63,    -127,
+                -255, -511, -1023, -2047, -4095, -8191, -16383, -32767};
 
-          for (int i = 0; i < 1; i++) {
-            decodeColor.index[i] = ((codebuf >> 29) & vqIndexMask);
-            if (((codebuf >> 31) & vqHeaderMask) == vqNoUpdateHeader) {
-              updatereadbuf(&codebuf, &newbuf, vqNoUpdateLength, &newbits,
-                            bufferVector);
-            } else {
-              decodeColor.color[decodeColor.index[i]] =
-                  ((codebuf >> 5) & vqColorMask);
-              updatereadbuf(&codebuf, &newbuf, vqUpdateLength, &newbits,
-                            bufferVector);
+            signedWordvalue = signedWordvalue + negPow2[k];
+        }
+        skipKbits(k);
+        return signedWordvalue;
+    }
+    int initJpgDecoding()
+    {
+        bytePos = 0;
+        loadQuantTable(qt[0]);
+        loadQuantTableCb(qt[1]);
+        //  Note: Added for Dual-JPEG
+        loadAdvanceQuantTable(qt[2]);
+        loadAdvanceQuantTableCb(qt[3]);
+        return 1;
+    }
+
+    void setQuantTable(const uint8_t *basic_table, uint8_t scale_factor,
+                       std::array<uint8_t, 64> &newtable)
+    // Set quantization table and zigzag reorder it
+    {
+        uint8_t i;
+        long temp;
+        for (i = 0; i < 64; i++)
+        {
+            temp = (static_cast<long>(basic_table[i] * 16) / scale_factor);
+            /* limit the values to the valid range */
+            if (temp <= 0L)
+            {
+                temp = 1L;
             }
-          }
-          vqDecompress(txb, tyb, reinterpret_cast<char *>(outBuffer.data()), 0,
-                       &decodeColor);
-          break;
-        case JpgBlock::VQ_SKIP_1_COLOR_CODE:
-          txb = (codebuf & 0x0FF00000) >> 20;
-          tyb = (codebuf & 0x0FF000) >> 12;
-
-          updatereadbuf(&codebuf, &newbuf, blockAsT2100SkipLength, &newbits,
-                        bufferVector);
-          decodeColor.bitMapBits = 0;
-
-          for (int i = 0; i < 1; i++) {
-            decodeColor.index[i] = ((codebuf >> 29) & vqIndexMask);
-            if (((codebuf >> 31) & vqHeaderMask) == vqNoUpdateHeader) {
-              updatereadbuf(&codebuf, &newbuf, vqNoUpdateLength, &newbits,
-                            bufferVector);
-            } else {
-              decodeColor.color[decodeColor.index[i]] =
-                  ((codebuf >> 5) & vqColorMask);
-              updatereadbuf(&codebuf, &newbuf, vqUpdateLength, &newbits,
-                            bufferVector);
+            if (temp > 255L)
+            {
+                temp = 255L; /* limit to baseline range if requested */
             }
-          }
-          vqDecompress(txb, tyb, reinterpret_cast<char *>(outBuffer.data()), 0,
-                       &decodeColor);
-          break;
+            newtable[zigzag[i]] = static_cast<uint8_t>(temp);
+        }
+    }
 
-        case JpgBlock::VQ_NO_SKIP_2_COLOR_CODE:
-          updatereadbuf(&codebuf, &newbuf, blockAsT2100StartLength, &newbits,
-                        bufferVector);
-          decodeColor.bitMapBits = 1;
+    void updatereadbuf(uint32_t *codebuf, uint32_t *newbuf, int walks,
+                       int *newbits, std::vector<uint32_t> &buffer)
+    {
+        unsigned long readbuf;
 
-          for (int i = 0; i < 2; i++) {
-            decodeColor.index[i] = ((codebuf >> 29) & vqIndexMask);
-            if (((codebuf >> 31) & vqHeaderMask) == vqNoUpdateHeader) {
-              updatereadbuf(&codebuf, &newbuf, vqNoUpdateLength, &newbits,
-                            bufferVector);
-            } else {
-              decodeColor.color[decodeColor.index[i]] =
-                  ((codebuf >> 5) & vqColorMask);
-              updatereadbuf(&codebuf, &newbuf, vqUpdateLength, &newbits,
-                            bufferVector);
+        if ((*newbits - walks) <= 0)
+        {
+            readbuf = buffer[bufferIndex];
+            bufferIndex++;
+            *codebuf = (*codebuf << walks) |
+                       ((*newbuf | (readbuf >> (*newbits))) >> (32 - walks));
+            *newbuf = readbuf << (walks - *newbits);
+            *newbits = 32 + *newbits - walks;
+        }
+        else
+        {
+            *codebuf = (*codebuf << walks) | (*newbuf >> (32 - walks));
+            *newbuf = *newbuf << walks;
+            *newbits -= walks;
+        }
+    }
+
+    uint32_t decode(std::vector<uint32_t> &bufferVector, unsigned long width,
+                    unsigned long height, YuvMode yuvmode_in, int ySelector,
+                    int uvSelector)
+    {
+        ColorCache decodeColor;
+        if (width != userWidth || height != userHeight ||
+            yuvmode_in != yuvmode || ySelector != ySelector ||
+            uvSelector != uvSelector)
+        {
+            yuvmode = yuvmode_in;
+            ySelector = ySelector;   // 0-7
+            uvSelector = uvSelector; // 0-7
+            userHeight = height;
+            userWidth = width;
+            width = width;
+            height = height;
+
+            // TODO(ed) Magic number section.  Document appropriately
+            advanceSelector = 0; // 0-7
+            mapping = 0;         // 0 or 1
+
+            if (yuvmode == YuvMode::YUV420)
+            {
+                if ((width % 16) != 0u)
+                {
+                    width = width + 16 - (width % 16);
+                }
+                if ((height % 16) != 0u)
+                {
+                    height = height + 16 - (height % 16);
+                }
             }
-          }
-          vqDecompress(txb, tyb, reinterpret_cast<char *>(outBuffer.data()), 0,
-                       &decodeColor);
-          break;
-        case JpgBlock::VQ_SKIP_2_COLOR_CODE:
-          txb = (codebuf & 0x0FF00000) >> 20;
-          tyb = (codebuf & 0x0FF000) >> 12;
-
-          updatereadbuf(&codebuf, &newbuf, blockAsT2100SkipLength, &newbits,
-                        bufferVector);
-          decodeColor.bitMapBits = 1;
-
-          for (int i = 0; i < 2; i++) {
-            decodeColor.index[i] = ((codebuf >> 29) & vqIndexMask);
-            if (((codebuf >> 31) & vqHeaderMask) == vqNoUpdateHeader) {
-              updatereadbuf(&codebuf, &newbuf, vqNoUpdateLength, &newbits,
-                            bufferVector);
-            } else {
-              decodeColor.color[decodeColor.index[i]] =
-                  ((codebuf >> 5) & vqColorMask);
-              updatereadbuf(&codebuf, &newbuf, vqUpdateLength, &newbits,
-                            bufferVector);
+            else
+            {
+                if ((width % 8) != 0u)
+                {
+                    width = width + 8 - (width % 8);
+                }
+                if ((height % 8) != 0u)
+                {
+                    height = height + 8 - (height % 8);
+                }
             }
-          }
-          vqDecompress(txb, tyb, reinterpret_cast<char *>(outBuffer.data()), 0,
-                       &decodeColor);
 
-          break;
-        case JpgBlock::VQ_NO_SKIP_4_COLOR_CODE:
-          updatereadbuf(&codebuf, &newbuf, blockAsT2100StartLength, &newbits,
-                        bufferVector);
-          decodeColor.bitMapBits = 2;
+            initJpgDecoding();
+        }
+        // TODO(ed) cleanup cruft
+        buffer = bufferVector.data();
 
-          for (unsigned char &i : decodeColor.index) {
-            i = ((codebuf >> 29) & vqIndexMask);
-            if (((codebuf >> 31) & vqHeaderMask) == vqNoUpdateHeader) {
-              updatereadbuf(&codebuf, &newbuf, vqNoUpdateLength, &newbits,
-                            bufferVector);
-            } else {
-              decodeColor.color[i] = ((codebuf >> 5) & vqColorMask);
-              updatereadbuf(&codebuf, &newbuf, vqUpdateLength, &newbits,
-                            bufferVector);
+        codebuf = bufferVector[0];
+        newbuf = bufferVector[1];
+        bufferIndex = 2;
+
+        txb = tyb = 0;
+        newbits = 32;
+        dcy = dcCb = dcCr = 0;
+
+        static const uint32_t vqHeaderMask = 0x01;
+        static const uint32_t vqNoUpdateHeader = 0x00;
+        static const uint32_t vqUpdateHeader = 0x01;
+        static const int vqNoUpdateLength = 0x03;
+        static const int vqUpdateLength = 0x1B;
+        static const uint32_t vqIndexMask = 0x03;
+        static const uint32_t vqColorMask = 0xFFFFFF;
+
+        static const int blockAsT2100StartLength = 0x04;
+        static const int blockAsT2100SkipLength = 20; // S:1 H:3 X:8 Y:8
+
+        do
+        {
+            auto blockHeader = static_cast<JpgBlock>((codebuf >> 28) & 0xFF);
+            switch (blockHeader)
+            {
+                case JpgBlock::JPEG_NO_SKIP_CODE:
+                    updatereadbuf(&codebuf, &newbuf, blockAsT2100StartLength,
+                                  &newbits, bufferVector);
+                    decompress(txb, tyb,
+                               reinterpret_cast<char *>(outBuffer.data()), 0);
+                    break;
+                case JpgBlock::FRAME_END_CODE:
+                    return 0;
+                    break;
+                case JpgBlock::JPEG_SKIP_CODE:
+
+                    txb = (codebuf & 0x0FF00000) >> 20;
+                    tyb = (codebuf & 0x0FF000) >> 12;
+
+                    updatereadbuf(&codebuf, &newbuf, blockAsT2100SkipLength,
+                                  &newbits, bufferVector);
+                    decompress(txb, tyb,
+                               reinterpret_cast<char *>(outBuffer.data()), 0);
+                    break;
+                case JpgBlock::VQ_NO_SKIP_1_COLOR_CODE:
+                    updatereadbuf(&codebuf, &newbuf, blockAsT2100StartLength,
+                                  &newbits, bufferVector);
+                    decodeColor.bitMapBits = 0;
+
+                    for (int i = 0; i < 1; i++)
+                    {
+                        decodeColor.index[i] = ((codebuf >> 29) & vqIndexMask);
+                        if (((codebuf >> 31) & vqHeaderMask) ==
+                            vqNoUpdateHeader)
+                        {
+                            updatereadbuf(&codebuf, &newbuf, vqNoUpdateLength,
+                                          &newbits, bufferVector);
+                        }
+                        else
+                        {
+                            decodeColor.color[decodeColor.index[i]] =
+                                ((codebuf >> 5) & vqColorMask);
+                            updatereadbuf(&codebuf, &newbuf, vqUpdateLength,
+                                          &newbits, bufferVector);
+                        }
+                    }
+                    vqDecompress(txb, tyb,
+                                 reinterpret_cast<char *>(outBuffer.data()), 0,
+                                 &decodeColor);
+                    break;
+                case JpgBlock::VQ_SKIP_1_COLOR_CODE:
+                    txb = (codebuf & 0x0FF00000) >> 20;
+                    tyb = (codebuf & 0x0FF000) >> 12;
+
+                    updatereadbuf(&codebuf, &newbuf, blockAsT2100SkipLength,
+                                  &newbits, bufferVector);
+                    decodeColor.bitMapBits = 0;
+
+                    for (int i = 0; i < 1; i++)
+                    {
+                        decodeColor.index[i] = ((codebuf >> 29) & vqIndexMask);
+                        if (((codebuf >> 31) & vqHeaderMask) ==
+                            vqNoUpdateHeader)
+                        {
+                            updatereadbuf(&codebuf, &newbuf, vqNoUpdateLength,
+                                          &newbits, bufferVector);
+                        }
+                        else
+                        {
+                            decodeColor.color[decodeColor.index[i]] =
+                                ((codebuf >> 5) & vqColorMask);
+                            updatereadbuf(&codebuf, &newbuf, vqUpdateLength,
+                                          &newbits, bufferVector);
+                        }
+                    }
+                    vqDecompress(txb, tyb,
+                                 reinterpret_cast<char *>(outBuffer.data()), 0,
+                                 &decodeColor);
+                    break;
+
+                case JpgBlock::VQ_NO_SKIP_2_COLOR_CODE:
+                    updatereadbuf(&codebuf, &newbuf, blockAsT2100StartLength,
+                                  &newbits, bufferVector);
+                    decodeColor.bitMapBits = 1;
+
+                    for (int i = 0; i < 2; i++)
+                    {
+                        decodeColor.index[i] = ((codebuf >> 29) & vqIndexMask);
+                        if (((codebuf >> 31) & vqHeaderMask) ==
+                            vqNoUpdateHeader)
+                        {
+                            updatereadbuf(&codebuf, &newbuf, vqNoUpdateLength,
+                                          &newbits, bufferVector);
+                        }
+                        else
+                        {
+                            decodeColor.color[decodeColor.index[i]] =
+                                ((codebuf >> 5) & vqColorMask);
+                            updatereadbuf(&codebuf, &newbuf, vqUpdateLength,
+                                          &newbits, bufferVector);
+                        }
+                    }
+                    vqDecompress(txb, tyb,
+                                 reinterpret_cast<char *>(outBuffer.data()), 0,
+                                 &decodeColor);
+                    break;
+                case JpgBlock::VQ_SKIP_2_COLOR_CODE:
+                    txb = (codebuf & 0x0FF00000) >> 20;
+                    tyb = (codebuf & 0x0FF000) >> 12;
+
+                    updatereadbuf(&codebuf, &newbuf, blockAsT2100SkipLength,
+                                  &newbits, bufferVector);
+                    decodeColor.bitMapBits = 1;
+
+                    for (int i = 0; i < 2; i++)
+                    {
+                        decodeColor.index[i] = ((codebuf >> 29) & vqIndexMask);
+                        if (((codebuf >> 31) & vqHeaderMask) ==
+                            vqNoUpdateHeader)
+                        {
+                            updatereadbuf(&codebuf, &newbuf, vqNoUpdateLength,
+                                          &newbits, bufferVector);
+                        }
+                        else
+                        {
+                            decodeColor.color[decodeColor.index[i]] =
+                                ((codebuf >> 5) & vqColorMask);
+                            updatereadbuf(&codebuf, &newbuf, vqUpdateLength,
+                                          &newbits, bufferVector);
+                        }
+                    }
+                    vqDecompress(txb, tyb,
+                                 reinterpret_cast<char *>(outBuffer.data()), 0,
+                                 &decodeColor);
+
+                    break;
+                case JpgBlock::VQ_NO_SKIP_4_COLOR_CODE:
+                    updatereadbuf(&codebuf, &newbuf, blockAsT2100StartLength,
+                                  &newbits, bufferVector);
+                    decodeColor.bitMapBits = 2;
+
+                    for (unsigned char &i : decodeColor.index)
+                    {
+                        i = ((codebuf >> 29) & vqIndexMask);
+                        if (((codebuf >> 31) & vqHeaderMask) ==
+                            vqNoUpdateHeader)
+                        {
+                            updatereadbuf(&codebuf, &newbuf, vqNoUpdateLength,
+                                          &newbits, bufferVector);
+                        }
+                        else
+                        {
+                            decodeColor.color[i] =
+                                ((codebuf >> 5) & vqColorMask);
+                            updatereadbuf(&codebuf, &newbuf, vqUpdateLength,
+                                          &newbits, bufferVector);
+                        }
+                    }
+                    vqDecompress(txb, tyb,
+                                 reinterpret_cast<char *>(outBuffer.data()), 0,
+                                 &decodeColor);
+
+                    break;
+
+                case JpgBlock::VQ_SKIP_4_COLOR_CODE:
+                    txb = (codebuf & 0x0FF00000) >> 20;
+                    tyb = (codebuf & 0x0FF000) >> 12;
+
+                    updatereadbuf(&codebuf, &newbuf, blockAsT2100SkipLength,
+                                  &newbits, bufferVector);
+                    decodeColor.bitMapBits = 2;
+
+                    for (unsigned char &i : decodeColor.index)
+                    {
+                        i = ((codebuf >> 29) & vqIndexMask);
+                        if (((codebuf >> 31) & vqHeaderMask) ==
+                            vqNoUpdateHeader)
+                        {
+                            updatereadbuf(&codebuf, &newbuf, vqNoUpdateLength,
+                                          &newbits, bufferVector);
+                        }
+                        else
+                        {
+                            decodeColor.color[i] =
+                                ((codebuf >> 5) & vqColorMask);
+                            updatereadbuf(&codebuf, &newbuf, vqUpdateLength,
+                                          &newbits, bufferVector);
+                        }
+                    }
+                    vqDecompress(txb, tyb,
+                                 reinterpret_cast<char *>(outBuffer.data()), 0,
+                                 &decodeColor);
+
+                    break;
+                case JpgBlock::JPEG_SKIP_PASS2_CODE:
+                    txb = (codebuf & 0x0FF00000) >> 20;
+                    tyb = (codebuf & 0x0FF000) >> 12;
+
+                    updatereadbuf(&codebuf, &newbuf, blockAsT2100SkipLength,
+                                  &newbits, bufferVector);
+                    decompress2Pass(txb, tyb,
+                                    reinterpret_cast<char *>(outBuffer.data()),
+                                    2);
+
+                    break;
+                default:
+                    // TODO(ed) propogate errors upstream
+                    return -1;
+                    break;
             }
-          }
-          vqDecompress(txb, tyb, reinterpret_cast<char *>(outBuffer.data()), 0,
-                       &decodeColor);
+            moveBlockIndex();
 
-          break;
+        } while (bufferIndex <= bufferVector.size());
 
-        case JpgBlock::VQ_SKIP_4_COLOR_CODE:
-          txb = (codebuf & 0x0FF00000) >> 20;
-          tyb = (codebuf & 0x0FF000) >> 12;
-
-          updatereadbuf(&codebuf, &newbuf, blockAsT2100SkipLength, &newbits,
-                        bufferVector);
-          decodeColor.bitMapBits = 2;
-
-          for (unsigned char &i : decodeColor.index) {
-            i = ((codebuf >> 29) & vqIndexMask);
-            if (((codebuf >> 31) & vqHeaderMask) == vqNoUpdateHeader) {
-              updatereadbuf(&codebuf, &newbuf, vqNoUpdateLength, &newbits,
-                            bufferVector);
-            } else {
-              decodeColor.color[i] = ((codebuf >> 5) & vqColorMask);
-              updatereadbuf(&codebuf, &newbuf, vqUpdateLength, &newbits,
-                            bufferVector);
-            }
-          }
-          vqDecompress(txb, tyb, reinterpret_cast<char *>(outBuffer.data()), 0,
-                       &decodeColor);
-
-          break;
-        case JpgBlock::JPEG_SKIP_PASS2_CODE:
-          txb = (codebuf & 0x0FF00000) >> 20;
-          tyb = (codebuf & 0x0FF000) >> 12;
-
-          updatereadbuf(&codebuf, &newbuf, blockAsT2100SkipLength, &newbits,
-                        bufferVector);
-          decompress2Pass(txb, tyb, reinterpret_cast<char *>(outBuffer.data()),
-                          2);
-
-          break;
-        default:
-          // TODO(ed) propogate errors upstream
-          return -1;
-          break;
-      }
-      moveBlockIndex();
-
-    } while (bufferIndex <= bufferVector.size());
-
-    return -1;
-  }
+        return -1;
+    }
 
 #ifdef cimg_version
-  void dump_to_bitmap_file() {
-    cimg_library::CImg<unsigned char> image(width, height, 1, 3);
-    for (int y = 0; y < width; y++) {
-      for (int x = 0; x < height; x++) {
-        auto pixel = outBuffer[x + (y * width)];
-        image(x, y, 0) = pixel.r;
-        image(x, y, 1) = pixel.g;
-        image(x, y, 2) = pixel.b;
-      }
+    void dump_to_bitmap_file()
+    {
+        cimg_library::CImg<unsigned char> image(width, height, 1, 3);
+        for (int y = 0; y < width; y++)
+        {
+            for (int x = 0; x < height; x++)
+            {
+                auto pixel = outBuffer[x + (y * width)];
+                image(x, y, 0) = pixel.r;
+                image(x, y, 1) = pixel.g;
+                image(x, y, 2) = pixel.b;
+            }
+        }
+        image.save("/tmp/file2.bmp");
     }
-    image.save("/tmp/file2.bmp");
-  }
 #endif
 
- private:
-  YuvMode yuvmode{};
-  // width and height are the modes your display used
-  unsigned long width{};
-  unsigned long height{};
-  unsigned long userWidth{};
-  unsigned long userHeight{};
-  unsigned char ySelector{};
-  int scalefactor;
-  int scalefactoruv;
-  int advancescalefactor;
-  int advancescalefactoruv;
-  int mapping{};
-  unsigned char uvSelector{};
-  unsigned char advanceSelector{};
-  int bytePos{};  // current byte position
+  private:
+    YuvMode yuvmode{};
+    // width and height are the modes your display used
+    unsigned long width{};
+    unsigned long height{};
+    unsigned long userWidth{};
+    unsigned long userHeight{};
+    unsigned char ySelector{};
+    int scalefactor;
+    int scalefactoruv;
+    int advancescalefactor;
+    int advancescalefactoruv;
+    int mapping{};
+    unsigned char uvSelector{};
+    unsigned char advanceSelector{};
+    int bytePos{}; // current byte position
 
-  // quantization tables, no more than 4 quantization tables
-  std::array<std::array<long, 64>, 4> qt{};
+    // quantization tables, no more than 4 quantization tables
+    std::array<std::array<long, 64>, 4> qt{};
 
-  // DC huffman tables , no more than 4 (0..3)
-  std::array<HuffmanTable, 4> htdc{};
-  // AC huffman tables (0..3)
-  std::array<HuffmanTable, 4> htac{};
-  std::array<int, 256> mCrToR{};
-  std::array<int, 256> mCbToB{};
-  std::array<int, 256> mCrToG{};
-  std::array<int, 256> mCbToG{};
-  std::array<int, 256> mY{};
-  unsigned long bufferIndex{};
-  uint32_t codebuf{}, newbuf{}, readbuf{};
-  const unsigned char *stdLuminanceQt{};
-  const uint8_t *stdChrominanceQt{};
+    // DC huffman tables , no more than 4 (0..3)
+    std::array<HuffmanTable, 4> htdc{};
+    // AC huffman tables (0..3)
+    std::array<HuffmanTable, 4> htac{};
+    std::array<int, 256> mCrToR{};
+    std::array<int, 256> mCbToB{};
+    std::array<int, 256> mCrToG{};
+    std::array<int, 256> mCbToG{};
+    std::array<int, 256> mY{};
+    unsigned long bufferIndex{};
+    uint32_t codebuf{}, newbuf{}, readbuf{};
+    const unsigned char *stdLuminanceQt{};
+    const uint8_t *stdChrominanceQt{};
 
-  signed short int dcy{}, dcCb{}, dcCr{};  // Coeficientii DC pentru Y,Cb,Cr
-  signed short int dctCoeff[384]{};
-  // std::vector<signed short int> dctCoeff;  // Current DCT_coefficients
-  // quantization table number for Y, Cb, Cr
-  uint8_t yqNr = 0, cbQNr = 1, crQNr = 1;
-  // DC Huffman table number for Y,Cb, Cr
-  uint8_t ydcNr = 0, cbDcNr = 1, crDcNr = 1;
-  // AC Huffman table number for Y,Cb, Cr
-  uint8_t yacNr = 0, cbAcNr = 1, crAcNr = 1;
-  int txb = 0;
-  int tyb = 0;
-  int newbits{};
-  uint8_t *rlimitTable{};
-  std::vector<RGB> yuvBuffer;
-  // TODO(ed) this shouldn't exist.  It is cruft that needs cleaning up
-  uint32_t *buffer{};
+    signed short int dcy{}, dcCb{}, dcCr{}; // Coeficientii DC pentru Y,Cb,Cr
+    signed short int dctCoeff[384]{};
+    // std::vector<signed short int> dctCoeff;  // Current DCT_coefficients
+    // quantization table number for Y, Cb, Cr
+    uint8_t yqNr = 0, cbQNr = 1, crQNr = 1;
+    // DC Huffman table number for Y,Cb, Cr
+    uint8_t ydcNr = 0, cbDcNr = 1, crDcNr = 1;
+    // AC Huffman table number for Y,Cb, Cr
+    uint8_t yacNr = 0, cbAcNr = 1, crAcNr = 1;
+    int txb = 0;
+    int tyb = 0;
+    int newbits{};
+    uint8_t *rlimitTable{};
+    std::vector<RGB> yuvBuffer;
+    // TODO(ed) this shouldn't exist.  It is cruft that needs cleaning up
+    uint32_t *buffer{};
 
- public:
-  std::vector<RGB> outBuffer;
+  public:
+    std::vector<RGB> outBuffer;
 };
-}  // namespace ast_video
\ No newline at end of file
+} // namespace ast_video
\ No newline at end of file
diff --git a/include/ast_video_puller.hpp b/include/ast_video_puller.hpp
index c2ccea2..520fc68 100644
--- a/include/ast_video_puller.hpp
+++ b/include/ast_video_puller.hpp
@@ -1,186 +1,212 @@
 #pragma once
 
 #include <ast_video_types.hpp>
+#include <boost/asio.hpp>
 #include <cassert>
 #include <iostream>
 #include <mutex>
 #include <vector>
-#include <boost/asio.hpp>
 
-namespace ast_video {
+namespace ast_video
+{
 
 //
 // Cursor struct is used in User Mode
 //
-struct AstCurAttributionTag {
-  unsigned int posX;
-  unsigned int posY;
-  unsigned int curWidth;
-  unsigned int curHeight;
-  unsigned int curType;  // 0:mono 1:color 2:disappear cursor
-  unsigned int curChangeFlag;
+struct AstCurAttributionTag
+{
+    unsigned int posX;
+    unsigned int posY;
+    unsigned int curWidth;
+    unsigned int curHeight;
+    unsigned int curType; // 0:mono 1:color 2:disappear cursor
+    unsigned int curChangeFlag;
 };
 
 //
 // For storing Cursor Information
 //
-struct AstCursorTag {
-  AstCurAttributionTag attr;
-  // unsigned char     icon[MAX_CUR_OFFSETX*MAX_CUR_OFFSETY*2];
-  unsigned char *icon;  //[64*64*2];
+struct AstCursorTag
+{
+    AstCurAttributionTag attr;
+    // unsigned char     icon[MAX_CUR_OFFSETX*MAX_CUR_OFFSETY*2];
+    unsigned char *icon; //[64*64*2];
 };
 
 //
 // For select image format, i.e. 422 JPG420, 444 JPG444, lumin/chrom table, 0
 // ~ 11, low to high
 //
-struct FeaturesTag {
-  short jpgFmt;  // 422:JPG420, 444:JPG444
-  short luminTbl;
-  short chromTbl;
-  short toleranceNoise;
-  int w;
-  int h;
-  unsigned char *buf;
+struct FeaturesTag
+{
+    short jpgFmt; // 422:JPG420, 444:JPG444
+    short luminTbl;
+    short chromTbl;
+    short toleranceNoise;
+    int w;
+    int h;
+    unsigned char *buf;
 };
 
 //
 // For configure video engine control registers
 //
-struct ImageInfo {
-  short doImageRefresh;  // Action 0:motion 1:fullframe 2:quick cursor
-  char qcValid;          // quick cursor enable/disable
-  unsigned int len;
-  int crypttype;
-  char cryptkey[16];
-  union {
-    FeaturesTag features;
-    AstCursorTag cursorInfo;
-  } parameter;
+struct ImageInfo
+{
+    short doImageRefresh; // Action 0:motion 1:fullframe 2:quick cursor
+    char qcValid;         // quick cursor enable/disable
+    unsigned int len;
+    int crypttype;
+    char cryptkey[16];
+    union
+    {
+        FeaturesTag features;
+        AstCursorTag cursorInfo;
+    } parameter;
 };
 
-class SimpleVideoPuller {
- public:
-  SimpleVideoPuller() : imageInfo(){};
+class SimpleVideoPuller
+{
+  public:
+    SimpleVideoPuller() : imageInfo(){};
 
-  void initialize() {
-    std::cout << "Opening /dev/video\n";
-    videoFd = open("/dev/video", O_RDWR);
-    if (videoFd == 0) {
-      std::cout << "Failed to open /dev/video\n";
-      throw std::runtime_error("Failed to open /dev/video");
-    }
-    std::cout << "Opened successfully\n";
-  }
-
-  RawVideoBuffer readVideo() {
-    assert(videoFd != 0);
-    RawVideoBuffer raw;
-
-    imageInfo.doImageRefresh = 1;  // full frame refresh
-    imageInfo.qcValid = 0;         // quick cursor disabled
-    imageInfo.parameter.features.buf =
-        reinterpret_cast<unsigned char *>(raw.buffer.data());
-    imageInfo.crypttype = -1;
-    std::cout << "Writing\n";
-
-    int status;
-    /*
-    status = write(videoFd, reinterpret_cast<char*>(&imageInfo),
-                        sizeof(imageInfo));
-    if (status != sizeof(imageInfo)) {
-      std::cout << "Write failed.  Return: " << status << "\n";
-      perror("perror output:");
+    void initialize()
+    {
+        std::cout << "Opening /dev/video\n";
+        videoFd = open("/dev/video", O_RDWR);
+        if (videoFd == 0)
+        {
+            std::cout << "Failed to open /dev/video\n";
+            throw std::runtime_error("Failed to open /dev/video");
+        }
+        std::cout << "Opened successfully\n";
     }
 
-    std::cout << "Write done\n";
-    */
-    std::cout << "Reading\n";
-    status =
-        read(videoFd, reinterpret_cast<char *>(&imageInfo), sizeof(imageInfo));
-    std::cout << "Done reading\n";
+    RawVideoBuffer readVideo()
+    {
+        assert(videoFd != 0);
+        RawVideoBuffer raw;
 
-    if (status != 0) {
-      std::cerr << "Read failed with status " << status << "\n";
+        imageInfo.doImageRefresh = 1; // full frame refresh
+        imageInfo.qcValid = 0;        // quick cursor disabled
+        imageInfo.parameter.features.buf =
+            reinterpret_cast<unsigned char *>(raw.buffer.data());
+        imageInfo.crypttype = -1;
+        std::cout << "Writing\n";
+
+        int status;
+        /*
+        status = write(videoFd, reinterpret_cast<char*>(&imageInfo),
+                            sizeof(imageInfo));
+        if (status != sizeof(imageInfo)) {
+          std::cout << "Write failed.  Return: " << status << "\n";
+          perror("perror output:");
+        }
+
+        std::cout << "Write done\n";
+        */
+        std::cout << "Reading\n";
+        status = read(videoFd, reinterpret_cast<char *>(&imageInfo),
+                      sizeof(imageInfo));
+        std::cout << "Done reading\n";
+
+        if (status != 0)
+        {
+            std::cerr << "Read failed with status " << status << "\n";
+        }
+
+        raw.buffer.resize(imageInfo.len);
+
+        raw.height = imageInfo.parameter.features.h;
+        raw.width = imageInfo.parameter.features.w;
+        if (imageInfo.parameter.features.jpgFmt == 422)
+        {
+            raw.mode = YuvMode::YUV420;
+        }
+        else
+        {
+            raw.mode = YuvMode::YUV444;
+        }
+        return raw;
     }
 
-    raw.buffer.resize(imageInfo.len);
-
-    raw.height = imageInfo.parameter.features.h;
-    raw.width = imageInfo.parameter.features.w;
-    if (imageInfo.parameter.features.jpgFmt == 422) {
-      raw.mode = YuvMode::YUV420;
-    } else {
-      raw.mode = YuvMode::YUV444;
-    }
-    return raw;
-  }
-
- private:
-  int videoFd{};
-  ImageInfo imageInfo;
+  private:
+    int videoFd{};
+    ImageInfo imageInfo;
 };
 
 #if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
-class AsyncVideoPuller {
- public:
-  using video_callback = std::function<void(RawVideoBuffer &)>;
+class AsyncVideoPuller
+{
+  public:
+    using video_callback = std::function<void(RawVideoBuffer &)>;
 
-  explicit AsyncVideoPuller(boost::asio::io_service &ioService)
-      : imageInfo(), devVideo(ioService, open("/dev/video", O_RDWR)) {
-    videobuf = std::make_shared<RawVideoBuffer>();
+    explicit AsyncVideoPuller(boost::asio::io_service &ioService) :
+        imageInfo(), devVideo(ioService, open("/dev/video", O_RDWR))
+    {
+        videobuf = std::make_shared<RawVideoBuffer>();
 
-    imageInfo.doImageRefresh = 1;  // full frame refresh
-    imageInfo.qcValid = 0;         // quick cursor disabled
-    imageInfo.parameter.features.buf =
-        reinterpret_cast<unsigned char *>(videobuf->buffer.data());
-    imageInfo.crypttype = -1;
-  };
+        imageInfo.doImageRefresh = 1; // full frame refresh
+        imageInfo.qcValid = 0;        // quick cursor disabled
+        imageInfo.parameter.features.buf =
+            reinterpret_cast<unsigned char *>(videobuf->buffer.data());
+        imageInfo.crypttype = -1;
+    };
 
-  void registerCallback(video_callback &callback) {
-    std::lock_guard<std::mutex> lock(callbackMutex);
-    callbacks.push_back(callback);
-    startRead();
-  }
-
-  void startRead() {
-    auto mutableBuffer = boost::asio::buffer(&imageInfo, sizeof(imageInfo));
-    boost::asio::async_read(devVideo, mutableBuffer,
-                            [this](const boost::system::error_code &ec,
-                                   std::size_t bytes_transferred) {
-                              if (ec) {
-                                std::cerr << "Read failed with status " << ec
-                                          << "\n";
-                              } else {
-                                this->readDone();
-                              }
-                            });
-  }
-
-  void readDone() {
-    std::cout << "Done reading\n";
-    videobuf->buffer.resize(imageInfo.len);
-
-    videobuf->height = imageInfo.parameter.features.h;
-    videobuf->width = imageInfo.parameter.features.w;
-    if (imageInfo.parameter.features.jpgFmt == 422) {
-      videobuf->mode = YuvMode::YUV420;
-    } else {
-      videobuf->mode = YuvMode::YUV444;
+    void registerCallback(video_callback &callback)
+    {
+        std::lock_guard<std::mutex> lock(callbackMutex);
+        callbacks.push_back(callback);
+        startRead();
     }
-    std::lock_guard<std::mutex> lock(callbackMutex);
-    for (auto &callback : callbacks) {
-      // TODO(ed) call callbacks async and double buffer frames
-      callback(*videobuf);
-    }
-  }
 
- private:
-  std::shared_ptr<RawVideoBuffer> videobuf;
-  boost::asio::posix::stream_descriptor devVideo;
-  ImageInfo imageInfo;
-  std::mutex callbackMutex;
-  std::vector<video_callback> callbacks;
+    void startRead()
+    {
+        auto mutableBuffer = boost::asio::buffer(&imageInfo, sizeof(imageInfo));
+        boost::asio::async_read(devVideo, mutableBuffer,
+                                [this](const boost::system::error_code &ec,
+                                       std::size_t bytes_transferred) {
+                                    if (ec)
+                                    {
+                                        std::cerr << "Read failed with status "
+                                                  << ec << "\n";
+                                    }
+                                    else
+                                    {
+                                        this->readDone();
+                                    }
+                                });
+    }
+
+    void readDone()
+    {
+        std::cout << "Done reading\n";
+        videobuf->buffer.resize(imageInfo.len);
+
+        videobuf->height = imageInfo.parameter.features.h;
+        videobuf->width = imageInfo.parameter.features.w;
+        if (imageInfo.parameter.features.jpgFmt == 422)
+        {
+            videobuf->mode = YuvMode::YUV420;
+        }
+        else
+        {
+            videobuf->mode = YuvMode::YUV444;
+        }
+        std::lock_guard<std::mutex> lock(callbackMutex);
+        for (auto &callback : callbacks)
+        {
+            // TODO(ed) call callbacks async and double buffer frames
+            callback(*videobuf);
+        }
+    }
+
+  private:
+    std::shared_ptr<RawVideoBuffer> videobuf;
+    boost::asio::posix::stream_descriptor devVideo;
+    ImageInfo imageInfo;
+    std::mutex callbackMutex;
+    std::vector<video_callback> callbacks;
 };
-#endif  // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
-}  // namespace ast_video
+#endif // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
+} // namespace ast_video
diff --git a/include/ast_video_types.hpp b/include/ast_video_types.hpp
index f980146..aeef1d8 100644
--- a/include/ast_video_types.hpp
+++ b/include/ast_video_types.hpp
@@ -2,18 +2,24 @@
 
 #include <cstdint>
 #include <vector>
-namespace ast_video {
-enum class YuvMode { YUV444 = 0, YUV420 = 1 };
-
-class RawVideoBuffer {
- public:
-  RawVideoBuffer() : buffer(1024 * 1024 * 10, 0){};
-  unsigned long height{};
-  unsigned long width{};
-  int ySelector{};
-  int uvSelector{};
-  YuvMode mode;
-  // TODO(ed) determine a more appropriate buffer size
-  std::vector<uint32_t> buffer;
+namespace ast_video
+{
+enum class YuvMode
+{
+    YUV444 = 0,
+    YUV420 = 1
 };
-}  // namespace ast_video
\ No newline at end of file
+
+class RawVideoBuffer
+{
+  public:
+    RawVideoBuffer() : buffer(1024 * 1024 * 10, 0){};
+    unsigned long height{};
+    unsigned long width{};
+    int ySelector{};
+    int uvSelector{};
+    YuvMode mode;
+    // TODO(ed) determine a more appropriate buffer size
+    std::vector<uint32_t> buffer;
+};
+} // namespace ast_video
\ No newline at end of file
diff --git a/include/dbus_monitor.hpp b/include/dbus_monitor.hpp
index e8b1a32..5dcd5ca 100644
--- a/include/dbus_monitor.hpp
+++ b/include/dbus_monitor.hpp
@@ -1,26 +1,33 @@
 #pragma once
-#include <dbus_singleton.hpp>
-#include <sdbusplus/bus/match.hpp>
 #include <crow/app.h>
 #include <crow/websocket.h>
+
 #include <boost/container/flat_map.hpp>
 #include <boost/container/flat_set.hpp>
+#include <dbus_singleton.hpp>
+#include <sdbusplus/bus/match.hpp>
 
-namespace nlohmann {
+namespace nlohmann
+{
 template <typename... Args>
-struct adl_serializer<sdbusplus::message::variant<Args...>> {
-  static void to_json(json& j, const sdbusplus::message::variant<Args...>& v) {
-    mapbox::util::apply_visitor([&](auto&& val) { j = val; }, v);
-  }
+struct adl_serializer<sdbusplus::message::variant<Args...>>
+{
+    static void to_json(json& j, const sdbusplus::message::variant<Args...>& v)
+    {
+        mapbox::util::apply_visitor([&](auto&& val) { j = val; }, v);
+    }
 };
-}  // namespace nlohmann
+} // namespace nlohmann
 
-namespace crow {
-namespace dbus_monitor {
+namespace crow
+{
+namespace dbus_monitor
+{
 
-struct DbusWebsocketSession {
-  std::vector<std::unique_ptr<sdbusplus::bus::match::match>> matches;
-  boost::container::flat_set<std::string> interfaces;
+struct DbusWebsocketSession
+{
+    std::vector<std::unique_ptr<sdbusplus::bus::match::match>> matches;
+    boost::container::flat_set<std::string> interfaces;
 };
 
 static boost::container::flat_map<crow::websocket::Connection*,
@@ -28,165 +35,198 @@
     sessions;
 
 inline int onPropertyUpdate(sd_bus_message* m, void* userdata,
-                            sd_bus_error* ret_error) {
-  if (ret_error == nullptr || sd_bus_error_is_set(ret_error)) {
-    BMCWEB_LOG_ERROR << "Got sdbus error on match";
-    return 0;
-  }
-  crow::websocket::Connection* connection =
-      static_cast<crow::websocket::Connection*>(userdata);
-  auto thisSession = sessions.find(connection);
-  if (thisSession == sessions.end()) {
-    BMCWEB_LOG_ERROR << "Couldn't find dbus connection " << connection;
-    return 0;
-  }
-  sdbusplus::message::message message(m);
-  using VariantType =
-      sdbusplus::message::variant<std::string, bool, int64_t, uint64_t, double>;
-  nlohmann::json j{{"event", message.get_member()},
-                   {"path", message.get_path()}};
-  if (strcmp(message.get_member(), "PropertiesChanged") == 0) {
-    std::string interface_name;
-    boost::container::flat_map<std::string, VariantType> values;
-    message.read(interface_name, values);
-    j["properties"] = values;
-    j["interface"] = std::move(interface_name);
-
-  } else if (strcmp(message.get_member(), "InterfacesAdded") == 0) {
-    std::string object_name;
-    boost::container::flat_map<
-        std::string, boost::container::flat_map<std::string, VariantType>>
-        values;
-    message.read(object_name, values);
-    for (const std::pair<std::string,
-                         boost::container::flat_map<std::string, VariantType>>&
-             paths : values) {
-      auto it = thisSession->second.interfaces.find(paths.first);
-      if (it != thisSession->second.interfaces.end()) {
-        j["interfaces"][paths.first] = paths.second;
-      }
+                            sd_bus_error* ret_error)
+{
+    if (ret_error == nullptr || sd_bus_error_is_set(ret_error))
+    {
+        BMCWEB_LOG_ERROR << "Got sdbus error on match";
+        return 0;
     }
-  } else {
-    BMCWEB_LOG_CRITICAL << "message " << message.get_member()
-                        << " was unexpected";
-    return 0;
-  }
+    crow::websocket::Connection* connection =
+        static_cast<crow::websocket::Connection*>(userdata);
+    auto thisSession = sessions.find(connection);
+    if (thisSession == sessions.end())
+    {
+        BMCWEB_LOG_ERROR << "Couldn't find dbus connection " << connection;
+        return 0;
+    }
+    sdbusplus::message::message message(m);
+    using VariantType = sdbusplus::message::variant<std::string, bool, int64_t,
+                                                    uint64_t, double>;
+    nlohmann::json j{{"event", message.get_member()},
+                     {"path", message.get_path()}};
+    if (strcmp(message.get_member(), "PropertiesChanged") == 0)
+    {
+        std::string interface_name;
+        boost::container::flat_map<std::string, VariantType> values;
+        message.read(interface_name, values);
+        j["properties"] = values;
+        j["interface"] = std::move(interface_name);
+    }
+    else if (strcmp(message.get_member(), "InterfacesAdded") == 0)
+    {
+        std::string object_name;
+        boost::container::flat_map<
+            std::string, boost::container::flat_map<std::string, VariantType>>
+            values;
+        message.read(object_name, values);
+        for (const std::pair<
+                 std::string,
+                 boost::container::flat_map<std::string, VariantType>>& paths :
+             values)
+        {
+            auto it = thisSession->second.interfaces.find(paths.first);
+            if (it != thisSession->second.interfaces.end())
+            {
+                j["interfaces"][paths.first] = paths.second;
+            }
+        }
+    }
+    else
+    {
+        BMCWEB_LOG_CRITICAL << "message " << message.get_member()
+                            << " was unexpected";
+        return 0;
+    }
 
-  connection->sendText(j.dump());
-  return 0;
+    connection->sendText(j.dump());
+    return 0;
 };
 
-template <typename... Middlewares>
-void requestRoutes(Crow<Middlewares...>& app) {
-  BMCWEB_ROUTE(app, "/subscribe")
-      .websocket()
-      .onopen([&](crow::websocket::Connection& conn) {
-        BMCWEB_LOG_DEBUG << "Connection " << &conn << " opened";
-        sessions[&conn] = DbusWebsocketSession();
-      })
-      .onclose([&](crow::websocket::Connection& conn,
-                   const std::string& reason) { sessions.erase(&conn); })
-      .onmessage([&](crow::websocket::Connection& conn, const std::string& data,
-                     bool is_binary) {
-        DbusWebsocketSession& thisSession = sessions[&conn];
-        BMCWEB_LOG_DEBUG << "Connection " << &conn << " recevied " << data;
-        nlohmann::json j = nlohmann::json::parse(data, nullptr, false);
-        if (j.is_discarded()) {
-          BMCWEB_LOG_ERROR << "Unable to parse json data for monitor";
-          conn.close("Unable to parse json request");
-          return;
-        }
-        nlohmann::json::iterator interfaces = j.find("interfaces");
-        if (interfaces != j.end()) {
-          thisSession.interfaces.reserve(interfaces->size());
-          for (auto& interface : *interfaces) {
-            const std::string* str = interface.get_ptr<const std::string*>();
-            if (str != nullptr) {
-              thisSession.interfaces.insert(*str);
-            }
-          }
-        }
-
-        nlohmann::json::iterator paths = j.find("paths");
-        if (paths != j.end()) {
-          int interfaceCount = thisSession.interfaces.size();
-          if (interfaceCount == 0) {
-            interfaceCount = 1;
-          }
-          // Reserve our matches upfront.  For each path there is 1 for
-          // interfacesAdded, and InterfaceCount number for PropertiesChanged
-          thisSession.matches.reserve(thisSession.matches.size() +
-                                      paths->size() * (1 + interfaceCount));
-        }
-        std::string object_manager_match_string;
-        std::string properties_match_string;
-        std::string object_manager_interfaces_match_string;
-        // These regexes derived on the rules here:
-        // https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names
-        std::regex validPath("^/([A-Za-z0-9_]+/?)*$");
-        std::regex validInterface(
-            "^[A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)+$");
-
-        for (const auto& thisPath : *paths) {
-          const std::string* thisPathString =
-              thisPath.get_ptr<const std::string*>();
-          if (thisPathString == nullptr) {
-            BMCWEB_LOG_ERROR << "subscribe path isn't a string?";
-            conn.close();
-            return;
-          }
-          if (!std::regex_match(*thisPathString, validPath)) {
-            BMCWEB_LOG_ERROR << "Invalid path name " << *thisPathString;
-            conn.close();
-            return;
-          }
-          properties_match_string =
-              ("type='signal',"
-               "interface='org.freedesktop.DBus.Properties',"
-               "path_namespace='" +
-               *thisPathString +
-               "',"
-               "member='PropertiesChanged'");
-          // If interfaces weren't specified, add a single match for all
-          // interfaces
-          if (thisSession.interfaces.size() == 0) {
-            BMCWEB_LOG_DEBUG << "Creating match " << properties_match_string;
-
-            thisSession.matches.emplace_back(
-                std::make_unique<sdbusplus::bus::match::match>(
-                    *crow::connections::systemBus, properties_match_string,
-                    onPropertyUpdate, &conn));
-          } else {
-            // If interfaces were specified, add a match for each interface
-            for (const std::string& interface : thisSession.interfaces) {
-              if (!std::regex_match(interface, validInterface)) {
-                BMCWEB_LOG_ERROR << "Invalid interface name " << interface;
-                conn.close();
+template <typename... Middlewares> void requestRoutes(Crow<Middlewares...>& app)
+{
+    BMCWEB_ROUTE(app, "/subscribe")
+        .websocket()
+        .onopen([&](crow::websocket::Connection& conn) {
+            BMCWEB_LOG_DEBUG << "Connection " << &conn << " opened";
+            sessions[&conn] = DbusWebsocketSession();
+        })
+        .onclose([&](crow::websocket::Connection& conn,
+                     const std::string& reason) { sessions.erase(&conn); })
+        .onmessage([&](crow::websocket::Connection& conn,
+                       const std::string& data, bool is_binary) {
+            DbusWebsocketSession& thisSession = sessions[&conn];
+            BMCWEB_LOG_DEBUG << "Connection " << &conn << " recevied " << data;
+            nlohmann::json j = nlohmann::json::parse(data, nullptr, false);
+            if (j.is_discarded())
+            {
+                BMCWEB_LOG_ERROR << "Unable to parse json data for monitor";
+                conn.close("Unable to parse json request");
                 return;
-              }
-              std::string ifaceMatchString =
-                  properties_match_string + ",arg0='" + interface + "'";
-              BMCWEB_LOG_DEBUG << "Creating match " << ifaceMatchString;
-              thisSession.matches.emplace_back(
-                  std::make_unique<sdbusplus::bus::match::match>(
-                      *crow::connections::systemBus, ifaceMatchString,
-                      onPropertyUpdate, &conn));
             }
-          }
-          object_manager_match_string =
-              ("type='signal',"
-               "interface='org.freedesktop.DBus.ObjectManager',"
-               "path_namespace='" +
-               *thisPathString +
-               "',"
-               "member='InterfacesAdded'");
-          BMCWEB_LOG_DEBUG << "Creating match " << object_manager_match_string;
-          thisSession.matches.emplace_back(
-              std::make_unique<sdbusplus::bus::match::match>(
-                  *crow::connections::systemBus, object_manager_match_string,
-                  onPropertyUpdate, &conn));
-        }
-      });
+            nlohmann::json::iterator interfaces = j.find("interfaces");
+            if (interfaces != j.end())
+            {
+                thisSession.interfaces.reserve(interfaces->size());
+                for (auto& interface : *interfaces)
+                {
+                    const std::string* str =
+                        interface.get_ptr<const std::string*>();
+                    if (str != nullptr)
+                    {
+                        thisSession.interfaces.insert(*str);
+                    }
+                }
+            }
+
+            nlohmann::json::iterator paths = j.find("paths");
+            if (paths != j.end())
+            {
+                int interfaceCount = thisSession.interfaces.size();
+                if (interfaceCount == 0)
+                {
+                    interfaceCount = 1;
+                }
+                // Reserve our matches upfront.  For each path there is 1 for
+                // interfacesAdded, and InterfaceCount number for
+                // PropertiesChanged
+                thisSession.matches.reserve(thisSession.matches.size() +
+                                            paths->size() *
+                                                (1 + interfaceCount));
+            }
+            std::string object_manager_match_string;
+            std::string properties_match_string;
+            std::string object_manager_interfaces_match_string;
+            // These regexes derived on the rules here:
+            // https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names
+            std::regex validPath("^/([A-Za-z0-9_]+/?)*$");
+            std::regex validInterface(
+                "^[A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)+$");
+
+            for (const auto& thisPath : *paths)
+            {
+                const std::string* thisPathString =
+                    thisPath.get_ptr<const std::string*>();
+                if (thisPathString == nullptr)
+                {
+                    BMCWEB_LOG_ERROR << "subscribe path isn't a string?";
+                    conn.close();
+                    return;
+                }
+                if (!std::regex_match(*thisPathString, validPath))
+                {
+                    BMCWEB_LOG_ERROR << "Invalid path name " << *thisPathString;
+                    conn.close();
+                    return;
+                }
+                properties_match_string =
+                    ("type='signal',"
+                     "interface='org.freedesktop.DBus.Properties',"
+                     "path_namespace='" +
+                     *thisPathString +
+                     "',"
+                     "member='PropertiesChanged'");
+                // If interfaces weren't specified, add a single match for all
+                // interfaces
+                if (thisSession.interfaces.size() == 0)
+                {
+                    BMCWEB_LOG_DEBUG << "Creating match "
+                                     << properties_match_string;
+
+                    thisSession.matches.emplace_back(
+                        std::make_unique<sdbusplus::bus::match::match>(
+                            *crow::connections::systemBus,
+                            properties_match_string, onPropertyUpdate, &conn));
+                }
+                else
+                {
+                    // If interfaces were specified, add a match for each
+                    // interface
+                    for (const std::string& interface : thisSession.interfaces)
+                    {
+                        if (!std::regex_match(interface, validInterface))
+                        {
+                            BMCWEB_LOG_ERROR << "Invalid interface name "
+                                             << interface;
+                            conn.close();
+                            return;
+                        }
+                        std::string ifaceMatchString = properties_match_string +
+                                                       ",arg0='" + interface +
+                                                       "'";
+                        BMCWEB_LOG_DEBUG << "Creating match "
+                                         << ifaceMatchString;
+                        thisSession.matches.emplace_back(
+                            std::make_unique<sdbusplus::bus::match::match>(
+                                *crow::connections::systemBus, ifaceMatchString,
+                                onPropertyUpdate, &conn));
+                    }
+                }
+                object_manager_match_string =
+                    ("type='signal',"
+                     "interface='org.freedesktop.DBus.ObjectManager',"
+                     "path_namespace='" +
+                     *thisPathString +
+                     "',"
+                     "member='InterfacesAdded'");
+                BMCWEB_LOG_DEBUG << "Creating match "
+                                 << object_manager_match_string;
+                thisSession.matches.emplace_back(
+                    std::make_unique<sdbusplus::bus::match::match>(
+                        *crow::connections::systemBus,
+                        object_manager_match_string, onPropertyUpdate, &conn));
+            }
+        });
 }
-}  // namespace dbus_monitor
-}  // namespace crow
+} // namespace dbus_monitor
+} // namespace crow
diff --git a/include/dbus_singleton.hpp b/include/dbus_singleton.hpp
index a4a16bb..2438152 100644
--- a/include/dbus_singleton.hpp
+++ b/include/dbus_singleton.hpp
@@ -1,21 +1,28 @@
 #pragma once
-#include <sdbusplus/asio/connection.hpp>
 #include <iostream>
+#include <sdbusplus/asio/connection.hpp>
 
-namespace mapbox {
+namespace mapbox
+{
 template <typename T, typename... Types>
-const T* getPtr(const mapbox::util::variant<Types...>& v) {
-  if (v.template is<std::remove_const_t<T>>()) {
-    return &v.template get_unchecked<std::remove_const_t<T>>();
-  } else {
-    return nullptr;
-  }
+const T* getPtr(const mapbox::util::variant<Types...>& v)
+{
+    if (v.template is<std::remove_const_t<T>>())
+    {
+        return &v.template get_unchecked<std::remove_const_t<T>>();
+    }
+    else
+    {
+        return nullptr;
+    }
 }
-}  // namespace mapbox
+} // namespace mapbox
 
-namespace crow {
-namespace connections {
+namespace crow
+{
+namespace connections
+{
 static std::shared_ptr<sdbusplus::asio::connection> systemBus;
 
-}  // namespace connections
-}  // namespace crow
+} // namespace connections
+} // namespace crow
diff --git a/include/gzip_helper.hpp b/include/gzip_helper.hpp
index e14fc1b..be13809 100644
--- a/include/gzip_helper.hpp
+++ b/include/gzip_helper.hpp
@@ -1,56 +1,65 @@
 #pragma once
 
 #include <zlib.h>
+
 #include <cstring>
 #include <string>
 
 inline bool gzipInflate(const std::string& compressedBytes,
-                        std::string& uncompressedBytes) {
-  if (compressedBytes.empty()) {
-    uncompressedBytes = compressedBytes;
-    return true;
-  }
-
-  uncompressedBytes.clear();
-
-  unsigned half_length = compressedBytes.size() / 2;
-
-  z_stream strm{};
-
-  // The following line is nolint because we're declaring away constness.
-  // It's not clear why the input buffers on zlib aren't const, so this is a
-  // bit of a cheat for the moment
-  strm.next_in = (Bytef*)compressedBytes.data();  // NOLINT
-  strm.avail_in = compressedBytes.size();
-  strm.total_out = 0;
-  strm.zalloc = Z_NULL;
-  strm.zfree = Z_NULL;
-
-  bool done = false;
-
-  if (inflateInit2(&strm, (16 + MAX_WBITS)) != Z_OK) {
-    return false;
-  }
-
-  while (!done) {
-    // If our output buffer is too small
-    if (strm.total_out >= uncompressedBytes.size()) {
-      uncompressedBytes.resize(uncompressedBytes.size() + half_length);
+                        std::string& uncompressedBytes)
+{
+    if (compressedBytes.empty())
+    {
+        uncompressedBytes = compressedBytes;
+        return true;
     }
 
-    strm.next_out =
-        (Bytef*)(uncompressedBytes.data() + strm.total_out);  // NOLINT
-    strm.avail_out =
-        ((uLong)uncompressedBytes.size() - strm.total_out);  // NOLINT
+    uncompressedBytes.clear();
 
-    // Inflate another chunk.
-    int err = inflate(&strm, Z_SYNC_FLUSH);
-    if (err == Z_STREAM_END) {
-      done = true;
-    } else if (err != Z_OK) {
-      break;
+    unsigned half_length = compressedBytes.size() / 2;
+
+    z_stream strm{};
+
+    // The following line is nolint because we're declaring away constness.
+    // It's not clear why the input buffers on zlib aren't const, so this is a
+    // bit of a cheat for the moment
+    strm.next_in = (Bytef*)compressedBytes.data(); // NOLINT
+    strm.avail_in = compressedBytes.size();
+    strm.total_out = 0;
+    strm.zalloc = Z_NULL;
+    strm.zfree = Z_NULL;
+
+    bool done = false;
+
+    if (inflateInit2(&strm, (16 + MAX_WBITS)) != Z_OK)
+    {
+        return false;
     }
-  }
 
-  return inflateEnd(&strm) == Z_OK;
+    while (!done)
+    {
+        // If our output buffer is too small
+        if (strm.total_out >= uncompressedBytes.size())
+        {
+            uncompressedBytes.resize(uncompressedBytes.size() + half_length);
+        }
+
+        strm.next_out =
+            (Bytef*)(uncompressedBytes.data() + strm.total_out); // NOLINT
+        strm.avail_out =
+            ((uLong)uncompressedBytes.size() - strm.total_out); // NOLINT
+
+        // Inflate another chunk.
+        int err = inflate(&strm, Z_SYNC_FLUSH);
+        if (err == Z_STREAM_END)
+        {
+            done = true;
+        }
+        else if (err != Z_OK)
+        {
+            break;
+        }
+    }
+
+    return inflateEnd(&strm) == Z_OK;
 }
\ No newline at end of file
diff --git a/include/http_utility.hpp b/include/http_utility.hpp
index f2d3172..e13dfc0 100644
--- a/include/http_utility.hpp
+++ b/include/http_utility.hpp
@@ -1,21 +1,27 @@
 #pragma once
 #include <boost/algorithm/string.hpp>
 
-namespace http_helpers {
-inline bool requestPrefersHtml(const crow::Request& req) {
-  boost::string_view header = req.getHeaderValue("accept");
-  std::vector<std::string> encodings;
-  // chrome currently sends 6 accepts headers, firefox sends 4.
-  encodings.reserve(6);
-  boost::split(encodings, header, boost::is_any_of(", "),
-               boost::token_compress_on);
-  for (const std::string& encoding : encodings) {
-    if (encoding == "text/html") {
-      return true;
-    } else if (encoding == "application/json") {
-      return false;
+namespace http_helpers
+{
+inline bool requestPrefersHtml(const crow::Request& req)
+{
+    boost::string_view header = req.getHeaderValue("accept");
+    std::vector<std::string> encodings;
+    // chrome currently sends 6 accepts headers, firefox sends 4.
+    encodings.reserve(6);
+    boost::split(encodings, header, boost::is_any_of(", "),
+                 boost::token_compress_on);
+    for (const std::string& encoding : encodings)
+    {
+        if (encoding == "text/html")
+        {
+            return true;
+        }
+        else if (encoding == "application/json")
+        {
+            return false;
+        }
     }
-  }
-  return false;
+    return false;
 }
-}  // namespace http_helpers
\ No newline at end of file
+} // namespace http_helpers
\ No newline at end of file
diff --git a/include/image_upload.hpp b/include/image_upload.hpp
index df5c1ae..2b84db8 100644
--- a/include/image_upload.hpp
+++ b/include/image_upload.hpp
@@ -1,103 +1,113 @@
 #pragma once
 
-#include <dbus_singleton.hpp>
-#include <cstdio>
-#include <fstream>
-#include <memory>
 #include <crow/app.h>
+
 #include <boost/uuid/uuid.hpp>
 #include <boost/uuid/uuid_generators.hpp>
 #include <boost/uuid/uuid_io.hpp>
+#include <cstdio>
+#include <dbus_singleton.hpp>
+#include <fstream>
+#include <memory>
 
-namespace crow {
-namespace image_upload {
+namespace crow
+{
+namespace image_upload
+{
 
 std::unique_ptr<sdbusplus::bus::match::match> fwUpdateMatcher;
 
 inline void uploadImageHandler(const crow::Request& req, crow::Response& res,
-                               const std::string& filename) {
-  // Only allow one FW update at a time
-  if (fwUpdateMatcher != nullptr) {
-    res.addHeader("Retry-After", "30");
-    res.result(boost::beast::http::status::service_unavailable);
-    res.end();
-    return;
-  }
-  // Make this const static so it survives outside this method
-  static boost::asio::deadline_timer timeout(*req.ioService,
-                                             boost::posix_time::seconds(5));
-
-  timeout.expires_from_now(boost::posix_time::seconds(5));
-
-  timeout.async_wait([&res](const boost::system::error_code& ec) {
-    fwUpdateMatcher = nullptr;
-    if (ec == asio::error::operation_aborted) {
-      // expected, we were canceled before the timer completed.
-      return;
-    }
-    BMCWEB_LOG_ERROR << "Timed out waiting for log event";
-
-    if (ec) {
-      BMCWEB_LOG_ERROR << "Async_wait failed " << ec;
-      return;
-    }
-
-    res.result(boost::beast::http::status::internal_server_error);
-    res.end();
-  });
-
-  std::function<void(sdbusplus::message::message&)> callback =
-      [&res](sdbusplus::message::message& m) {
-        BMCWEB_LOG_DEBUG << "Match fired";
-        boost::system::error_code ec;
-        timeout.cancel(ec);
-        if (ec) {
-          BMCWEB_LOG_ERROR << "error canceling timer " << ec;
-        }
-        std::string versionInfo;
-        m.read(versionInfo);  // Read in the object path that was just created
-
-        std::size_t index = versionInfo.rfind('/');
-        if (index != std::string::npos) {
-          versionInfo.erase(0, index);
-        }
-        res.jsonValue = {{"data", std::move(versionInfo)},
-                         {"message", "200 OK"},
-                         {"status", "ok"}};
-        BMCWEB_LOG_DEBUG << "ending response";
+                               const std::string& filename)
+{
+    // Only allow one FW update at a time
+    if (fwUpdateMatcher != nullptr)
+    {
+        res.addHeader("Retry-After", "30");
+        res.result(boost::beast::http::status::service_unavailable);
         res.end();
+        return;
+    }
+    // Make this const static so it survives outside this method
+    static boost::asio::deadline_timer timeout(*req.ioService,
+                                               boost::posix_time::seconds(5));
+
+    timeout.expires_from_now(boost::posix_time::seconds(5));
+
+    timeout.async_wait([&res](const boost::system::error_code& ec) {
         fwUpdateMatcher = nullptr;
-      };
-  fwUpdateMatcher = std::make_unique<sdbusplus::bus::match::match>(
-      *crow::connections::systemBus,
-      "interface='org.freedesktop.DBus.ObjectManager',type='signal',"
-      "member='InterfacesAdded',path='/xyz/openbmc_project/logging'",
-      callback);
+        if (ec == asio::error::operation_aborted)
+        {
+            // expected, we were canceled before the timer completed.
+            return;
+        }
+        BMCWEB_LOG_ERROR << "Timed out waiting for log event";
 
-  std::string filepath(
-      "/tmp/images/" +
-      boost::uuids::to_string(boost::uuids::random_generator()()));
-  BMCWEB_LOG_DEBUG << "Writing file to " << filepath;
-  std::ofstream out(filepath, std::ofstream::out | std::ofstream::binary |
-                                  std::ofstream::trunc);
-  out << req.body;
-  out.close();
+        if (ec)
+        {
+            BMCWEB_LOG_ERROR << "Async_wait failed " << ec;
+            return;
+        }
+
+        res.result(boost::beast::http::status::internal_server_error);
+        res.end();
+    });
+
+    std::function<void(sdbusplus::message::message&)> callback =
+        [&res](sdbusplus::message::message& m) {
+            BMCWEB_LOG_DEBUG << "Match fired";
+            boost::system::error_code ec;
+            timeout.cancel(ec);
+            if (ec)
+            {
+                BMCWEB_LOG_ERROR << "error canceling timer " << ec;
+            }
+            std::string versionInfo;
+            m.read(
+                versionInfo); // Read in the object path that was just created
+
+            std::size_t index = versionInfo.rfind('/');
+            if (index != std::string::npos)
+            {
+                versionInfo.erase(0, index);
+            }
+            res.jsonValue = {{"data", std::move(versionInfo)},
+                             {"message", "200 OK"},
+                             {"status", "ok"}};
+            BMCWEB_LOG_DEBUG << "ending response";
+            res.end();
+            fwUpdateMatcher = nullptr;
+        };
+    fwUpdateMatcher = std::make_unique<sdbusplus::bus::match::match>(
+        *crow::connections::systemBus,
+        "interface='org.freedesktop.DBus.ObjectManager',type='signal',"
+        "member='InterfacesAdded',path='/xyz/openbmc_project/logging'",
+        callback);
+
+    std::string filepath(
+        "/tmp/images/" +
+        boost::uuids::to_string(boost::uuids::random_generator()()));
+    BMCWEB_LOG_DEBUG << "Writing file to " << filepath;
+    std::ofstream out(filepath, std::ofstream::out | std::ofstream::binary |
+                                    std::ofstream::trunc);
+    out << req.body;
+    out.close();
 }
 
-template <typename... Middlewares>
-void requestRoutes(Crow<Middlewares...>& app) {
-  BMCWEB_ROUTE(app, "/upload/image/<str>")
-      .methods("POST"_method,
-               "PUT"_method)([](const crow::Request& req, crow::Response& res,
-                                const std::string& filename) {
-        uploadImageHandler(req, res, filename);
-      });
+template <typename... Middlewares> void requestRoutes(Crow<Middlewares...>& app)
+{
+    BMCWEB_ROUTE(app, "/upload/image/<str>")
+        .methods("POST"_method,
+                 "PUT"_method)([](const crow::Request& req, crow::Response& res,
+                                  const std::string& filename) {
+            uploadImageHandler(req, res, filename);
+        });
 
-  BMCWEB_ROUTE(app, "/upload/image")
-      .methods("POST"_method,
-               "PUT"_method)([](const crow::Request& req, crow::Response& res) {
-        uploadImageHandler(req, res, "");
-      });
+    BMCWEB_ROUTE(app, "/upload/image")
+        .methods("POST"_method, "PUT"_method)(
+            [](const crow::Request& req, crow::Response& res) {
+                uploadImageHandler(req, res, "");
+            });
 }
-}  // namespace image_upload
-}  // namespace crow
+} // namespace image_upload
+} // namespace crow
diff --git a/include/openbmc_dbus_rest.hpp b/include/openbmc_dbus_rest.hpp
index 3e6443d..4f6c233 100644
--- a/include/openbmc_dbus_rest.hpp
+++ b/include/openbmc_dbus_rest.hpp
@@ -1,64 +1,78 @@
 #include <crow/app.h>
-
 #include <tinyxml2.h>
+
+#include <boost/algorithm/string.hpp>
+#include <boost/container/flat_set.hpp>
 #include <dbus_singleton.hpp>
 #include <experimental/filesystem>
 #include <fstream>
-#include <boost/algorithm/string.hpp>
-#include <boost/container/flat_set.hpp>
 
-namespace crow {
-namespace openbmc_mapper {
+namespace crow
+{
+namespace openbmc_mapper
+{
 
 void introspectObjects(crow::Response &res, std::string process_name,
                        std::string path,
-                       std::shared_ptr<nlohmann::json> transaction) {
-  crow::connections::systemBus->async_method_call(
-      [
-        &res, transaction, processName{std::move(process_name)},
-        objectPath{std::move(path)}
-      ](const boost::system::error_code ec, const std::string &introspect_xml) {
-        if (ec) {
-          BMCWEB_LOG_ERROR << "Introspect call failed with error: "
-                           << ec.message() << " on process: " << processName
-                           << " path: " << objectPath << "\n";
-
-        } else {
-          transaction->push_back({{"path", objectPath}});
-
-          tinyxml2::XMLDocument doc;
-
-          doc.Parse(introspect_xml.c_str());
-          tinyxml2::XMLNode *pRoot = doc.FirstChildElement("node");
-          if (pRoot == nullptr) {
-            BMCWEB_LOG_ERROR << "XML document failed to parse " << processName
-                             << " " << objectPath << "\n";
-
-          } else {
-            tinyxml2::XMLElement *node = pRoot->FirstChildElement("node");
-            while (node != nullptr) {
-              std::string childPath = node->Attribute("name");
-              std::string newpath;
-              if (objectPath != "/") {
-                newpath += objectPath;
-              }
-              newpath += "/" + childPath;
-              // introspect the subobjects as well
-              introspectObjects(res, processName, newpath, transaction);
-
-              node = node->NextSiblingElement("node");
+                       std::shared_ptr<nlohmann::json> transaction)
+{
+    crow::connections::systemBus->async_method_call(
+        [&res, transaction, processName{std::move(process_name)},
+         objectPath{std::move(path)}](const boost::system::error_code ec,
+                                      const std::string &introspect_xml) {
+            if (ec)
+            {
+                BMCWEB_LOG_ERROR
+                    << "Introspect call failed with error: " << ec.message()
+                    << " on process: " << processName << " path: " << objectPath
+                    << "\n";
             }
-          }
-        }
-        // if we're the last outstanding caller, finish the request
-        if (transaction.use_count() == 1) {
-          res.jsonValue = {{"status", "ok"},
-                           {"bus_name", processName},
-                           {"objects", std::move(*transaction)}};
-          res.end();
-        }
-      },
-      process_name, path, "org.freedesktop.DBus.Introspectable", "Introspect");
+            else
+            {
+                transaction->push_back({{"path", objectPath}});
+
+                tinyxml2::XMLDocument doc;
+
+                doc.Parse(introspect_xml.c_str());
+                tinyxml2::XMLNode *pRoot = doc.FirstChildElement("node");
+                if (pRoot == nullptr)
+                {
+                    BMCWEB_LOG_ERROR << "XML document failed to parse "
+                                     << processName << " " << objectPath
+                                     << "\n";
+                }
+                else
+                {
+                    tinyxml2::XMLElement *node =
+                        pRoot->FirstChildElement("node");
+                    while (node != nullptr)
+                    {
+                        std::string childPath = node->Attribute("name");
+                        std::string newpath;
+                        if (objectPath != "/")
+                        {
+                            newpath += objectPath;
+                        }
+                        newpath += "/" + childPath;
+                        // introspect the subobjects as well
+                        introspectObjects(res, processName, newpath,
+                                          transaction);
+
+                        node = node->NextSiblingElement("node");
+                    }
+                }
+            }
+            // if we're the last outstanding caller, finish the request
+            if (transaction.use_count() == 1)
+            {
+                res.jsonValue = {{"status", "ok"},
+                                 {"bus_name", processName},
+                                 {"objects", std::move(*transaction)}};
+                res.end();
+            }
+        },
+        process_name, path, "org.freedesktop.DBus.Introspectable",
+        "Introspect");
 }
 
 // A smattering of common types to unpack.  TODO(ed) this should really iterate
@@ -74,46 +88,60 @@
         std::string,
         boost::container::flat_map<std::string, DbusRestVariantType>>>>;
 
-void getManagedObjectsForEnumerate(
-    const std::string &object_name, const std::string &connection_name,
-    crow::Response &res, std::shared_ptr<nlohmann::json> transaction) {
-  crow::connections::systemBus->async_method_call(
-      [&res, transaction](const boost::system::error_code ec,
-                          const ManagedObjectType &objects) {
-        if (ec) {
-          BMCWEB_LOG_ERROR << ec;
-        } else {
-          nlohmann::json &dataJson = *transaction;
-
-          for (auto &objectPath : objects) {
-            BMCWEB_LOG_DEBUG
-                << "Reading object "
-                << static_cast<const std::string &>(objectPath.first);
-            nlohmann::json &objectJson =
-                dataJson[static_cast<const std::string &>(objectPath.first)];
-            if (objectJson.is_null()) {
-              objectJson = nlohmann::json::object();
+void getManagedObjectsForEnumerate(const std::string &object_name,
+                                   const std::string &connection_name,
+                                   crow::Response &res,
+                                   std::shared_ptr<nlohmann::json> transaction)
+{
+    crow::connections::systemBus->async_method_call(
+        [&res, transaction](const boost::system::error_code ec,
+                            const ManagedObjectType &objects) {
+            if (ec)
+            {
+                BMCWEB_LOG_ERROR << ec;
             }
-            for (const auto &interface : objectPath.second) {
-              for (const auto &property : interface.second) {
-                nlohmann::json &propertyJson = objectJson[property.first];
-                mapbox::util::apply_visitor(
-                    [&propertyJson](auto &&val) { propertyJson = val; },
-                    property.second);
-              }
-            }
-          }
-        }
+            else
+            {
+                nlohmann::json &dataJson = *transaction;
 
-        if (transaction.use_count() == 1) {
-          res.jsonValue = {{"message", "200 OK"},
-                           {"status", "ok"},
-                           {"data", std::move(*transaction)}};
-          res.end();
-        }
-      },
-      connection_name, object_name, "org.freedesktop.DBus.ObjectManager",
-      "GetManagedObjects");
+                for (auto &objectPath : objects)
+                {
+                    BMCWEB_LOG_DEBUG
+                        << "Reading object "
+                        << static_cast<const std::string &>(objectPath.first);
+                    nlohmann::json &objectJson =
+                        dataJson[static_cast<const std::string &>(
+                            objectPath.first)];
+                    if (objectJson.is_null())
+                    {
+                        objectJson = nlohmann::json::object();
+                    }
+                    for (const auto &interface : objectPath.second)
+                    {
+                        for (const auto &property : interface.second)
+                        {
+                            nlohmann::json &propertyJson =
+                                objectJson[property.first];
+                            mapbox::util::apply_visitor(
+                                [&propertyJson](auto &&val) {
+                                    propertyJson = val;
+                                },
+                                property.second);
+                        }
+                    }
+                }
+            }
+
+            if (transaction.use_count() == 1)
+            {
+                res.jsonValue = {{"message", "200 OK"},
+                                 {"status", "ok"},
+                                 {"data", std::move(*transaction)}};
+                res.end();
+            }
+        },
+        connection_name, object_name, "org.freedesktop.DBus.ObjectManager",
+        "GetManagedObjects");
 }
 
 using GetSubTreeType = std::vector<
@@ -121,1025 +149,1320 @@
               std::vector<std::pair<std::string, std::vector<std::string>>>>>;
 
 // Structure for storing data on an in progress action
-struct InProgressActionData {
-  InProgressActionData(crow::Response &res) : res(res){};
-  ~InProgressActionData() {
-    if (res.result() == boost::beast::http::status::internal_server_error) {
-      // Reset the json object to clear out any data that made it in before the
-      // error happened
-      // todo(ed) handle error condition with proper code
-      res.jsonValue = nlohmann::json::object();
+struct InProgressActionData
+{
+    InProgressActionData(crow::Response &res) : res(res){};
+    ~InProgressActionData()
+    {
+        if (res.result() == boost::beast::http::status::internal_server_error)
+        {
+            // Reset the json object to clear out any data that made it in
+            // before the error happened todo(ed) handle error condition with
+            // proper code
+            res.jsonValue = nlohmann::json::object();
+        }
+        res.end();
     }
-    res.end();
-  }
 
-  void setErrorStatus() {
-    res.result(boost::beast::http::status::internal_server_error);
-  }
-  crow::Response &res;
-  std::string path;
-  std::string methodName;
-  nlohmann::json arguments;
+    void setErrorStatus()
+    {
+        res.result(boost::beast::http::status::internal_server_error);
+    }
+    crow::Response &res;
+    std::string path;
+    std::string methodName;
+    nlohmann::json arguments;
 };
 
-std::vector<std::string> dbusArgSplit(const std::string &string) {
-  std::vector<std::string> ret;
-  if (string.empty()) {
-    return ret;
-  }
-  ret.push_back("");
-  int containerDepth = 0;
-
-  for (std::string::const_iterator character = string.begin();
-       character != string.end(); character++) {
-    ret.back() += *character;
-    switch (*character) {
-      case ('a'):
-        break;
-      case ('('):
-      case ('{'):
-        containerDepth++;
-        break;
-      case ('}'):
-      case (')'):
-        containerDepth--;
-        if (containerDepth == 0) {
-          if (character + 1 != string.end()) {
-            ret.push_back("");
-          }
-        }
-        break;
-      default:
-        if (containerDepth == 0) {
-          if (character + 1 != string.end()) {
-            ret.push_back("");
-          }
-        }
-        break;
+std::vector<std::string> dbusArgSplit(const std::string &string)
+{
+    std::vector<std::string> ret;
+    if (string.empty())
+    {
+        return ret;
     }
-  }
+    ret.push_back("");
+    int containerDepth = 0;
+
+    for (std::string::const_iterator character = string.begin();
+         character != string.end(); character++)
+    {
+        ret.back() += *character;
+        switch (*character)
+        {
+            case ('a'):
+                break;
+            case ('('):
+            case ('{'):
+                containerDepth++;
+                break;
+            case ('}'):
+            case (')'):
+                containerDepth--;
+                if (containerDepth == 0)
+                {
+                    if (character + 1 != string.end())
+                    {
+                        ret.push_back("");
+                    }
+                }
+                break;
+            default:
+                if (containerDepth == 0)
+                {
+                    if (character + 1 != string.end())
+                    {
+                        ret.push_back("");
+                    }
+                }
+                break;
+        }
+    }
 }
 
 int convertJsonToDbus(sd_bus_message *m, const std::string &arg_type,
-                      const nlohmann::json &input_json) {
-  int r = 0;
-  BMCWEB_LOG_DEBUG << "Converting " << input_json.dump()
-                   << " to type: " << arg_type;
-  const std::vector<std::string> argTypes = dbusArgSplit(arg_type);
+                      const nlohmann::json &input_json)
+{
+    int r = 0;
+    BMCWEB_LOG_DEBUG << "Converting " << input_json.dump()
+                     << " to type: " << arg_type;
+    const std::vector<std::string> argTypes = dbusArgSplit(arg_type);
 
-  // Assume a single object for now.
-  const nlohmann::json *j = &input_json;
-  nlohmann::json::const_iterator jIt = input_json.begin();
+    // Assume a single object for now.
+    const nlohmann::json *j = &input_json;
+    nlohmann::json::const_iterator jIt = input_json.begin();
 
-  for (const std::string &arg_code : argTypes) {
-    // If we are decoding multiple objects, grab the pointer to the iterator,
-    // and increment it for the next loop
-    if (argTypes.size() > 1) {
-      if (jIt == input_json.end()) {
-        return -2;
-      }
-      j = &*jIt;
-      jIt++;
-    }
-    const int64_t *int_value = j->get_ptr<const int64_t *>();
-    const uint64_t *uint_value = j->get_ptr<const uint64_t *>();
-    const std::string *string_value = j->get_ptr<const std::string *>();
-    const double *double_value = j->get_ptr<const double *>();
-    const bool *b = j->get_ptr<const bool *>();
-    int64_t v = 0;
-    double d = 0.0;
+    for (const std::string &arg_code : argTypes)
+    {
+        // If we are decoding multiple objects, grab the pointer to the
+        // iterator, and increment it for the next loop
+        if (argTypes.size() > 1)
+        {
+            if (jIt == input_json.end())
+            {
+                return -2;
+            }
+            j = &*jIt;
+            jIt++;
+        }
+        const int64_t *int_value = j->get_ptr<const int64_t *>();
+        const uint64_t *uint_value = j->get_ptr<const uint64_t *>();
+        const std::string *string_value = j->get_ptr<const std::string *>();
+        const double *double_value = j->get_ptr<const double *>();
+        const bool *b = j->get_ptr<const bool *>();
+        int64_t v = 0;
+        double d = 0.0;
 
-    // Do some basic type conversions that make sense.  uint can be converted to
-    // int.  int and uint can be converted to double
-    if (uint_value != nullptr && int_value == nullptr) {
-      v = static_cast<int64_t>(*uint_value);
-      int_value = &v;
-    }
-    if (uint_value != nullptr && double_value == nullptr) {
-      d = static_cast<double>(*uint_value);
-      double_value = &d;
-    }
-    if (int_value != nullptr && double_value == nullptr) {
-      d = static_cast<double>(*int_value);
-      double_value = &d;
-    }
-
-    if (arg_code == "s") {
-      if (string_value == nullptr) {
-        return -1;
-      }
-      r = sd_bus_message_append_basic(m, arg_code[0],
-                                      (void *)string_value->c_str());
-      if (r < 0) {
-        return r;
-      }
-    } else if (arg_code == "i") {
-      if (int_value == nullptr) {
-        return -1;
-      }
-      int32_t i = static_cast<int32_t>(*int_value);
-      r = sd_bus_message_append_basic(m, arg_code[0], &i);
-      if (r < 0) {
-        return r;
-      }
-    } else if (arg_code == "b") {
-      // lots of ways bool could be represented here.  Try them all
-      int bool_int = false;
-      if (int_value != nullptr) {
-        bool_int = *int_value > 0 ? 1 : 0;
-      } else if (b != nullptr) {
-        bool_int = b ? 1 : 0;
-      } else if (string_value != nullptr) {
-        bool_int = boost::istarts_with(*string_value, "t") ? 1 : 0;
-      } else {
-        return -1;
-      }
-      r = sd_bus_message_append_basic(m, arg_code[0], &bool_int);
-      if (r < 0) {
-        return r;
-      }
-    } else if (arg_code == "n") {
-      if (int_value == nullptr) {
-        return -1;
-      }
-      int16_t n = static_cast<int16_t>(*int_value);
-      r = sd_bus_message_append_basic(m, arg_code[0], &n);
-      if (r < 0) {
-        return r;
-      }
-    } else if (arg_code == "x") {
-      if (int_value == nullptr) {
-        return -1;
-      }
-      r = sd_bus_message_append_basic(m, arg_code[0], int_value);
-      if (r < 0) {
-        return r;
-      }
-    } else if (arg_code == "y") {
-      if (uint_value == nullptr) {
-        return -1;
-      }
-      uint8_t y = static_cast<uint8_t>(*uint_value);
-      r = sd_bus_message_append_basic(m, arg_code[0], &y);
-    } else if (arg_code == "q") {
-      if (uint_value == nullptr) {
-        return -1;
-      }
-      uint16_t q = static_cast<uint16_t>(*uint_value);
-      r = sd_bus_message_append_basic(m, arg_code[0], &q);
-    } else if (arg_code == "u") {
-      if (uint_value == nullptr) {
-        return -1;
-      }
-      uint32_t u = static_cast<uint32_t>(*uint_value);
-      r = sd_bus_message_append_basic(m, arg_code[0], &u);
-    } else if (arg_code == "t") {
-      if (uint_value == nullptr) {
-        return -1;
-      }
-      r = sd_bus_message_append_basic(m, arg_code[0], uint_value);
-    } else if (arg_code == "d") {
-      sd_bus_message_append_basic(m, arg_code[0], double_value);
-    } else if (boost::starts_with(arg_code, "a")) {
-      std::string contained_type = arg_code.substr(1);
-      r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY,
-                                        contained_type.c_str());
-      if (r < 0) {
-        return r;
-      }
-
-      for (nlohmann::json::const_iterator it = j->begin(); it != j->end();
-           ++it) {
-        r = convertJsonToDbus(m, contained_type, *it);
-        if (r < 0) {
-          return r;
+        // Do some basic type conversions that make sense.  uint can be
+        // converted to int.  int and uint can be converted to double
+        if (uint_value != nullptr && int_value == nullptr)
+        {
+            v = static_cast<int64_t>(*uint_value);
+            int_value = &v;
+        }
+        if (uint_value != nullptr && double_value == nullptr)
+        {
+            d = static_cast<double>(*uint_value);
+            double_value = &d;
+        }
+        if (int_value != nullptr && double_value == nullptr)
+        {
+            d = static_cast<double>(*int_value);
+            double_value = &d;
         }
 
-        it++;
-      }
-      sd_bus_message_close_container(m);
-    } else if (boost::starts_with(arg_code, "v")) {
-      std::string contained_type = arg_code.substr(1);
-      BMCWEB_LOG_DEBUG << "variant type: " << arg_code
-                       << " appending variant of type: " << contained_type;
-      r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT,
-                                        contained_type.c_str());
-      if (r < 0) {
-        return r;
-      }
-
-      r = convertJsonToDbus(m, contained_type, input_json);
-      if (r < 0) {
-        return r;
-      }
-
-      r = sd_bus_message_close_container(m);
-      if (r < 0) {
-        return r;
-      }
-    } else if (boost::starts_with(arg_code, "(") &&
-               boost::ends_with(arg_code, ")")) {
-      std::string contained_type = arg_code.substr(1, arg_code.size() - 1);
-      r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT,
-                                        contained_type.c_str());
-      nlohmann::json::const_iterator it = j->begin();
-      for (const std::string &arg_code : dbusArgSplit(arg_type)) {
-        if (it == j->end()) {
-          return -1;
+        if (arg_code == "s")
+        {
+            if (string_value == nullptr)
+            {
+                return -1;
+            }
+            r = sd_bus_message_append_basic(m, arg_code[0],
+                                            (void *)string_value->c_str());
+            if (r < 0)
+            {
+                return r;
+            }
         }
-        r = convertJsonToDbus(m, arg_code, *it);
-        if (r < 0) {
-          return r;
+        else if (arg_code == "i")
+        {
+            if (int_value == nullptr)
+            {
+                return -1;
+            }
+            int32_t i = static_cast<int32_t>(*int_value);
+            r = sd_bus_message_append_basic(m, arg_code[0], &i);
+            if (r < 0)
+            {
+                return r;
+            }
         }
-        it++;
-      }
-      r = sd_bus_message_close_container(m);
-    } else if (boost::starts_with(arg_code, "{") &&
-               boost::ends_with(arg_code, "}")) {
-      std::string contained_type = arg_code.substr(1, arg_code.size() - 1);
-      r = sd_bus_message_open_container(m, SD_BUS_TYPE_DICT_ENTRY,
-                                        contained_type.c_str());
-      std::vector<std::string> codes = dbusArgSplit(contained_type);
-      if (codes.size() != 2) {
-        return -1;
-      }
-      const std::string &key_type = codes[0];
-      const std::string &value_type = codes[1];
-      for (auto it : j->items()) {
-        r = convertJsonToDbus(m, key_type, it.key());
-        if (r < 0) {
-          return r;
+        else if (arg_code == "b")
+        {
+            // lots of ways bool could be represented here.  Try them all
+            int bool_int = false;
+            if (int_value != nullptr)
+            {
+                bool_int = *int_value > 0 ? 1 : 0;
+            }
+            else if (b != nullptr)
+            {
+                bool_int = b ? 1 : 0;
+            }
+            else if (string_value != nullptr)
+            {
+                bool_int = boost::istarts_with(*string_value, "t") ? 1 : 0;
+            }
+            else
+            {
+                return -1;
+            }
+            r = sd_bus_message_append_basic(m, arg_code[0], &bool_int);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (arg_code == "n")
+        {
+            if (int_value == nullptr)
+            {
+                return -1;
+            }
+            int16_t n = static_cast<int16_t>(*int_value);
+            r = sd_bus_message_append_basic(m, arg_code[0], &n);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (arg_code == "x")
+        {
+            if (int_value == nullptr)
+            {
+                return -1;
+            }
+            r = sd_bus_message_append_basic(m, arg_code[0], int_value);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (arg_code == "y")
+        {
+            if (uint_value == nullptr)
+            {
+                return -1;
+            }
+            uint8_t y = static_cast<uint8_t>(*uint_value);
+            r = sd_bus_message_append_basic(m, arg_code[0], &y);
+        }
+        else if (arg_code == "q")
+        {
+            if (uint_value == nullptr)
+            {
+                return -1;
+            }
+            uint16_t q = static_cast<uint16_t>(*uint_value);
+            r = sd_bus_message_append_basic(m, arg_code[0], &q);
+        }
+        else if (arg_code == "u")
+        {
+            if (uint_value == nullptr)
+            {
+                return -1;
+            }
+            uint32_t u = static_cast<uint32_t>(*uint_value);
+            r = sd_bus_message_append_basic(m, arg_code[0], &u);
+        }
+        else if (arg_code == "t")
+        {
+            if (uint_value == nullptr)
+            {
+                return -1;
+            }
+            r = sd_bus_message_append_basic(m, arg_code[0], uint_value);
+        }
+        else if (arg_code == "d")
+        {
+            sd_bus_message_append_basic(m, arg_code[0], double_value);
+        }
+        else if (boost::starts_with(arg_code, "a"))
+        {
+            std::string contained_type = arg_code.substr(1);
+            r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY,
+                                              contained_type.c_str());
+            if (r < 0)
+            {
+                return r;
+            }
+
+            for (nlohmann::json::const_iterator it = j->begin(); it != j->end();
+                 ++it)
+            {
+                r = convertJsonToDbus(m, contained_type, *it);
+                if (r < 0)
+                {
+                    return r;
+                }
+
+                it++;
+            }
+            sd_bus_message_close_container(m);
+        }
+        else if (boost::starts_with(arg_code, "v"))
+        {
+            std::string contained_type = arg_code.substr(1);
+            BMCWEB_LOG_DEBUG
+                << "variant type: " << arg_code
+                << " appending variant of type: " << contained_type;
+            r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT,
+                                              contained_type.c_str());
+            if (r < 0)
+            {
+                return r;
+            }
+
+            r = convertJsonToDbus(m, contained_type, input_json);
+            if (r < 0)
+            {
+                return r;
+            }
+
+            r = sd_bus_message_close_container(m);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (boost::starts_with(arg_code, "(") &&
+                 boost::ends_with(arg_code, ")"))
+        {
+            std::string contained_type =
+                arg_code.substr(1, arg_code.size() - 1);
+            r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT,
+                                              contained_type.c_str());
+            nlohmann::json::const_iterator it = j->begin();
+            for (const std::string &arg_code : dbusArgSplit(arg_type))
+            {
+                if (it == j->end())
+                {
+                    return -1;
+                }
+                r = convertJsonToDbus(m, arg_code, *it);
+                if (r < 0)
+                {
+                    return r;
+                }
+                it++;
+            }
+            r = sd_bus_message_close_container(m);
+        }
+        else if (boost::starts_with(arg_code, "{") &&
+                 boost::ends_with(arg_code, "}"))
+        {
+            std::string contained_type =
+                arg_code.substr(1, arg_code.size() - 1);
+            r = sd_bus_message_open_container(m, SD_BUS_TYPE_DICT_ENTRY,
+                                              contained_type.c_str());
+            std::vector<std::string> codes = dbusArgSplit(contained_type);
+            if (codes.size() != 2)
+            {
+                return -1;
+            }
+            const std::string &key_type = codes[0];
+            const std::string &value_type = codes[1];
+            for (auto it : j->items())
+            {
+                r = convertJsonToDbus(m, key_type, it.key());
+                if (r < 0)
+                {
+                    return r;
+                }
+
+                r = convertJsonToDbus(m, value_type, it.value());
+                if (r < 0)
+                {
+                    return r;
+                }
+            }
+            r = sd_bus_message_close_container(m);
+        }
+        else
+        {
+            return -2;
+        }
+        if (r < 0)
+        {
+            return r;
         }
 
-        r = convertJsonToDbus(m, value_type, it.value());
-        if (r < 0) {
-          return r;
+        if (argTypes.size() > 1)
+        {
+            jIt++;
         }
-      }
-      r = sd_bus_message_close_container(m);
-    } else {
-      return -2;
     }
-    if (r < 0) {
-      return r;
-    }
-
-    if (argTypes.size() > 1) {
-      jIt++;
-    }
-  }
 }
 
 void findActionOnInterface(std::shared_ptr<InProgressActionData> transaction,
-                           const std::string &connectionName) {
-  BMCWEB_LOG_DEBUG << "findActionOnInterface for connection " << connectionName;
-  crow::connections::systemBus->async_method_call(
-      [
-        transaction, connectionName{std::string(connectionName)}
-      ](const boost::system::error_code ec, const std::string &introspect_xml) {
-        BMCWEB_LOG_DEBUG << "got xml:\n " << introspect_xml;
-        if (ec) {
-          BMCWEB_LOG_ERROR << "Introspect call failed with error: "
-                           << ec.message() << " on process: " << connectionName
-                           << "\n";
-        } else {
-          tinyxml2::XMLDocument doc;
-
-          doc.Parse(introspect_xml.c_str());
-          tinyxml2::XMLNode *pRoot = doc.FirstChildElement("node");
-          if (pRoot == nullptr) {
-            BMCWEB_LOG_ERROR << "XML document failed to parse "
-                             << connectionName << "\n";
-
-          } else {
-            tinyxml2::XMLElement *interface_node =
-                pRoot->FirstChildElement("interface");
-            while (interface_node != nullptr) {
-              std::string this_interface_name =
-                  interface_node->Attribute("name");
-              tinyxml2::XMLElement *method_node =
-                  interface_node->FirstChildElement("method");
-              while (method_node != nullptr) {
-                std::string this_methodName = method_node->Attribute("name");
-                BMCWEB_LOG_DEBUG << "Found method: " << this_methodName;
-                if (this_methodName == transaction->methodName) {
-                  sdbusplus::message::message m =
-                      crow::connections::systemBus->new_method_call(
-                          connectionName.c_str(), transaction->path.c_str(),
-                          this_interface_name.c_str(),
-                          transaction->methodName.c_str());
-
-                  tinyxml2::XMLElement *argument_node =
-                      method_node->FirstChildElement("arg");
-
-                  nlohmann::json::const_iterator arg_it =
-                      transaction->arguments.begin();
-
-                  while (argument_node != nullptr) {
-                    std::string arg_direction =
-                        argument_node->Attribute("direction");
-                    if (arg_direction == "in") {
-                      std::string arg_type = argument_node->Attribute("type");
-                      if (arg_it == transaction->arguments.end()) {
-                        transaction->setErrorStatus();
-                        return;
-                      }
-                      if (convertJsonToDbus(m.get(), arg_type, *arg_it) < 0) {
-                        transaction->setErrorStatus();
-                        return;
-                      }
-
-                      arg_it++;
-                    }
-                    argument_node = method_node->NextSiblingElement("arg");
-                  }
-                  crow::connections::systemBus->async_send(
-                      m, [transaction](boost::system::error_code ec,
-                                       sdbusplus::message::message &m) {
-                        if (ec) {
-                          transaction->setErrorStatus();
-                          return;
-                        }
-                        transaction->res.jsonValue = {{"status", "ok"},
-                                                      {"message", "200 OK"},
-                                                      {"data", nullptr}};
-                      });
-                  break;
-                }
-                method_node = method_node->NextSiblingElement("method");
-              }
-              interface_node = interface_node->NextSiblingElement("interface");
+                           const std::string &connectionName)
+{
+    BMCWEB_LOG_DEBUG << "findActionOnInterface for connection "
+                     << connectionName;
+    crow::connections::systemBus->async_method_call(
+        [transaction, connectionName{std::string(connectionName)}](
+            const boost::system::error_code ec,
+            const std::string &introspect_xml) {
+            BMCWEB_LOG_DEBUG << "got xml:\n " << introspect_xml;
+            if (ec)
+            {
+                BMCWEB_LOG_ERROR
+                    << "Introspect call failed with error: " << ec.message()
+                    << " on process: " << connectionName << "\n";
             }
-          }
-        }
-      },
-      connectionName, transaction->path, "org.freedesktop.DBus.Introspectable",
-      "Introspect");
+            else
+            {
+                tinyxml2::XMLDocument doc;
+
+                doc.Parse(introspect_xml.c_str());
+                tinyxml2::XMLNode *pRoot = doc.FirstChildElement("node");
+                if (pRoot == nullptr)
+                {
+                    BMCWEB_LOG_ERROR << "XML document failed to parse "
+                                     << connectionName << "\n";
+                }
+                else
+                {
+                    tinyxml2::XMLElement *interface_node =
+                        pRoot->FirstChildElement("interface");
+                    while (interface_node != nullptr)
+                    {
+                        std::string this_interface_name =
+                            interface_node->Attribute("name");
+                        tinyxml2::XMLElement *method_node =
+                            interface_node->FirstChildElement("method");
+                        while (method_node != nullptr)
+                        {
+                            std::string this_methodName =
+                                method_node->Attribute("name");
+                            BMCWEB_LOG_DEBUG << "Found method: "
+                                             << this_methodName;
+                            if (this_methodName == transaction->methodName)
+                            {
+                                sdbusplus::message::message m =
+                                    crow::connections::systemBus
+                                        ->new_method_call(
+                                            connectionName.c_str(),
+                                            transaction->path.c_str(),
+                                            this_interface_name.c_str(),
+                                            transaction->methodName.c_str());
+
+                                tinyxml2::XMLElement *argument_node =
+                                    method_node->FirstChildElement("arg");
+
+                                nlohmann::json::const_iterator arg_it =
+                                    transaction->arguments.begin();
+
+                                while (argument_node != nullptr)
+                                {
+                                    std::string arg_direction =
+                                        argument_node->Attribute("direction");
+                                    if (arg_direction == "in")
+                                    {
+                                        std::string arg_type =
+                                            argument_node->Attribute("type");
+                                        if (arg_it ==
+                                            transaction->arguments.end())
+                                        {
+                                            transaction->setErrorStatus();
+                                            return;
+                                        }
+                                        if (convertJsonToDbus(m.get(), arg_type,
+                                                              *arg_it) < 0)
+                                        {
+                                            transaction->setErrorStatus();
+                                            return;
+                                        }
+
+                                        arg_it++;
+                                    }
+                                    argument_node =
+                                        method_node->NextSiblingElement("arg");
+                                }
+                                crow::connections::systemBus->async_send(
+                                    m, [transaction](
+                                           boost::system::error_code ec,
+                                           sdbusplus::message::message &m) {
+                                        if (ec)
+                                        {
+                                            transaction->setErrorStatus();
+                                            return;
+                                        }
+                                        transaction->res.jsonValue = {
+                                            {"status", "ok"},
+                                            {"message", "200 OK"},
+                                            {"data", nullptr}};
+                                    });
+                                break;
+                            }
+                            method_node =
+                                method_node->NextSiblingElement("method");
+                        }
+                        interface_node =
+                            interface_node->NextSiblingElement("interface");
+                    }
+                }
+            }
+        },
+        connectionName, transaction->path,
+        "org.freedesktop.DBus.Introspectable", "Introspect");
 }
 
 void handle_action(const crow::Request &req, crow::Response &res,
-                   const std::string &objectPath,
-                   const std::string &methodName) {
-  nlohmann::json requestDbusData =
-      nlohmann::json::parse(req.body, nullptr, false);
+                   const std::string &objectPath, const std::string &methodName)
+{
+    nlohmann::json requestDbusData =
+        nlohmann::json::parse(req.body, nullptr, false);
 
-  if (requestDbusData.is_discarded()) {
-    res.result(boost::beast::http::status::bad_request);
-    res.end();
-    return;
-  }
-  if (!requestDbusData.is_array()) {
-    res.result(boost::beast::http::status::bad_request);
-    res.end();
-    return;
-  }
-  auto transaction = std::make_shared<InProgressActionData>(res);
-
-  transaction->path = objectPath;
-  transaction->methodName = methodName;
-  transaction->arguments = std::move(requestDbusData);
-  crow::connections::systemBus->async_method_call(
-      [transaction](
-          const boost::system::error_code ec,
-          const std::vector<std::pair<std::string, std::vector<std::string>>>
-              &interface_names) {
-        if (ec || interface_names.size() <= 0) {
-          transaction->setErrorStatus();
-          return;
-        }
-
-        BMCWEB_LOG_DEBUG << "GetObject returned objects "
-                         << interface_names.size();
-
-        for (const std::pair<std::string, std::vector<std::string>> &object :
-             interface_names) {
-          findActionOnInterface(transaction, object.first);
-        }
-      },
-      "xyz.openbmc_project.ObjectMapper", "/xyz/openbmc_project/object_mapper",
-      "xyz.openbmc_project.ObjectMapper", "GetObject", objectPath,
-      std::array<std::string, 0>());
-}
-
-void handle_list(crow::Response &res, const std::string &objectPath) {
-  crow::connections::systemBus->async_method_call(
-      [&res](const boost::system::error_code ec,
-             std::vector<std::string> &objectPaths) {
-        if (ec) {
-          res.result(boost::beast::http::status::internal_server_error);
-        } else {
-          res.jsonValue = {{"status", "ok"},
-                           {"message", "200 OK"},
-                           {"data", std::move(objectPaths)}};
-        }
+    if (requestDbusData.is_discarded())
+    {
+        res.result(boost::beast::http::status::bad_request);
         res.end();
-      },
-      "xyz.openbmc_project.ObjectMapper", "/xyz/openbmc_project/object_mapper",
-      "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", objectPath,
-      static_cast<int32_t>(99), std::array<std::string, 0>());
+        return;
+    }
+    if (!requestDbusData.is_array())
+    {
+        res.result(boost::beast::http::status::bad_request);
+        res.end();
+        return;
+    }
+    auto transaction = std::make_shared<InProgressActionData>(res);
+
+    transaction->path = objectPath;
+    transaction->methodName = methodName;
+    transaction->arguments = std::move(requestDbusData);
+    crow::connections::systemBus->async_method_call(
+        [transaction](
+            const boost::system::error_code ec,
+            const std::vector<std::pair<std::string, std::vector<std::string>>>
+                &interface_names) {
+            if (ec || interface_names.size() <= 0)
+            {
+                transaction->setErrorStatus();
+                return;
+            }
+
+            BMCWEB_LOG_DEBUG << "GetObject returned objects "
+                             << interface_names.size();
+
+            for (const std::pair<std::string, std::vector<std::string>>
+                     &object : interface_names)
+            {
+                findActionOnInterface(transaction, object.first);
+            }
+        },
+        "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetObject", objectPath,
+        std::array<std::string, 0>());
 }
 
-void handle_enumerate(crow::Response &res, const std::string &objectPath) {
-  crow::connections::systemBus->async_method_call(
-      [&res, objectPath{std::string(objectPath)} ](
-          const boost::system::error_code ec,
-          const GetSubTreeType &object_names) {
-        if (ec) {
-          res.jsonValue = {{"message", "200 OK"},
-                           {"status", "ok"},
-                           {"data", nlohmann::json::object()}};
+void handle_list(crow::Response &res, const std::string &objectPath)
+{
+    crow::connections::systemBus->async_method_call(
+        [&res](const boost::system::error_code ec,
+               std::vector<std::string> &objectPaths) {
+            if (ec)
+            {
+                res.result(boost::beast::http::status::internal_server_error);
+            }
+            else
+            {
+                res.jsonValue = {{"status", "ok"},
+                                 {"message", "200 OK"},
+                                 {"data", std::move(objectPaths)}};
+            }
+            res.end();
+        },
+        "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", objectPath,
+        static_cast<int32_t>(99), std::array<std::string, 0>());
+}
 
-          res.end();
-          return;
-        }
+void handle_enumerate(crow::Response &res, const std::string &objectPath)
+{
+    crow::connections::systemBus->async_method_call(
+        [&res, objectPath{std::string(objectPath)}](
+            const boost::system::error_code ec,
+            const GetSubTreeType &object_names) {
+            if (ec)
+            {
+                res.jsonValue = {{"message", "200 OK"},
+                                 {"status", "ok"},
+                                 {"data", nlohmann::json::object()}};
 
-        boost::container::flat_set<std::string> connections;
+                res.end();
+                return;
+            }
 
-        for (const auto &object : object_names) {
-          for (const auto &Connection : object.second) {
-            connections.insert(Connection.first);
-          }
-        }
+            boost::container::flat_set<std::string> connections;
 
-        if (connections.size() <= 0) {
-          res.result(boost::beast::http::status::not_found);
-          res.end();
-          return;
-        }
-        auto transaction =
-            std::make_shared<nlohmann::json>(nlohmann::json::object());
-        for (const std::string &Connection : connections) {
-          getManagedObjectsForEnumerate(objectPath, Connection, res,
-                                        transaction);
-        }
-      },
-      "xyz.openbmc_project.ObjectMapper", "/xyz/openbmc_project/object_mapper",
-      "xyz.openbmc_project.ObjectMapper", "GetSubTree", objectPath, (int32_t)0,
-      std::array<std::string, 0>());
+            for (const auto &object : object_names)
+            {
+                for (const auto &Connection : object.second)
+                {
+                    connections.insert(Connection.first);
+                }
+            }
+
+            if (connections.size() <= 0)
+            {
+                res.result(boost::beast::http::status::not_found);
+                res.end();
+                return;
+            }
+            auto transaction =
+                std::make_shared<nlohmann::json>(nlohmann::json::object());
+            for (const std::string &Connection : connections)
+            {
+                getManagedObjectsForEnumerate(objectPath, Connection, res,
+                                              transaction);
+            }
+        },
+        "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetSubTree", objectPath,
+        (int32_t)0, std::array<std::string, 0>());
 }
 
 void handle_get(crow::Response &res, std::string &objectPath,
-                std::string &destProperty) {
-  BMCWEB_LOG_DEBUG << "handle_get: " << objectPath << " prop:" << destProperty;
-  std::shared_ptr<std::string> property_name =
-      std::make_shared<std::string>(std::move(destProperty));
+                std::string &destProperty)
+{
+    BMCWEB_LOG_DEBUG << "handle_get: " << objectPath
+                     << " prop:" << destProperty;
+    std::shared_ptr<std::string> property_name =
+        std::make_shared<std::string>(std::move(destProperty));
 
-  std::shared_ptr<std::string> path =
-      std::make_shared<std::string>(std::move(objectPath));
+    std::shared_ptr<std::string> path =
+        std::make_shared<std::string>(std::move(objectPath));
 
-  using GetObjectType =
-      std::vector<std::pair<std::string, std::vector<std::string>>>;
-  crow::connections::systemBus->async_method_call(
-      [&res, path, property_name](const boost::system::error_code ec,
-                                  const GetObjectType &object_names) {
-        if (ec || object_names.size() <= 0) {
-          res.result(boost::beast::http::status::not_found);
-          res.end();
-          return;
-        }
-        std::shared_ptr<nlohmann::json> response =
-            std::make_shared<nlohmann::json>(nlohmann::json::object());
-        // The mapper should never give us an empty interface names list, but
-        // check anyway
-        for (const std::pair<std::string, std::vector<std::string>> connection :
-             object_names) {
-          const std::vector<std::string> &interfaceNames = connection.second;
+    using GetObjectType =
+        std::vector<std::pair<std::string, std::vector<std::string>>>;
+    crow::connections::systemBus->async_method_call(
+        [&res, path, property_name](const boost::system::error_code ec,
+                                    const GetObjectType &object_names) {
+            if (ec || object_names.size() <= 0)
+            {
+                res.result(boost::beast::http::status::not_found);
+                res.end();
+                return;
+            }
+            std::shared_ptr<nlohmann::json> response =
+                std::make_shared<nlohmann::json>(nlohmann::json::object());
+            // The mapper should never give us an empty interface names list,
+            // but check anyway
+            for (const std::pair<std::string, std::vector<std::string>>
+                     connection : object_names)
+            {
+                const std::vector<std::string> &interfaceNames =
+                    connection.second;
 
-          if (interfaceNames.size() <= 0) {
-            res.result(boost::beast::http::status::not_found);
-            res.end();
-            return;
-          }
-
-          for (const std::string &interface : interfaceNames) {
-            crow::connections::systemBus->async_method_call(
-                [&res, response, property_name](
-                    const boost::system::error_code ec,
-                    const std::vector<std::pair<
-                        std::string, DbusRestVariantType>> &properties) {
-                  if (ec) {
-                    BMCWEB_LOG_ERROR << "Bad dbus request error: " << ec;
-                  } else {
-                    for (const std::pair<std::string, DbusRestVariantType>
-                             &property : properties) {
-                      // if property name is empty, or matches our search query,
-                      // add it to the response json
-
-                      if (property_name->empty()) {
-                        mapbox::util::apply_visitor(
-                            [&response, &property](auto &&val) {
-                              (*response)[property.first] = val;
-                            },
-                            property.second);
-                      } else if (property.first == *property_name) {
-                        mapbox::util::apply_visitor(
-                            [&response](auto &&val) { (*response) = val; },
-                            property.second);
-                      }
-                    }
-                  }
-                  if (response.use_count() == 1) {
-                    res.jsonValue = {{"status", "ok"},
-                                     {"message", "200 OK"},
-                                     {"data", *response}};
-
+                if (interfaceNames.size() <= 0)
+                {
+                    res.result(boost::beast::http::status::not_found);
                     res.end();
-                  }
-                },
-                connection.first, *path, "org.freedesktop.DBus.Properties",
-                "GetAll", interface);
-          }
-        }
-      },
-      "xyz.openbmc_project.ObjectMapper", "/xyz/openbmc_project/object_mapper",
-      "xyz.openbmc_project.ObjectMapper", "GetObject", *path,
-      std::array<std::string, 0>());
+                    return;
+                }
+
+                for (const std::string &interface : interfaceNames)
+                {
+                    crow::connections::systemBus->async_method_call(
+                        [&res, response, property_name](
+                            const boost::system::error_code ec,
+                            const std::vector<
+                                std::pair<std::string, DbusRestVariantType>>
+                                &properties) {
+                            if (ec)
+                            {
+                                BMCWEB_LOG_ERROR << "Bad dbus request error: "
+                                                 << ec;
+                            }
+                            else
+                            {
+                                for (const std::pair<std::string,
+                                                     DbusRestVariantType>
+                                         &property : properties)
+                                {
+                                    // if property name is empty, or matches our
+                                    // search query, add it to the response json
+
+                                    if (property_name->empty())
+                                    {
+                                        mapbox::util::apply_visitor(
+                                            [&response, &property](auto &&val) {
+                                                (*response)[property.first] =
+                                                    val;
+                                            },
+                                            property.second);
+                                    }
+                                    else if (property.first == *property_name)
+                                    {
+                                        mapbox::util::apply_visitor(
+                                            [&response](auto &&val) {
+                                                (*response) = val;
+                                            },
+                                            property.second);
+                                    }
+                                }
+                            }
+                            if (response.use_count() == 1)
+                            {
+                                res.jsonValue = {{"status", "ok"},
+                                                 {"message", "200 OK"},
+                                                 {"data", *response}};
+
+                                res.end();
+                            }
+                        },
+                        connection.first, *path,
+                        "org.freedesktop.DBus.Properties", "GetAll", interface);
+                }
+            }
+        },
+        "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetObject", *path,
+        std::array<std::string, 0>());
 }
 
-struct AsyncPutRequest {
-  AsyncPutRequest(crow::Response &res) : res(res) {
-    res.jsonValue = {
-        {"status", "ok"}, {"message", "200 OK"}, {"data", nullptr}};
-  }
-  ~AsyncPutRequest() {
-    if (res.result() == boost::beast::http::status::internal_server_error) {
-      // Reset the json object to clear out any data that made it in before the
-      // error happened
-      // todo(ed) handle error condition with proper code
-      res.jsonValue = nlohmann::json::object();
+struct AsyncPutRequest
+{
+    AsyncPutRequest(crow::Response &res) : res(res)
+    {
+        res.jsonValue = {
+            {"status", "ok"}, {"message", "200 OK"}, {"data", nullptr}};
+    }
+    ~AsyncPutRequest()
+    {
+        if (res.result() == boost::beast::http::status::internal_server_error)
+        {
+            // Reset the json object to clear out any data that made it in
+            // before the error happened todo(ed) handle error condition with
+            // proper code
+            res.jsonValue = nlohmann::json::object();
+        }
+
+        if (res.jsonValue.empty())
+        {
+            res.result(boost::beast::http::status::forbidden);
+            res.jsonValue = {
+                {"status", "error"},
+                {"message", "403 Forbidden"},
+                {"data",
+                 {{"message", "The specified property cannot be created: " +
+                                  propertyName}}}};
+        }
+
+        res.end();
     }
 
-    if (res.jsonValue.empty()) {
-      res.result(boost::beast::http::status::forbidden);
-      res.jsonValue = {
-          {"status", "error"},
-          {"message", "403 Forbidden"},
-          {"data",
-           {{"message",
-             "The specified property cannot be created: " + propertyName}}}};
+    void setErrorStatus()
+    {
+        res.result(boost::beast::http::status::internal_server_error);
     }
 
-    res.end();
-  }
-
-  void setErrorStatus() {
-    res.result(boost::beast::http::status::internal_server_error);
-  }
-
-  crow::Response &res;
-  std::string objectPath;
-  std::string propertyName;
-  nlohmann::json propertyValue;
+    crow::Response &res;
+    std::string objectPath;
+    std::string propertyName;
+    nlohmann::json propertyValue;
 };
 
 void handlePut(const crow::Request &req, crow::Response &res,
-               const std::string &objectPath, const std::string &destProperty) {
-  nlohmann::json requestDbusData =
-      nlohmann::json::parse(req.body, nullptr, false);
+               const std::string &objectPath, const std::string &destProperty)
+{
+    nlohmann::json requestDbusData =
+        nlohmann::json::parse(req.body, nullptr, false);
 
-  if (requestDbusData.is_discarded()) {
-    res.result(boost::beast::http::status::bad_request);
-    res.end();
-    return;
-  }
-
-  nlohmann::json::const_iterator propertyIt = requestDbusData.find("data");
-  if (propertyIt == requestDbusData.end()) {
-    res.result(boost::beast::http::status::bad_request);
-    res.end();
-    return;
-  }
-  const nlohmann::json &propertySetValue = *propertyIt;
-  auto transaction = std::make_shared<AsyncPutRequest>(res);
-  transaction->objectPath = objectPath;
-  transaction->propertyName = destProperty;
-  transaction->propertyValue = propertySetValue;
-
-  using GetObjectType =
-      std::vector<std::pair<std::string, std::vector<std::string>>>;
-
-  crow::connections::systemBus->async_method_call(
-      [transaction](const boost::system::error_code ec,
-                    const GetObjectType &object_names) {
-        if (!ec && object_names.size() <= 0) {
-          transaction->res.result(boost::beast::http::status::not_found);
-          return;
-        }
-
-        for (const std::pair<std::string, std::vector<std::string>> connection :
-             object_names) {
-          const std::string &connectionName = connection.first;
-
-          crow::connections::systemBus->async_method_call(
-              [ connectionName{std::string(connectionName)}, transaction ](
-                  const boost::system::error_code ec,
-                  const std::string &introspectXml) {
-                if (ec) {
-                  BMCWEB_LOG_ERROR
-                      << "Introspect call failed with error: " << ec.message()
-                      << " on process: " << connectionName;
-                  transaction->setErrorStatus();
-                  return;
-                }
-                tinyxml2::XMLDocument doc;
-
-                doc.Parse(introspectXml.c_str());
-                tinyxml2::XMLNode *pRoot = doc.FirstChildElement("node");
-                if (pRoot == nullptr) {
-                  BMCWEB_LOG_ERROR << "XML document failed to parse: "
-                                   << introspectXml;
-                  transaction->setErrorStatus();
-                  return;
-                }
-                tinyxml2::XMLElement *ifaceNode =
-                    pRoot->FirstChildElement("interface");
-                while (ifaceNode != nullptr) {
-                  const char *interfaceName = ifaceNode->Attribute("name");
-                  BMCWEB_LOG_DEBUG << "found interface " << interfaceName;
-                  tinyxml2::XMLElement *propNode =
-                      ifaceNode->FirstChildElement("property");
-                  while (propNode != nullptr) {
-                    const char *propertyName = propNode->Attribute("name");
-                    BMCWEB_LOG_DEBUG << "Found property " << propertyName;
-                    if (propertyName == transaction->propertyName) {
-                      const char *argType = propNode->Attribute("type");
-                      if (argType != nullptr) {
-                        sdbusplus::message::message m =
-                            crow::connections::systemBus->new_method_call(
-                                connectionName.c_str(),
-                                transaction->objectPath.c_str(),
-                                "org.freedesktop.DBus.Properties", "Set");
-                        m.append(interfaceName, transaction->propertyName);
-                        int r = sd_bus_message_open_container(
-                            m.get(), SD_BUS_TYPE_VARIANT, argType);
-                        if (r < 0) {
-                          transaction->setErrorStatus();
-                          return;
-                        }
-                        r = convertJsonToDbus(m.get(), argType,
-                                              transaction->propertyValue);
-                        if (r < 0) {
-                          transaction->setErrorStatus();
-                          return;
-                        }
-                        r = sd_bus_message_close_container(m.get());
-                        if (r < 0) {
-                          transaction->setErrorStatus();
-                          return;
-                        }
-
-                        crow::connections::systemBus->async_send(
-                            m, [transaction](boost::system::error_code ec,
-                                             sdbusplus::message::message &m) {
-                              BMCWEB_LOG_DEBUG << "sent";
-                              if (ec) {
-                                transaction->res.jsonValue["status"] = "error";
-                                transaction->res.jsonValue["message"] =
-                                    ec.message();
-                              }
-                            });
-                      }
-                    }
-                    propNode = propNode->NextSiblingElement("property");
-                  }
-                  ifaceNode = ifaceNode->NextSiblingElement("interface");
-                }
-              },
-              connectionName, transaction->objectPath,
-              "org.freedesktop.DBus.Introspectable", "Introspect");
-        }
-      },
-      "xyz.openbmc_project.ObjectMapper", "/xyz/openbmc_project/object_mapper",
-      "xyz.openbmc_project.ObjectMapper", "GetObject", transaction->objectPath,
-      std::array<std::string, 0>());
-}
-
-template <typename... Middlewares>
-void requestRoutes(Crow<Middlewares...> &app) {
-  BMCWEB_ROUTE(app, "/bus/")
-      .methods("GET"_method)([](const crow::Request &req, crow::Response &res) {
-        res.jsonValue = {{"busses", {{{"name", "system"}}}}, {"status", "ok"}};
-      });
-
-  BMCWEB_ROUTE(app, "/bus/system/")
-      .methods("GET"_method)([](const crow::Request &req, crow::Response &res) {
-
-        auto myCallback = [&res](const boost::system::error_code ec,
-                                 std::vector<std::string> &names) {
-          if (ec) {
-            BMCWEB_LOG_ERROR << "Dbus call failed with code " << ec;
-            res.result(boost::beast::http::status::internal_server_error);
-          } else {
-            std::sort(names.begin(), names.end());
-            nlohmann::json j{{"status", "ok"}};
-            auto &objectsSub = j["objects"];
-            for (auto &name : names) {
-              objectsSub.push_back({{"name", name}});
-            }
-            res.jsonValue = std::move(j);
-          }
-          res.end();
-        };
-        crow::connections::systemBus->async_method_call(
-            std::move(myCallback), "org.freedesktop.DBus", "/",
-            "org.freedesktop.DBus", "ListNames");
-      });
-
-  BMCWEB_ROUTE(app, "/list/")
-      .methods("GET"_method)([](const crow::Request &req, crow::Response &res) {
-        handle_list(res, "/");
-      });
-
-  BMCWEB_ROUTE(app, "/xyz/<path>")
-      .methods("GET"_method, "PUT"_method,
-               "POST"_method)([](const crow::Request &req, crow::Response &res,
-                                 const std::string &path) {
-        std::string objectPath = "/xyz/" + path;
-
-        // Trim any trailing "/" at the end
-        if (boost::ends_with(objectPath, "/")) {
-          objectPath.pop_back();
-        }
-
-        // If accessing a single attribute, fill in and update objectPath,
-        // otherwise leave destProperty blank
-        std::string destProperty = "";
-        const char *attrSeperator = "/attr/";
-        size_t attrPosition = path.find(attrSeperator);
-        if (attrPosition != path.npos) {
-          objectPath = "/xyz/" + path.substr(0, attrPosition);
-          destProperty =
-              path.substr(attrPosition + strlen(attrSeperator), path.length());
-        }
-
-        if (req.method() == "POST"_method) {
-          constexpr const char *action_seperator = "/action/";
-          size_t action_position = path.find(action_seperator);
-          if (action_position != path.npos) {
-            objectPath = "/xyz/" + path.substr(0, action_position);
-            std::string post_property = path.substr(
-                (action_position + strlen(action_seperator)), path.length());
-            handle_action(req, res, objectPath, post_property);
-            return;
-          }
-        } else if (req.method() == "GET"_method) {
-          if (boost::ends_with(objectPath, "/enumerate")) {
-            objectPath.erase(objectPath.end() - 10, objectPath.end());
-            handle_enumerate(res, objectPath);
-          } else if (boost::ends_with(objectPath, "/list")) {
-            objectPath.erase(objectPath.end() - 5, objectPath.end());
-            handle_list(res, objectPath);
-          } else {
-            handle_get(res, objectPath, destProperty);
-          }
-          return;
-        } else if (req.method() == "PUT"_method) {
-          handlePut(req, res, objectPath, destProperty);
-          return;
-        }
-
-        res.result(boost::beast::http::status::method_not_allowed);
-        res.end();
-      });
-
-  BMCWEB_ROUTE(app, "/bus/system/<str>/")
-      .methods("GET"_method)([](const crow::Request &req, crow::Response &res,
-                                const std::string &Connection) {
-        std::shared_ptr<nlohmann::json> transaction;
-        introspectObjects(res, Connection, "/", transaction);
-      });
-
-  BMCWEB_ROUTE(app, "/download/dump/<str>/")
-      .methods("GET"_method)([](const crow::Request &req, crow::Response &res,
-                                const std::string &dumpId) {
-        std::regex validFilename("^[\\w\\- ]+(\\.?[\\w\\- ]+)$");
-        if (!std::regex_match(dumpId, validFilename)) {
-          res.result(boost::beast::http::status::not_found);
-          res.end();
-          return;
-        }
-        std::experimental::filesystem::path loc(
-            "/var/lib/phosphor-debug-collector/dumps");
-
-        loc += dumpId;
-
-        if (!std::experimental::filesystem::exists(loc) ||
-            !std::experimental::filesystem::is_directory(loc)) {
-          res.result(boost::beast::http::status::not_found);
-          res.end();
-          return;
-        }
-        std::experimental::filesystem::directory_iterator files(loc);
-        for (auto &file : files) {
-          std::ifstream readFile(file.path());
-          if (readFile.good()) {
-            continue;
-          }
-          res.addHeader("Content-Type", "application/octet-stream");
-          res.body() = {std::istreambuf_iterator<char>(readFile),
-                        std::istreambuf_iterator<char>()};
-          res.end();
-        }
-        res.result(boost::beast::http::status::not_found);
+    if (requestDbusData.is_discarded())
+    {
+        res.result(boost::beast::http::status::bad_request);
         res.end();
         return;
-      });
+    }
 
-  BMCWEB_ROUTE(app, "/bus/system/<str>/<path>")
-      .methods("GET"_method)([](const crow::Request &req, crow::Response &res,
-                                const std::string &processName,
-                                const std::string &requestedPath) {
-        std::vector<std::string> strs;
-        boost::split(strs, requestedPath, boost::is_any_of("/"));
-        std::string objectPath;
-        std::string interfaceName;
-        std::string methodName;
-        auto it = strs.begin();
-        if (it == strs.end()) {
-          objectPath = "/";
-        }
-        while (it != strs.end()) {
-          // Check if segment contains ".".  If it does, it must be an
-          // interface
-          if (it->find(".") != std::string::npos) {
-            break;
-            // THis check is neccesary as the trailing slash gets parsed as
-            // part of our <path> specifier above, which causes the normal
-            // trailing backslash redirector to fail.
-          } else if (!it->empty()) {
-            objectPath += "/" + *it;
-          }
-          it++;
-        }
-        if (it != strs.end()) {
-          interfaceName = *it;
-          it++;
+    nlohmann::json::const_iterator propertyIt = requestDbusData.find("data");
+    if (propertyIt == requestDbusData.end())
+    {
+        res.result(boost::beast::http::status::bad_request);
+        res.end();
+        return;
+    }
+    const nlohmann::json &propertySetValue = *propertyIt;
+    auto transaction = std::make_shared<AsyncPutRequest>(res);
+    transaction->objectPath = objectPath;
+    transaction->propertyName = destProperty;
+    transaction->propertyValue = propertySetValue;
 
-          // after interface, we might have a method name
-          if (it != strs.end()) {
-            methodName = *it;
-            it++;
-          }
-        }
-        if (it != strs.end()) {
-          // if there is more levels past the method name, something went
-          // wrong, return not found
-          res.result(boost::beast::http::status::not_found);
-          res.end();
-          return;
-        }
-        if (interfaceName.empty()) {
-          crow::connections::systemBus->async_method_call(
-              [&, processName, objectPath](const boost::system::error_code ec,
-                                           const std::string &introspect_xml) {
-                if (ec) {
-                  BMCWEB_LOG_ERROR
-                      << "Introspect call failed with error: " << ec.message()
-                      << " on process: " << processName
-                      << " path: " << objectPath << "\n";
+    using GetObjectType =
+        std::vector<std::pair<std::string, std::vector<std::string>>>;
 
-                } else {
-                  tinyxml2::XMLDocument doc;
+    crow::connections::systemBus->async_method_call(
+        [transaction](const boost::system::error_code ec,
+                      const GetObjectType &object_names) {
+            if (!ec && object_names.size() <= 0)
+            {
+                transaction->res.result(boost::beast::http::status::not_found);
+                return;
+            }
 
-                  doc.Parse(introspect_xml.c_str());
-                  tinyxml2::XMLNode *pRoot = doc.FirstChildElement("node");
-                  if (pRoot == nullptr) {
-                    BMCWEB_LOG_ERROR << "XML document failed to parse "
-                                     << processName << " " << objectPath
-                                     << "\n";
-                    res.jsonValue = {{"status", "XML parse error"}};
-                    res.result(
-                        boost::beast::http::status::internal_server_error);
-                  } else {
-                    nlohmann::json interfacesArray = nlohmann::json::array();
-                    tinyxml2::XMLElement *interface =
-                        pRoot->FirstChildElement("interface");
+            for (const std::pair<std::string, std::vector<std::string>>
+                     connection : object_names)
+            {
+                const std::string &connectionName = connection.first;
 
-                    while (interface != nullptr) {
-                      std::string ifaceName = interface->Attribute("name");
-                      interfacesArray.push_back({{"name", ifaceName}});
-
-                      interface = interface->NextSiblingElement("interface");
-                    }
-                    res.jsonValue = {{"status", "ok"},
-                                     {"bus_name", processName},
-                                     {"interfaces", interfacesArray},
-                                     {"objectPath", objectPath}};
-                  }
-                }
-                res.end();
-              },
-              processName, objectPath, "org.freedesktop.DBus.Introspectable",
-              "Introspect");
-        } else {
-          crow::connections::systemBus->async_method_call(
-              [
-                    &, processName, objectPath,
-                    interface_name{std::move(interfaceName)}
-              ](const boost::system::error_code ec,
-                const std::string &introspect_xml) {
-                if (ec) {
-                  BMCWEB_LOG_ERROR
-                      << "Introspect call failed with error: " << ec.message()
-                      << " on process: " << processName
-                      << " path: " << objectPath << "\n";
-
-                } else {
-                  tinyxml2::XMLDocument doc;
-
-                  doc.Parse(introspect_xml.c_str());
-                  tinyxml2::XMLNode *pRoot = doc.FirstChildElement("node");
-                  if (pRoot == nullptr) {
-                    BMCWEB_LOG_ERROR << "XML document failed to parse "
-                                     << processName << " " << objectPath
-                                     << "\n";
-                    res.result(
-                        boost::beast::http::status::internal_server_error);
-
-                  } else {
-                    tinyxml2::XMLElement *node =
-                        pRoot->FirstChildElement("node");
-
-                    // if we know we're the only call, build the json directly
-                    nlohmann::json methodsArray = nlohmann::json::array();
-                    nlohmann::json signalsArray = nlohmann::json::array();
-                    tinyxml2::XMLElement *interface =
-                        pRoot->FirstChildElement("interface");
-
-                    while (interface != nullptr) {
-                      std::string ifaceName = interface->Attribute("name");
-
-                      if (ifaceName == interfaceName) {
-                        tinyxml2::XMLElement *methods =
-                            interface->FirstChildElement("method");
-                        while (methods != nullptr) {
-                          nlohmann::json argsArray = nlohmann::json::array();
-                          tinyxml2::XMLElement *arg =
-                              methods->FirstChildElement("arg");
-                          while (arg != nullptr) {
-                            argsArray.push_back(
-                                {{"name", arg->Attribute("name")},
-                                 {"type", arg->Attribute("type")},
-                                 {"direction", arg->Attribute("direction")}});
-                            arg = arg->NextSiblingElement("arg");
-                          }
-                          methodsArray.push_back(
-                              {{"name", methods->Attribute("name")},
-                               {"uri", "/bus/system/" + processName +
-                                           objectPath + "/" + interfaceName +
-                                           "/" + methods->Attribute("name")},
-                               {"args", argsArray}});
-                          methods = methods->NextSiblingElement("method");
+                crow::connections::systemBus->async_method_call(
+                    [connectionName{std::string(connectionName)},
+                     transaction](const boost::system::error_code ec,
+                                  const std::string &introspectXml) {
+                        if (ec)
+                        {
+                            BMCWEB_LOG_ERROR
+                                << "Introspect call failed with error: "
+                                << ec.message()
+                                << " on process: " << connectionName;
+                            transaction->setErrorStatus();
+                            return;
                         }
-                        tinyxml2::XMLElement *signals =
-                            interface->FirstChildElement("signal");
-                        while (signals != nullptr) {
-                          nlohmann::json argsArray = nlohmann::json::array();
+                        tinyxml2::XMLDocument doc;
 
-                          tinyxml2::XMLElement *arg =
-                              signals->FirstChildElement("arg");
-                          while (arg != nullptr) {
-                            std::string name = arg->Attribute("name");
-                            std::string type = arg->Attribute("type");
-                            argsArray.push_back({
-                                {"name", name},
-                                {"type", type},
-                            });
-                            arg = arg->NextSiblingElement("arg");
-                          }
-                          signalsArray.push_back(
-                              {{"name", signals->Attribute("name")},
-                               {"args", argsArray}});
-                          signals = signals->NextSiblingElement("signal");
+                        doc.Parse(introspectXml.c_str());
+                        tinyxml2::XMLNode *pRoot =
+                            doc.FirstChildElement("node");
+                        if (pRoot == nullptr)
+                        {
+                            BMCWEB_LOG_ERROR << "XML document failed to parse: "
+                                             << introspectXml;
+                            transaction->setErrorStatus();
+                            return;
                         }
+                        tinyxml2::XMLElement *ifaceNode =
+                            pRoot->FirstChildElement("interface");
+                        while (ifaceNode != nullptr)
+                        {
+                            const char *interfaceName =
+                                ifaceNode->Attribute("name");
+                            BMCWEB_LOG_DEBUG << "found interface "
+                                             << interfaceName;
+                            tinyxml2::XMLElement *propNode =
+                                ifaceNode->FirstChildElement("property");
+                            while (propNode != nullptr)
+                            {
+                                const char *propertyName =
+                                    propNode->Attribute("name");
+                                BMCWEB_LOG_DEBUG << "Found property "
+                                                 << propertyName;
+                                if (propertyName == transaction->propertyName)
+                                {
+                                    const char *argType =
+                                        propNode->Attribute("type");
+                                    if (argType != nullptr)
+                                    {
+                                        sdbusplus::message::message m =
+                                            crow::connections::systemBus
+                                                ->new_method_call(
+                                                    connectionName.c_str(),
+                                                    transaction->objectPath
+                                                        .c_str(),
+                                                    "org.freedesktop.DBus."
+                                                    "Properties",
+                                                    "Set");
+                                        m.append(interfaceName,
+                                                 transaction->propertyName);
+                                        int r = sd_bus_message_open_container(
+                                            m.get(), SD_BUS_TYPE_VARIANT,
+                                            argType);
+                                        if (r < 0)
+                                        {
+                                            transaction->setErrorStatus();
+                                            return;
+                                        }
+                                        r = convertJsonToDbus(
+                                            m.get(), argType,
+                                            transaction->propertyValue);
+                                        if (r < 0)
+                                        {
+                                            transaction->setErrorStatus();
+                                            return;
+                                        }
+                                        r = sd_bus_message_close_container(
+                                            m.get());
+                                        if (r < 0)
+                                        {
+                                            transaction->setErrorStatus();
+                                            return;
+                                        }
 
-                        res.jsonValue = {
-                            {"status", "ok"},
-                            {"bus_name", processName},
-                            {"interface", interfaceName},
-                            {"methods", methodsArray},
-                            {"objectPath", objectPath},
-                            {"properties", nlohmann::json::object()},
-                            {"signals", signalsArray}};
-
-                        break;
-                      }
-
-                      interface = interface->NextSiblingElement("interface");
-                    }
-                    if (interface == nullptr) {
-                      // if we got to the end of the list and never found a
-                      // match, throw 404
-                      res.result(boost::beast::http::status::not_found);
-                    }
-                  }
-                }
-                res.end();
-              },
-              processName, objectPath, "org.freedesktop.DBus.Introspectable",
-              "Introspect");
-        }
-      });
+                                        crow::connections::systemBus
+                                            ->async_send(
+                                                m,
+                                                [transaction](
+                                                    boost::system::error_code
+                                                        ec,
+                                                    sdbusplus::message::message
+                                                        &m) {
+                                                    BMCWEB_LOG_DEBUG << "sent";
+                                                    if (ec)
+                                                    {
+                                                        transaction->res
+                                                            .jsonValue
+                                                                ["status"] =
+                                                            "error";
+                                                        transaction->res
+                                                            .jsonValue
+                                                                ["message"] =
+                                                            ec.message();
+                                                    }
+                                                });
+                                    }
+                                }
+                                propNode =
+                                    propNode->NextSiblingElement("property");
+                            }
+                            ifaceNode =
+                                ifaceNode->NextSiblingElement("interface");
+                        }
+                    },
+                    connectionName, transaction->objectPath,
+                    "org.freedesktop.DBus.Introspectable", "Introspect");
+            }
+        },
+        "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetObject",
+        transaction->objectPath, std::array<std::string, 0>());
 }
-}  // namespace openbmc_mapper
-}  // namespace crow
+
+template <typename... Middlewares> void requestRoutes(Crow<Middlewares...> &app)
+{
+    BMCWEB_ROUTE(app, "/bus/")
+        .methods("GET"_method)(
+            [](const crow::Request &req, crow::Response &res) {
+                res.jsonValue = {{"busses", {{{"name", "system"}}}},
+                                 {"status", "ok"}};
+            });
+
+    BMCWEB_ROUTE(app, "/bus/system/")
+        .methods("GET"_method)(
+            [](const crow::Request &req, crow::Response &res) {
+                auto myCallback = [&res](const boost::system::error_code ec,
+                                         std::vector<std::string> &names) {
+                    if (ec)
+                    {
+                        BMCWEB_LOG_ERROR << "Dbus call failed with code " << ec;
+                        res.result(
+                            boost::beast::http::status::internal_server_error);
+                    }
+                    else
+                    {
+                        std::sort(names.begin(), names.end());
+                        nlohmann::json j{{"status", "ok"}};
+                        auto &objectsSub = j["objects"];
+                        for (auto &name : names)
+                        {
+                            objectsSub.push_back({{"name", name}});
+                        }
+                        res.jsonValue = std::move(j);
+                    }
+                    res.end();
+                };
+                crow::connections::systemBus->async_method_call(
+                    std::move(myCallback), "org.freedesktop.DBus", "/",
+                    "org.freedesktop.DBus", "ListNames");
+            });
+
+    BMCWEB_ROUTE(app, "/list/")
+        .methods("GET"_method)(
+            [](const crow::Request &req, crow::Response &res) {
+                handle_list(res, "/");
+            });
+
+    BMCWEB_ROUTE(app, "/xyz/<path>")
+        .methods("GET"_method, "PUT"_method,
+                 "POST"_method)([](const crow::Request &req,
+                                   crow::Response &res,
+                                   const std::string &path) {
+            std::string objectPath = "/xyz/" + path;
+
+            // Trim any trailing "/" at the end
+            if (boost::ends_with(objectPath, "/"))
+            {
+                objectPath.pop_back();
+            }
+
+            // If accessing a single attribute, fill in and update objectPath,
+            // otherwise leave destProperty blank
+            std::string destProperty = "";
+            const char *attrSeperator = "/attr/";
+            size_t attrPosition = path.find(attrSeperator);
+            if (attrPosition != path.npos)
+            {
+                objectPath = "/xyz/" + path.substr(0, attrPosition);
+                destProperty = path.substr(attrPosition + strlen(attrSeperator),
+                                           path.length());
+            }
+
+            if (req.method() == "POST"_method)
+            {
+                constexpr const char *action_seperator = "/action/";
+                size_t action_position = path.find(action_seperator);
+                if (action_position != path.npos)
+                {
+                    objectPath = "/xyz/" + path.substr(0, action_position);
+                    std::string post_property = path.substr(
+                        (action_position + strlen(action_seperator)),
+                        path.length());
+                    handle_action(req, res, objectPath, post_property);
+                    return;
+                }
+            }
+            else if (req.method() == "GET"_method)
+            {
+                if (boost::ends_with(objectPath, "/enumerate"))
+                {
+                    objectPath.erase(objectPath.end() - 10, objectPath.end());
+                    handle_enumerate(res, objectPath);
+                }
+                else if (boost::ends_with(objectPath, "/list"))
+                {
+                    objectPath.erase(objectPath.end() - 5, objectPath.end());
+                    handle_list(res, objectPath);
+                }
+                else
+                {
+                    handle_get(res, objectPath, destProperty);
+                }
+                return;
+            }
+            else if (req.method() == "PUT"_method)
+            {
+                handlePut(req, res, objectPath, destProperty);
+                return;
+            }
+
+            res.result(boost::beast::http::status::method_not_allowed);
+            res.end();
+        });
+
+    BMCWEB_ROUTE(app, "/bus/system/<str>/")
+        .methods("GET"_method)([](const crow::Request &req, crow::Response &res,
+                                  const std::string &Connection) {
+            std::shared_ptr<nlohmann::json> transaction;
+            introspectObjects(res, Connection, "/", transaction);
+        });
+
+    BMCWEB_ROUTE(app, "/download/dump/<str>/")
+        .methods("GET"_method)([](const crow::Request &req, crow::Response &res,
+                                  const std::string &dumpId) {
+            std::regex validFilename("^[\\w\\- ]+(\\.?[\\w\\- ]+)$");
+            if (!std::regex_match(dumpId, validFilename))
+            {
+                res.result(boost::beast::http::status::not_found);
+                res.end();
+                return;
+            }
+            std::experimental::filesystem::path loc(
+                "/var/lib/phosphor-debug-collector/dumps");
+
+            loc += dumpId;
+
+            if (!std::experimental::filesystem::exists(loc) ||
+                !std::experimental::filesystem::is_directory(loc))
+            {
+                res.result(boost::beast::http::status::not_found);
+                res.end();
+                return;
+            }
+            std::experimental::filesystem::directory_iterator files(loc);
+            for (auto &file : files)
+            {
+                std::ifstream readFile(file.path());
+                if (readFile.good())
+                {
+                    continue;
+                }
+                res.addHeader("Content-Type", "application/octet-stream");
+                res.body() = {std::istreambuf_iterator<char>(readFile),
+                              std::istreambuf_iterator<char>()};
+                res.end();
+            }
+            res.result(boost::beast::http::status::not_found);
+            res.end();
+            return;
+        });
+
+    BMCWEB_ROUTE(app, "/bus/system/<str>/<path>")
+        .methods("GET"_method)([](const crow::Request &req, crow::Response &res,
+                                  const std::string &processName,
+                                  const std::string &requestedPath) {
+            std::vector<std::string> strs;
+            boost::split(strs, requestedPath, boost::is_any_of("/"));
+            std::string objectPath;
+            std::string interfaceName;
+            std::string methodName;
+            auto it = strs.begin();
+            if (it == strs.end())
+            {
+                objectPath = "/";
+            }
+            while (it != strs.end())
+            {
+                // Check if segment contains ".".  If it does, it must be an
+                // interface
+                if (it->find(".") != std::string::npos)
+                {
+                    break;
+                    // THis check is neccesary as the trailing slash gets parsed
+                    // as part of our <path> specifier above, which causes the
+                    // normal trailing backslash redirector to fail.
+                }
+                else if (!it->empty())
+                {
+                    objectPath += "/" + *it;
+                }
+                it++;
+            }
+            if (it != strs.end())
+            {
+                interfaceName = *it;
+                it++;
+
+                // after interface, we might have a method name
+                if (it != strs.end())
+                {
+                    methodName = *it;
+                    it++;
+                }
+            }
+            if (it != strs.end())
+            {
+                // if there is more levels past the method name, something went
+                // wrong, return not found
+                res.result(boost::beast::http::status::not_found);
+                res.end();
+                return;
+            }
+            if (interfaceName.empty())
+            {
+                crow::connections::systemBus->async_method_call(
+                    [&, processName,
+                     objectPath](const boost::system::error_code ec,
+                                 const std::string &introspect_xml) {
+                        if (ec)
+                        {
+                            BMCWEB_LOG_ERROR
+                                << "Introspect call failed with error: "
+                                << ec.message()
+                                << " on process: " << processName
+                                << " path: " << objectPath << "\n";
+                        }
+                        else
+                        {
+                            tinyxml2::XMLDocument doc;
+
+                            doc.Parse(introspect_xml.c_str());
+                            tinyxml2::XMLNode *pRoot =
+                                doc.FirstChildElement("node");
+                            if (pRoot == nullptr)
+                            {
+                                BMCWEB_LOG_ERROR
+                                    << "XML document failed to parse "
+                                    << processName << " " << objectPath << "\n";
+                                res.jsonValue = {{"status", "XML parse error"}};
+                                res.result(boost::beast::http::status::
+                                               internal_server_error);
+                            }
+                            else
+                            {
+                                nlohmann::json interfacesArray =
+                                    nlohmann::json::array();
+                                tinyxml2::XMLElement *interface =
+                                    pRoot->FirstChildElement("interface");
+
+                                while (interface != nullptr)
+                                {
+                                    std::string ifaceName =
+                                        interface->Attribute("name");
+                                    interfacesArray.push_back(
+                                        {{"name", ifaceName}});
+
+                                    interface = interface->NextSiblingElement(
+                                        "interface");
+                                }
+                                res.jsonValue = {
+                                    {"status", "ok"},
+                                    {"bus_name", processName},
+                                    {"interfaces", interfacesArray},
+                                    {"objectPath", objectPath}};
+                            }
+                        }
+                        res.end();
+                    },
+                    processName, objectPath,
+                    "org.freedesktop.DBus.Introspectable", "Introspect");
+            }
+            else
+            {
+                crow::connections::systemBus->async_method_call(
+                    [&, processName, objectPath,
+                     interface_name{std::move(interfaceName)}](
+                        const boost::system::error_code ec,
+                        const std::string &introspect_xml) {
+                        if (ec)
+                        {
+                            BMCWEB_LOG_ERROR
+                                << "Introspect call failed with error: "
+                                << ec.message()
+                                << " on process: " << processName
+                                << " path: " << objectPath << "\n";
+                        }
+                        else
+                        {
+                            tinyxml2::XMLDocument doc;
+
+                            doc.Parse(introspect_xml.c_str());
+                            tinyxml2::XMLNode *pRoot =
+                                doc.FirstChildElement("node");
+                            if (pRoot == nullptr)
+                            {
+                                BMCWEB_LOG_ERROR
+                                    << "XML document failed to parse "
+                                    << processName << " " << objectPath << "\n";
+                                res.result(boost::beast::http::status::
+                                               internal_server_error);
+                            }
+                            else
+                            {
+                                tinyxml2::XMLElement *node =
+                                    pRoot->FirstChildElement("node");
+
+                                // if we know we're the only call, build the
+                                // json directly
+                                nlohmann::json methodsArray =
+                                    nlohmann::json::array();
+                                nlohmann::json signalsArray =
+                                    nlohmann::json::array();
+                                tinyxml2::XMLElement *interface =
+                                    pRoot->FirstChildElement("interface");
+
+                                while (interface != nullptr)
+                                {
+                                    std::string ifaceName =
+                                        interface->Attribute("name");
+
+                                    if (ifaceName == interfaceName)
+                                    {
+                                        tinyxml2::XMLElement *methods =
+                                            interface->FirstChildElement(
+                                                "method");
+                                        while (methods != nullptr)
+                                        {
+                                            nlohmann::json argsArray =
+                                                nlohmann::json::array();
+                                            tinyxml2::XMLElement *arg =
+                                                methods->FirstChildElement(
+                                                    "arg");
+                                            while (arg != nullptr)
+                                            {
+                                                argsArray.push_back(
+                                                    {{"name",
+                                                      arg->Attribute("name")},
+                                                     {"type",
+                                                      arg->Attribute("type")},
+                                                     {"direction",
+                                                      arg->Attribute(
+                                                          "direction")}});
+                                                arg = arg->NextSiblingElement(
+                                                    "arg");
+                                            }
+                                            methodsArray.push_back(
+                                                {{"name",
+                                                  methods->Attribute("name")},
+                                                 {"uri",
+                                                  "/bus/system/" + processName +
+                                                      objectPath + "/" +
+                                                      interfaceName + "/" +
+                                                      methods->Attribute(
+                                                          "name")},
+                                                 {"args", argsArray}});
+                                            methods =
+                                                methods->NextSiblingElement(
+                                                    "method");
+                                        }
+                                        tinyxml2::XMLElement *signals =
+                                            interface->FirstChildElement(
+                                                "signal");
+                                        while (signals != nullptr)
+                                        {
+                                            nlohmann::json argsArray =
+                                                nlohmann::json::array();
+
+                                            tinyxml2::XMLElement *arg =
+                                                signals->FirstChildElement(
+                                                    "arg");
+                                            while (arg != nullptr)
+                                            {
+                                                std::string name =
+                                                    arg->Attribute("name");
+                                                std::string type =
+                                                    arg->Attribute("type");
+                                                argsArray.push_back({
+                                                    {"name", name},
+                                                    {"type", type},
+                                                });
+                                                arg = arg->NextSiblingElement(
+                                                    "arg");
+                                            }
+                                            signalsArray.push_back(
+                                                {{"name",
+                                                  signals->Attribute("name")},
+                                                 {"args", argsArray}});
+                                            signals =
+                                                signals->NextSiblingElement(
+                                                    "signal");
+                                        }
+
+                                        res.jsonValue = {
+                                            {"status", "ok"},
+                                            {"bus_name", processName},
+                                            {"interface", interfaceName},
+                                            {"methods", methodsArray},
+                                            {"objectPath", objectPath},
+                                            {"properties",
+                                             nlohmann::json::object()},
+                                            {"signals", signalsArray}};
+
+                                        break;
+                                    }
+
+                                    interface = interface->NextSiblingElement(
+                                        "interface");
+                                }
+                                if (interface == nullptr)
+                                {
+                                    // if we got to the end of the list and
+                                    // never found a match, throw 404
+                                    res.result(
+                                        boost::beast::http::status::not_found);
+                                }
+                            }
+                        }
+                        res.end();
+                    },
+                    processName, objectPath,
+                    "org.freedesktop.DBus.Introspectable", "Introspect");
+            }
+        });
+}
+} // namespace openbmc_mapper
+} // namespace crow
diff --git a/include/pam_authenticate.hpp b/include/pam_authenticate.hpp
index 65e4740..f51f9aa 100644
--- a/include/pam_authenticate.hpp
+++ b/include/pam_authenticate.hpp
@@ -1,72 +1,84 @@
 #pragma once
 
 #include <security/pam_appl.h>
+
+#include <boost/utility/string_view.hpp>
 #include <cstring>
 #include <memory>
-#include <boost/utility/string_view.hpp>
 
 // function used to get user input
 inline int pamFunctionConversation(int numMsg, const struct pam_message** msg,
-                                   struct pam_response** resp,
-                                   void* appdataPtr) {
-  if (appdataPtr == nullptr) {
-    return PAM_AUTH_ERR;
-  }
-  auto* pass = reinterpret_cast<char*>(
-      malloc(std::strlen(reinterpret_cast<char*>(appdataPtr)) + 1));
-  std::strcpy(pass, reinterpret_cast<char*>(appdataPtr));
+                                   struct pam_response** resp, void* appdataPtr)
+{
+    if (appdataPtr == nullptr)
+    {
+        return PAM_AUTH_ERR;
+    }
+    auto* pass = reinterpret_cast<char*>(
+        malloc(std::strlen(reinterpret_cast<char*>(appdataPtr)) + 1));
+    std::strcpy(pass, reinterpret_cast<char*>(appdataPtr));
 
-  *resp = reinterpret_cast<pam_response*>(
-      calloc(numMsg, sizeof(struct pam_response)));
+    *resp = reinterpret_cast<pam_response*>(
+        calloc(numMsg, sizeof(struct pam_response)));
 
-  for (int i = 0; i < numMsg; ++i) {
-    /* Ignore all PAM messages except prompting for hidden input */
-    if (msg[i]->msg_style != PAM_PROMPT_ECHO_OFF) {
-      continue;
+    for (int i = 0; i < numMsg; ++i)
+    {
+        /* Ignore all PAM messages except prompting for hidden input */
+        if (msg[i]->msg_style != PAM_PROMPT_ECHO_OFF)
+        {
+            continue;
+        }
+
+        /* Assume PAM is only prompting for the password as hidden input */
+        resp[i]->resp = pass;
     }
 
-    /* Assume PAM is only prompting for the password as hidden input */
-    resp[i]->resp = pass;
-  }
-
-  return PAM_SUCCESS;
+    return PAM_SUCCESS;
 }
 
 inline bool pamAuthenticateUser(const boost::string_view username,
-                                const boost::string_view password) {
-  std::string userStr(username);
-  std::string passStr(password);
-  const struct pam_conv localConversation = {
-      pamFunctionConversation, const_cast<char*>(passStr.c_str())};
-  pam_handle_t* localAuthHandle = NULL;  // this gets set by pam_start
+                                const boost::string_view password)
+{
+    std::string userStr(username);
+    std::string passStr(password);
+    const struct pam_conv localConversation = {
+        pamFunctionConversation, const_cast<char*>(passStr.c_str())};
+    pam_handle_t* localAuthHandle = NULL; // this gets set by pam_start
 
-  if (pam_start("webserver", userStr.c_str(), &localConversation,
-                &localAuthHandle) != PAM_SUCCESS) {
-    return false;
-  }
-  int retval =
-      pam_authenticate(localAuthHandle, PAM_SILENT | PAM_DISALLOW_NULL_AUTHTOK);
-
-  if (retval != PAM_SUCCESS) {
-    if (retval == PAM_AUTH_ERR) {
-      // printf("Authentication failure.\n");
-    } else {
-      // printf("pam_authenticate returned %d\n", retval);
+    if (pam_start("webserver", userStr.c_str(), &localConversation,
+                  &localAuthHandle) != PAM_SUCCESS)
+    {
+        return false;
     }
-    pam_end(localAuthHandle, PAM_SUCCESS);
-    return false;
-  }
+    int retval = pam_authenticate(localAuthHandle,
+                                  PAM_SILENT | PAM_DISALLOW_NULL_AUTHTOK);
 
-  /* check that the account is healthy */
-  if (pam_acct_mgmt(localAuthHandle, PAM_DISALLOW_NULL_AUTHTOK) !=
-      PAM_SUCCESS) {
-    pam_end(localAuthHandle, PAM_SUCCESS);
-    return false;
-  }
+    if (retval != PAM_SUCCESS)
+    {
+        if (retval == PAM_AUTH_ERR)
+        {
+            // printf("Authentication failure.\n");
+        }
+        else
+        {
+            // printf("pam_authenticate returned %d\n", retval);
+        }
+        pam_end(localAuthHandle, PAM_SUCCESS);
+        return false;
+    }
 
-  if (pam_end(localAuthHandle, PAM_SUCCESS) != PAM_SUCCESS) {
-    return false;
-  }
+    /* check that the account is healthy */
+    if (pam_acct_mgmt(localAuthHandle, PAM_DISALLOW_NULL_AUTHTOK) !=
+        PAM_SUCCESS)
+    {
+        pam_end(localAuthHandle, PAM_SUCCESS);
+        return false;
+    }
 
-  return true;
+    if (pam_end(localAuthHandle, PAM_SUCCESS) != PAM_SUCCESS)
+    {
+        return false;
+    }
+
+    return true;
 }
diff --git a/include/persistent_data_middleware.hpp b/include/persistent_data_middleware.hpp
index 706f6f4..b384f02 100644
--- a/include/persistent_data_middleware.hpp
+++ b/include/persistent_data_middleware.hpp
@@ -1,121 +1,165 @@
 #pragma once
 
-#include <nlohmann/json.hpp>
-#include <pam_authenticate.hpp>
-#include <sessions.hpp>
-#include <webassets.hpp>
-#include <random>
 #include <crow/app.h>
 #include <crow/http_request.h>
 #include <crow/http_response.h>
+
 #include <boost/container/flat_map.hpp>
 #include <boost/uuid/uuid.hpp>
 #include <boost/uuid/uuid_generators.hpp>
 #include <boost/uuid/uuid_io.hpp>
+#include <nlohmann/json.hpp>
+#include <pam_authenticate.hpp>
+#include <random>
+#include <sessions.hpp>
+#include <webassets.hpp>
 
-namespace crow {
+namespace crow
+{
 
-namespace persistent_data {
+namespace persistent_data
+{
 
-class Middleware {
-  // todo(ed) should read this from a fixed location somewhere, not CWD
-  static constexpr const char* filename = "bmcweb_persistent_data.json";
-  int jsonRevision = 1;
+class Middleware
+{
+    // todo(ed) should read this from a fixed location somewhere, not CWD
+    static constexpr const char* filename = "bmcweb_persistent_data.json";
+    int jsonRevision = 1;
 
- public:
-  struct Context {};
+  public:
+    struct Context
+    {
+    };
 
-  Middleware() { readData(); }
-
-  ~Middleware() {
-    if (persistent_data::SessionStore::getInstance().needsWrite()) {
-      writeData();
+    Middleware()
+    {
+        readData();
     }
-  }
 
-  void beforeHandle(crow::Request& req, Response& res, Context& ctx) {}
-
-  void afterHandle(Request& req, Response& res, Context& ctx) {}
-
-  // TODO(ed) this should really use protobuf, or some other serialization
-  // library, but adding another dependency is somewhat outside the scope of
-  // this application for the moment
-  void readData() {
-    std::ifstream persistentFile(filename);
-    int fileRevision = 0;
-    if (persistentFile.is_open()) {
-      // call with exceptions disabled
-      auto data = nlohmann::json::parse(persistentFile, nullptr, false);
-      if (data.is_discarded()) {
-        BMCWEB_LOG_ERROR << "Error parsing persistent data in json file.";
-      } else {
-        for (const auto& item : data.items()) {
-          if (item.key() == "revision") {
-            fileRevision = 0;
-
-            const uint64_t* uintPtr = item.value().get_ptr<const uint64_t*>();
-            if (uintPtr == nullptr) {
-              BMCWEB_LOG_ERROR << "Failed to read revision flag";
-            } else {
-              fileRevision = *uintPtr;
-            }
-          } else if (item.key() == "system_uuid") {
-            const std::string* jSystemUuid =
-                item.value().get_ptr<const std::string*>();
-            if (jSystemUuid != nullptr) {
-              systemUuid = *jSystemUuid;
-            }
-          } else if (item.key() == "sessions") {
-            for (const auto& elem : item.value()) {
-              std::shared_ptr<UserSession> newSession =
-                  UserSession::fromJson(elem);
-
-              if (newSession == nullptr) {
-                BMCWEB_LOG_ERROR
-                    << "Problem reading session from persistent store";
-                continue;
-              }
-
-              BMCWEB_LOG_DEBUG << "Restored session: " << newSession->csrfToken
-                               << " " << newSession->uniqueId << " "
-                               << newSession->sessionToken;
-              SessionStore::getInstance().authTokens.emplace(
-                  newSession->sessionToken, newSession);
-            }
-          } else {
-            // Do nothing in the case of extra fields.  We may have cases where
-            // fields are added in the future, and we want to at least attempt
-            // to gracefully support downgrades in that case, even if we don't
-            // officially support it
-          }
+    ~Middleware()
+    {
+        if (persistent_data::SessionStore::getInstance().needsWrite())
+        {
+            writeData();
         }
-      }
     }
-    bool needWrite = false;
 
-    if (systemUuid.empty()) {
-      systemUuid = boost::uuids::to_string(boost::uuids::random_generator()());
-      needWrite = true;
+    void beforeHandle(crow::Request& req, Response& res, Context& ctx)
+    {
     }
-    if (fileRevision < jsonRevision) {
-      needWrite = true;
-    }
-    // write revision changes or system uuid changes immediately
-    if (needWrite) {
-      writeData();
-    }
-  }
 
-  void writeData() {
-    std::ofstream persistentFile(filename);
-    nlohmann::json data{{"sessions", SessionStore::getInstance().authTokens},
-                        {"system_uuid", systemUuid},
-                        {"revision", jsonRevision}};
-    persistentFile << data;
-  }
+    void afterHandle(Request& req, Response& res, Context& ctx)
+    {
+    }
 
-  std::string systemUuid{""};
+    // TODO(ed) this should really use protobuf, or some other serialization
+    // library, but adding another dependency is somewhat outside the scope of
+    // this application for the moment
+    void readData()
+    {
+        std::ifstream persistentFile(filename);
+        int fileRevision = 0;
+        if (persistentFile.is_open())
+        {
+            // call with exceptions disabled
+            auto data = nlohmann::json::parse(persistentFile, nullptr, false);
+            if (data.is_discarded())
+            {
+                BMCWEB_LOG_ERROR
+                    << "Error parsing persistent data in json file.";
+            }
+            else
+            {
+                for (const auto& item : data.items())
+                {
+                    if (item.key() == "revision")
+                    {
+                        fileRevision = 0;
+
+                        const uint64_t* uintPtr =
+                            item.value().get_ptr<const uint64_t*>();
+                        if (uintPtr == nullptr)
+                        {
+                            BMCWEB_LOG_ERROR << "Failed to read revision flag";
+                        }
+                        else
+                        {
+                            fileRevision = *uintPtr;
+                        }
+                    }
+                    else if (item.key() == "system_uuid")
+                    {
+                        const std::string* jSystemUuid =
+                            item.value().get_ptr<const std::string*>();
+                        if (jSystemUuid != nullptr)
+                        {
+                            systemUuid = *jSystemUuid;
+                        }
+                    }
+                    else if (item.key() == "sessions")
+                    {
+                        for (const auto& elem : item.value())
+                        {
+                            std::shared_ptr<UserSession> newSession =
+                                UserSession::fromJson(elem);
+
+                            if (newSession == nullptr)
+                            {
+                                BMCWEB_LOG_ERROR << "Problem reading session "
+                                                    "from persistent store";
+                                continue;
+                            }
+
+                            BMCWEB_LOG_DEBUG
+                                << "Restored session: " << newSession->csrfToken
+                                << " " << newSession->uniqueId << " "
+                                << newSession->sessionToken;
+                            SessionStore::getInstance().authTokens.emplace(
+                                newSession->sessionToken, newSession);
+                        }
+                    }
+                    else
+                    {
+                        // Do nothing in the case of extra fields.  We may have
+                        // cases where fields are added in the future, and we
+                        // want to at least attempt to gracefully support
+                        // downgrades in that case, even if we don't officially
+                        // support it
+                    }
+                }
+            }
+        }
+        bool needWrite = false;
+
+        if (systemUuid.empty())
+        {
+            systemUuid =
+                boost::uuids::to_string(boost::uuids::random_generator()());
+            needWrite = true;
+        }
+        if (fileRevision < jsonRevision)
+        {
+            needWrite = true;
+        }
+        // write revision changes or system uuid changes immediately
+        if (needWrite)
+        {
+            writeData();
+        }
+    }
+
+    void writeData()
+    {
+        std::ofstream persistentFile(filename);
+        nlohmann::json data{
+            {"sessions", SessionStore::getInstance().authTokens},
+            {"system_uuid", systemUuid},
+            {"revision", jsonRevision}};
+        persistentFile << data;
+    }
+
+    std::string systemUuid{""};
 };
 
-}  // namespace persistent_data
-}  // namespace crow
+} // namespace persistent_data
+} // namespace crow
diff --git a/include/redfish_v1.hpp b/include/redfish_v1.hpp
index b81aa54..13e1838 100644
--- a/include/redfish_v1.hpp
+++ b/include/redfish_v1.hpp
@@ -1,15 +1,18 @@
 #pragma once
 
+#include <crow/app.h>
+
+#include <boost/algorithm/string.hpp>
 #include <dbus_singleton.hpp>
-#include <persistent_data_middleware.hpp>
-#include <token_authorization_middleware.hpp>
 #include <fstream>
+#include <persistent_data_middleware.hpp>
 #include <streambuf>
 #include <string>
-#include <crow/app.h>
-#include <boost/algorithm/string.hpp>
-namespace crow {
-namespace redfish {
+#include <token_authorization_middleware.hpp>
+namespace crow
+{
+namespace redfish
+{
 
 using ManagedObjectType = std::vector<std::pair<
     sdbusplus::message::object_path,
@@ -17,108 +20,130 @@
         std::string, boost::container::flat_map<
                          std::string, sdbusplus::message::variant<bool>>>>>;
 
-template <typename... Middlewares>
-void requestRoutes(Crow<Middlewares...>& app) {
-  BMCWEB_ROUTE(app, "/redfish/")
-      .methods("GET"_method)([](const crow::Request& req, crow::Response& res) {
-        res.jsonValue = {{"v1", "/redfish/v1/"}};
-        res.end();
-      });
+template <typename... Middlewares> void requestRoutes(Crow<Middlewares...>& app)
+{
+    BMCWEB_ROUTE(app, "/redfish/")
+        .methods("GET"_method)(
+            [](const crow::Request& req, crow::Response& res) {
+                res.jsonValue = {{"v1", "/redfish/v1/"}};
+                res.end();
+            });
 
-  BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Accounts/")
-      .methods(
-          "GET"_method)([&](const crow::Request& req, crow::Response& res) {
-        crow::connections::systemBus->async_method_call(
-            [&](const boost::system::error_code ec,
-                const ManagedObjectType& users) {
-              if (ec) {
-                res.result(boost::beast::http::status::internal_server_error);
-              } else {
-                res.jsonValue = {
-                    {"@odata.context",
-                     "/redfish/v1/"
-                     "$metadata#ManagerAccountCollection."
-                     "ManagerAccountCollection"},
-                    {"@odata.id", "/redfish/v1/AccountService/Accounts"},
-                    {"@odata.type",
-                     "#ManagerAccountCollection.ManagerAccountCollection"},
-                    {"Name", "Accounts Collection"},
-                    {"Description", "BMC User Accounts"},
-                    {"Members@odata.count", users.size()}};
-                nlohmann::json memberArray = nlohmann::json::array();
-                int userIndex = 0;
-                for (auto& user : users) {
-                  const std::string& path =
-                      static_cast<const std::string&>(user.first);
-                  std::size_t lastIndex = path.rfind("/");
-                  if (lastIndex == std::string::npos) {
-                    lastIndex = 0;
-                  } else {
-                    lastIndex += 1;
-                  }
-                  memberArray.push_back(
-                      {{"@odata.id", "/redfish/v1/AccountService/Accounts/" +
-                                         path.substr(lastIndex)}});
-                }
-                res.jsonValue["Members"] = memberArray;
-              }
-              res.end();
-            },
-            "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
-            "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
-      });
+    BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Accounts/")
+        .methods(
+            "GET"_method)([&](const crow::Request& req, crow::Response& res) {
+            crow::connections::systemBus->async_method_call(
+                [&](const boost::system::error_code ec,
+                    const ManagedObjectType& users) {
+                    if (ec)
+                    {
+                        res.result(
+                            boost::beast::http::status::internal_server_error);
+                    }
+                    else
+                    {
+                        res.jsonValue = {
+                            {"@odata.context",
+                             "/redfish/v1/"
+                             "$metadata#ManagerAccountCollection."
+                             "ManagerAccountCollection"},
+                            {"@odata.id",
+                             "/redfish/v1/AccountService/Accounts"},
+                            {"@odata.type", "#ManagerAccountCollection."
+                                            "ManagerAccountCollection"},
+                            {"Name", "Accounts Collection"},
+                            {"Description", "BMC User Accounts"},
+                            {"Members@odata.count", users.size()}};
+                        nlohmann::json memberArray = nlohmann::json::array();
+                        int userIndex = 0;
+                        for (auto& user : users)
+                        {
+                            const std::string& path =
+                                static_cast<const std::string&>(user.first);
+                            std::size_t lastIndex = path.rfind("/");
+                            if (lastIndex == std::string::npos)
+                            {
+                                lastIndex = 0;
+                            }
+                            else
+                            {
+                                lastIndex += 1;
+                            }
+                            memberArray.push_back(
+                                {{"@odata.id",
+                                  "/redfish/v1/AccountService/Accounts/" +
+                                      path.substr(lastIndex)}});
+                        }
+                        res.jsonValue["Members"] = memberArray;
+                    }
+                    res.end();
+                },
+                "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
+                "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+        });
 
-  BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Accounts/<str>/")
-      .methods("GET"_method)([](const crow::Request& req, crow::Response& res,
-                                const std::string& account_name) {
-
-        crow::connections::systemBus->async_method_call(
-            [&, accountName{std::move(account_name)} ](
-                const boost::system::error_code ec,
-                const ManagedObjectType& users) {
-              if (ec) {
-                res.result(boost::beast::http::status::internal_server_error);
-              } else {
-                for (auto& user : users) {
-                  const std::string& path =
-                      static_cast<const std::string&>(user.first);
-                  std::size_t lastIndex = path.rfind("/");
-                  if (lastIndex == std::string::npos) {
-                    lastIndex = 0;
-                  } else {
-                    lastIndex += 1;
-                  }
-                  if (path.substr(lastIndex) == accountName) {
-                    res.jsonValue = {
-                        {"@odata.context",
-                         "/redfish/v1/$metadata#ManagerAccount.ManagerAccount"},
-                        {"@odata.id", "/redfish/v1/AccountService/Accounts/1"},
-                        {"@odata.type",
-                         "#ManagerAccount.v1_0_3.ManagerAccount"},
-                        {"Id", "1"},
-                        {"Name", "User Account"},
-                        {"Description", "User Account"},
-                        {"Enabled", false},
-                        {"Password", nullptr},
-                        {"UserName", accountName},
-                        {"RoleId", "Administrator"},
-                        {"Links",
-                         {{"Role",
-                           {{"@odata.id",
-                             "/redfish/v1/AccountService/Roles/"
-                             "Administrator"}}}}}};
-                    break;
-                  }
-                }
-                if (res.jsonValue.is_null()) {
-                  res.result(boost::beast::http::status::not_found);
-                }
-              }
-              res.end();
-            },
-            "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
-            "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
-      });
+    BMCWEB_ROUTE(app, "/redfish/v1/AccountService/Accounts/<str>/")
+        .methods("GET"_method)([](const crow::Request& req, crow::Response& res,
+                                  const std::string& account_name) {
+            crow::connections::systemBus->async_method_call(
+                [&, accountName{std::move(account_name)}](
+                    const boost::system::error_code ec,
+                    const ManagedObjectType& users) {
+                    if (ec)
+                    {
+                        res.result(
+                            boost::beast::http::status::internal_server_error);
+                    }
+                    else
+                    {
+                        for (auto& user : users)
+                        {
+                            const std::string& path =
+                                static_cast<const std::string&>(user.first);
+                            std::size_t lastIndex = path.rfind("/");
+                            if (lastIndex == std::string::npos)
+                            {
+                                lastIndex = 0;
+                            }
+                            else
+                            {
+                                lastIndex += 1;
+                            }
+                            if (path.substr(lastIndex) == accountName)
+                            {
+                                res.jsonValue = {
+                                    {"@odata.context",
+                                     "/redfish/v1/"
+                                     "$metadata#ManagerAccount.ManagerAccount"},
+                                    {"@odata.id",
+                                     "/redfish/v1/AccountService/Accounts/1"},
+                                    {"@odata.type",
+                                     "#ManagerAccount.v1_0_3.ManagerAccount"},
+                                    {"Id", "1"},
+                                    {"Name", "User Account"},
+                                    {"Description", "User Account"},
+                                    {"Enabled", false},
+                                    {"Password", nullptr},
+                                    {"UserName", accountName},
+                                    {"RoleId", "Administrator"},
+                                    {"Links",
+                                     {{"Role",
+                                       {{"@odata.id",
+                                         "/redfish/v1/AccountService/Roles/"
+                                         "Administrator"}}}}}};
+                                break;
+                            }
+                        }
+                        if (res.jsonValue.is_null())
+                        {
+                            res.result(boost::beast::http::status::not_found);
+                        }
+                    }
+                    res.end();
+                },
+                "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
+                "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+        });
 }
-}  // namespace redfish
-}  // namespace crow
+} // namespace redfish
+} // namespace crow
diff --git a/include/security_headers_middleware.hpp b/include/security_headers_middleware.hpp
index 750f87b..561fd81 100644
--- a/include/security_headers_middleware.hpp
+++ b/include/security_headers_middleware.hpp
@@ -3,7 +3,8 @@
 #include <crow/http_request.h>
 #include <crow/http_response.h>
 
-namespace crow {
+namespace crow
+{
 static const char* strictTransportSecurityKey = "Strict-Transport-Security";
 static const char* strictTransportSecurityValue =
     "max-age=31536000; includeSubdomains; preload";
@@ -26,40 +27,46 @@
 static const char* cacheControlKey = "Cache-Control";
 static const char* cacheControlValue = "no-Store,no-Cache";
 
-struct SecurityHeadersMiddleware {
-  struct Context {};
+struct SecurityHeadersMiddleware
+{
+    struct Context
+    {
+    };
 
-  void beforeHandle(crow::Request& req, Response& res, Context& ctx) {
+    void beforeHandle(crow::Request& req, Response& res, Context& ctx)
+    {
 #ifdef BMCWEB_INSECURE_DISABLE_XSS_PREVENTION
-    if ("OPTIONS"_method == req.method()) {
-      res.end();
+        if ("OPTIONS"_method == req.method())
+        {
+            res.end();
+        }
+#endif
     }
-#endif
-  }
 
-  void afterHandle(Request& req, Response& res, Context& ctx) {
-    /*
-     TODO(ed) these should really check content types.  for example,
-     X-UA-Compatible header doesn't make sense when retrieving a JSON or
-     javascript file.  It doesn't hurt anything, it's just ugly.
-     */
-    res.addHeader(strictTransportSecurityKey, strictTransportSecurityValue);
-    res.addHeader(uaCompatabilityKey, uaCompatabilityValue);
-    res.addHeader(xframeKey, xframeValue);
-    res.addHeader(xssKey, xssValue);
-    res.addHeader(contentSecurityKey, contentSecurityValue);
-    res.addHeader(pragmaKey, pragmaValue);
-    res.addHeader(cacheControlKey, cacheControlValue);
+    void afterHandle(Request& req, Response& res, Context& ctx)
+    {
+        /*
+         TODO(ed) these should really check content types.  for example,
+         X-UA-Compatible header doesn't make sense when retrieving a JSON or
+         javascript file.  It doesn't hurt anything, it's just ugly.
+         */
+        res.addHeader(strictTransportSecurityKey, strictTransportSecurityValue);
+        res.addHeader(uaCompatabilityKey, uaCompatabilityValue);
+        res.addHeader(xframeKey, xframeValue);
+        res.addHeader(xssKey, xssValue);
+        res.addHeader(contentSecurityKey, contentSecurityValue);
+        res.addHeader(pragmaKey, pragmaValue);
+        res.addHeader(cacheControlKey, cacheControlValue);
 
 #ifdef BMCWEB_INSECURE_DISABLE_XSS_PREVENTION
 
-    res.addHeader("Access-Control-Allow-Origin", "http://localhost:8080");
-    res.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH");
-    res.addHeader("Access-Control-Allow-Credentials", "true");
-    res.addHeader("Access-Control-Allow-Headers",
-                  "Origin, Content-Type, Accept, Cookie, X-XSRF-TOKEN");
+        res.addHeader("Access-Control-Allow-Origin", "http://localhost:8080");
+        res.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH");
+        res.addHeader("Access-Control-Allow-Credentials", "true");
+        res.addHeader("Access-Control-Allow-Headers",
+                      "Origin, Content-Type, Accept, Cookie, X-XSRF-TOKEN");
 
 #endif
-  }
+    }
 };
-}  // namespace crow
+} // namespace crow
diff --git a/include/sessions.hpp b/include/sessions.hpp
index f549fde..510f566 100644
--- a/include/sessions.hpp
+++ b/include/sessions.hpp
@@ -1,232 +1,284 @@
 #pragma once
 
-#include <nlohmann/json.hpp>
-#include <pam_authenticate.hpp>
-#include <webassets.hpp>
-#include <random>
 #include <crow/app.h>
 #include <crow/http_request.h>
 #include <crow/http_response.h>
+
 #include <boost/container/flat_map.hpp>
 #include <boost/uuid/uuid.hpp>
 #include <boost/uuid/uuid_generators.hpp>
 #include <boost/uuid/uuid_io.hpp>
+#include <nlohmann/json.hpp>
+#include <pam_authenticate.hpp>
+#include <random>
+#include <webassets.hpp>
 
-namespace crow {
+namespace crow
+{
 
-namespace persistent_data {
+namespace persistent_data
+{
 
-enum class PersistenceType {
-  TIMEOUT,        // User session times out after a predetermined amount of time
-  SINGLE_REQUEST  // User times out once this request is completed.
+enum class PersistenceType
+{
+    TIMEOUT, // User session times out after a predetermined amount of time
+    SINGLE_REQUEST // User times out once this request is completed.
 };
 
-struct UserSession {
-  std::string uniqueId;
-  std::string sessionToken;
-  std::string username;
-  std::string csrfToken;
-  std::chrono::time_point<std::chrono::steady_clock> lastUpdated;
-  PersistenceType persistence;
+struct UserSession
+{
+    std::string uniqueId;
+    std::string sessionToken;
+    std::string username;
+    std::string csrfToken;
+    std::chrono::time_point<std::chrono::steady_clock> lastUpdated;
+    PersistenceType persistence;
 
-  /**
-   * @brief Fills object with data from UserSession's JSON representation
-   *
-   * This replaces nlohmann's from_json to ensure no-throw approach
-   *
-   * @param[in] j   JSON object from which data should be loaded
-   *
-   * @return a shared pointer if data has been loaded properly, nullptr
-   * otherwise
-   */
-  static std::shared_ptr<UserSession> fromJson(const nlohmann::json& j) {
-    std::shared_ptr<UserSession> userSession = std::make_shared<UserSession>();
-    for (const auto& element : j.items()) {
-      const std::string* thisValue =
-          element.value().get_ptr<const std::string*>();
-      if (thisValue == nullptr) {
-        BMCWEB_LOG_ERROR << "Error reading persistent store.  Property "
-                         << element.key() << " was not of type string";
-        return nullptr;
-      }
-      if (element.key() == "unique_id") {
-        userSession->uniqueId = *thisValue;
-      } else if (element.key() == "session_token") {
-        userSession->sessionToken = *thisValue;
-      } else if (element.key() == "csrf_token") {
-        userSession->csrfToken = *thisValue;
-      } else if (element.key() == "username") {
-        userSession->username = *thisValue;
-      } else {
-        BMCWEB_LOG_ERROR << "Got unexpected property reading persistent file: "
-                         << element.key();
-        return nullptr;
-      }
+    /**
+     * @brief Fills object with data from UserSession's JSON representation
+     *
+     * This replaces nlohmann's from_json to ensure no-throw approach
+     *
+     * @param[in] j   JSON object from which data should be loaded
+     *
+     * @return a shared pointer if data has been loaded properly, nullptr
+     * otherwise
+     */
+    static std::shared_ptr<UserSession> fromJson(const nlohmann::json& j)
+    {
+        std::shared_ptr<UserSession> userSession =
+            std::make_shared<UserSession>();
+        for (const auto& element : j.items())
+        {
+            const std::string* thisValue =
+                element.value().get_ptr<const std::string*>();
+            if (thisValue == nullptr)
+            {
+                BMCWEB_LOG_ERROR << "Error reading persistent store.  Property "
+                                 << element.key() << " was not of type string";
+                return nullptr;
+            }
+            if (element.key() == "unique_id")
+            {
+                userSession->uniqueId = *thisValue;
+            }
+            else if (element.key() == "session_token")
+            {
+                userSession->sessionToken = *thisValue;
+            }
+            else if (element.key() == "csrf_token")
+            {
+                userSession->csrfToken = *thisValue;
+            }
+            else if (element.key() == "username")
+            {
+                userSession->username = *thisValue;
+            }
+            else
+            {
+                BMCWEB_LOG_ERROR
+                    << "Got unexpected property reading persistent file: "
+                    << element.key();
+                return nullptr;
+            }
+        }
+
+        // For now, sessions that were persisted through a reboot get their idle
+        // timer reset.  This could probably be overcome with a better
+        // understanding of wall clock time and steady timer time, possibly
+        // persisting values with wall clock time instead of steady timer, but
+        // the tradeoffs of all the corner cases involved are non-trivial, so
+        // this is done temporarily
+        userSession->lastUpdated = std::chrono::steady_clock::now();
+        userSession->persistence = PersistenceType::TIMEOUT;
+
+        return userSession;
     }
-
-    // For now, sessions that were persisted through a reboot get their idle
-    // timer reset.  This could probably be overcome with a better understanding
-    // of wall clock time and steady timer time, possibly persisting values with
-    // wall clock time instead of steady timer, but the tradeoffs of all the
-    // corner cases involved are non-trivial, so this is done temporarily
-    userSession->lastUpdated = std::chrono::steady_clock::now();
-    userSession->persistence = PersistenceType::TIMEOUT;
-
-    return userSession;
-  }
 };
 
 class Middleware;
 
-class SessionStore {
- public:
-  std::shared_ptr<UserSession> generateUserSession(
-      const boost::string_view username,
-      PersistenceType persistence = PersistenceType::TIMEOUT) {
-    // TODO(ed) find a secure way to not generate session identifiers if
-    // persistence is set to SINGLE_REQUEST
-    static constexpr std::array<char, 62> alphanum = {
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'b', 'C',
-        'D', 'E', 'F', 'g', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
-        'Q', 'r', 'S', 'T', 'U', 'v', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c',
-        'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
-        'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
+class SessionStore
+{
+  public:
+    std::shared_ptr<UserSession> generateUserSession(
+        const boost::string_view username,
+        PersistenceType persistence = PersistenceType::TIMEOUT)
+    {
+        // TODO(ed) find a secure way to not generate session identifiers if
+        // persistence is set to SINGLE_REQUEST
+        static constexpr std::array<char, 62> alphanum = {
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'b', 'C',
+            'D', 'E', 'F', 'g', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+            'Q', 'r', 'S', 'T', 'U', 'v', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c',
+            'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
+            'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
 
-    // entropy: 30 characters, 62 possibilities.  log2(62^30) = 178 bits of
-    // entropy.  OWASP recommends at least 60
-    // https://www.owasp.org/index.php/Session_Management_Cheat_Sheet#Session_ID_Entropy
-    std::string sessionToken;
-    sessionToken.resize(20, '0');
-    std::uniform_int_distribution<int> dist(0, alphanum.size() - 1);
-    for (int i = 0; i < sessionToken.size(); ++i) {
-      sessionToken[i] = alphanum[dist(rd)];
-    }
-    // Only need csrf tokens for cookie based auth, token doesn't matter
-    std::string csrfToken;
-    csrfToken.resize(20, '0');
-    for (int i = 0; i < csrfToken.size(); ++i) {
-      csrfToken[i] = alphanum[dist(rd)];
-    }
-
-    std::string uniqueId;
-    uniqueId.resize(10, '0');
-    for (int i = 0; i < uniqueId.size(); ++i) {
-      uniqueId[i] = alphanum[dist(rd)];
-    }
-    auto session = std::make_shared<UserSession>(
-        UserSession{uniqueId, sessionToken, std::string(username), csrfToken,
-                    std::chrono::steady_clock::now(), persistence});
-    auto it = authTokens.emplace(std::make_pair(sessionToken, session));
-    // Only need to write to disk if session isn't about to be destroyed.
-    needWrite = persistence == PersistenceType::TIMEOUT;
-    return it.first->second;
-  }
-
-  std::shared_ptr<UserSession> loginSessionByToken(
-      const boost::string_view token) {
-    applySessionTimeouts();
-    auto sessionIt = authTokens.find(std::string(token));
-    if (sessionIt == authTokens.end()) {
-      return nullptr;
-    }
-    std::shared_ptr<UserSession> userSession = sessionIt->second;
-    userSession->lastUpdated = std::chrono::steady_clock::now();
-    return userSession;
-  }
-
-  std::shared_ptr<UserSession> getSessionByUid(const boost::string_view uid) {
-    applySessionTimeouts();
-    // TODO(Ed) this is inefficient
-    auto sessionIt = authTokens.begin();
-    while (sessionIt != authTokens.end()) {
-      if (sessionIt->second->uniqueId == uid) {
-        return sessionIt->second;
-      }
-      sessionIt++;
-    }
-    return nullptr;
-  }
-
-  void removeSession(std::shared_ptr<UserSession> session) {
-    authTokens.erase(session->sessionToken);
-    needWrite = true;
-  }
-
-  std::vector<const std::string*> getUniqueIds(
-      bool getAll = true,
-      const PersistenceType& type = PersistenceType::SINGLE_REQUEST) {
-    applySessionTimeouts();
-
-    std::vector<const std::string*> ret;
-    ret.reserve(authTokens.size());
-    for (auto& session : authTokens) {
-      if (getAll || type == session.second->persistence) {
-        ret.push_back(&session.second->uniqueId);
-      }
-    }
-    return ret;
-  }
-
-  bool needsWrite() { return needWrite; }
-  int getTimeoutInSeconds() const {
-    return std::chrono::seconds(timeoutInMinutes).count();
-  };
-
-  // Persistent data middleware needs to be able to serialize our authTokens
-  // structure, which is private
-  friend Middleware;
-
-  static SessionStore& getInstance() {
-    static SessionStore sessionStore;
-    return sessionStore;
-  }
-
-  SessionStore(const SessionStore&) = delete;
-  SessionStore& operator=(const SessionStore&) = delete;
-
- private:
-  SessionStore() : timeoutInMinutes(60) {}
-
-  void applySessionTimeouts() {
-    auto timeNow = std::chrono::steady_clock::now();
-    if (timeNow - lastTimeoutUpdate > std::chrono::minutes(1)) {
-      lastTimeoutUpdate = timeNow;
-      auto authTokensIt = authTokens.begin();
-      while (authTokensIt != authTokens.end()) {
-        if (timeNow - authTokensIt->second->lastUpdated >= timeoutInMinutes) {
-          authTokensIt = authTokens.erase(authTokensIt);
-          needWrite = true;
-        } else {
-          authTokensIt++;
+        // entropy: 30 characters, 62 possibilities.  log2(62^30) = 178 bits of
+        // entropy.  OWASP recommends at least 60
+        // https://www.owasp.org/index.php/Session_Management_Cheat_Sheet#Session_ID_Entropy
+        std::string sessionToken;
+        sessionToken.resize(20, '0');
+        std::uniform_int_distribution<int> dist(0, alphanum.size() - 1);
+        for (int i = 0; i < sessionToken.size(); ++i)
+        {
+            sessionToken[i] = alphanum[dist(rd)];
         }
-      }
+        // Only need csrf tokens for cookie based auth, token doesn't matter
+        std::string csrfToken;
+        csrfToken.resize(20, '0');
+        for (int i = 0; i < csrfToken.size(); ++i)
+        {
+            csrfToken[i] = alphanum[dist(rd)];
+        }
+
+        std::string uniqueId;
+        uniqueId.resize(10, '0');
+        for (int i = 0; i < uniqueId.size(); ++i)
+        {
+            uniqueId[i] = alphanum[dist(rd)];
+        }
+        auto session = std::make_shared<UserSession>(UserSession{
+            uniqueId, sessionToken, std::string(username), csrfToken,
+            std::chrono::steady_clock::now(), persistence});
+        auto it = authTokens.emplace(std::make_pair(sessionToken, session));
+        // Only need to write to disk if session isn't about to be destroyed.
+        needWrite = persistence == PersistenceType::TIMEOUT;
+        return it.first->second;
     }
-  }
-  std::chrono::time_point<std::chrono::steady_clock> lastTimeoutUpdate;
-  boost::container::flat_map<std::string, std::shared_ptr<UserSession>>
-      authTokens;
-  std::random_device rd;
-  bool needWrite{false};
-  std::chrono::minutes timeoutInMinutes;
+
+    std::shared_ptr<UserSession>
+        loginSessionByToken(const boost::string_view token)
+    {
+        applySessionTimeouts();
+        auto sessionIt = authTokens.find(std::string(token));
+        if (sessionIt == authTokens.end())
+        {
+            return nullptr;
+        }
+        std::shared_ptr<UserSession> userSession = sessionIt->second;
+        userSession->lastUpdated = std::chrono::steady_clock::now();
+        return userSession;
+    }
+
+    std::shared_ptr<UserSession> getSessionByUid(const boost::string_view uid)
+    {
+        applySessionTimeouts();
+        // TODO(Ed) this is inefficient
+        auto sessionIt = authTokens.begin();
+        while (sessionIt != authTokens.end())
+        {
+            if (sessionIt->second->uniqueId == uid)
+            {
+                return sessionIt->second;
+            }
+            sessionIt++;
+        }
+        return nullptr;
+    }
+
+    void removeSession(std::shared_ptr<UserSession> session)
+    {
+        authTokens.erase(session->sessionToken);
+        needWrite = true;
+    }
+
+    std::vector<const std::string*> getUniqueIds(
+        bool getAll = true,
+        const PersistenceType& type = PersistenceType::SINGLE_REQUEST)
+    {
+        applySessionTimeouts();
+
+        std::vector<const std::string*> ret;
+        ret.reserve(authTokens.size());
+        for (auto& session : authTokens)
+        {
+            if (getAll || type == session.second->persistence)
+            {
+                ret.push_back(&session.second->uniqueId);
+            }
+        }
+        return ret;
+    }
+
+    bool needsWrite()
+    {
+        return needWrite;
+    }
+    int getTimeoutInSeconds() const
+    {
+        return std::chrono::seconds(timeoutInMinutes).count();
+    };
+
+    // Persistent data middleware needs to be able to serialize our authTokens
+    // structure, which is private
+    friend Middleware;
+
+    static SessionStore& getInstance()
+    {
+        static SessionStore sessionStore;
+        return sessionStore;
+    }
+
+    SessionStore(const SessionStore&) = delete;
+    SessionStore& operator=(const SessionStore&) = delete;
+
+  private:
+    SessionStore() : timeoutInMinutes(60)
+    {
+    }
+
+    void applySessionTimeouts()
+    {
+        auto timeNow = std::chrono::steady_clock::now();
+        if (timeNow - lastTimeoutUpdate > std::chrono::minutes(1))
+        {
+            lastTimeoutUpdate = timeNow;
+            auto authTokensIt = authTokens.begin();
+            while (authTokensIt != authTokens.end())
+            {
+                if (timeNow - authTokensIt->second->lastUpdated >=
+                    timeoutInMinutes)
+                {
+                    authTokensIt = authTokens.erase(authTokensIt);
+                    needWrite = true;
+                }
+                else
+                {
+                    authTokensIt++;
+                }
+            }
+        }
+    }
+    std::chrono::time_point<std::chrono::steady_clock> lastTimeoutUpdate;
+    boost::container::flat_map<std::string, std::shared_ptr<UserSession>>
+        authTokens;
+    std::random_device rd;
+    bool needWrite{false};
+    std::chrono::minutes timeoutInMinutes;
 };
 
-}  // namespace persistent_data
-}  // namespace crow
+} // namespace persistent_data
+} // namespace crow
 
 // to_json(...) definition for objects of UserSession type
-namespace nlohmann {
+namespace nlohmann
+{
 template <>
-struct adl_serializer<std::shared_ptr<crow::persistent_data::UserSession>> {
-  static void to_json(
-      nlohmann::json& j,
-      const std::shared_ptr<crow::persistent_data::UserSession>& p) {
-    if (p->persistence !=
-        crow::persistent_data::PersistenceType::SINGLE_REQUEST) {
-      j = nlohmann::json{{"unique_id", p->uniqueId},
-                         {"session_token", p->sessionToken},
-                         {"username", p->username},
-                         {"csrf_token", p->csrfToken}};
+struct adl_serializer<std::shared_ptr<crow::persistent_data::UserSession>>
+{
+    static void
+        to_json(nlohmann::json& j,
+                const std::shared_ptr<crow::persistent_data::UserSession>& p)
+    {
+        if (p->persistence !=
+            crow::persistent_data::PersistenceType::SINGLE_REQUEST)
+        {
+            j = nlohmann::json{{"unique_id", p->uniqueId},
+                               {"session_token", p->sessionToken},
+                               {"username", p->username},
+                               {"csrf_token", p->csrfToken}};
+        }
     }
-  }
 };
-}  // namespace nlohmann
+} // namespace nlohmann
diff --git a/include/ssl_key_handler.hpp b/include/ssl_key_handler.hpp
index 4eac803..47893bf 100644
--- a/include/ssl_key_handler.hpp
+++ b/include/ssl_key_handler.hpp
@@ -10,304 +10,355 @@
 #include <openssl/rand.h>
 #include <openssl/rsa.h>
 #include <openssl/ssl.h>
-#include <random>
-#include <boost/asio.hpp>
 
-namespace ensuressl {
+#include <boost/asio.hpp>
+#include <random>
+
+namespace ensuressl
+{
 static void initOpenssl();
 static void cleanupOpenssl();
 static EVP_PKEY *createRsaKey();
 static EVP_PKEY *createEcKey();
 static void handleOpensslError();
 
-inline bool verifyOpensslKeyCert(const std::string &filepath) {
-  bool privateKeyValid = false;
-  bool certValid = false;
+inline bool verifyOpensslKeyCert(const std::string &filepath)
+{
+    bool privateKeyValid = false;
+    bool certValid = false;
 
-  std::cout << "Checking certs in file " << filepath << "\n";
+    std::cout << "Checking certs in file " << filepath << "\n";
 
-  FILE *file = fopen(filepath.c_str(), "r");
-  if (file != NULL) {
-    EVP_PKEY *pkey = PEM_read_PrivateKey(file, NULL, NULL, NULL);
-    int rc;
-    if (pkey != nullptr) {
-      RSA *rsa = EVP_PKEY_get1_RSA(pkey);
-      if (rsa != nullptr) {
-        std::cout << "Found an RSA key\n";
-        if (RSA_check_key(rsa) == 1) {
-          // private_key_valid = true;
-        } else {
-          std::cerr << "Key not valid error number " << ERR_get_error() << "\n";
+    FILE *file = fopen(filepath.c_str(), "r");
+    if (file != NULL)
+    {
+        EVP_PKEY *pkey = PEM_read_PrivateKey(file, NULL, NULL, NULL);
+        int rc;
+        if (pkey != nullptr)
+        {
+            RSA *rsa = EVP_PKEY_get1_RSA(pkey);
+            if (rsa != nullptr)
+            {
+                std::cout << "Found an RSA key\n";
+                if (RSA_check_key(rsa) == 1)
+                {
+                    // private_key_valid = true;
+                }
+                else
+                {
+                    std::cerr << "Key not valid error number "
+                              << ERR_get_error() << "\n";
+                }
+                RSA_free(rsa);
+            }
+            else
+            {
+                EC_KEY *ec = EVP_PKEY_get1_EC_KEY(pkey);
+                if (ec != nullptr)
+                {
+                    std::cout << "Found an EC key\n";
+                    if (EC_KEY_check_key(ec) == 1)
+                    {
+                        privateKeyValid = true;
+                    }
+                    else
+                    {
+                        std::cerr << "Key not valid error number "
+                                  << ERR_get_error() << "\n";
+                    }
+                    EC_KEY_free(ec);
+                }
+            }
+
+            if (privateKeyValid)
+            {
+                X509 *x509 = PEM_read_X509(file, NULL, NULL, NULL);
+                if (x509 == nullptr)
+                {
+                    std::cout << "error getting x509 cert " << ERR_get_error()
+                              << "\n";
+                }
+                else
+                {
+                    rc = X509_verify(x509, pkey);
+                    if (rc == 1)
+                    {
+                        certValid = true;
+                    }
+                    else
+                    {
+                        std::cerr << "Error in verifying private key signature "
+                                  << ERR_get_error() << "\n";
+                    }
+                }
+            }
+
+            EVP_PKEY_free(pkey);
         }
-        RSA_free(rsa);
-      } else {
-        EC_KEY *ec = EVP_PKEY_get1_EC_KEY(pkey);
-        if (ec != nullptr) {
-          std::cout << "Found an EC key\n";
-          if (EC_KEY_check_key(ec) == 1) {
-            privateKeyValid = true;
-          } else {
-            std::cerr << "Key not valid error number " << ERR_get_error()
-                      << "\n";
-          }
-          EC_KEY_free(ec);
-        }
-      }
-
-      if (privateKeyValid) {
-        X509 *x509 = PEM_read_X509(file, NULL, NULL, NULL);
-        if (x509 == nullptr) {
-          std::cout << "error getting x509 cert " << ERR_get_error() << "\n";
-        } else {
-          rc = X509_verify(x509, pkey);
-          if (rc == 1) {
-            certValid = true;
-          } else {
-            std::cerr << "Error in verifying private key signature "
-                      << ERR_get_error() << "\n";
-          }
-        }
-      }
-
-      EVP_PKEY_free(pkey);
+        fclose(file);
     }
-    fclose(file);
-  }
-  return certValid;
+    return certValid;
 }
 
-inline void generateSslCertificate(const std::string &filepath) {
-  FILE *pFile = NULL;
-  std::cout << "Generating new keys\n";
-  initOpenssl();
+inline void generateSslCertificate(const std::string &filepath)
+{
+    FILE *pFile = NULL;
+    std::cout << "Generating new keys\n";
+    initOpenssl();
 
-  // std::cerr << "Generating RSA key";
-  // EVP_PKEY *pRsaPrivKey = create_rsa_key();
+    // std::cerr << "Generating RSA key";
+    // EVP_PKEY *pRsaPrivKey = create_rsa_key();
 
-  std::cerr << "Generating EC key\n";
-  EVP_PKEY *pRsaPrivKey = createEcKey();
-  if (pRsaPrivKey != nullptr) {
-    std::cerr << "Generating x509 Certificate\n";
-    // Use this code to directly generate a certificate
-    X509 *x509;
-    x509 = X509_new();
-    if (x509 != nullptr) {
-      // get a random number from the RNG for the certificate serial number
-      // If this is not random, regenerating certs throws broswer errors
-      std::random_device rd;
-      int serial = rd();
+    std::cerr << "Generating EC key\n";
+    EVP_PKEY *pRsaPrivKey = createEcKey();
+    if (pRsaPrivKey != nullptr)
+    {
+        std::cerr << "Generating x509 Certificate\n";
+        // Use this code to directly generate a certificate
+        X509 *x509;
+        x509 = X509_new();
+        if (x509 != nullptr)
+        {
+            // get a random number from the RNG for the certificate serial
+            // number If this is not random, regenerating certs throws broswer
+            // errors
+            std::random_device rd;
+            int serial = rd();
 
-      ASN1_INTEGER_set(X509_get_serialNumber(x509), serial);
+            ASN1_INTEGER_set(X509_get_serialNumber(x509), serial);
 
-      // not before this moment
-      X509_gmtime_adj(X509_get_notBefore(x509), 0);
-      // Cert is valid for 10 years
-      X509_gmtime_adj(X509_get_notAfter(x509), 60L * 60L * 24L * 365L * 10L);
+            // not before this moment
+            X509_gmtime_adj(X509_get_notBefore(x509), 0);
+            // Cert is valid for 10 years
+            X509_gmtime_adj(X509_get_notAfter(x509),
+                            60L * 60L * 24L * 365L * 10L);
 
-      // set the public key to the key we just generated
-      X509_set_pubkey(x509, pRsaPrivKey);
+            // set the public key to the key we just generated
+            X509_set_pubkey(x509, pRsaPrivKey);
 
-      // get the subject name
-      X509_NAME *name;
-      name = X509_get_subject_name(x509);
+            // get the subject name
+            X509_NAME *name;
+            name = X509_get_subject_name(x509);
 
-      X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC,
-                                 reinterpret_cast<const unsigned char *>("US"),
-                                 -1, -1, 0);
-      X509_NAME_add_entry_by_txt(
-          name, "O", MBSTRING_ASC,
-          reinterpret_cast<const unsigned char *>("Intel BMC"), -1, -1, 0);
-      X509_NAME_add_entry_by_txt(
-          name, "CN", MBSTRING_ASC,
-          reinterpret_cast<const unsigned char *>("testhost"), -1, -1, 0);
-      // set the CSR options
-      X509_set_issuer_name(x509, name);
+            X509_NAME_add_entry_by_txt(
+                name, "C", MBSTRING_ASC,
+                reinterpret_cast<const unsigned char *>("US"), -1, -1, 0);
+            X509_NAME_add_entry_by_txt(
+                name, "O", MBSTRING_ASC,
+                reinterpret_cast<const unsigned char *>("Intel BMC"), -1, -1,
+                0);
+            X509_NAME_add_entry_by_txt(
+                name, "CN", MBSTRING_ASC,
+                reinterpret_cast<const unsigned char *>("testhost"), -1, -1, 0);
+            // set the CSR options
+            X509_set_issuer_name(x509, name);
 
-      // Sign the certificate with our private key
-      X509_sign(x509, pRsaPrivKey, EVP_sha256());
+            // Sign the certificate with our private key
+            X509_sign(x509, pRsaPrivKey, EVP_sha256());
 
-      pFile = fopen(filepath.c_str(), "wt");
+            pFile = fopen(filepath.c_str(), "wt");
 
-      if (pFile != nullptr) {
-        PEM_write_PrivateKey(pFile, pRsaPrivKey, NULL, NULL, 0, 0, NULL);
+            if (pFile != nullptr)
+            {
+                PEM_write_PrivateKey(pFile, pRsaPrivKey, NULL, NULL, 0, 0,
+                                     NULL);
 
-        PEM_write_X509(pFile, x509);
-        fclose(pFile);
-        pFile = NULL;
-      }
+                PEM_write_X509(pFile, x509);
+                fclose(pFile);
+                pFile = NULL;
+            }
 
-      X509_free(x509);
+            X509_free(x509);
+        }
+
+        EVP_PKEY_free(pRsaPrivKey);
+        pRsaPrivKey = NULL;
     }
 
-    EVP_PKEY_free(pRsaPrivKey);
-    pRsaPrivKey = NULL;
-  }
-
-  // cleanup_openssl();
+    // cleanup_openssl();
 }
 
-EVP_PKEY *createRsaKey() {
-  RSA *pRSA = NULL;
+EVP_PKEY *createRsaKey()
+{
+    RSA *pRSA = NULL;
 #if OPENSSL_VERSION_NUMBER < 0x00908000L
-  pRSA = RSA_generate_key(2048, RSA_3, NULL, NULL);
+    pRSA = RSA_generate_key(2048, RSA_3, NULL, NULL);
 #else
-  RSA_generate_key_ex(pRSA, 2048, NULL, NULL);
+    RSA_generate_key_ex(pRSA, 2048, NULL, NULL);
 #endif
 
-  EVP_PKEY *pKey = EVP_PKEY_new();
-  if ((pRSA != nullptr) && (pKey != nullptr) &&
-      EVP_PKEY_assign_RSA(pKey, pRSA)) {
-    /* pKey owns pRSA from now */
-    if (RSA_check_key(pRSA) <= 0) {
-      fprintf(stderr, "RSA_check_key failed.\n");
-      handleOpensslError();
-      EVP_PKEY_free(pKey);
-      pKey = NULL;
-    }
-  } else {
-    handleOpensslError();
-    if (pRSA != nullptr) {
-      RSA_free(pRSA);
-      pRSA = NULL;
-    }
-    if (pKey != nullptr) {
-      EVP_PKEY_free(pKey);
-      pKey = NULL;
-    }
-  }
-  return pKey;
-}
-
-EVP_PKEY *createEcKey() {
-  EVP_PKEY *pKey = NULL;
-  int eccgrp = 0;
-  eccgrp = OBJ_txt2nid("prime256v1");
-
-  EC_KEY *myecc = EC_KEY_new_by_curve_name(eccgrp);
-  if (myecc != nullptr) {
-    EC_KEY_set_asn1_flag(myecc, OPENSSL_EC_NAMED_CURVE);
-    EC_KEY_generate_key(myecc);
-    pKey = EVP_PKEY_new();
-    if (pKey != nullptr) {
-      if (EVP_PKEY_assign_EC_KEY(pKey, myecc)) {
+    EVP_PKEY *pKey = EVP_PKEY_new();
+    if ((pRSA != nullptr) && (pKey != nullptr) &&
+        EVP_PKEY_assign_RSA(pKey, pRSA))
+    {
         /* pKey owns pRSA from now */
-        if (EC_KEY_check_key(myecc) <= 0) {
-          fprintf(stderr, "EC_check_key failed.\n");
+        if (RSA_check_key(pRSA) <= 0)
+        {
+            fprintf(stderr, "RSA_check_key failed.\n");
+            handleOpensslError();
+            EVP_PKEY_free(pKey);
+            pKey = NULL;
         }
-      }
     }
-  }
-  return pKey;
+    else
+    {
+        handleOpensslError();
+        if (pRSA != nullptr)
+        {
+            RSA_free(pRSA);
+            pRSA = NULL;
+        }
+        if (pKey != nullptr)
+        {
+            EVP_PKEY_free(pKey);
+            pKey = NULL;
+        }
+    }
+    return pKey;
 }
 
-void initOpenssl() {
+EVP_PKEY *createEcKey()
+{
+    EVP_PKEY *pKey = NULL;
+    int eccgrp = 0;
+    eccgrp = OBJ_txt2nid("prime256v1");
+
+    EC_KEY *myecc = EC_KEY_new_by_curve_name(eccgrp);
+    if (myecc != nullptr)
+    {
+        EC_KEY_set_asn1_flag(myecc, OPENSSL_EC_NAMED_CURVE);
+        EC_KEY_generate_key(myecc);
+        pKey = EVP_PKEY_new();
+        if (pKey != nullptr)
+        {
+            if (EVP_PKEY_assign_EC_KEY(pKey, myecc))
+            {
+                /* pKey owns pRSA from now */
+                if (EC_KEY_check_key(myecc) <= 0)
+                {
+                    fprintf(stderr, "EC_check_key failed.\n");
+                }
+            }
+        }
+    }
+    return pKey;
+}
+
+void initOpenssl()
+{
 #if OPENSSL_VERSION_NUMBER < 0x10100000L
-  SSL_load_error_strings();
-  OpenSSL_add_all_algorithms();
-  RAND_load_file("/dev/urandom", 1024);
+    SSL_load_error_strings();
+    OpenSSL_add_all_algorithms();
+    RAND_load_file("/dev/urandom", 1024);
 #endif
 }
 
-void cleanupOpenssl() {
-  CRYPTO_cleanup_all_ex_data();
-  ERR_free_strings();
+void cleanupOpenssl()
+{
+    CRYPTO_cleanup_all_ex_data();
+    ERR_free_strings();
 #if OPENSSL_VERSION_NUMBER < 0x10100000L
-  ERR_remove_thread_state(0);
+    ERR_remove_thread_state(0);
 #endif
-  EVP_cleanup();
+    EVP_cleanup();
 }
 
-void handleOpensslError() { ERR_print_errors_fp(stderr); }
-inline void ensureOpensslKeyPresentAndValid(const std::string &filepath) {
-  bool pemFileValid = false;
+void handleOpensslError()
+{
+    ERR_print_errors_fp(stderr);
+}
+inline void ensureOpensslKeyPresentAndValid(const std::string &filepath)
+{
+    bool pemFileValid = false;
 
-  pemFileValid = verifyOpensslKeyCert(filepath);
+    pemFileValid = verifyOpensslKeyCert(filepath);
 
-  if (!pemFileValid) {
-    std::cerr << "Error in verifying signature, regenerating\n";
-    generateSslCertificate(filepath);
-  }
+    if (!pemFileValid)
+    {
+        std::cerr << "Error in verifying signature, regenerating\n";
+        generateSslCertificate(filepath);
+    }
 }
 
-inline boost::asio::ssl::context getSslContext(
-    const std::string &ssl_pem_file) {
-  boost::asio::ssl::context mSslContext{boost::asio::ssl::context::sslv23};
-  mSslContext.set_options(boost::asio::ssl::context::default_workarounds |
-                          boost::asio::ssl::context::no_sslv2 |
-                          boost::asio::ssl::context::no_sslv3 |
-                          boost::asio::ssl::context::single_dh_use |
-                          boost::asio::ssl::context::no_tlsv1 |
-                          boost::asio::ssl::context::no_tlsv1_1);
+inline boost::asio::ssl::context getSslContext(const std::string &ssl_pem_file)
+{
+    boost::asio::ssl::context mSslContext{boost::asio::ssl::context::sslv23};
+    mSslContext.set_options(boost::asio::ssl::context::default_workarounds |
+                            boost::asio::ssl::context::no_sslv2 |
+                            boost::asio::ssl::context::no_sslv3 |
+                            boost::asio::ssl::context::single_dh_use |
+                            boost::asio::ssl::context::no_tlsv1 |
+                            boost::asio::ssl::context::no_tlsv1_1);
 
-  // m_ssl_context.set_verify_mode(boost::asio::ssl::verify_peer);
-  mSslContext.use_certificate_file(ssl_pem_file,
-                                   boost::asio::ssl::context::pem);
-  mSslContext.use_private_key_file(ssl_pem_file,
-                                   boost::asio::ssl::context::pem);
+    // m_ssl_context.set_verify_mode(boost::asio::ssl::verify_peer);
+    mSslContext.use_certificate_file(ssl_pem_file,
+                                     boost::asio::ssl::context::pem);
+    mSslContext.use_private_key_file(ssl_pem_file,
+                                     boost::asio::ssl::context::pem);
 
-  // Set up EC curves to auto (boost asio doesn't have a method for this)
-  // There is a pull request to add this.  Once this is included in an asio
-  // drop, use the right way
-  // http://stackoverflow.com/questions/18929049/boost-asio-with-ecdsa-certificate-issue
-  if (SSL_CTX_set_ecdh_auto(mSslContext.native_handle(), 1) != 1) {
-    BMCWEB_LOG_ERROR << "Error setting tmp ecdh list\n";
-  }
+    // Set up EC curves to auto (boost asio doesn't have a method for this)
+    // There is a pull request to add this.  Once this is included in an asio
+    // drop, use the right way
+    // http://stackoverflow.com/questions/18929049/boost-asio-with-ecdsa-certificate-issue
+    if (SSL_CTX_set_ecdh_auto(mSslContext.native_handle(), 1) != 1)
+    {
+        BMCWEB_LOG_ERROR << "Error setting tmp ecdh list\n";
+    }
 
-  // From mozilla "compatibility"
-  std::string mozillaCompatibilityCiphers =
-      "ECDHE-ECDSA-CHACHA20-POLY1305:"
-      "ECDHE-RSA-CHACHA20-POLY1305:"
-      "ECDHE-ECDSA-AES128-GCM-SHA256:"
-      "ECDHE-RSA-AES128-GCM-SHA256:"
-      "ECDHE-ECDSA-AES256-GCM-SHA384:"
-      "ECDHE-RSA-AES256-GCM-SHA384:"
-      "DHE-RSA-AES128-GCM-SHA256:"
-      "DHE-RSA-AES256-GCM-SHA384:"
-      "ECDHE-ECDSA-AES128-SHA256:"
-      "ECDHE-RSA-AES128-SHA256:"
-      "ECDHE-ECDSA-AES128-SHA:"
-      "ECDHE-RSA-AES256-SHA384:"
-      "ECDHE-RSA-AES128-SHA:"
-      "ECDHE-ECDSA-AES256-SHA384:"
-      "ECDHE-ECDSA-AES256-SHA:"
-      "ECDHE-RSA-AES256-SHA:"
-      "DHE-RSA-AES128-SHA256:"
-      "DHE-RSA-AES128-SHA:"
-      "DHE-RSA-AES256-SHA256:"
-      "DHE-RSA-AES256-SHA:"
-      "ECDHE-ECDSA-DES-CBC3-SHA:"
-      "ECDHE-RSA-DES-CBC3-SHA:"
-      "EDH-RSA-DES-CBC3-SHA:"
-      "AES128-GCM-SHA256:"
-      "AES256-GCM-SHA384:"
-      "AES128-SHA256:"
-      "AES256-SHA256:"
-      "AES128-SHA:"
-      "AES256-SHA:"
-      "DES-CBC3-SHA:"
-      "!DSS";
+    // From mozilla "compatibility"
+    std::string mozillaCompatibilityCiphers = "ECDHE-ECDSA-CHACHA20-POLY1305:"
+                                              "ECDHE-RSA-CHACHA20-POLY1305:"
+                                              "ECDHE-ECDSA-AES128-GCM-SHA256:"
+                                              "ECDHE-RSA-AES128-GCM-SHA256:"
+                                              "ECDHE-ECDSA-AES256-GCM-SHA384:"
+                                              "ECDHE-RSA-AES256-GCM-SHA384:"
+                                              "DHE-RSA-AES128-GCM-SHA256:"
+                                              "DHE-RSA-AES256-GCM-SHA384:"
+                                              "ECDHE-ECDSA-AES128-SHA256:"
+                                              "ECDHE-RSA-AES128-SHA256:"
+                                              "ECDHE-ECDSA-AES128-SHA:"
+                                              "ECDHE-RSA-AES256-SHA384:"
+                                              "ECDHE-RSA-AES128-SHA:"
+                                              "ECDHE-ECDSA-AES256-SHA384:"
+                                              "ECDHE-ECDSA-AES256-SHA:"
+                                              "ECDHE-RSA-AES256-SHA:"
+                                              "DHE-RSA-AES128-SHA256:"
+                                              "DHE-RSA-AES128-SHA:"
+                                              "DHE-RSA-AES256-SHA256:"
+                                              "DHE-RSA-AES256-SHA:"
+                                              "ECDHE-ECDSA-DES-CBC3-SHA:"
+                                              "ECDHE-RSA-DES-CBC3-SHA:"
+                                              "EDH-RSA-DES-CBC3-SHA:"
+                                              "AES128-GCM-SHA256:"
+                                              "AES256-GCM-SHA384:"
+                                              "AES128-SHA256:"
+                                              "AES256-SHA256:"
+                                              "AES128-SHA:"
+                                              "AES256-SHA:"
+                                              "DES-CBC3-SHA:"
+                                              "!DSS";
 
-  // From mozilla "modern"
-  std::string mozillaModernCiphers =
-      "ECDHE-ECDSA-AES256-GCM-SHA384:"
-      "ECDHE-RSA-AES256-GCM-SHA384:"
-      "ECDHE-ECDSA-CHACHA20-POLY1305:"
-      "ECDHE-RSA-CHACHA20-POLY1305:"
-      "ECDHE-ECDSA-AES128-GCM-SHA256:"
-      "ECDHE-RSA-AES128-GCM-SHA256:"
-      "ECDHE-ECDSA-AES256-SHA384:"
-      "ECDHE-RSA-AES256-SHA384:"
-      "ECDHE-ECDSA-AES128-SHA256:"
-      "ECDHE-RSA-AES128-SHA256";
+    // From mozilla "modern"
+    std::string mozillaModernCiphers = "ECDHE-ECDSA-AES256-GCM-SHA384:"
+                                       "ECDHE-RSA-AES256-GCM-SHA384:"
+                                       "ECDHE-ECDSA-CHACHA20-POLY1305:"
+                                       "ECDHE-RSA-CHACHA20-POLY1305:"
+                                       "ECDHE-ECDSA-AES128-GCM-SHA256:"
+                                       "ECDHE-RSA-AES128-GCM-SHA256:"
+                                       "ECDHE-ECDSA-AES256-SHA384:"
+                                       "ECDHE-RSA-AES256-SHA384:"
+                                       "ECDHE-ECDSA-AES128-SHA256:"
+                                       "ECDHE-RSA-AES128-SHA256";
 
-  std::string aesOnlyCiphers = "AES128+EECDH:AES128+EDH:!aNULL:!eNULL";
+    std::string aesOnlyCiphers = "AES128+EECDH:AES128+EDH:!aNULL:!eNULL";
 
-  if (SSL_CTX_set_cipher_list(mSslContext.native_handle(),
-                              mozillaCompatibilityCiphers.c_str()) != 1) {
-    BMCWEB_LOG_ERROR << "Error setting cipher list\n";
-  }
-  return mSslContext;
+    if (SSL_CTX_set_cipher_list(mSslContext.native_handle(),
+                                mozillaCompatibilityCiphers.c_str()) != 1)
+    {
+        BMCWEB_LOG_ERROR << "Error setting cipher list\n";
+    }
+    return mSslContext;
 }
-}  // namespace ensuressl
+} // namespace ensuressl
 
 #endif
\ No newline at end of file
diff --git a/include/token_authorization_middleware.hpp b/include/token_authorization_middleware.hpp
index 2e286e1..c419c97 100644
--- a/include/token_authorization_middleware.hpp
+++ b/include/token_authorization_middleware.hpp
@@ -1,359 +1,448 @@
 #pragma once
 
-#include <pam_authenticate.hpp>
-#include <persistent_data_middleware.hpp>
-#include <webassets.hpp>
-#include <random>
 #include <crow/app.h>
 #include <crow/common.h>
 #include <crow/http_request.h>
 #include <crow/http_response.h>
+
 #include <boost/container/flat_set.hpp>
+#include <pam_authenticate.hpp>
+#include <persistent_data_middleware.hpp>
+#include <random>
+#include <webassets.hpp>
 
-namespace crow {
+namespace crow
+{
 
-namespace token_authorization {
+namespace token_authorization
+{
 
-class Middleware {
- public:
-  struct Context {
-    std::shared_ptr<crow::persistent_data::UserSession> session;
-  };
+class Middleware
+{
+  public:
+    struct Context
+    {
+        std::shared_ptr<crow::persistent_data::UserSession> session;
+    };
 
-  void beforeHandle(crow::Request& req, Response& res, Context& ctx) {
-    if (isOnWhitelist(req)) {
-      return;
-    }
-
-    ctx.session = performXtokenAuth(req);
-    if (ctx.session == nullptr) {
-      ctx.session = performCookieAuth(req);
-    }
-    if (ctx.session == nullptr) {
-      boost::string_view authHeader = req.getHeaderValue("Authorization");
-      if (!authHeader.empty()) {
-        // Reject any kind of auth other than basic or token
-        if (boost::starts_with(authHeader, "Token ")) {
-          ctx.session = performTokenAuth(authHeader);
-        } else if (boost::starts_with(authHeader, "Basic ")) {
-          ctx.session = performBasicAuth(authHeader);
+    void beforeHandle(crow::Request& req, Response& res, Context& ctx)
+    {
+        if (isOnWhitelist(req))
+        {
+            return;
         }
-      }
-    }
 
-    if (ctx.session == nullptr) {
-      BMCWEB_LOG_WARNING << "[AuthMiddleware] authorization failed";
-
-      // If it's a browser connecting, don't send the HTTP authenticate header,
-      // to avoid possible CSRF attacks with basic auth
-      if (http_helpers::requestPrefersHtml(req)) {
-        res.result(boost::beast::http::status::temporary_redirect);
-        res.addHeader("Location", "/#/login");
-      } else {
-        res.result(boost::beast::http::status::unauthorized);
-        // only send the WWW-authenticate header if this isn't a xhr from the
-        // browser.  most scripts,
-        if (req.getHeaderValue("User-Agent").empty()) {
-          res.addHeader("WWW-Authenticate", "Basic");
+        ctx.session = performXtokenAuth(req);
+        if (ctx.session == nullptr)
+        {
+            ctx.session = performCookieAuth(req);
         }
-      }
+        if (ctx.session == nullptr)
+        {
+            boost::string_view authHeader = req.getHeaderValue("Authorization");
+            if (!authHeader.empty())
+            {
+                // Reject any kind of auth other than basic or token
+                if (boost::starts_with(authHeader, "Token "))
+                {
+                    ctx.session = performTokenAuth(authHeader);
+                }
+                else if (boost::starts_with(authHeader, "Basic "))
+                {
+                    ctx.session = performBasicAuth(authHeader);
+                }
+            }
+        }
 
-      res.end();
-      return;
+        if (ctx.session == nullptr)
+        {
+            BMCWEB_LOG_WARNING << "[AuthMiddleware] authorization failed";
+
+            // If it's a browser connecting, don't send the HTTP authenticate
+            // header, to avoid possible CSRF attacks with basic auth
+            if (http_helpers::requestPrefersHtml(req))
+            {
+                res.result(boost::beast::http::status::temporary_redirect);
+                res.addHeader("Location", "/#/login");
+            }
+            else
+            {
+                res.result(boost::beast::http::status::unauthorized);
+                // only send the WWW-authenticate header if this isn't a xhr
+                // from the browser.  most scripts,
+                if (req.getHeaderValue("User-Agent").empty())
+                {
+                    res.addHeader("WWW-Authenticate", "Basic");
+                }
+            }
+
+            res.end();
+            return;
+        }
+
+        // TODO get user privileges here and propagate it via MW Context
+        // else let the request continue unharmed
     }
 
-    // TODO get user privileges here and propagate it via MW Context
-    // else let the request continue unharmed
-  }
-
-  template <typename AllContext>
-  void afterHandle(Request& req, Response& res, Context& ctx,
-                   AllContext& allctx) {
-    // TODO(ed) THis should really be handled by the persistent data
-    // middleware, but because it is upstream, it doesn't have access to the
-    // session information.  Should the data middleware persist the current
-    // user session?
-    if (ctx.session != nullptr &&
-        ctx.session->persistence ==
-            crow::persistent_data::PersistenceType::SINGLE_REQUEST) {
-      persistent_data::SessionStore::getInstance().removeSession(ctx.session);
-    }
-  }
-
- private:
-  const std::shared_ptr<crow::persistent_data::UserSession> performBasicAuth(
-      boost::string_view auth_header) const {
-    BMCWEB_LOG_DEBUG << "[AuthMiddleware] Basic authentication";
-
-    std::string authData;
-    boost::string_view param = auth_header.substr(strlen("Basic "));
-    if (!crow::utility::base64Decode(param, authData)) {
-      return nullptr;
-    }
-    std::size_t separator = authData.find(':');
-    if (separator == std::string::npos) {
-      return nullptr;
+    template <typename AllContext>
+    void afterHandle(Request& req, Response& res, Context& ctx,
+                     AllContext& allctx)
+    {
+        // TODO(ed) THis should really be handled by the persistent data
+        // middleware, but because it is upstream, it doesn't have access to the
+        // session information.  Should the data middleware persist the current
+        // user session?
+        if (ctx.session != nullptr &&
+            ctx.session->persistence ==
+                crow::persistent_data::PersistenceType::SINGLE_REQUEST)
+        {
+            persistent_data::SessionStore::getInstance().removeSession(
+                ctx.session);
+        }
     }
 
-    std::string user = authData.substr(0, separator);
-    separator += 1;
-    if (separator > authData.size()) {
-      return nullptr;
-    }
-    std::string pass = authData.substr(separator);
+  private:
+    const std::shared_ptr<crow::persistent_data::UserSession>
+        performBasicAuth(boost::string_view auth_header) const
+    {
+        BMCWEB_LOG_DEBUG << "[AuthMiddleware] Basic authentication";
 
-    BMCWEB_LOG_DEBUG << "[AuthMiddleware] Authenticating user: " << user;
+        std::string authData;
+        boost::string_view param = auth_header.substr(strlen("Basic "));
+        if (!crow::utility::base64Decode(param, authData))
+        {
+            return nullptr;
+        }
+        std::size_t separator = authData.find(':');
+        if (separator == std::string::npos)
+        {
+            return nullptr;
+        }
 
-    if (!pamAuthenticateUser(user, pass)) {
-      return nullptr;
+        std::string user = authData.substr(0, separator);
+        separator += 1;
+        if (separator > authData.size())
+        {
+            return nullptr;
+        }
+        std::string pass = authData.substr(separator);
+
+        BMCWEB_LOG_DEBUG << "[AuthMiddleware] Authenticating user: " << user;
+
+        if (!pamAuthenticateUser(user, pass))
+        {
+            return nullptr;
+        }
+
+        // TODO(ed) generateUserSession is a little expensive for basic
+        // auth, as it generates some random identifiers that will never be
+        // used.  This should have a "fast" path for when user tokens aren't
+        // needed.
+        // This whole flow needs to be revisited anyway, as we can't be
+        // calling directly into pam for every request
+        return persistent_data::SessionStore::getInstance().generateUserSession(
+            user, crow::persistent_data::PersistenceType::SINGLE_REQUEST);
     }
 
-    // TODO(ed) generateUserSession is a little expensive for basic
-    // auth, as it generates some random identifiers that will never be
-    // used.  This should have a "fast" path for when user tokens aren't
-    // needed.
-    // This whole flow needs to be revisited anyway, as we can't be
-    // calling directly into pam for every request
-    return persistent_data::SessionStore::getInstance().generateUserSession(
-        user, crow::persistent_data::PersistenceType::SINGLE_REQUEST);
-  }
+    const std::shared_ptr<crow::persistent_data::UserSession>
+        performTokenAuth(boost::string_view auth_header) const
+    {
+        BMCWEB_LOG_DEBUG << "[AuthMiddleware] Token authentication";
 
-  const std::shared_ptr<crow::persistent_data::UserSession> performTokenAuth(
-      boost::string_view auth_header) const {
-    BMCWEB_LOG_DEBUG << "[AuthMiddleware] Token authentication";
-
-    boost::string_view token = auth_header.substr(strlen("Token "));
-    auto session =
-        persistent_data::SessionStore::getInstance().loginSessionByToken(token);
-    return session;
-  }
-
-  const std::shared_ptr<crow::persistent_data::UserSession> performXtokenAuth(
-      const crow::Request& req) const {
-    BMCWEB_LOG_DEBUG << "[AuthMiddleware] X-Auth-Token authentication";
-
-    boost::string_view token = req.getHeaderValue("X-Auth-Token");
-    if (token.empty()) {
-      return nullptr;
-    }
-    auto session =
-        persistent_data::SessionStore::getInstance().loginSessionByToken(token);
-    return session;
-  }
-
-  const std::shared_ptr<crow::persistent_data::UserSession> performCookieAuth(
-      const crow::Request& req) const {
-    BMCWEB_LOG_DEBUG << "[AuthMiddleware] Cookie authentication";
-
-    boost::string_view cookieValue = req.getHeaderValue("Cookie");
-    if (cookieValue.empty()) {
-      return nullptr;
+        boost::string_view token = auth_header.substr(strlen("Token "));
+        auto session =
+            persistent_data::SessionStore::getInstance().loginSessionByToken(
+                token);
+        return session;
     }
 
-    auto startIndex = cookieValue.find("SESSION=");
-    if (startIndex == std::string::npos) {
-      return nullptr;
-    }
-    startIndex += sizeof("SESSION=") - 1;
-    auto endIndex = cookieValue.find(";", startIndex);
-    if (endIndex == std::string::npos) {
-      endIndex = cookieValue.size();
-    }
-    boost::string_view authKey =
-        cookieValue.substr(startIndex, endIndex - startIndex);
+    const std::shared_ptr<crow::persistent_data::UserSession>
+        performXtokenAuth(const crow::Request& req) const
+    {
+        BMCWEB_LOG_DEBUG << "[AuthMiddleware] X-Auth-Token authentication";
 
-    const std::shared_ptr<crow::persistent_data::UserSession> session =
-        persistent_data::SessionStore::getInstance().loginSessionByToken(
-            authKey);
-    if (session == nullptr) {
-      return nullptr;
+        boost::string_view token = req.getHeaderValue("X-Auth-Token");
+        if (token.empty())
+        {
+            return nullptr;
+        }
+        auto session =
+            persistent_data::SessionStore::getInstance().loginSessionByToken(
+                token);
+        return session;
     }
+
+    const std::shared_ptr<crow::persistent_data::UserSession>
+        performCookieAuth(const crow::Request& req) const
+    {
+        BMCWEB_LOG_DEBUG << "[AuthMiddleware] Cookie authentication";
+
+        boost::string_view cookieValue = req.getHeaderValue("Cookie");
+        if (cookieValue.empty())
+        {
+            return nullptr;
+        }
+
+        auto startIndex = cookieValue.find("SESSION=");
+        if (startIndex == std::string::npos)
+        {
+            return nullptr;
+        }
+        startIndex += sizeof("SESSION=") - 1;
+        auto endIndex = cookieValue.find(";", startIndex);
+        if (endIndex == std::string::npos)
+        {
+            endIndex = cookieValue.size();
+        }
+        boost::string_view authKey =
+            cookieValue.substr(startIndex, endIndex - startIndex);
+
+        const std::shared_ptr<crow::persistent_data::UserSession> session =
+            persistent_data::SessionStore::getInstance().loginSessionByToken(
+                authKey);
+        if (session == nullptr)
+        {
+            return nullptr;
+        }
 #ifndef BMCWEB_INSECURE_DISABLE_CSRF_PREVENTION
-    // RFC7231 defines methods that need csrf protection
-    if (req.method() != "GET"_method) {
-      boost::string_view csrf = req.getHeaderValue("X-XSRF-TOKEN");
-      // Make sure both tokens are filled
-      if (csrf.empty() || session->csrfToken.empty()) {
-        return nullptr;
-      }
-      // Reject if csrf token not available
-      if (csrf != session->csrfToken) {
-        return nullptr;
-      }
-    }
+        // RFC7231 defines methods that need csrf protection
+        if (req.method() != "GET"_method)
+        {
+            boost::string_view csrf = req.getHeaderValue("X-XSRF-TOKEN");
+            // Make sure both tokens are filled
+            if (csrf.empty() || session->csrfToken.empty())
+            {
+                return nullptr;
+            }
+            // Reject if csrf token not available
+            if (csrf != session->csrfToken)
+            {
+                return nullptr;
+            }
+        }
 #endif
-    return session;
-  }
-
-  // checks if request can be forwarded without authentication
-  bool isOnWhitelist(const crow::Request& req) const {
-    // it's allowed to GET root node without authentica tion
-    if ("GET"_method == req.method()) {
-      if (req.url == "/redfish/v1" || req.url == "/redfish/v1/" ||
-          req.url == "/redfish" || req.url == "/redfish/" ||
-          req.url == "/redfish/v1/odata" || req.url == "/redfish/v1/odata/") {
-        return true;
-      } else if (crow::webassets::routes.find(std::string(req.url)) !=
-                 crow::webassets::routes.end()) {
-        return true;
-      }
+        return session;
     }
 
-    // it's allowed to POST on session collection & login without
-    // authentication
-    if ("POST"_method == req.method()) {
-      if ((req.url == "/redfish/v1/SessionService/Sessions") ||
-          (req.url == "/redfish/v1/SessionService/Sessions/") ||
-          (req.url == "/login")) {
-        return true;
-      }
-    }
+    // checks if request can be forwarded without authentication
+    bool isOnWhitelist(const crow::Request& req) const
+    {
+        // it's allowed to GET root node without authentica tion
+        if ("GET"_method == req.method())
+        {
+            if (req.url == "/redfish/v1" || req.url == "/redfish/v1/" ||
+                req.url == "/redfish" || req.url == "/redfish/" ||
+                req.url == "/redfish/v1/odata" ||
+                req.url == "/redfish/v1/odata/")
+            {
+                return true;
+            }
+            else if (crow::webassets::routes.find(std::string(req.url)) !=
+                     crow::webassets::routes.end())
+            {
+                return true;
+            }
+        }
 
-    return false;
-  }
+        // it's allowed to POST on session collection & login without
+        // authentication
+        if ("POST"_method == req.method())
+        {
+            if ((req.url == "/redfish/v1/SessionService/Sessions") ||
+                (req.url == "/redfish/v1/SessionService/Sessions/") ||
+                (req.url == "/login"))
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
 };
 
 // TODO(ed) see if there is a better way to allow middlewares to request
 // routes.
 // Possibly an init function on first construction?
-template <typename... Middlewares>
-void requestRoutes(Crow<Middlewares...>& app) {
-  static_assert(
-      black_magic::Contains<persistent_data::Middleware, Middlewares...>::value,
-      "token_authorization middleware must be enabled in app to use "
-      "auth routes");
-  BMCWEB_ROUTE(app, "/login")
-      .methods(
-          "POST"_method)([&](const crow::Request& req, crow::Response& res) {
-        boost::string_view contentType = req.getHeaderValue("content-type");
-        boost::string_view username;
-        boost::string_view password;
+template <typename... Middlewares> void requestRoutes(Crow<Middlewares...>& app)
+{
+    static_assert(
+        black_magic::Contains<persistent_data::Middleware,
+                              Middlewares...>::value,
+        "token_authorization middleware must be enabled in app to use "
+        "auth routes");
+    BMCWEB_ROUTE(app, "/login")
+        .methods(
+            "POST"_method)([&](const crow::Request& req, crow::Response& res) {
+            boost::string_view contentType = req.getHeaderValue("content-type");
+            boost::string_view username;
+            boost::string_view password;
 
-        bool looksLikeIbm = false;
+            bool looksLikeIbm = false;
 
-        // This object needs to be declared at this scope so the strings
-        // within it are not destroyed before we can use them
-        nlohmann::json loginCredentials;
-        // Check if auth was provided by a payload
-        if (contentType == "application/json") {
-          loginCredentials = nlohmann::json::parse(req.body, nullptr, false);
-          if (loginCredentials.is_discarded()) {
-            res.result(boost::beast::http::status::bad_request);
+            // This object needs to be declared at this scope so the strings
+            // within it are not destroyed before we can use them
+            nlohmann::json loginCredentials;
+            // Check if auth was provided by a payload
+            if (contentType == "application/json")
+            {
+                loginCredentials =
+                    nlohmann::json::parse(req.body, nullptr, false);
+                if (loginCredentials.is_discarded())
+                {
+                    res.result(boost::beast::http::status::bad_request);
+                    res.end();
+                    return;
+                }
+
+                // check for username/password in the root object
+                // THis method is how intel APIs authenticate
+                nlohmann::json::iterator userIt =
+                    loginCredentials.find("username");
+                nlohmann::json::iterator passIt =
+                    loginCredentials.find("password");
+                if (userIt != loginCredentials.end() &&
+                    passIt != loginCredentials.end())
+                {
+                    const std::string* userStr =
+                        userIt->get_ptr<const std::string*>();
+                    const std::string* passStr =
+                        passIt->get_ptr<const std::string*>();
+                    if (userStr != nullptr && passStr != nullptr)
+                    {
+                        username = *userStr;
+                        password = *passStr;
+                    }
+                }
+                else
+                {
+                    // Openbmc appears to push a data object that contains the
+                    // same keys (username and password), attempt to use that
+                    auto dataIt = loginCredentials.find("data");
+                    if (dataIt != loginCredentials.end())
+                    {
+                        // Some apis produce an array of value ["username",
+                        // "password"]
+                        if (dataIt->is_array())
+                        {
+                            if (dataIt->size() == 2)
+                            {
+                                nlohmann::json::iterator userIt2 =
+                                    dataIt->begin();
+                                nlohmann::json::iterator passIt2 =
+                                    dataIt->begin() + 1;
+                                looksLikeIbm = true;
+                                if (userIt2 != dataIt->end() &&
+                                    passIt2 != dataIt->end())
+                                {
+                                    const std::string* userStr =
+                                        userIt2->get_ptr<const std::string*>();
+                                    const std::string* passStr =
+                                        passIt2->get_ptr<const std::string*>();
+                                    if (userStr != nullptr &&
+                                        passStr != nullptr)
+                                    {
+                                        username = *userStr;
+                                        password = *passStr;
+                                    }
+                                }
+                            }
+                        }
+                        else if (dataIt->is_object())
+                        {
+                            nlohmann::json::iterator userIt2 =
+                                dataIt->find("username");
+                            nlohmann::json::iterator passIt2 =
+                                dataIt->find("password");
+                            if (userIt2 != dataIt->end() &&
+                                passIt2 != dataIt->end())
+                            {
+                                const std::string* userStr =
+                                    userIt2->get_ptr<const std::string*>();
+                                const std::string* passStr =
+                                    passIt2->get_ptr<const std::string*>();
+                                if (userStr != nullptr && passStr != nullptr)
+                                {
+                                    username = *userStr;
+                                    password = *passStr;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            else
+            {
+                // check if auth was provided as a headers
+                username = req.getHeaderValue("username");
+                password = req.getHeaderValue("password");
+            }
+
+            if (!username.empty() && !password.empty())
+            {
+                if (!pamAuthenticateUser(username, password))
+                {
+                    res.result(boost::beast::http::status::unauthorized);
+                }
+                else
+                {
+                    auto session = persistent_data::SessionStore::getInstance()
+                                       .generateUserSession(username);
+
+                    if (looksLikeIbm)
+                    {
+                        // IBM requires a very specific login structure, and
+                        // doesn't actually look at the status code.
+                        // TODO(ed).... Fix that upstream
+                        res.jsonValue = {
+                            {"data",
+                             "User '" + std::string(username) + "' logged in"},
+                            {"message", "200 OK"},
+                            {"status", "ok"}};
+
+                        // Hack alert.  Boost beast by default doesn't let you
+                        // declare multiple headers of the same name, and in
+                        // most cases this is fine.  Unfortunately here we need
+                        // to set the Session cookie, which requires the
+                        // httpOnly attribute, as well as the XSRF cookie, which
+                        // requires it to not have an httpOnly attribute. To get
+                        // the behavior we want, we simply inject the second
+                        // "set-cookie" string into the value header, and get
+                        // the result we want, even though we are technicaly
+                        // declaring two headers here.
+                        res.addHeader("Set-Cookie",
+                                      "XSRF-TOKEN=" + session->csrfToken +
+                                          "; Secure\r\nSet-Cookie: SESSION=" +
+                                          session->sessionToken +
+                                          "; Secure; HttpOnly");
+                    }
+                    else
+                    {
+                        // if content type is json, assume json token
+                        res.jsonValue = {{"token", session->sessionToken}};
+                    }
+                }
+            }
+            else
+            {
+                res.result(boost::beast::http::status::bad_request);
+            }
+            res.end();
+        });
+
+    BMCWEB_ROUTE(app, "/logout")
+        .methods(
+            "POST"_method)([&](const crow::Request& req, crow::Response& res) {
+            auto& session =
+                app.template getContext<token_authorization::Middleware>(req)
+                    .session;
+            if (session != nullptr)
+            {
+                persistent_data::SessionStore::getInstance().removeSession(
+                    session);
+            }
             res.end();
             return;
-          }
-
-          // check for username/password in the root object
-          // THis method is how intel APIs authenticate
-          nlohmann::json::iterator userIt = loginCredentials.find("username");
-          nlohmann::json::iterator passIt = loginCredentials.find("password");
-          if (userIt != loginCredentials.end() &&
-              passIt != loginCredentials.end()) {
-            const std::string* userStr = userIt->get_ptr<const std::string*>();
-            const std::string* passStr = passIt->get_ptr<const std::string*>();
-            if (userStr != nullptr && passStr != nullptr) {
-              username = *userStr;
-              password = *passStr;
-            }
-          } else {
-            // Openbmc appears to push a data object that contains the same
-            // keys (username and password), attempt to use that
-            auto dataIt = loginCredentials.find("data");
-            if (dataIt != loginCredentials.end()) {
-              // Some apis produce an array of value ["username",
-              // "password"]
-              if (dataIt->is_array()) {
-                if (dataIt->size() == 2) {
-                  nlohmann::json::iterator userIt2 = dataIt->begin();
-                  nlohmann::json::iterator passIt2 = dataIt->begin() + 1;
-                  looksLikeIbm = true;
-                  if (userIt2 != dataIt->end() && passIt2 != dataIt->end()) {
-                    const std::string* userStr =
-                        userIt2->get_ptr<const std::string*>();
-                    const std::string* passStr =
-                        passIt2->get_ptr<const std::string*>();
-                    if (userStr != nullptr && passStr != nullptr) {
-                      username = *userStr;
-                      password = *passStr;
-                    }
-                  }
-                }
-
-              } else if (dataIt->is_object()) {
-                nlohmann::json::iterator userIt2 = dataIt->find("username");
-                nlohmann::json::iterator passIt2 = dataIt->find("password");
-                if (userIt2 != dataIt->end() && passIt2 != dataIt->end()) {
-                  const std::string* userStr =
-                      userIt2->get_ptr<const std::string*>();
-                  const std::string* passStr =
-                      passIt2->get_ptr<const std::string*>();
-                  if (userStr != nullptr && passStr != nullptr) {
-                    username = *userStr;
-                    password = *passStr;
-                  }
-                }
-              }
-            }
-          }
-        } else {
-          // check if auth was provided as a headers
-          username = req.getHeaderValue("username");
-          password = req.getHeaderValue("password");
-        }
-
-        if (!username.empty() && !password.empty()) {
-          if (!pamAuthenticateUser(username, password)) {
-            res.result(boost::beast::http::status::unauthorized);
-          } else {
-            auto session = persistent_data::SessionStore::getInstance()
-                               .generateUserSession(username);
-
-            if (looksLikeIbm) {
-              // IBM requires a very specific login structure, and doesn't
-              // actually look at the status code.  TODO(ed).... Fix that
-              // upstream
-              res.jsonValue = {
-                  {"data", "User '" + std::string(username) + "' logged in"},
-                  {"message", "200 OK"},
-                  {"status", "ok"}};
-
-              // Hack alert.  Boost beast by default doesn't let you declare
-              // multiple headers of the same name, and in most cases this is
-              // fine.  Unfortunately here we need to set the Session cookie,
-              // which requires the httpOnly attribute, as well as the XSRF
-              // cookie, which requires it to not have an httpOnly attribute.
-              // To get the behavior we want, we simply inject the second
-              // "set-cookie" string into the value header, and get the result
-              // we want, even though we are technicaly declaring two headers
-              // here.
-              res.addHeader("Set-Cookie",
-                            "XSRF-TOKEN=" + session->csrfToken +
-                                "; Secure\r\nSet-Cookie: SESSION=" +
-                                session->sessionToken + "; Secure; HttpOnly");
-            } else {
-              // if content type is json, assume json token
-              res.jsonValue = {{"token", session->sessionToken}};
-            }
-          }
-
-        } else {
-          res.result(boost::beast::http::status::bad_request);
-        }
-        res.end();
-      });
-
-  BMCWEB_ROUTE(app, "/logout")
-      .methods(
-          "POST"_method)([&](const crow::Request& req, crow::Response& res) {
-        auto& session =
-            app.template getContext<token_authorization::Middleware>(req)
-                .session;
-        if (session != nullptr) {
-          persistent_data::SessionStore::getInstance().removeSession(session);
-        }
-        res.end();
-        return;
-      });
+        });
 }
-}  // namespace token_authorization
-}  // namespace crow
+} // namespace token_authorization
+} // namespace crow
diff --git a/include/web_kvm.hpp b/include/web_kvm.hpp
index ad4b352..747a137 100644
--- a/include/web_kvm.hpp
+++ b/include/web_kvm.hpp
@@ -1,181 +1,202 @@
-#include <string>
 #include <crow/app.h>
-#include <boost/endian/arithmetic.hpp>
 
 #include <ast_jpeg_decoder.hpp>
 #include <ast_video_puller.hpp>
+#include <boost/endian/arithmetic.hpp>
+#include <string>
 
-namespace crow {
-namespace kvm {
+namespace crow
+{
+namespace kvm
+{
 
 static const std::string rfb33VersionString = "RFB 003.003\n";
 static const std::string rfb37VersionString = "RFB 003.007\n";
 static const std::string rfb38VersionString = "RFB 003.008\n";
 
-enum class RfbAuthScheme : uint8_t {
-  connection_failed = 0,
-  no_authentication = 1,
-  vnc_authentication = 2
+enum class RfbAuthScheme : uint8_t
+{
+    connection_failed = 0,
+    no_authentication = 1,
+    vnc_authentication = 2
 };
 
-struct PixelFormatStruct {
-  boost::endian::big_uint8_t bitsPerPixel;
-  boost::endian::big_uint8_t depth;
-  boost::endian::big_uint8_t isBigEndian;
-  boost::endian::big_uint8_t isTrueColor;
-  boost::endian::big_uint16_t redMax;
-  boost::endian::big_uint16_t greenMax;
-  boost::endian::big_uint16_t blueMax;
-  boost::endian::big_uint8_t redShift;
-  boost::endian::big_uint8_t greenShift;
-  boost::endian::big_uint8_t blueShift;
-  boost::endian::big_uint8_t pad1;
-  boost::endian::big_uint8_t pad2;
-  boost::endian::big_uint8_t pad3;
+struct PixelFormatStruct
+{
+    boost::endian::big_uint8_t bitsPerPixel;
+    boost::endian::big_uint8_t depth;
+    boost::endian::big_uint8_t isBigEndian;
+    boost::endian::big_uint8_t isTrueColor;
+    boost::endian::big_uint16_t redMax;
+    boost::endian::big_uint16_t greenMax;
+    boost::endian::big_uint16_t blueMax;
+    boost::endian::big_uint8_t redShift;
+    boost::endian::big_uint8_t greenShift;
+    boost::endian::big_uint8_t blueShift;
+    boost::endian::big_uint8_t pad1;
+    boost::endian::big_uint8_t pad2;
+    boost::endian::big_uint8_t pad3;
 };
 
-struct ServerInitializationMsg {
-  boost::endian::big_uint16_t framebufferWidth;
-  boost::endian::big_uint16_t framebufferHeight;
-  PixelFormatStruct pixelFormat;
-  boost::endian::big_uint32_t nameLength;
+struct ServerInitializationMsg
+{
+    boost::endian::big_uint16_t framebufferWidth;
+    boost::endian::big_uint16_t framebufferHeight;
+    PixelFormatStruct pixelFormat;
+    boost::endian::big_uint32_t nameLength;
 };
 
-enum class client_to_server_msg_type : uint8_t {
-  set_pixel_format = 0,
-  fix_color_map_entries = 1,
-  set_encodings = 2,
-  framebuffer_update_request = 3,
-  key_event = 4,
-  pointer_event = 5,
-  client_cut_text = 6
+enum class client_to_server_msg_type : uint8_t
+{
+    set_pixel_format = 0,
+    fix_color_map_entries = 1,
+    set_encodings = 2,
+    framebuffer_update_request = 3,
+    key_event = 4,
+    pointer_event = 5,
+    client_cut_text = 6
 };
 
-enum class server_to_client_message_type : uint8_t {
-  framebuffer_update = 0,
-  set_color_map_entries = 1,
-  bell_message = 2,
-  server_cut_text = 3
+enum class server_to_client_message_type : uint8_t
+{
+    framebuffer_update = 0,
+    set_color_map_entries = 1,
+    bell_message = 2,
+    server_cut_text = 3
 };
 
-struct SetPixelFormatMsg {
-  boost::endian::big_uint8_t pad1;
-  boost::endian::big_uint8_t pad2;
-  boost::endian::big_uint8_t pad3;
-  PixelFormatStruct pixelFormat;
+struct SetPixelFormatMsg
+{
+    boost::endian::big_uint8_t pad1;
+    boost::endian::big_uint8_t pad2;
+    boost::endian::big_uint8_t pad3;
+    PixelFormatStruct pixelFormat;
 };
 
-struct FrameBufferUpdateReq {
-  boost::endian::big_uint8_t incremental;
-  boost::endian::big_uint16_t xPosition;
-  boost::endian::big_uint16_t yPosition;
-  boost::endian::big_uint16_t width;
-  boost::endian::big_uint16_t height;
+struct FrameBufferUpdateReq
+{
+    boost::endian::big_uint8_t incremental;
+    boost::endian::big_uint16_t xPosition;
+    boost::endian::big_uint16_t yPosition;
+    boost::endian::big_uint16_t width;
+    boost::endian::big_uint16_t height;
 };
 
-struct KeyEventMsg {
-  boost::endian::big_uint8_t downFlag;
-  boost::endian::big_uint8_t pad1;
-  boost::endian::big_uint8_t pad2;
-  boost::endian::big_uint32_t key;
+struct KeyEventMsg
+{
+    boost::endian::big_uint8_t downFlag;
+    boost::endian::big_uint8_t pad1;
+    boost::endian::big_uint8_t pad2;
+    boost::endian::big_uint32_t key;
 };
 
-struct PointerEventMsg {
-  boost::endian::big_uint8_t buttonMask;
-  boost::endian::big_uint16_t xPosition;
-  boost::endian::big_uint16_t yPosition;
+struct PointerEventMsg
+{
+    boost::endian::big_uint8_t buttonMask;
+    boost::endian::big_uint16_t xPosition;
+    boost::endian::big_uint16_t yPosition;
 };
 
-struct ClientCutTextMsg {
-  std::vector<uint8_t> data;
+struct ClientCutTextMsg
+{
+    std::vector<uint8_t> data;
 };
 
-enum class encoding_type : uint32_t {
-  raw = 0x00,
-  copy_rectangle = 0x01,
-  rising_rectangle = 0x02,
-  corre = 0x04,
-  hextile = 0x05,
-  zlib = 0x06,
-  tight = 0x07,
-  zlibhex = 0x08,
-  ultra = 0x09,
-  zrle = 0x10,
-  zywrle = 0x011,
-  cache_enable = 0xFFFF0001,
-  xor_enable = 0xFFFF0006,
-  server_state_ultranvc = 0xFFFF8000,
-  enable_keepAlive = 0xFFFF8001,
-  enableftp_protocol_version = 0xFFFF8002,
-  tight_compress_level_0 = 0xFFFFFF00,
-  tight_compress_level_9 = 0xFFFFFF09,
-  x_cursor = 0xFFFFFF10,
-  rich_cursor = 0xFFFFFF11,
-  pointer_pos = 0xFFFFFF18,
-  last_rect = 0xFFFFFF20,
-  new_framebuffer_size = 0xFFFFFF21,
-  tight_quality_level_0 = 0xFFFFFFE0,
-  tight_quality_level_9 = 0xFFFFFFE9
+enum class encoding_type : uint32_t
+{
+    raw = 0x00,
+    copy_rectangle = 0x01,
+    rising_rectangle = 0x02,
+    corre = 0x04,
+    hextile = 0x05,
+    zlib = 0x06,
+    tight = 0x07,
+    zlibhex = 0x08,
+    ultra = 0x09,
+    zrle = 0x10,
+    zywrle = 0x011,
+    cache_enable = 0xFFFF0001,
+    xor_enable = 0xFFFF0006,
+    server_state_ultranvc = 0xFFFF8000,
+    enable_keepAlive = 0xFFFF8001,
+    enableftp_protocol_version = 0xFFFF8002,
+    tight_compress_level_0 = 0xFFFFFF00,
+    tight_compress_level_9 = 0xFFFFFF09,
+    x_cursor = 0xFFFFFF10,
+    rich_cursor = 0xFFFFFF11,
+    pointer_pos = 0xFFFFFF18,
+    last_rect = 0xFFFFFF20,
+    new_framebuffer_size = 0xFFFFFF21,
+    tight_quality_level_0 = 0xFFFFFFE0,
+    tight_quality_level_9 = 0xFFFFFFE9
 };
 
-struct FramebufferRectangle {
-  boost::endian::big_uint16_t x{};
-  boost::endian::big_uint16_t y{};
-  boost::endian::big_uint16_t width{};
-  boost::endian::big_uint16_t height{};
-  boost::endian::big_uint32_t encoding{};
-  std::vector<uint8_t> data;
+struct FramebufferRectangle
+{
+    boost::endian::big_uint16_t x{};
+    boost::endian::big_uint16_t y{};
+    boost::endian::big_uint16_t width{};
+    boost::endian::big_uint16_t height{};
+    boost::endian::big_uint32_t encoding{};
+    std::vector<uint8_t> data;
 };
 
-struct FramebufferUpdateMsg {
-  boost::endian::big_uint8_t messageType{};
-  std::vector<FramebufferRectangle> rectangles;
+struct FramebufferUpdateMsg
+{
+    boost::endian::big_uint8_t messageType{};
+    std::vector<FramebufferRectangle> rectangles;
 };
 
-inline std::string serialize(const FramebufferUpdateMsg& msg) {
-  // calculate the size of the needed vector for serialization
-  size_t vectorSize = 4;
-  for (const auto& rect : msg.rectangles) {
-    vectorSize += 12 + rect.data.size();
-  }
+inline std::string serialize(const FramebufferUpdateMsg& msg)
+{
+    // calculate the size of the needed vector for serialization
+    size_t vectorSize = 4;
+    for (const auto& rect : msg.rectangles)
+    {
+        vectorSize += 12 + rect.data.size();
+    }
 
-  std::string serialized(vectorSize, 0);
+    std::string serialized(vectorSize, 0);
 
-  size_t i = 0;
-  serialized[i++] = static_cast<char>(
-      server_to_client_message_type::framebuffer_update);  // Type
-  serialized[i++] = 0;                                     // Pad byte
-  boost::endian::big_uint16_t numberOfRectangles = msg.rectangles.size();
-  std::memcpy(&serialized[i], &numberOfRectangles, sizeof(numberOfRectangles));
-  i += sizeof(numberOfRectangles);
+    size_t i = 0;
+    serialized[i++] = static_cast<char>(
+        server_to_client_message_type::framebuffer_update); // Type
+    serialized[i++] = 0;                                    // Pad byte
+    boost::endian::big_uint16_t numberOfRectangles = msg.rectangles.size();
+    std::memcpy(&serialized[i], &numberOfRectangles,
+                sizeof(numberOfRectangles));
+    i += sizeof(numberOfRectangles);
 
-  for (const auto& rect : msg.rectangles) {
-    // copy the first part of the struct
-    size_t bufferSize =
-        sizeof(FramebufferRectangle) - sizeof(std::vector<uint8_t>);
-    std::memcpy(&serialized[i], &rect, bufferSize);
-    i += bufferSize;
+    for (const auto& rect : msg.rectangles)
+    {
+        // copy the first part of the struct
+        size_t bufferSize =
+            sizeof(FramebufferRectangle) - sizeof(std::vector<uint8_t>);
+        std::memcpy(&serialized[i], &rect, bufferSize);
+        i += bufferSize;
 
-    std::memcpy(&serialized[i], rect.data.data(), rect.data.size());
-    i += rect.data.size();
-  }
+        std::memcpy(&serialized[i], rect.data.data(), rect.data.size());
+        i += rect.data.size();
+    }
 
-  return serialized;
+    return serialized;
 }
 
-enum class VncState {
-  UNSTARTED,
-  AWAITING_CLIENT_VERSION,
-  AWAITING_CLIENT_AUTH_METHOD,
-  AWAITING_CLIENT_INIT_msg,
-  MAIN_LOOP
+enum class VncState
+{
+    UNSTARTED,
+    AWAITING_CLIENT_VERSION,
+    AWAITING_CLIENT_AUTH_METHOD,
+    AWAITING_CLIENT_INIT_msg,
+    MAIN_LOOP
 };
 
-class ConnectionMetadata {
- public:
-  ConnectionMetadata(){};
+class ConnectionMetadata
+{
+  public:
+    ConnectionMetadata(){};
 
-  VncState vncState{VncState::UNSTARTED};
+    VncState vncState{VncState::UNSTARTED};
 };
 
 using meta_list = std::vector<ConnectionMetadata>;
@@ -183,171 +204,219 @@
 
 ConnectionMetadata meta;
 
-template <typename... Middlewares>
-void requestRoutes(Crow<Middlewares...>& app) {
-  BMCWEB_ROUTE(app, "/kvmws")
-      .websocket()
-      .onopen([&](crow::websocket::Connection& conn) {
-        if (meta.vncState == VncState::UNSTARTED) {
-          meta.vncState = VncState::AWAITING_CLIENT_VERSION;
-          conn.sendBinary(rfb38VersionString);
-        } else {  // SHould never happen
-          conn.close();
-        }
-
-      })
-      .onclose(
-          [&](crow::websocket::Connection& conn, const std::string& reason) {
-            meta.vncState = VncState::UNSTARTED;
-          })
-      .onmessage([&](crow::websocket::Connection& conn, const std::string& data,
-                     bool is_binary) {
-        switch (meta.vncState) {
-          case VncState::AWAITING_CLIENT_VERSION: {
-            std::cout << "Client sent: " << data;
-            if (data == rfb38VersionString || data == rfb37VersionString) {
-              std::string authTypes{1,
-                                    (uint8_t)RfbAuthScheme::no_authentication};
-              conn.sendBinary(authTypes);
-              meta.vncState = VncState::AWAITING_CLIENT_AUTH_METHOD;
-            } else if (data == rfb33VersionString) {
-              // TODO(ed)  Support older protocols
-              meta.vncState = VncState::UNSTARTED;
-              conn.close();
-            } else {
-              // TODO(ed)  Support older protocols
-              meta.vncState = VncState::UNSTARTED;
-              conn.close();
+template <typename... Middlewares> void requestRoutes(Crow<Middlewares...>& app)
+{
+    BMCWEB_ROUTE(app, "/kvmws")
+        .websocket()
+        .onopen([&](crow::websocket::Connection& conn) {
+            if (meta.vncState == VncState::UNSTARTED)
+            {
+                meta.vncState = VncState::AWAITING_CLIENT_VERSION;
+                conn.sendBinary(rfb38VersionString);
             }
-          } break;
-          case VncState::AWAITING_CLIENT_AUTH_METHOD: {
-            std::string securityResult{{0, 0, 0, 0}};
-            if (data[0] == (uint8_t)RfbAuthScheme::no_authentication) {
-              meta.vncState = VncState::AWAITING_CLIENT_INIT_msg;
-            } else {
-              // Mark auth as failed
-              securityResult[3] = 1;
-              meta.vncState = VncState::UNSTARTED;
+            else
+            { // SHould never happen
+                conn.close();
             }
-            conn.sendBinary(securityResult);
-          } break;
-          case VncState::AWAITING_CLIENT_INIT_msg: {
-            // Now send the server initialization
-            ServerInitializationMsg serverInitMsg{};
-            serverInitMsg.framebufferWidth = 800;
-            serverInitMsg.framebufferHeight = 600;
-            serverInitMsg.pixelFormat.bitsPerPixel = 32;
-            serverInitMsg.pixelFormat.isBigEndian = 0;
-            serverInitMsg.pixelFormat.isTrueColor = 1;
-            serverInitMsg.pixelFormat.redMax = 255;
-            serverInitMsg.pixelFormat.greenMax = 255;
-            serverInitMsg.pixelFormat.blueMax = 255;
-            serverInitMsg.pixelFormat.redShift = 16;
-            serverInitMsg.pixelFormat.greenShift = 8;
-            serverInitMsg.pixelFormat.blueShift = 0;
-            serverInitMsg.nameLength = 0;
-            std::cout << "size: " << sizeof(serverInitMsg);
-            // TODO(ed) this is ugly.  Crow should really have a span type
-            // interface
-            // to avoid the copy, but alas, today it does not.
-            std::string s(reinterpret_cast<char*>(&serverInitMsg),
-                          sizeof(serverInitMsg));
-            std::cout << "s.size() " << s.size();
-            conn.sendBinary(s);
-            meta.vncState = VncState::MAIN_LOOP;
-          } break;
-          case VncState::MAIN_LOOP: {
-            if (data.size() >= sizeof(client_to_server_msg_type)) {
-              auto type = static_cast<client_to_server_msg_type>(data[0]);
-              std::cout << "Received client message type "
-                        << static_cast<std::size_t>(type) << "\n";
-              switch (type) {
-                case client_to_server_msg_type::set_pixel_format: {
-                } break;
-
-                case client_to_server_msg_type::fix_color_map_entries: {
-                } break;
-                case client_to_server_msg_type::set_encodings: {
-                } break;
-                case client_to_server_msg_type::framebuffer_update_request: {
-                  // Make sure the buffer is long enough to handle what we're
-                  // about to do
-                  if (data.size() >= sizeof(FrameBufferUpdateReq) +
-                                         sizeof(client_to_server_msg_type)) {
-                    auto msg = reinterpret_cast<const FrameBufferUpdateReq*>(
-                        data.data() +  // NOLINT
-                        sizeof(client_to_server_msg_type));
-                    // TODO(ed) find a better way to do this deserialization
-
-                    // Todo(ed) lifecycle of the video puller and decoder
-                    // should be
-                    // with the websocket, not recreated every time
-                    ast_video::SimpleVideoPuller p;
-                    p.initialize();
-                    auto out = p.readVideo();
-                    ast_video::AstJpegDecoder d;
-                    d.decode(out.buffer, out.width, out.height, out.mode,
-                             out.ySelector, out.uvSelector);
-
-                    FramebufferUpdateMsg bufferUpdateMsg;
-
-                    // If the viewer is requesting a full update, force write
-                    // of all pixels
-
-                    FramebufferRectangle thisRect;
-                    thisRect.x = msg->xPosition;
-                    thisRect.y = msg->yPosition;
-                    thisRect.width = out.width;
-                    thisRect.height = out.height;
-                    thisRect.encoding =
-                        static_cast<uint8_t>(encoding_type::raw);
-                    std::cout << "Encoding is " << thisRect.encoding;
-                    thisRect.data.reserve(
-                        static_cast<std::size_t>(thisRect.width) *
-                        static_cast<std::size_t>(thisRect.height) * 4);
-                    std::cout << "Width " << out.width << " Height "
-                              << out.height;
-
-                    for (int i = 0; i < out.width * out.height; i++) {
-                      auto& pixel = d.outBuffer[i];
-                      thisRect.data.push_back(pixel.b);
-                      thisRect.data.push_back(pixel.g);
-                      thisRect.data.push_back(pixel.r);
-                      thisRect.data.push_back(0);
+        })
+        .onclose(
+            [&](crow::websocket::Connection& conn, const std::string& reason) {
+                meta.vncState = VncState::UNSTARTED;
+            })
+        .onmessage([&](crow::websocket::Connection& conn,
+                       const std::string& data, bool is_binary) {
+            switch (meta.vncState)
+            {
+                case VncState::AWAITING_CLIENT_VERSION:
+                {
+                    std::cout << "Client sent: " << data;
+                    if (data == rfb38VersionString ||
+                        data == rfb37VersionString)
+                    {
+                        std::string authTypes{
+                            1, (uint8_t)RfbAuthScheme::no_authentication};
+                        conn.sendBinary(authTypes);
+                        meta.vncState = VncState::AWAITING_CLIENT_AUTH_METHOD;
                     }
-
-                    bufferUpdateMsg.rectangles.push_back(std::move(thisRect));
-                    auto serialized = serialize(bufferUpdateMsg);
-
-                    conn.sendBinary(serialized);
-
-                  }  // TODO(Ed) handle error
-
+                    else if (data == rfb33VersionString)
+                    {
+                        // TODO(ed)  Support older protocols
+                        meta.vncState = VncState::UNSTARTED;
+                        conn.close();
+                    }
+                    else
+                    {
+                        // TODO(ed)  Support older protocols
+                        meta.vncState = VncState::UNSTARTED;
+                        conn.close();
+                    }
                 }
-
                 break;
+                case VncState::AWAITING_CLIENT_AUTH_METHOD:
+                {
+                    std::string securityResult{{0, 0, 0, 0}};
+                    if (data[0] == (uint8_t)RfbAuthScheme::no_authentication)
+                    {
+                        meta.vncState = VncState::AWAITING_CLIENT_INIT_msg;
+                    }
+                    else
+                    {
+                        // Mark auth as failed
+                        securityResult[3] = 1;
+                        meta.vncState = VncState::UNSTARTED;
+                    }
+                    conn.sendBinary(securityResult);
+                }
+                break;
+                case VncState::AWAITING_CLIENT_INIT_msg:
+                {
+                    // Now send the server initialization
+                    ServerInitializationMsg serverInitMsg{};
+                    serverInitMsg.framebufferWidth = 800;
+                    serverInitMsg.framebufferHeight = 600;
+                    serverInitMsg.pixelFormat.bitsPerPixel = 32;
+                    serverInitMsg.pixelFormat.isBigEndian = 0;
+                    serverInitMsg.pixelFormat.isTrueColor = 1;
+                    serverInitMsg.pixelFormat.redMax = 255;
+                    serverInitMsg.pixelFormat.greenMax = 255;
+                    serverInitMsg.pixelFormat.blueMax = 255;
+                    serverInitMsg.pixelFormat.redShift = 16;
+                    serverInitMsg.pixelFormat.greenShift = 8;
+                    serverInitMsg.pixelFormat.blueShift = 0;
+                    serverInitMsg.nameLength = 0;
+                    std::cout << "size: " << sizeof(serverInitMsg);
+                    // TODO(ed) this is ugly.  Crow should really have a span
+                    // type interface to avoid the copy, but alas, today it does
+                    // not.
+                    std::string s(reinterpret_cast<char*>(&serverInitMsg),
+                                  sizeof(serverInitMsg));
+                    std::cout << "s.size() " << s.size();
+                    conn.sendBinary(s);
+                    meta.vncState = VncState::MAIN_LOOP;
+                }
+                break;
+                case VncState::MAIN_LOOP:
+                {
+                    if (data.size() >= sizeof(client_to_server_msg_type))
+                    {
+                        auto type =
+                            static_cast<client_to_server_msg_type>(data[0]);
+                        std::cout << "Received client message type "
+                                  << static_cast<std::size_t>(type) << "\n";
+                        switch (type)
+                        {
+                            case client_to_server_msg_type::set_pixel_format:
+                            {
+                            }
+                            break;
 
-                case client_to_server_msg_type::key_event: {
-                } break;
+                            case client_to_server_msg_type::
+                                fix_color_map_entries:
+                            {
+                            }
+                            break;
+                            case client_to_server_msg_type::set_encodings:
+                            {
+                            }
+                            break;
+                            case client_to_server_msg_type::
+                                framebuffer_update_request:
+                            {
+                                // Make sure the buffer is long enough to handle
+                                // what we're about to do
+                                if (data.size() >=
+                                    sizeof(FrameBufferUpdateReq) +
+                                        sizeof(client_to_server_msg_type))
+                                {
+                                    auto msg = reinterpret_cast<
+                                        const FrameBufferUpdateReq*>(
+                                        data.data() + // NOLINT
+                                        sizeof(client_to_server_msg_type));
+                                    // TODO(ed) find a better way to do this
+                                    // deserialization
 
-                case client_to_server_msg_type::pointer_event: {
-                } break;
+                                    // Todo(ed) lifecycle of the video puller
+                                    // and decoder should be with the websocket,
+                                    // not recreated every time
+                                    ast_video::SimpleVideoPuller p;
+                                    p.initialize();
+                                    auto out = p.readVideo();
+                                    ast_video::AstJpegDecoder d;
+                                    d.decode(out.buffer, out.width, out.height,
+                                             out.mode, out.ySelector,
+                                             out.uvSelector);
 
-                case client_to_server_msg_type::client_cut_text: {
-                } break;
+                                    FramebufferUpdateMsg bufferUpdateMsg;
 
-                default:
-                  break;
-              }
+                                    // If the viewer is requesting a full
+                                    // update, force write of all pixels
+
+                                    FramebufferRectangle thisRect;
+                                    thisRect.x = msg->xPosition;
+                                    thisRect.y = msg->yPosition;
+                                    thisRect.width = out.width;
+                                    thisRect.height = out.height;
+                                    thisRect.encoding = static_cast<uint8_t>(
+                                        encoding_type::raw);
+                                    std::cout << "Encoding is "
+                                              << thisRect.encoding;
+                                    thisRect.data.reserve(
+                                        static_cast<std::size_t>(
+                                            thisRect.width) *
+                                        static_cast<std::size_t>(
+                                            thisRect.height) *
+                                        4);
+                                    std::cout << "Width " << out.width
+                                              << " Height " << out.height;
+
+                                    for (int i = 0; i < out.width * out.height;
+                                         i++)
+                                    {
+                                        auto& pixel = d.outBuffer[i];
+                                        thisRect.data.push_back(pixel.b);
+                                        thisRect.data.push_back(pixel.g);
+                                        thisRect.data.push_back(pixel.r);
+                                        thisRect.data.push_back(0);
+                                    }
+
+                                    bufferUpdateMsg.rectangles.push_back(
+                                        std::move(thisRect));
+                                    auto serialized =
+                                        serialize(bufferUpdateMsg);
+
+                                    conn.sendBinary(serialized);
+
+                                } // TODO(Ed) handle error
+                            }
+
+                            break;
+
+                            case client_to_server_msg_type::key_event:
+                            {
+                            }
+                            break;
+
+                            case client_to_server_msg_type::pointer_event:
+                            {
+                            }
+                            break;
+
+                            case client_to_server_msg_type::client_cut_text:
+                            {
+                            }
+                            break;
+
+                            default:
+                                break;
+                        }
+                    }
+                }
+                break;
+                case VncState::UNSTARTED:
+                    // Error?  TODO
+                    break;
             }
-
-          } break;
-          case VncState::UNSTARTED:
-            // Error?  TODO
-            break;
-        }
-
-      });
+        });
 }
-}  // namespace kvm
-}  // namespace crow
\ No newline at end of file
+} // namespace kvm
+} // namespace crow
\ No newline at end of file
diff --git a/include/webassets.hpp b/include/webassets.hpp
index 5eabffe..7f1c1f5 100644
--- a/include/webassets.hpp
+++ b/include/webassets.hpp
@@ -1,137 +1,161 @@
 #pragma once
 
-#include <experimental/filesystem>
-#include <fstream>
-#include <string>
 #include <crow/app.h>
 #include <crow/http_request.h>
 #include <crow/http_response.h>
 #include <crow/routing.h>
+
 #include <boost/algorithm/string/replace.hpp>
 #include <boost/container/flat_set.hpp>
+#include <experimental/filesystem>
+#include <fstream>
+#include <string>
 
-namespace crow {
-namespace webassets {
+namespace crow
+{
+namespace webassets
+{
 
 namespace filesystem = std::experimental::filesystem;
 
-struct CmpStr {
-  bool operator()(const char* a, const char* b) const {
-    return std::strcmp(a, b) < 0;
-  }
+struct CmpStr
+{
+    bool operator()(const char* a, const char* b) const
+    {
+        return std::strcmp(a, b) < 0;
+    }
 };
 
 static boost::container::flat_set<std::string> routes;
 
-template <typename... Middlewares>
-void requestRoutes(Crow<Middlewares...>& app) {
-  const static boost::container::flat_map<const char*, const char*, CmpStr>
-      contentTypes{
-          {{".css", "text/css;charset=UTF-8"},
-           {".html", "text/html;charset=UTF-8"},
-           {".js", "text/html;charset=UTF-8"},
-           {".png", "image/png;charset=UTF-8"},
-           {".woff", "application/x-font-woff"},
-           {".woff2", "application/x-font-woff2"},
-           {".gif", "image/gif"},
-           {".ico", "image/x-icon"},
-           {".ttf", "application/x-font-ttf"},
-           {".svg", "image/svg+xml"},
-           {".eot", "application/vnd.ms-fontobject"},
-           {".xml", "application/xml"},
-           {".jpg", "image/jpeg"},
-           {".jpeg", "image/jpeg"},
-           {".json", "application/json"},
-           // dev tools don't care about map type, setting to json causes
-           // browser to show as text
-           // https://stackoverflow.com/questions/19911929/what-mime-type-should-i-use-for-javascript-source-map-files
-           {".map", "application/json"}}};
-  filesystem::path rootpath{"/usr/share/www/"};
-  filesystem::recursive_directory_iterator dirIter(rootpath);
-  // In certain cases, we might have both a gzipped version of the file AND a
-  // non-gzipped version.  To avoid duplicated routes, we need to make sure we
-  // get the gzipped version first.  Because the gzipped path should be longer
-  // than the non gzipped path, if we sort in Ascending order, we should be
-  // guaranteed to get the gzip version first.
-  std::vector<filesystem::directory_entry> paths(filesystem::begin(dirIter),
-                                                 filesystem::end(dirIter));
-  std::sort(paths.rbegin(), paths.rend());
+template <typename... Middlewares> void requestRoutes(Crow<Middlewares...>& app)
+{
+    const static boost::container::flat_map<const char*, const char*, CmpStr>
+        contentTypes{
+            {{".css", "text/css;charset=UTF-8"},
+             {".html", "text/html;charset=UTF-8"},
+             {".js", "text/html;charset=UTF-8"},
+             {".png", "image/png;charset=UTF-8"},
+             {".woff", "application/x-font-woff"},
+             {".woff2", "application/x-font-woff2"},
+             {".gif", "image/gif"},
+             {".ico", "image/x-icon"},
+             {".ttf", "application/x-font-ttf"},
+             {".svg", "image/svg+xml"},
+             {".eot", "application/vnd.ms-fontobject"},
+             {".xml", "application/xml"},
+             {".jpg", "image/jpeg"},
+             {".jpeg", "image/jpeg"},
+             {".json", "application/json"},
+             // dev tools don't care about map type, setting to json causes
+             // browser to show as text
+             // https://stackoverflow.com/questions/19911929/what-mime-type-should-i-use-for-javascript-source-map-files
+             {".map", "application/json"}}};
+    filesystem::path rootpath{"/usr/share/www/"};
+    filesystem::recursive_directory_iterator dirIter(rootpath);
+    // In certain cases, we might have both a gzipped version of the file AND a
+    // non-gzipped version.  To avoid duplicated routes, we need to make sure we
+    // get the gzipped version first.  Because the gzipped path should be longer
+    // than the non gzipped path, if we sort in Ascending order, we should be
+    // guaranteed to get the gzip version first.
+    std::vector<filesystem::directory_entry> paths(filesystem::begin(dirIter),
+                                                   filesystem::end(dirIter));
+    std::sort(paths.rbegin(), paths.rend());
 
-  for (const filesystem::directory_entry& dir : paths) {
-    filesystem::path absolutePath = dir.path();
-    filesystem::path relativePath{
-        absolutePath.string().substr(rootpath.string().size() - 1)};
-    if (filesystem::is_directory(dir)) {
-      // don't recurse into hidden directories or symlinks
-      if (boost::starts_with(dir.path().filename().string(), ".") ||
-          filesystem::is_symlink(dir)) {
-        dirIter.disable_recursion_pending();
-      }
-    } else if (filesystem::is_regular_file(dir)) {
-      std::string extension = relativePath.extension();
-      filesystem::path webpath = relativePath;
-      const char* contentEncoding = nullptr;
-
-      if (extension == ".gz") {
-        webpath = webpath.replace_extension("");
-        // Use the non-gzip version for determining content type
-        extension = webpath.extension().string();
-        contentEncoding = "gzip";
-      }
-
-      if (boost::starts_with(webpath.filename().string(), "index.")) {
-        webpath = webpath.parent_path();
-        if (webpath.string().size() == 0 || webpath.string().back() != '/') {
-          // insert the non-directory version of this path
-          routes.insert(webpath);
-          webpath += "/";
+    for (const filesystem::directory_entry& dir : paths)
+    {
+        filesystem::path absolutePath = dir.path();
+        filesystem::path relativePath{
+            absolutePath.string().substr(rootpath.string().size() - 1)};
+        if (filesystem::is_directory(dir))
+        {
+            // don't recurse into hidden directories or symlinks
+            if (boost::starts_with(dir.path().filename().string(), ".") ||
+                filesystem::is_symlink(dir))
+            {
+                dirIter.disable_recursion_pending();
+            }
         }
-      }
+        else if (filesystem::is_regular_file(dir))
+        {
+            std::string extension = relativePath.extension();
+            filesystem::path webpath = relativePath;
+            const char* contentEncoding = nullptr;
 
-      std::pair<boost::container::flat_set<std::string>::iterator, bool>
-          inserted = routes.insert(webpath);
-
-      if (!inserted.second) {
-        // Got a duplicated path.  This is expected in certain situations
-        BMCWEB_LOG_DEBUG << "Got duplicated path " << webpath;
-        continue;
-      }
-      const char* contentType = nullptr;
-
-      auto contentTypeIt = contentTypes.find(extension.c_str());
-      if (contentTypeIt == contentTypes.end()) {
-        BMCWEB_LOG_ERROR << "Cannot determine content-type for " << absolutePath
-                         << " with extension " << extension;
-      } else {
-        contentType = contentTypeIt->second;
-      }
-
-      app.routeDynamic(webpath)(
-          [absolutePath, contentType, contentEncoding](const crow::Request& req,
-                                                       crow::Response& res) {
-            if (contentType != nullptr) {
-              res.addHeader("Content-Type", contentType);
+            if (extension == ".gz")
+            {
+                webpath = webpath.replace_extension("");
+                // Use the non-gzip version for determining content type
+                extension = webpath.extension().string();
+                contentEncoding = "gzip";
             }
 
-            if (contentEncoding != nullptr) {
-              res.addHeader("Content-Encoding", contentEncoding);
+            if (boost::starts_with(webpath.filename().string(), "index."))
+            {
+                webpath = webpath.parent_path();
+                if (webpath.string().size() == 0 ||
+                    webpath.string().back() != '/')
+                {
+                    // insert the non-directory version of this path
+                    routes.insert(webpath);
+                    webpath += "/";
+                }
             }
 
-            // res.set_header("Cache-Control", "public, max-age=86400");
-            std::ifstream inf(absolutePath);
-            if (!inf) {
-              BMCWEB_LOG_DEBUG << "failed to read file";
-              res.result(boost::beast::http::status::internal_server_error);
-              res.end();
-              return;
+            std::pair<boost::container::flat_set<std::string>::iterator, bool>
+                inserted = routes.insert(webpath);
+
+            if (!inserted.second)
+            {
+                // Got a duplicated path.  This is expected in certain
+                // situations
+                BMCWEB_LOG_DEBUG << "Got duplicated path " << webpath;
+                continue;
+            }
+            const char* contentType = nullptr;
+
+            auto contentTypeIt = contentTypes.find(extension.c_str());
+            if (contentTypeIt == contentTypes.end())
+            {
+                BMCWEB_LOG_ERROR << "Cannot determine content-type for "
+                                 << absolutePath << " with extension "
+                                 << extension;
+            }
+            else
+            {
+                contentType = contentTypeIt->second;
             }
 
-            res.body() = {std::istreambuf_iterator<char>(inf),
-                          std::istreambuf_iterator<char>()};
-            res.end();
-          });
+            app.routeDynamic(webpath)(
+                [absolutePath, contentType, contentEncoding](
+                    const crow::Request& req, crow::Response& res) {
+                    if (contentType != nullptr)
+                    {
+                        res.addHeader("Content-Type", contentType);
+                    }
+
+                    if (contentEncoding != nullptr)
+                    {
+                        res.addHeader("Content-Encoding", contentEncoding);
+                    }
+
+                    // res.set_header("Cache-Control", "public, max-age=86400");
+                    std::ifstream inf(absolutePath);
+                    if (!inf)
+                    {
+                        BMCWEB_LOG_DEBUG << "failed to read file";
+                        res.result(
+                            boost::beast::http::status::internal_server_error);
+                        res.end();
+                        return;
+                    }
+
+                    res.body() = {std::istreambuf_iterator<char>(inf),
+                                  std::istreambuf_iterator<char>()};
+                    res.end();
+                });
+        }
     }
-  }
-}  // namespace webassets
-}  // namespace webassets
-}  // namespace crow
+} // namespace webassets
+} // namespace webassets
+} // namespace crow
diff --git a/redfish-core/include/error_messages.hpp b/redfish-core/include/error_messages.hpp
index 4865516..085b76f 100644
--- a/redfish-core/include/error_messages.hpp
+++ b/redfish-core/include/error_messages.hpp
@@ -24,9 +24,11 @@
 #pragma once
 #include <nlohmann/json.hpp>
 
-namespace redfish {
+namespace redfish
+{
 
-namespace messages {
+namespace messages
+{
 
 constexpr const char* messageVersionPrefix = "Base.1.2.0.";
 constexpr const char* messageAnnotation = "@Message.ExtendedInfo";
@@ -636,6 +638,6 @@
  * AUTOGENERATED FUNCTIONS END *
  *********************************/
 
-}  // namespace messages
+} // namespace messages
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/include/node.hpp b/redfish-core/include/node.hpp
index 20d2951..8dbb0c2 100644
--- a/redfish-core/include/node.hpp
+++ b/redfish-core/include/node.hpp
@@ -18,161 +18,190 @@
 #include "privileges.hpp"
 #include "token_authorization_middleware.hpp"
 #include "webserver_common.hpp"
+
 #include "crow.h"
 
-namespace redfish {
+namespace redfish
+{
 
 /**
  * AsyncResp
  * Gathers data needed for response processing after async calls are done
  */
-class AsyncResp {
- public:
-  AsyncResp(crow::Response& response) : res(response) {}
+class AsyncResp
+{
+  public:
+    AsyncResp(crow::Response& response) : res(response)
+    {
+    }
 
-  ~AsyncResp() { res.end(); }
+    ~AsyncResp()
+    {
+        res.end();
+    }
 
-  crow::Response& res;
+    crow::Response& res;
 };
 
 /**
  * @brief  Abstract class used for implementing Redfish nodes.
  *
  */
-class Node {
- public:
-  template <typename... Params>
-  Node(CrowApp& app, std::string&& entityUrl, Params... params) {
-    app.routeDynamic(entityUrl.c_str())
-        .methods("GET"_method, "PATCH"_method, "POST"_method,
-                 "DELETE"_method)([&](const crow::Request& req,
-                                      crow::Response& res, Params... params) {
-          std::vector<std::string> paramVec = {params...};
-          dispatchRequest(app, req, res, paramVec);
-        });
-  }
-
-  virtual ~Node() = default;
-
-  const std::string* getUrl() const {
-    auto odataId = json.find("@odata.id");
-    if (odataId == json.end()) {
-      return nullptr;
+class Node
+{
+  public:
+    template <typename... Params>
+    Node(CrowApp& app, std::string&& entityUrl, Params... params)
+    {
+        app.routeDynamic(entityUrl.c_str())
+            .methods("GET"_method, "PATCH"_method, "POST"_method,
+                     "DELETE"_method)([&](const crow::Request& req,
+                                          crow::Response& res,
+                                          Params... params) {
+                std::vector<std::string> paramVec = {params...};
+                dispatchRequest(app, req, res, paramVec);
+            });
     }
 
-    return odataId->get_ptr<const std::string*>();
-  }
+    virtual ~Node() = default;
 
-  /**
-   * @brief Inserts subroute fields into for the node's json in the form:
-   *        "subroute_name" : { "odata.id": "node_url/subroute_name/" }
-   *        Excludes metadata urls starting with "$" and child urls having
-   *        more than one level.
-   *
-   * @return  None
-   */
-  void getSubRoutes(const std::vector<std::unique_ptr<Node>>& allNodes) {
-    const std::string* url = getUrl();
-    if (url == nullptr) {
-      // BMCWEB_LOG_CRITICAL << "Unable to get url for route";
-      return;
+    const std::string* getUrl() const
+    {
+        auto odataId = json.find("@odata.id");
+        if (odataId == json.end())
+        {
+            return nullptr;
+        }
+
+        return odataId->get_ptr<const std::string*>();
     }
 
-    for (const auto& node : allNodes) {
-      const std::string* route = node->getUrl();
-      if (route == nullptr) {
-        // BMCWEB_LOG_CRITICAL << "Unable to get url for route";
-        continue;
-      }
-      if (boost::starts_with(*route, *url)) {
-        std::string subRoute = route->substr(url->size());
-        if (subRoute.empty()) {
-          continue;
+    /**
+     * @brief Inserts subroute fields into for the node's json in the form:
+     *        "subroute_name" : { "odata.id": "node_url/subroute_name/" }
+     *        Excludes metadata urls starting with "$" and child urls having
+     *        more than one level.
+     *
+     * @return  None
+     */
+    void getSubRoutes(const std::vector<std::unique_ptr<Node>>& allNodes)
+    {
+        const std::string* url = getUrl();
+        if (url == nullptr)
+        {
+            // BMCWEB_LOG_CRITICAL << "Unable to get url for route";
+            return;
         }
 
-        if (boost::starts_with(subRoute, "/")) {
-          subRoute.erase(0, 1);
+        for (const auto& node : allNodes)
+        {
+            const std::string* route = node->getUrl();
+            if (route == nullptr)
+            {
+                // BMCWEB_LOG_CRITICAL << "Unable to get url for route";
+                continue;
+            }
+            if (boost::starts_with(*route, *url))
+            {
+                std::string subRoute = route->substr(url->size());
+                if (subRoute.empty())
+                {
+                    continue;
+                }
+
+                if (boost::starts_with(subRoute, "/"))
+                {
+                    subRoute.erase(0, 1);
+                }
+
+                if (boost::ends_with(subRoute, "/"))
+                {
+                    subRoute.pop_back();
+                }
+
+                if (!boost::starts_with(subRoute, "$") &&
+                    subRoute.find('/') == std::string::npos)
+                {
+                    json[subRoute] = nlohmann::json{{"@odata.id", *route}};
+                }
+            }
         }
-
-        if (boost::ends_with(subRoute, "/")) {
-          subRoute.pop_back();
-        }
-
-        if (!boost::starts_with(subRoute, "$") &&
-            subRoute.find('/') == std::string::npos) {
-          json[subRoute] = nlohmann::json{{"@odata.id", *route}};
-        }
-      }
-    }
-  }
-
-  OperationMap entityPrivileges;
-
- protected:
-  // Node is designed to be an abstract class, so doGet is pure virtual
-  virtual void doGet(crow::Response& res, const crow::Request& req,
-                     const std::vector<std::string>& params) {
-    res.result(boost::beast::http::status::method_not_allowed);
-    res.end();
-  }
-
-  virtual void doPatch(crow::Response& res, const crow::Request& req,
-                       const std::vector<std::string>& params) {
-    res.result(boost::beast::http::status::method_not_allowed);
-    res.end();
-  }
-
-  virtual void doPost(crow::Response& res, const crow::Request& req,
-                      const std::vector<std::string>& params) {
-    res.result(boost::beast::http::status::method_not_allowed);
-    res.end();
-  }
-
-  virtual void doDelete(crow::Response& res, const crow::Request& req,
-                        const std::vector<std::string>& params) {
-    res.result(boost::beast::http::status::method_not_allowed);
-    res.end();
-  }
-
-  nlohmann::json json;
-
- private:
-  void dispatchRequest(CrowApp& app, const crow::Request& req,
-                       crow::Response& res,
-                       const std::vector<std::string>& params) {
-    auto ctx =
-        app.template getContext<crow::token_authorization::Middleware>(req);
-
-    if (!isMethodAllowedForUser(req.method(), entityPrivileges,
-                                ctx.session->username)) {
-      res.result(boost::beast::http::status::method_not_allowed);
-      res.end();
-      return;
     }
 
-    switch (req.method()) {
-      case "GET"_method:
-        doGet(res, req, params);
-        break;
+    OperationMap entityPrivileges;
 
-      case "PATCH"_method:
-        doPatch(res, req, params);
-        break;
-
-      case "POST"_method:
-        doPost(res, req, params);
-        break;
-
-      case "DELETE"_method:
-        doDelete(res, req, params);
-        break;
-
-      default:
-        res.result(boost::beast::http::status::not_found);
+  protected:
+    // Node is designed to be an abstract class, so doGet is pure virtual
+    virtual void doGet(crow::Response& res, const crow::Request& req,
+                       const std::vector<std::string>& params)
+    {
+        res.result(boost::beast::http::status::method_not_allowed);
         res.end();
     }
-    return;
-  }
+
+    virtual void doPatch(crow::Response& res, const crow::Request& req,
+                         const std::vector<std::string>& params)
+    {
+        res.result(boost::beast::http::status::method_not_allowed);
+        res.end();
+    }
+
+    virtual void doPost(crow::Response& res, const crow::Request& req,
+                        const std::vector<std::string>& params)
+    {
+        res.result(boost::beast::http::status::method_not_allowed);
+        res.end();
+    }
+
+    virtual void doDelete(crow::Response& res, const crow::Request& req,
+                          const std::vector<std::string>& params)
+    {
+        res.result(boost::beast::http::status::method_not_allowed);
+        res.end();
+    }
+
+    nlohmann::json json;
+
+  private:
+    void dispatchRequest(CrowApp& app, const crow::Request& req,
+                         crow::Response& res,
+                         const std::vector<std::string>& params)
+    {
+        auto ctx =
+            app.template getContext<crow::token_authorization::Middleware>(req);
+
+        if (!isMethodAllowedForUser(req.method(), entityPrivileges,
+                                    ctx.session->username))
+        {
+            res.result(boost::beast::http::status::method_not_allowed);
+            res.end();
+            return;
+        }
+
+        switch (req.method())
+        {
+            case "GET"_method:
+                doGet(res, req, params);
+                break;
+
+            case "PATCH"_method:
+                doPatch(res, req, params);
+                break;
+
+            case "POST"_method:
+                doPost(res, req, params);
+                break;
+
+            case "DELETE"_method:
+                doDelete(res, req, params);
+                break;
+
+            default:
+                res.result(boost::beast::http::status::not_found);
+                res.end();
+        }
+        return;
+    }
 };
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/include/privileges.hpp b/redfish-core/include/privileges.hpp
index 437bb15..0f6b903 100644
--- a/redfish-core/include/privileges.hpp
+++ b/redfish-core/include/privileges.hpp
@@ -16,15 +16,21 @@
 #pragma once
 
 #include <bitset>
-#include <cstdint>
-#include <vector>
-#include "crow.h"
 #include <boost/container/flat_map.hpp>
 #include <boost/optional.hpp>
+#include <cstdint>
+#include <vector>
 
-namespace redfish {
+#include "crow.h"
 
-enum class PrivilegeType { BASE, OEM };
+namespace redfish
+{
+
+enum class PrivilegeType
+{
+    BASE,
+    OEM
+};
 
 /** @brief A fixed array of compile time privileges  */
 constexpr std::array<const char*, 5> basePrivileges{
@@ -56,105 +62,118 @@
  *        (user domain) and false otherwise.
  *
  */
-class Privileges {
- public:
-  /**
-   * @brief Constructs object without any privileges active
-   *
-   */
-  Privileges() = default;
+class Privileges
+{
+  public:
+    /**
+     * @brief Constructs object without any privileges active
+     *
+     */
+    Privileges() = default;
 
-  /**
-   * @brief Constructs object with given privileges active
-   *
-   * @param[in] privilegeList  List of privileges to be activated
-   *
-   */
-  Privileges(std::initializer_list<const char*> privilegeList) {
-    for (const char* privilege : privilegeList) {
-      if (!setSinglePrivilege(privilege)) {
-        BMCWEB_LOG_CRITICAL << "Unable to set privilege " << privilege
-                            << "in constructor";
-      }
-    }
-  }
-
-  /**
-   * @brief Sets given privilege in the bitset
-   *
-   * @param[in] privilege  Privilege to be set
-   *
-   * @return               None
-   *
-   */
-  bool setSinglePrivilege(const char* privilege) {
-    for (int searchIndex = 0; searchIndex < privilegeNames.size();
-         searchIndex++) {
-      if (privilege == privilegeNames[searchIndex]) {
-        privilegeBitset.set(searchIndex);
-        return true;
-      }
+    /**
+     * @brief Constructs object with given privileges active
+     *
+     * @param[in] privilegeList  List of privileges to be activated
+     *
+     */
+    Privileges(std::initializer_list<const char*> privilegeList)
+    {
+        for (const char* privilege : privilegeList)
+        {
+            if (!setSinglePrivilege(privilege))
+            {
+                BMCWEB_LOG_CRITICAL << "Unable to set privilege " << privilege
+                                    << "in constructor";
+            }
+        }
     }
 
-    return false;
-  }
+    /**
+     * @brief Sets given privilege in the bitset
+     *
+     * @param[in] privilege  Privilege to be set
+     *
+     * @return               None
+     *
+     */
+    bool setSinglePrivilege(const char* privilege)
+    {
+        for (int searchIndex = 0; searchIndex < privilegeNames.size();
+             searchIndex++)
+        {
+            if (privilege == privilegeNames[searchIndex])
+            {
+                privilegeBitset.set(searchIndex);
+                return true;
+            }
+        }
 
-  /**
-   * @brief Sets given privilege in the bitset
-   *
-   * @param[in] privilege  Privilege to be set
-   *
-   * @return               None
-   *
-   */
-  bool setSinglePrivilege(const std::string& privilege) {
-    return setSinglePrivilege(privilege.c_str());
-  }
-
-  /**
-   * @brief Retrieves names of all active privileges for a given type
-   *
-   * @param[in] type    Base or OEM
-   *
-   * @return            Vector of active privileges.  Pointers are valid until
-   * the setSinglePrivilege is called, or the Privilege structure is destroyed
-   *
-   */
-  std::vector<const std::string*> getActivePrivilegeNames(
-      const PrivilegeType type) const {
-    std::vector<const std::string*> activePrivileges;
-
-    int searchIndex = 0;
-    int endIndex = basePrivilegeCount;
-    if (type == PrivilegeType::OEM) {
-      searchIndex = basePrivilegeCount - 1;
-      endIndex = privilegeNames.size();
+        return false;
     }
 
-    for (; searchIndex < endIndex; searchIndex++) {
-      if (privilegeBitset.test(searchIndex)) {
-        activePrivileges.emplace_back(&privilegeNames[searchIndex]);
-      }
+    /**
+     * @brief Sets given privilege in the bitset
+     *
+     * @param[in] privilege  Privilege to be set
+     *
+     * @return               None
+     *
+     */
+    bool setSinglePrivilege(const std::string& privilege)
+    {
+        return setSinglePrivilege(privilege.c_str());
     }
 
-    return activePrivileges;
-  }
+    /**
+     * @brief Retrieves names of all active privileges for a given type
+     *
+     * @param[in] type    Base or OEM
+     *
+     * @return            Vector of active privileges.  Pointers are valid until
+     * the setSinglePrivilege is called, or the Privilege structure is destroyed
+     *
+     */
+    std::vector<const std::string*>
+        getActivePrivilegeNames(const PrivilegeType type) const
+    {
+        std::vector<const std::string*> activePrivileges;
 
-  /**
-   * @brief Determines if this Privilege set is a superset of the given
-   * privilege set
-   *
-   * @param[in] privilege  Privilege to be checked
-   *
-   * @return               None
-   *
-   */
-  bool isSupersetOf(const Privileges& p) const {
-    return (privilegeBitset & p.privilegeBitset) == p.privilegeBitset;
-  }
+        int searchIndex = 0;
+        int endIndex = basePrivilegeCount;
+        if (type == PrivilegeType::OEM)
+        {
+            searchIndex = basePrivilegeCount - 1;
+            endIndex = privilegeNames.size();
+        }
 
- private:
-  std::bitset<maxPrivilegeCount> privilegeBitset = 0;
+        for (; searchIndex < endIndex; searchIndex++)
+        {
+            if (privilegeBitset.test(searchIndex))
+            {
+                activePrivileges.emplace_back(&privilegeNames[searchIndex]);
+            }
+        }
+
+        return activePrivileges;
+    }
+
+    /**
+     * @brief Determines if this Privilege set is a superset of the given
+     * privilege set
+     *
+     * @param[in] privilege  Privilege to be checked
+     *
+     * @return               None
+     *
+     */
+    bool isSupersetOf(const Privileges& p) const
+    {
+        return (privilegeBitset & p.privilegeBitset) == p.privilegeBitset;
+    }
+
+  private:
+    std::bitset<maxPrivilegeCount> privilegeBitset = 0;
 };
 
 using OperationMap = boost::container::flat_map<boost::beast::http::verb,
@@ -171,23 +190,28 @@
  */
 inline bool isMethodAllowedWithPrivileges(const boost::beast::http::verb method,
                                           const OperationMap& operationMap,
-                                          const Privileges& userPrivileges) {
-  const auto& it = operationMap.find(method);
-  if (it == operationMap.end()) {
-    return false;
-  }
-
-  // If there are no privileges assigned, assume no privileges required
-  if (it->second.empty()) {
-    return true;
-  }
-
-  for (auto& requiredPrivileges : it->second) {
-    if (userPrivileges.isSupersetOf(requiredPrivileges)) {
-      return true;
+                                          const Privileges& userPrivileges)
+{
+    const auto& it = operationMap.find(method);
+    if (it == operationMap.end())
+    {
+        return false;
     }
-  }
-  return false;
+
+    // If there are no privileges assigned, assume no privileges required
+    if (it->second.empty())
+    {
+        return true;
+    }
+
+    for (auto& requiredPrivileges : it->second)
+    {
+        if (userPrivileges.isSupersetOf(requiredPrivileges))
+        {
+            return true;
+        }
+    }
+    return false;
 }
 
 /**
@@ -201,13 +225,14 @@
  */
 inline bool isMethodAllowedForUser(const boost::beast::http::verb method,
                                    const OperationMap& operationMap,
-                                   const std::string& user) {
-  // TODO: load user privileges from configuration as soon as its available
-  // now we are granting all privileges to everyone.
-  Privileges userPrivileges{"Login", "ConfigureManager", "ConfigureSelf",
-                            "ConfigureUsers", "ConfigureComponents"};
+                                   const std::string& user)
+{
+    // TODO: load user privileges from configuration as soon as its available
+    // now we are granting all privileges to everyone.
+    Privileges userPrivileges{"Login", "ConfigureManager", "ConfigureSelf",
+                              "ConfigureUsers", "ConfigureComponents"};
 
-  return isMethodAllowedWithPrivileges(method, operationMap, userPrivileges);
+    return isMethodAllowedWithPrivileges(method, operationMap, userPrivileges);
 }
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp
index ab60abb..7f41b63 100644
--- a/redfish-core/include/redfish.hpp
+++ b/redfish-core/include/redfish.hpp
@@ -28,48 +28,53 @@
 #include "../lib/update_service.hpp"
 #include "webserver_common.hpp"
 
-namespace redfish {
+namespace redfish
+{
 /*
  * @brief Top level class installing and providing Redfish services
  */
-class RedfishService {
- public:
-  /*
-   * @brief Redfish service constructor
-   *
-   * Loads Redfish configuration and installs schema resources
-   *
-   * @param[in] app   Crow app on which Redfish will initialize
-   */
-  RedfishService(CrowApp& app) {
-    nodes.emplace_back(std::make_unique<AccountService>(app));
-    nodes.emplace_back(std::make_unique<SessionCollection>(app));
-    nodes.emplace_back(std::make_unique<Roles>(app));
-    nodes.emplace_back(std::make_unique<RoleCollection>(app));
-    nodes.emplace_back(std::make_unique<ServiceRoot>(app));
-    nodes.emplace_back(std::make_unique<NetworkProtocol>(app));
-    nodes.emplace_back(std::make_unique<SessionService>(app));
-    nodes.emplace_back(std::make_unique<EthernetCollection>(app));
-    nodes.emplace_back(std::make_unique<EthernetInterface>(app));
-    nodes.emplace_back(std::make_unique<Thermal>(app));
-    nodes.emplace_back(std::make_unique<ManagerCollection>(app));
-    nodes.emplace_back(std::make_unique<Manager>(app));
-    nodes.emplace_back(std::make_unique<ChassisCollection>(app));
-    nodes.emplace_back(std::make_unique<Chassis>(app));
-    nodes.emplace_back(std::make_unique<UpdateService>(app));
-    nodes.emplace_back(std::make_unique<SoftwareInventoryCollection>(app));
-    nodes.emplace_back(std::make_unique<SoftwareInventory>(app));
-    nodes.emplace_back(std::make_unique<VlanNetworkInterfaceCollection>(app));
-    nodes.emplace_back(std::make_unique<SystemsCollection>(app));
-    nodes.emplace_back(std::make_unique<Systems>(app));
+class RedfishService
+{
+  public:
+    /*
+     * @brief Redfish service constructor
+     *
+     * Loads Redfish configuration and installs schema resources
+     *
+     * @param[in] app   Crow app on which Redfish will initialize
+     */
+    RedfishService(CrowApp& app)
+    {
+        nodes.emplace_back(std::make_unique<AccountService>(app));
+        nodes.emplace_back(std::make_unique<SessionCollection>(app));
+        nodes.emplace_back(std::make_unique<Roles>(app));
+        nodes.emplace_back(std::make_unique<RoleCollection>(app));
+        nodes.emplace_back(std::make_unique<ServiceRoot>(app));
+        nodes.emplace_back(std::make_unique<NetworkProtocol>(app));
+        nodes.emplace_back(std::make_unique<SessionService>(app));
+        nodes.emplace_back(std::make_unique<EthernetCollection>(app));
+        nodes.emplace_back(std::make_unique<EthernetInterface>(app));
+        nodes.emplace_back(std::make_unique<Thermal>(app));
+        nodes.emplace_back(std::make_unique<ManagerCollection>(app));
+        nodes.emplace_back(std::make_unique<Manager>(app));
+        nodes.emplace_back(std::make_unique<ChassisCollection>(app));
+        nodes.emplace_back(std::make_unique<Chassis>(app));
+        nodes.emplace_back(std::make_unique<UpdateService>(app));
+        nodes.emplace_back(std::make_unique<SoftwareInventoryCollection>(app));
+        nodes.emplace_back(std::make_unique<SoftwareInventory>(app));
+        nodes.emplace_back(
+            std::make_unique<VlanNetworkInterfaceCollection>(app));
+        nodes.emplace_back(std::make_unique<SystemsCollection>(app));
+        nodes.emplace_back(std::make_unique<Systems>(app));
 
-    for (auto& node : nodes) {
-      node->getSubRoutes(nodes);
+        for (auto& node : nodes)
+        {
+            node->getSubRoutes(nodes);
+        }
     }
-  }
 
- private:
-  std::vector<std::unique_ptr<Node>> nodes;
+  private:
+    std::vector<std::unique_ptr<Node>> nodes;
 };
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/include/utils/json_utils.hpp b/redfish-core/include/utils/json_utils.hpp
index 25ac954..bde81ce 100644
--- a/redfish-core/include/utils/json_utils.hpp
+++ b/redfish-core/include/utils/json_utils.hpp
@@ -14,26 +14,36 @@
 // limitations under the License.
 */
 #pragma once
-#include <nlohmann/json.hpp>
 #include <crow/http_request.h>
 #include <crow/http_response.h>
 
-namespace redfish {
+#include <nlohmann/json.hpp>
 
-namespace json_util {
+namespace redfish
+{
+
+namespace json_util
+{
 
 /**
  * @brief Defines JSON utils operation status
  */
-enum class Result { SUCCESS, NOT_EXIST, WRONG_TYPE, NULL_POINTER };
+enum class Result
+{
+    SUCCESS,
+    NOT_EXIST,
+    WRONG_TYPE,
+    NULL_POINTER
+};
 
 /**
  * @brief Describes JSON utils messages requirement
  */
-enum class MessageSetting {
-  NONE = 0x0,       ///< No messages will be added
-  MISSING = 0x1,    ///< PropertyMissing message will be added
-  TYPE_ERROR = 0x2  ///< PropertyValueTypeError message will be added
+enum class MessageSetting
+{
+    NONE = 0x0,      ///< No messages will be added
+    MISSING = 0x1,   ///< PropertyMissing message will be added
+    TYPE_ERROR = 0x2 ///< PropertyValueTypeError message will be added
 };
 
 /**
@@ -287,6 +297,6 @@
 bool processJsonFromRequest(crow::Response& res, const crow::Request& req,
                             nlohmann::json& reqJson);
 
-}  // namespace json_util
+} // namespace json_util
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/lib/account_service.hpp b/redfish-core/lib/account_service.hpp
index 47b4c4c..c58cafd 100644
--- a/redfish-core/lib/account_service.hpp
+++ b/redfish-core/lib/account_service.hpp
@@ -17,40 +17,45 @@
 
 #include "node.hpp"
 
-namespace redfish {
+namespace redfish
+{
 
-class AccountService : public Node {
- public:
-  AccountService(CrowApp& app) : Node(app, "/redfish/v1/AccountService/") {
-    Node::json["@odata.id"] = "/redfish/v1/AccountService";
-    Node::json["@odata.type"] = "#AccountService.v1_1_0.AccountService";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata#AccountService.AccountService";
-    Node::json["Id"] = "AccountService";
-    Node::json["Description"] = "BMC User Accounts";
-    Node::json["Name"] = "Account Service";
-    Node::json["ServiceEnabled"] = true;
-    Node::json["MinPasswordLength"] = 1;
-    Node::json["MaxPasswordLength"] = 20;
-    Node::json["Accounts"]["@odata.id"] = "/redfish/v1/AccountService/Accounts";
-    Node::json["Roles"]["@odata.id"] = "/redfish/v1/AccountService/Roles";
+class AccountService : public Node
+{
+  public:
+    AccountService(CrowApp& app) : Node(app, "/redfish/v1/AccountService/")
+    {
+        Node::json["@odata.id"] = "/redfish/v1/AccountService";
+        Node::json["@odata.type"] = "#AccountService.v1_1_0.AccountService";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata#AccountService.AccountService";
+        Node::json["Id"] = "AccountService";
+        Node::json["Description"] = "BMC User Accounts";
+        Node::json["Name"] = "Account Service";
+        Node::json["ServiceEnabled"] = true;
+        Node::json["MinPasswordLength"] = 1;
+        Node::json["MaxPasswordLength"] = 20;
+        Node::json["Accounts"]["@odata.id"] =
+            "/redfish/v1/AccountService/Accounts";
+        Node::json["Roles"]["@odata.id"] = "/redfish/v1/AccountService/Roles";
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get,
-         {{"ConfigureUsers"}, {"ConfigureManager"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureUsers"}}},
-        {boost::beast::http::verb::put, {{"ConfigureUsers"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureUsers"}}},
-        {boost::beast::http::verb::post, {{"ConfigureUsers"}}}};
-  }
+        entityPrivileges = {
+            {boost::beast::http::verb::get,
+             {{"ConfigureUsers"}, {"ConfigureManager"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureUsers"}}},
+            {boost::beast::http::verb::put, {{"ConfigureUsers"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureUsers"}}},
+            {boost::beast::http::verb::post, {{"ConfigureUsers"}}}};
+    }
 
- private:
-  void doGet(crow::Response& res, const crow::Request& req,
-             const std::vector<std::string>& params) override {
-    res.jsonValue = Node::json;
-    res.end();
-  }
+  private:
+    void doGet(crow::Response& res, const crow::Request& req,
+               const std::vector<std::string>& params) override
+    {
+        res.jsonValue = Node::json;
+        res.end();
+    }
 };
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/lib/chassis.hpp b/redfish-core/lib/chassis.hpp
index b1c20a5..7b68a27 100644
--- a/redfish-core/lib/chassis.hpp
+++ b/redfish-core/lib/chassis.hpp
@@ -16,9 +16,11 @@
 #pragma once
 
 #include "node.hpp"
+
 #include <boost/container/flat_map.hpp>
 
-namespace redfish {
+namespace redfish
+{
 
 /**
  * DBus types primitives for several generic DBus interfaces
@@ -47,220 +49,251 @@
  * This perhaps shall be different file, which has to be chosen on compile time
  * depending on OEM needs
  */
-class OnDemandChassisProvider {
- public:
-  /**
-   * Function that retrieves all Chassis available through EntityManager.
-   * @param callback a function that shall be called to convert Dbus output into
-   * JSON.
-   */
-  template <typename CallbackFunc>
-  void getChassisList(CallbackFunc &&callback) {
-    const std::array<const char *, 4> interfaces = {
-        "xyz.openbmc_project.Inventory.Item.Board",
-        "xyz.openbmc_project.Inventory.Item.Chassis",
-        "xyz.openbmc_project.Inventory.Item.PowerSupply",
-        "xyz.openbmc_project.Inventory.Item.System",
+class OnDemandChassisProvider
+{
+  public:
+    /**
+     * Function that retrieves all Chassis available through EntityManager.
+     * @param callback a function that shall be called to convert Dbus output
+     * into JSON.
+     */
+    template <typename CallbackFunc>
+    void getChassisList(CallbackFunc &&callback)
+    {
+        const std::array<const char *, 4> interfaces = {
+            "xyz.openbmc_project.Inventory.Item.Board",
+            "xyz.openbmc_project.Inventory.Item.Chassis",
+            "xyz.openbmc_project.Inventory.Item.PowerSupply",
+            "xyz.openbmc_project.Inventory.Item.System",
+        };
+        crow::connections::systemBus->async_method_call(
+            [callback{std::move(callback)}](
+                const boost::system::error_code error_code,
+                const std::vector<std::string> &resp) {
+                // Callback requires vector<string> to retrieve all available
+                // chassis list.
+                std::vector<std::string> chassisList;
+                if (error_code)
+                {
+                    // Something wrong on DBus, the error_code is not important
+                    // at this moment, just return success=false, and empty
+                    // output. Since size of vector may vary depending on
+                    // information from Entity Manager, and empty output could
+                    // not be treated same way as error.
+                    callback(false, chassisList);
+                    return;
+                }
+                // Iterate over all retrieved ObjectPaths.
+                for (const std::string &objpath : resp)
+                {
+                    std::size_t lastPos = objpath.rfind("/");
+                    if (lastPos != std::string::npos)
+                    {
+                        // and put it into output vector.
+                        chassisList.emplace_back(objpath.substr(lastPos + 1));
+                    }
+                }
+                // Finally make a callback with useful data
+                callback(true, chassisList);
+            },
+            "xyz.openbmc_project.ObjectMapper",
+            "/xyz/openbmc_project/object_mapper",
+            "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
+            "/xyz/openbmc_project/inventory", int32_t(3), interfaces);
     };
-    crow::connections::systemBus->async_method_call(
-        [callback{std::move(callback)}](
-            const boost::system::error_code error_code,
-            const std::vector<std::string> &resp) {
-          // Callback requires vector<string> to retrieve all available chassis
-          // list.
-          std::vector<std::string> chassisList;
-          if (error_code) {
-            // Something wrong on DBus, the error_code is not important at this
-            // moment, just return success=false, and empty output. Since size
-            // of vector may vary depending on information from Entity Manager,
-            // and empty output could not be treated same way as error.
-            callback(false, chassisList);
-            return;
-          }
-          // Iterate over all retrieved ObjectPaths.
-          for (const std::string &objpath : resp) {
-            std::size_t lastPos = objpath.rfind("/");
-            if (lastPos != std::string::npos) {
-              // and put it into output vector.
-              chassisList.emplace_back(objpath.substr(lastPos + 1));
-            }
-          }
-          // Finally make a callback with useful data
-          callback(true, chassisList);
-        },
-        "xyz.openbmc_project.ObjectMapper",
-        "/xyz/openbmc_project/object_mapper",
-        "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
-        "/xyz/openbmc_project/inventory", int32_t(3), interfaces);
-  };
 };
 
 /**
  * ChassisCollection derived class for delivering Chassis Collection Schema
  */
-class ChassisCollection : public Node {
- public:
-  ChassisCollection(CrowApp &app) : Node(app, "/redfish/v1/Chassis/") {
-    Node::json["@odata.type"] = "#ChassisCollection.ChassisCollection";
-    Node::json["@odata.id"] = "/redfish/v1/Chassis";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata#ChassisCollection.ChassisCollection";
-    Node::json["Name"] = "Chassis Collection";
+class ChassisCollection : public Node
+{
+  public:
+    ChassisCollection(CrowApp &app) : Node(app, "/redfish/v1/Chassis/")
+    {
+        Node::json["@odata.type"] = "#ChassisCollection.ChassisCollection";
+        Node::json["@odata.id"] = "/redfish/v1/Chassis";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata#ChassisCollection.ChassisCollection";
+        Node::json["Name"] = "Chassis Collection";
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-  }
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
+    }
 
- private:
-  /**
-   * Functions triggers appropriate requests on DBus
-   */
-  void doGet(crow::Response &res, const crow::Request &req,
-             const std::vector<std::string> &params) override {
-    // get chassis list, and call the below callback for JSON preparation
-    chassisProvider.getChassisList(
-        [&](const bool &success, const std::vector<std::string> &output) {
-          if (success) {
-            // ... prepare json array with appropriate @odata.id links
-            nlohmann::json chassisArray = nlohmann::json::array();
-            for (const std::string &chassisItem : output) {
-              chassisArray.push_back(
-                  {{"@odata.id", "/redfish/v1/Chassis/" + chassisItem}});
-            }
-            // Then attach members, count size and return,
-            Node::json["Members"] = chassisArray;
-            Node::json["Members@odata.count"] = chassisArray.size();
-            res.jsonValue = Node::json;
-          } else {
-            // ... otherwise, return INTERNALL ERROR
-            res.result(boost::beast::http::status::internal_server_error);
-          }
-          res.end();
-        });
-  }
+  private:
+    /**
+     * Functions triggers appropriate requests on DBus
+     */
+    void doGet(crow::Response &res, const crow::Request &req,
+               const std::vector<std::string> &params) override
+    {
+        // get chassis list, and call the below callback for JSON preparation
+        chassisProvider.getChassisList(
+            [&](const bool &success, const std::vector<std::string> &output) {
+                if (success)
+                {
+                    // ... prepare json array with appropriate @odata.id links
+                    nlohmann::json chassisArray = nlohmann::json::array();
+                    for (const std::string &chassisItem : output)
+                    {
+                        chassisArray.push_back(
+                            {{"@odata.id",
+                              "/redfish/v1/Chassis/" + chassisItem}});
+                    }
+                    // Then attach members, count size and return,
+                    Node::json["Members"] = chassisArray;
+                    Node::json["Members@odata.count"] = chassisArray.size();
+                    res.jsonValue = Node::json;
+                }
+                else
+                {
+                    // ... otherwise, return INTERNALL ERROR
+                    res.result(
+                        boost::beast::http::status::internal_server_error);
+                }
+                res.end();
+            });
+    }
 
-  // Chassis Provider object
-  // TODO(Pawel) consider move it to singleton
-  OnDemandChassisProvider chassisProvider;
+    // Chassis Provider object
+    // TODO(Pawel) consider move it to singleton
+    OnDemandChassisProvider chassisProvider;
 };
 
 /**
  * Chassis override class for delivering Chassis Schema
  */
-class Chassis : public Node {
- public:
-  Chassis(CrowApp &app)
-      : Node(app, "/redfish/v1/Chassis/<str>/", std::string()) {
-    Node::json["@odata.type"] = "#Chassis.v1_4_0.Chassis";
-    Node::json["@odata.id"] = "/redfish/v1/Chassis";
-    Node::json["@odata.context"] = "/redfish/v1/$metadata#Chassis.Chassis";
-    Node::json["Name"] = "Chassis Collection";
-    Node::json["ChassisType"] = "RackMount";
+class Chassis : public Node
+{
+  public:
+    Chassis(CrowApp &app) :
+        Node(app, "/redfish/v1/Chassis/<str>/", std::string())
+    {
+        Node::json["@odata.type"] = "#Chassis.v1_4_0.Chassis";
+        Node::json["@odata.id"] = "/redfish/v1/Chassis";
+        Node::json["@odata.context"] = "/redfish/v1/$metadata#Chassis.Chassis";
+        Node::json["Name"] = "Chassis Collection";
+        Node::json["ChassisType"] = "RackMount";
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-  }
-
- private:
-  /**
-   * Functions triggers appropriate requests on DBus
-   */
-  void doGet(crow::Response &res, const crow::Request &req,
-             const std::vector<std::string> &params) override {
-    // Check if there is required param, truly entering this shall be
-    // impossible.
-    if (params.size() != 1) {
-      res.result(boost::beast::http::status::internal_server_error);
-      res.end();
-      return;
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
     }
 
-    res.jsonValue = Node::json;
-    const std::string &chassisId = params[0];
-    crow::connections::systemBus->async_method_call(
-        [&res, chassisId(std::string(chassisId)) ](
-            const boost::system::error_code error_code,
-            const std::vector<std::pair<
-                std::string,
-                std::vector<std::pair<std::string, std::vector<std::string>>>>>
-                &subtree) {
-          if (error_code) {
-            res.jsonValue = {};
+  private:
+    /**
+     * Functions triggers appropriate requests on DBus
+     */
+    void doGet(crow::Response &res, const crow::Request &req,
+               const std::vector<std::string> &params) override
+    {
+        // Check if there is required param, truly entering this shall be
+        // impossible.
+        if (params.size() != 1)
+        {
             res.result(boost::beast::http::status::internal_server_error);
             res.end();
             return;
-          }
-          // Iterate over all retrieved ObjectPaths.
-          for (const std::pair<std::string,
-                               std::vector<std::pair<std::string,
-                                                     std::vector<std::string>>>>
-                   &object : subtree) {
-            const std::string &path = object.first;
-            const std::vector<std::pair<std::string, std::vector<std::string>>>
-                &connectionNames = object.second;
+        }
 
-            if (!boost::ends_with(path, chassisId)) {
-              continue;
-            }
-            if (connectionNames.size() < 1) {
-              BMCWEB_LOG_ERROR << "Only got " << connectionNames.size()
-                               << " Connection names";
-              continue;
-            }
+        res.jsonValue = Node::json;
+        const std::string &chassisId = params[0];
+        crow::connections::systemBus->async_method_call(
+            [&res, chassisId(std::string(chassisId))](
+                const boost::system::error_code error_code,
+                const std::vector<std::pair<
+                    std::string, std::vector<std::pair<
+                                     std::string, std::vector<std::string>>>>>
+                    &subtree) {
+                if (error_code)
+                {
+                    res.jsonValue = {};
+                    res.result(
+                        boost::beast::http::status::internal_server_error);
+                    res.end();
+                    return;
+                }
+                // Iterate over all retrieved ObjectPaths.
+                for (const std::pair<
+                         std::string,
+                         std::vector<
+                             std::pair<std::string, std::vector<std::string>>>>
+                         &object : subtree)
+                {
+                    const std::string &path = object.first;
+                    const std::vector<
+                        std::pair<std::string, std::vector<std::string>>>
+                        &connectionNames = object.second;
 
-            const std::string connectionName = connectionNames[0].first;
-            crow::connections::systemBus->async_method_call(
-                [&res, chassisId(std::string(chassisId)) ](
-                    const boost::system::error_code error_code,
-                    const std::vector<std::pair<std::string, VariantType>>
-                        &propertiesList) {
-                  for (const std::pair<std::string, VariantType> &property :
-                       propertiesList) {
-                    const std::string *value =
-                        mapbox::getPtr<const std::string>(property.second);
-                    if (value != nullptr) {
-                      res.jsonValue[property.first] = *value;
+                    if (!boost::ends_with(path, chassisId))
+                    {
+                        continue;
                     }
-                  }
-                  res.jsonValue["Name"] = chassisId;
-                  res.jsonValue["Id"] = chassisId;
-                  res.jsonValue["Thermal"] = {
-                      {"@odata.id",
-                       "/redfish/v1/Chassis/" + chassisId + "/Thermal"}};
-                  res.end();
-                },
-                connectionName, path, "org.freedesktop.DBus.Properties",
-                "GetAll", "xyz.openbmc_project.Inventory.Decorator.Asset");
-            // Found the Connection we were looking for, return
-            return;
-          }
+                    if (connectionNames.size() < 1)
+                    {
+                        BMCWEB_LOG_ERROR << "Only got "
+                                         << connectionNames.size()
+                                         << " Connection names";
+                        continue;
+                    }
 
-          // Couldn't find an object with that name.  return an error
-          res.result(boost::beast::http::status::not_found);
+                    const std::string connectionName = connectionNames[0].first;
+                    crow::connections::systemBus->async_method_call(
+                        [&res, chassisId(std::string(chassisId))](
+                            const boost::system::error_code error_code,
+                            const std::vector<std::pair<
+                                std::string, VariantType>> &propertiesList) {
+                            for (const std::pair<std::string, VariantType>
+                                     &property : propertiesList)
+                            {
+                                const std::string *value =
+                                    mapbox::getPtr<const std::string>(
+                                        property.second);
+                                if (value != nullptr)
+                                {
+                                    res.jsonValue[property.first] = *value;
+                                }
+                            }
+                            res.jsonValue["Name"] = chassisId;
+                            res.jsonValue["Id"] = chassisId;
+                            res.jsonValue["Thermal"] = {
+                                {"@odata.id", "/redfish/v1/Chassis/" +
+                                                  chassisId + "/Thermal"}};
+                            res.end();
+                        },
+                        connectionName, path, "org.freedesktop.DBus.Properties",
+                        "GetAll",
+                        "xyz.openbmc_project.Inventory.Decorator.Asset");
+                    // Found the Connection we were looking for, return
+                    return;
+                }
 
-          res.end();
-        },
-        "xyz.openbmc_project.ObjectMapper",
-        "/xyz/openbmc_project/object_mapper",
-        "xyz.openbmc_project.ObjectMapper", "GetSubTree",
-        "/xyz/openbmc_project/inventory", int32_t(0),
-        std::array<const char *, 1>{
-            "xyz.openbmc_project.Inventory.Decorator.Asset"});
-  }
+                // Couldn't find an object with that name.  return an error
+                res.result(boost::beast::http::status::not_found);
 
-  // Chassis Provider object
-  // TODO(Pawel) consider move it to singleton
-  OnDemandChassisProvider chassisProvider;
-};  // namespace redfish
+                res.end();
+            },
+            "xyz.openbmc_project.ObjectMapper",
+            "/xyz/openbmc_project/object_mapper",
+            "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+            "/xyz/openbmc_project/inventory", int32_t(0),
+            std::array<const char *, 1>{
+                "xyz.openbmc_project.Inventory.Decorator.Asset"});
+    }
 
-}  // namespace redfish
+    // Chassis Provider object
+    // TODO(Pawel) consider move it to singleton
+    OnDemandChassisProvider chassisProvider;
+}; // namespace redfish
+
+} // namespace redfish
diff --git a/redfish-core/lib/ethernet.hpp b/redfish-core/lib/ethernet.hpp
index 01111a4..0c64279 100644
--- a/redfish-core/lib/ethernet.hpp
+++ b/redfish-core/lib/ethernet.hpp
@@ -15,13 +15,14 @@
 */
 #pragma once
 
+#include <boost/container/flat_map.hpp>
 #include <dbus_singleton.hpp>
 #include <error_messages.hpp>
 #include <node.hpp>
 #include <utils/json_utils.hpp>
-#include <boost/container/flat_map.hpp>
 
-namespace redfish {
+namespace redfish
+{
 
 /**
  * DBus types primitives for several generic DBus interfaces
@@ -45,35 +46,40 @@
  * Structure for keeping IPv4 data required by Redfish
  * TODO(Pawel) consider change everything to ptr, or to non-ptr values.
  */
-struct IPv4AddressData {
-  std::string id;
-  const std::string *address;
-  const std::string *domain;
-  const std::string *gateway;
-  std::string netmask;
-  std::string origin;
-  bool global;
-  /**
-   * @brief Operator< to enable sorting
-   *
-   * @param[in] obj   Object to compare with
-   *
-   * @return This object id < supplied object id
-   */
-  bool operator<(const IPv4AddressData &obj) const { return (id < obj.id); }
+struct IPv4AddressData
+{
+    std::string id;
+    const std::string *address;
+    const std::string *domain;
+    const std::string *gateway;
+    std::string netmask;
+    std::string origin;
+    bool global;
+    /**
+     * @brief Operator< to enable sorting
+     *
+     * @param[in] obj   Object to compare with
+     *
+     * @return This object id < supplied object id
+     */
+    bool operator<(const IPv4AddressData &obj) const
+    {
+        return (id < obj.id);
+    }
 };
 
 /**
  * Structure for keeping basic single Ethernet Interface information
  * available from DBus
  */
-struct EthernetInterfaceData {
-  const unsigned int *speed;
-  const bool *autoNeg;
-  const std::string *hostname;
-  const std::string *defaultGateway;
-  const std::string *macAddress;
-  const unsigned int *vlanId;
+struct EthernetInterfaceData
+{
+    const unsigned int *speed;
+    const bool *autoNeg;
+    const std::string *hostname;
+    const std::string *defaultGateway;
+    const std::string *macAddress;
+    const unsigned int *vlanId;
 };
 
 /**
@@ -85,1264 +91,1493 @@
  * This perhaps shall be different file, which has to be chosen on compile time
  * depending on OEM needs
  */
-class OnDemandEthernetProvider {
- private:
-  // Consts that may have influence on EthernetProvider performance/memory usage
-  const size_t maxIpV4AddressesPerInterface = 10;
+class OnDemandEthernetProvider
+{
+  private:
+    // Consts that may have influence on EthernetProvider performance/memory
+    // usage
+    const size_t maxIpV4AddressesPerInterface = 10;
 
-  // Helper function that allows to extract GetAllPropertiesType from
-  // GetManagedObjectsType, based on object path, and interface name
-  const PropertiesMapType *extractInterfaceProperties(
-      const sdbusplus::message::object_path &objpath,
-      const std::string &interface, const GetManagedObjectsType &dbus_data) {
-    const auto &dbusObj = dbus_data.find(objpath);
-    if (dbusObj != dbus_data.end()) {
-      const auto &iface = dbusObj->second.find(interface);
-      if (iface != dbusObj->second.end()) {
-        return &iface->second;
-      }
-    }
-    return nullptr;
-  }
-
-  // Helper Wrapper that does inline object_path conversion from string
-  // into sdbusplus::message::object_path type
-  inline const PropertiesMapType *extractInterfaceProperties(
-      const std::string &objpath, const std::string &interface,
-      const GetManagedObjectsType &dbus_data) {
-    const auto &dbusObj = sdbusplus::message::object_path{objpath};
-    return extractInterfaceProperties(dbusObj, interface, dbus_data);
-  }
-
-  // Helper function that allows to get pointer to the property from
-  // GetAllPropertiesType native, or extracted by GetAllPropertiesType
-  template <typename T>
-  inline T const *const extractProperty(const PropertiesMapType &properties,
-                                        const std::string &name) {
-    const auto &property = properties.find(name);
-    if (property != properties.end()) {
-      return mapbox::getPtr<const T>(property->second);
-    }
-    return nullptr;
-  }
-  // TODO(Pawel) Consider to move the above functions to dbus
-  // generic_interfaces.hpp
-
-  // Helper function that extracts data from several dbus objects and several
-  // interfaces required by single ethernet interface instance
-  void extractEthernetInterfaceData(const std::string &ethifaceId,
-                                    const GetManagedObjectsType &dbus_data,
-                                    EthernetInterfaceData &eth_data) {
-    // Extract data that contains MAC Address
-    const PropertiesMapType *macProperties = extractInterfaceProperties(
-        "/xyz/openbmc_project/network/" + ethifaceId,
-        "xyz.openbmc_project.Network.MACAddress", dbus_data);
-
-    if (macProperties != nullptr) {
-      eth_data.macAddress =
-          extractProperty<std::string>(*macProperties, "MACAddress");
-    }
-
-    const PropertiesMapType *vlanProperties = extractInterfaceProperties(
-        "/xyz/openbmc_project/network/" + ethifaceId,
-        "xyz.openbmc_project.Network.VLAN", dbus_data);
-
-    if (vlanProperties != nullptr) {
-      eth_data.vlanId = extractProperty<unsigned int>(*vlanProperties, "Id");
-    }
-
-    // Extract data that contains link information (auto negotiation and speed)
-    const PropertiesMapType *ethProperties = extractInterfaceProperties(
-        "/xyz/openbmc_project/network/" + ethifaceId,
-        "xyz.openbmc_project.Network.EthernetInterface", dbus_data);
-
-    if (ethProperties != nullptr) {
-      eth_data.autoNeg = extractProperty<bool>(*ethProperties, "AutoNeg");
-      eth_data.speed = extractProperty<unsigned int>(*ethProperties, "Speed");
-    }
-
-    // Extract data that contains network config (HostName and DefaultGW)
-    const PropertiesMapType *configProperties = extractInterfaceProperties(
-        "/xyz/openbmc_project/network/config",
-        "xyz.openbmc_project.Network.SystemConfiguration", dbus_data);
-
-    if (configProperties != nullptr) {
-      eth_data.hostname =
-          extractProperty<std::string>(*configProperties, "HostName");
-      eth_data.defaultGateway =
-          extractProperty<std::string>(*configProperties, "DefaultGateway");
-    }
-  }
-
-  // Helper function that changes bits netmask notation (i.e. /24)
-  // into full dot notation
-  inline std::string getNetmask(unsigned int bits) {
-    uint32_t value = 0xffffffff << (32 - bits);
-    std::string netmask = std::to_string((value >> 24) & 0xff) + "." +
-                          std::to_string((value >> 16) & 0xff) + "." +
-                          std::to_string((value >> 8) & 0xff) + "." +
-                          std::to_string(value & 0xff);
-    return netmask;
-  }
-
-  // Helper function that extracts data for single ethernet ipv4 address
-  void extractIPv4Data(const std::string &ethifaceId,
-                       const GetManagedObjectsType &dbus_data,
-                       std::vector<IPv4AddressData> &ipv4_config) {
-    const std::string pathStart =
-        "/xyz/openbmc_project/network/" + ethifaceId + "/ipv4/";
-
-    // Since there might be several IPv4 configurations aligned with
-    // single ethernet interface, loop over all of them
-    for (auto &objpath : dbus_data) {
-      // Check if proper patter for object path appears
-      if (boost::starts_with(static_cast<const std::string &>(objpath.first),
-                             pathStart)) {
-        // and get approrpiate interface
-        const auto &interface =
-            objpath.second.find("xyz.openbmc_project.Network.IP");
-        if (interface != objpath.second.end()) {
-          // Make a properties 'shortcut', to make everything more readable
-          const PropertiesMapType &properties = interface->second;
-          // Instance IPv4AddressData structure, and set as appropriate
-          IPv4AddressData ipv4Address;
-
-          ipv4Address.id = static_cast<const std::string &>(objpath.first)
-                               .substr(pathStart.size());
-
-          // IPv4 address
-          ipv4Address.address =
-              extractProperty<std::string>(properties, "Address");
-          // IPv4 gateway
-          ipv4Address.gateway =
-              extractProperty<std::string>(properties, "Gateway");
-
-          // Origin is kind of DBus object so fetch pointer...
-          const std::string *origin =
-              extractProperty<std::string>(properties, "Origin");
-          if (origin != nullptr) {
-            ipv4Address.origin =
-                translateAddressOriginBetweenDBusAndRedfish(origin, true, true);
-          }
-
-          // Netmask is presented as PrefixLength
-          const auto *mask =
-              extractProperty<uint8_t>(properties, "PrefixLength");
-          if (mask != nullptr) {
-            // convert it to the string
-            ipv4Address.netmask = getNetmask(*mask);
-          }
-
-          // Attach IPv4 only if address is present
-          if (ipv4Address.address != nullptr) {
-            // Check if given address is local, or global
-            if (boost::starts_with(*ipv4Address.address, "169.254")) {
-              ipv4Address.global = false;
-            } else {
-              ipv4Address.global = true;
+    // Helper function that allows to extract GetAllPropertiesType from
+    // GetManagedObjectsType, based on object path, and interface name
+    const PropertiesMapType *extractInterfaceProperties(
+        const sdbusplus::message::object_path &objpath,
+        const std::string &interface, const GetManagedObjectsType &dbus_data)
+    {
+        const auto &dbusObj = dbus_data.find(objpath);
+        if (dbusObj != dbus_data.end())
+        {
+            const auto &iface = dbusObj->second.find(interface);
+            if (iface != dbusObj->second.end())
+            {
+                return &iface->second;
             }
-            ipv4_config.emplace_back(std::move(ipv4Address));
-          }
         }
-      }
+        return nullptr;
+    }
+
+    // Helper Wrapper that does inline object_path conversion from string
+    // into sdbusplus::message::object_path type
+    inline const PropertiesMapType *
+        extractInterfaceProperties(const std::string &objpath,
+                                   const std::string &interface,
+                                   const GetManagedObjectsType &dbus_data)
+    {
+        const auto &dbusObj = sdbusplus::message::object_path{objpath};
+        return extractInterfaceProperties(dbusObj, interface, dbus_data);
+    }
+
+    // Helper function that allows to get pointer to the property from
+    // GetAllPropertiesType native, or extracted by GetAllPropertiesType
+    template <typename T>
+    inline T const *const extractProperty(const PropertiesMapType &properties,
+                                          const std::string &name)
+    {
+        const auto &property = properties.find(name);
+        if (property != properties.end())
+        {
+            return mapbox::getPtr<const T>(property->second);
+        }
+        return nullptr;
+    }
+    // TODO(Pawel) Consider to move the above functions to dbus
+    // generic_interfaces.hpp
+
+    // Helper function that extracts data from several dbus objects and several
+    // interfaces required by single ethernet interface instance
+    void extractEthernetInterfaceData(const std::string &ethifaceId,
+                                      const GetManagedObjectsType &dbus_data,
+                                      EthernetInterfaceData &eth_data)
+    {
+        // Extract data that contains MAC Address
+        const PropertiesMapType *macProperties = extractInterfaceProperties(
+            "/xyz/openbmc_project/network/" + ethifaceId,
+            "xyz.openbmc_project.Network.MACAddress", dbus_data);
+
+        if (macProperties != nullptr)
+        {
+            eth_data.macAddress =
+                extractProperty<std::string>(*macProperties, "MACAddress");
+        }
+
+        const PropertiesMapType *vlanProperties = extractInterfaceProperties(
+            "/xyz/openbmc_project/network/" + ethifaceId,
+            "xyz.openbmc_project.Network.VLAN", dbus_data);
+
+        if (vlanProperties != nullptr)
+        {
+            eth_data.vlanId =
+                extractProperty<unsigned int>(*vlanProperties, "Id");
+        }
+
+        // Extract data that contains link information (auto negotiation and
+        // speed)
+        const PropertiesMapType *ethProperties = extractInterfaceProperties(
+            "/xyz/openbmc_project/network/" + ethifaceId,
+            "xyz.openbmc_project.Network.EthernetInterface", dbus_data);
+
+        if (ethProperties != nullptr)
+        {
+            eth_data.autoNeg = extractProperty<bool>(*ethProperties, "AutoNeg");
+            eth_data.speed =
+                extractProperty<unsigned int>(*ethProperties, "Speed");
+        }
+
+        // Extract data that contains network config (HostName and DefaultGW)
+        const PropertiesMapType *configProperties = extractInterfaceProperties(
+            "/xyz/openbmc_project/network/config",
+            "xyz.openbmc_project.Network.SystemConfiguration", dbus_data);
+
+        if (configProperties != nullptr)
+        {
+            eth_data.hostname =
+                extractProperty<std::string>(*configProperties, "HostName");
+            eth_data.defaultGateway = extractProperty<std::string>(
+                *configProperties, "DefaultGateway");
+        }
+    }
+
+    // Helper function that changes bits netmask notation (i.e. /24)
+    // into full dot notation
+    inline std::string getNetmask(unsigned int bits)
+    {
+        uint32_t value = 0xffffffff << (32 - bits);
+        std::string netmask = std::to_string((value >> 24) & 0xff) + "." +
+                              std::to_string((value >> 16) & 0xff) + "." +
+                              std::to_string((value >> 8) & 0xff) + "." +
+                              std::to_string(value & 0xff);
+        return netmask;
+    }
+
+    // Helper function that extracts data for single ethernet ipv4 address
+    void extractIPv4Data(const std::string &ethifaceId,
+                         const GetManagedObjectsType &dbus_data,
+                         std::vector<IPv4AddressData> &ipv4_config)
+    {
+        const std::string pathStart =
+            "/xyz/openbmc_project/network/" + ethifaceId + "/ipv4/";
+
+        // Since there might be several IPv4 configurations aligned with
+        // single ethernet interface, loop over all of them
+        for (auto &objpath : dbus_data)
+        {
+            // Check if proper patter for object path appears
+            if (boost::starts_with(
+                    static_cast<const std::string &>(objpath.first), pathStart))
+            {
+                // and get approrpiate interface
+                const auto &interface =
+                    objpath.second.find("xyz.openbmc_project.Network.IP");
+                if (interface != objpath.second.end())
+                {
+                    // Make a properties 'shortcut', to make everything more
+                    // readable
+                    const PropertiesMapType &properties = interface->second;
+                    // Instance IPv4AddressData structure, and set as
+                    // appropriate
+                    IPv4AddressData ipv4Address;
+
+                    ipv4Address.id =
+                        static_cast<const std::string &>(objpath.first)
+                            .substr(pathStart.size());
+
+                    // IPv4 address
+                    ipv4Address.address =
+                        extractProperty<std::string>(properties, "Address");
+                    // IPv4 gateway
+                    ipv4Address.gateway =
+                        extractProperty<std::string>(properties, "Gateway");
+
+                    // Origin is kind of DBus object so fetch pointer...
+                    const std::string *origin =
+                        extractProperty<std::string>(properties, "Origin");
+                    if (origin != nullptr)
+                    {
+                        ipv4Address.origin =
+                            translateAddressOriginBetweenDBusAndRedfish(
+                                origin, true, true);
+                    }
+
+                    // Netmask is presented as PrefixLength
+                    const auto *mask =
+                        extractProperty<uint8_t>(properties, "PrefixLength");
+                    if (mask != nullptr)
+                    {
+                        // convert it to the string
+                        ipv4Address.netmask = getNetmask(*mask);
+                    }
+
+                    // Attach IPv4 only if address is present
+                    if (ipv4Address.address != nullptr)
+                    {
+                        // Check if given address is local, or global
+                        if (boost::starts_with(*ipv4Address.address, "169.254"))
+                        {
+                            ipv4Address.global = false;
+                        }
+                        else
+                        {
+                            ipv4Address.global = true;
+                        }
+                        ipv4_config.emplace_back(std::move(ipv4Address));
+                    }
+                }
+            }
+        }
+
+        /**
+         * We have to sort this vector and ensure that order of IPv4 addresses
+         * is consistent between GETs to allow modification and deletion in
+         * PATCHes
+         */
+        std::sort(ipv4_config.begin(), ipv4_config.end());
+    }
+
+    static const constexpr int ipV4AddressSectionsCount = 4;
+
+  public:
+    /**
+     * @brief Creates VLAN for given interface with given Id through D-Bus
+     *
+     * @param[in] ifaceId       Id of interface for which VLAN will be created
+     * @param[in] inputVlanId   ID of the new VLAN
+     * @param[in] callback      Function that will be called after the operation
+     *
+     * @return None.
+     */
+    template <typename CallbackFunc>
+    void createVlan(const std::string &ifaceId, const uint64_t &inputVlanId,
+                    CallbackFunc &&callback)
+    {
+        crow::connections::systemBus->async_method_call(
+            callback, "xyz.openbmc_project.Network",
+            "/xyz/openbmc_project/network",
+            "xyz.openbmc_project.Network.VLAN.Create", "VLAN", ifaceId,
+            static_cast<uint32_t>(inputVlanId));
+    };
+
+    /**
+     * @brief Sets given Id on the given VLAN interface through D-Bus
+     *
+     * @param[in] ifaceId       Id of VLAN interface that should be modified
+     * @param[in] inputVlanId   New ID of the VLAN
+     * @param[in] callback      Function that will be called after the operation
+     *
+     * @return None.
+     */
+    template <typename CallbackFunc>
+    static void changeVlanId(const std::string &ifaceId,
+                             const uint32_t &inputVlanId,
+                             CallbackFunc &&callback)
+    {
+        crow::connections::systemBus->async_method_call(
+            callback, "xyz.openbmc_project.Network",
+            std::string("/xyz/openbmc_project/network/") + ifaceId,
+            "org.freedesktop.DBus.Properties", "Set",
+            "xyz.openbmc_project.Network.VLAN", "Id",
+            sdbusplus::message::variant<uint32_t>(inputVlanId));
+    };
+
+    /**
+     * @brief Helper function that verifies IP address to check if it is in
+     *        proper format. If bits pointer is provided, also calculates active
+     *        bit count for Subnet Mask.
+     *
+     * @param[in]  ip     IP that will be verified
+     * @param[out] bits   Calculated mask in bits notation
+     *
+     * @return true in case of success, false otherwise
+     */
+    bool ipv4VerifyIpAndGetBitcount(const std::string &ip,
+                                    uint8_t *bits = nullptr)
+    {
+        std::vector<std::string> bytesInMask;
+
+        boost::split(bytesInMask, ip, boost::is_any_of("."));
+
+        if (bytesInMask.size() != ipV4AddressSectionsCount)
+        {
+            return false;
+        }
+
+        if (bits != nullptr)
+        {
+            *bits = 0;
+        }
+
+        char *endPtr;
+        long previousValue = 255;
+        bool firstZeroInByteHit;
+        for (const std::string &byte : bytesInMask)
+        {
+            if (byte.empty())
+            {
+                return false;
+            }
+
+            // Use strtol instead of stroi to avoid exceptions
+            long value = std::strtol(byte.c_str(), &endPtr, 10);
+
+            // endPtr should point to the end of the string, otherwise given
+            // string is not 100% number
+            if (*endPtr != '\0')
+            {
+                return false;
+            }
+
+            // Value should be contained in byte
+            if (value < 0 || value > 255)
+            {
+                return false;
+            }
+
+            if (bits != nullptr)
+            {
+                // Mask has to be continuous between bytes
+                if (previousValue != 255 && value != 0)
+                {
+                    return false;
+                }
+
+                // Mask has to be continuous inside bytes
+                firstZeroInByteHit = false;
+
+                // Count bits
+                for (int bitIdx = 7; bitIdx >= 0; bitIdx--)
+                {
+                    if (value & (1 << bitIdx))
+                    {
+                        if (firstZeroInByteHit)
+                        {
+                            // Continuity not preserved
+                            return false;
+                        }
+                        else
+                        {
+                            (*bits)++;
+                        }
+                    }
+                    else
+                    {
+                        firstZeroInByteHit = true;
+                    }
+                }
+            }
+
+            previousValue = value;
+        }
+
+        return true;
     }
 
     /**
-     * We have to sort this vector and ensure that order of IPv4 addresses
-     * is consistent between GETs to allow modification and deletion in PATCHes
+     * @brief Changes IPv4 address type property (Address, Gateway)
+     *
+     * @param[in] ifaceId     Id of interface whose IP should be modified
+     * @param[in] ipIdx       index of IP in input array that should be modified
+     * @param[in] ipHash      DBus Hash id of modified IP
+     * @param[in] name        Name of field in JSON representation
+     * @param[in] newValue    New value that should be written
+     * @param[io] asyncResp   Response object that will be returned to client
+     *
+     * @return true if give IP is valid and has been sent do D-Bus, false
+     * otherwise
      */
-    std::sort(ipv4_config.begin(), ipv4_config.end());
-  }
-
-  static const constexpr int ipV4AddressSectionsCount = 4;
-
- public:
-  /**
-   * @brief Creates VLAN for given interface with given Id through D-Bus
-   *
-   * @param[in] ifaceId       Id of interface for which VLAN will be created
-   * @param[in] inputVlanId   ID of the new VLAN
-   * @param[in] callback      Function that will be called after the operation
-   *
-   * @return None.
-   */
-  template <typename CallbackFunc>
-  void createVlan(const std::string &ifaceId, const uint64_t &inputVlanId,
-                  CallbackFunc &&callback) {
-    crow::connections::systemBus->async_method_call(
-        callback, "xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
-        "xyz.openbmc_project.Network.VLAN.Create", "VLAN", ifaceId,
-        static_cast<uint32_t>(inputVlanId));
-  };
-
-  /**
-   * @brief Sets given Id on the given VLAN interface through D-Bus
-   *
-   * @param[in] ifaceId       Id of VLAN interface that should be modified
-   * @param[in] inputVlanId   New ID of the VLAN
-   * @param[in] callback      Function that will be called after the operation
-   *
-   * @return None.
-   */
-  template <typename CallbackFunc>
-  static void changeVlanId(const std::string &ifaceId,
-                           const uint32_t &inputVlanId,
-                           CallbackFunc &&callback) {
-    crow::connections::systemBus->async_method_call(
-        callback, "xyz.openbmc_project.Network",
-        std::string("/xyz/openbmc_project/network/") + ifaceId,
-        "org.freedesktop.DBus.Properties", "Set",
-        "xyz.openbmc_project.Network.VLAN", "Id",
-        sdbusplus::message::variant<uint32_t>(inputVlanId));
-  };
-
-  /**
-   * @brief Helper function that verifies IP address to check if it is in
-   *        proper format. If bits pointer is provided, also calculates active
-   *        bit count for Subnet Mask.
-   *
-   * @param[in]  ip     IP that will be verified
-   * @param[out] bits   Calculated mask in bits notation
-   *
-   * @return true in case of success, false otherwise
-   */
-  bool ipv4VerifyIpAndGetBitcount(const std::string &ip,
-                                  uint8_t *bits = nullptr) {
-    std::vector<std::string> bytesInMask;
-
-    boost::split(bytesInMask, ip, boost::is_any_of("."));
-
-    if (bytesInMask.size() != ipV4AddressSectionsCount) {
-      return false;
-    }
-
-    if (bits != nullptr) {
-      *bits = 0;
-    }
-
-    char *endPtr;
-    long previousValue = 255;
-    bool firstZeroInByteHit;
-    for (const std::string &byte : bytesInMask) {
-      if (byte.empty()) {
-        return false;
-      }
-
-      // Use strtol instead of stroi to avoid exceptions
-      long value = std::strtol(byte.c_str(), &endPtr, 10);
-
-      // endPtr should point to the end of the string, otherwise given string
-      // is not 100% number
-      if (*endPtr != '\0') {
-        return false;
-      }
-
-      // Value should be contained in byte
-      if (value < 0 || value > 255) {
-        return false;
-      }
-
-      if (bits != nullptr) {
-        // Mask has to be continuous between bytes
-        if (previousValue != 255 && value != 0) {
-          return false;
-        }
-
-        // Mask has to be continuous inside bytes
-        firstZeroInByteHit = false;
-
-        // Count bits
-        for (int bitIdx = 7; bitIdx >= 0; bitIdx--) {
-          if (value & (1 << bitIdx)) {
-            if (firstZeroInByteHit) {
-              // Continuity not preserved
-              return false;
-            } else {
-              (*bits)++;
+    void changeIPv4AddressProperty(const std::string &ifaceId, int ipIdx,
+                                   const std::string &ipHash,
+                                   const std::string &name,
+                                   const std::string &newValue,
+                                   const std::shared_ptr<AsyncResp> &asyncResp)
+    {
+        auto callback = [asyncResp, ipIdx{std::move(ipIdx)},
+                         name{std::move(name)}, newValue{std::move(newValue)}](
+                            const boost::system::error_code ec) {
+            if (ec)
+            {
+                messages::addMessageToJson(
+                    asyncResp->res.jsonValue, messages::internalError(),
+                    "/IPv4Addresses/" + std::to_string(ipIdx) + "/" + name);
             }
-          } else {
-            firstZeroInByteHit = true;
-          }
-        }
-      }
-
-      previousValue = value;
-    }
-
-    return true;
-  }
-
-  /**
-   * @brief Changes IPv4 address type property (Address, Gateway)
-   *
-   * @param[in] ifaceId     Id of interface whose IP should be modified
-   * @param[in] ipIdx       index of IP in input array that should be modified
-   * @param[in] ipHash      DBus Hash id of modified IP
-   * @param[in] name        Name of field in JSON representation
-   * @param[in] newValue    New value that should be written
-   * @param[io] asyncResp   Response object that will be returned to client
-   *
-   * @return true if give IP is valid and has been sent do D-Bus, false
-   * otherwise
-   */
-  void changeIPv4AddressProperty(const std::string &ifaceId, int ipIdx,
-                                 const std::string &ipHash,
-                                 const std::string &name,
-                                 const std::string &newValue,
-                                 const std::shared_ptr<AsyncResp> &asyncResp) {
-    auto callback = [
-      asyncResp, ipIdx{std::move(ipIdx)}, name{std::move(name)},
-      newValue{std::move(newValue)}
-    ](const boost::system::error_code ec) {
-      if (ec) {
-        messages::addMessageToJson(
-            asyncResp->res.jsonValue, messages::internalError(),
-            "/IPv4Addresses/" + std::to_string(ipIdx) + "/" + name);
-      } else {
-        asyncResp->res.jsonValue["IPv4Addresses"][ipIdx][name] = newValue;
-      }
-    };
-
-    crow::connections::systemBus->async_method_call(
-        std::move(callback), "xyz.openbmc_project.Network",
-        "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash,
-        "org.freedesktop.DBus.Properties", "Set",
-        "xyz.openbmc_project.Network.IP", name,
-        sdbusplus::message::variant<std::string>(newValue));
-  };
-
-  /**
-   * @brief Changes IPv4 address origin property
-   *
-   * @param[in] ifaceId       Id of interface whose IP should be modified
-   * @param[in] ipIdx         index of IP in input array that should be modified
-   * @param[in] ipHash        DBus Hash id of modified IP
-   * @param[in] newValue      New value in Redfish format
-   * @param[in] newValueDbus  New value in D-Bus format
-   * @param[io] asyncResp     Response object that will be returned to client
-   *
-   * @return true if give IP is valid and has been sent do D-Bus, false
-   * otherwise
-   */
-  void changeIPv4Origin(const std::string &ifaceId, int ipIdx,
-                        const std::string &ipHash, const std::string &newValue,
-                        const std::string &newValueDbus,
-                        const std::shared_ptr<AsyncResp> &asyncResp) {
-    auto callback =
-        [ asyncResp, ipIdx{std::move(ipIdx)},
-          newValue{std::move(newValue)} ](const boost::system::error_code ec) {
-      if (ec) {
-        messages::addMessageToJson(
-            asyncResp->res.jsonValue, messages::internalError(),
-            "/IPv4Addresses/" + std::to_string(ipIdx) + "/AddressOrigin");
-      } else {
-        asyncResp->res.jsonValue["IPv4Addresses"][ipIdx]["AddressOrigin"] =
-            newValue;
-      }
-    };
-
-    crow::connections::systemBus->async_method_call(
-        std::move(callback), "xyz.openbmc_project.Network",
-        "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash,
-        "org.freedesktop.DBus.Properties", "Set",
-        "xyz.openbmc_project.Network.IP", "Origin",
-        sdbusplus::message::variant<std::string>(newValueDbus));
-  };
-
-  /**
-   * @brief Modifies SubnetMask for given IP
-   *
-   * @param[in] ifaceId      Id of interface whose IP should be modified
-   * @param[in] ipIdx        index of IP in input array that should be modified
-   * @param[in] ipHash       DBus Hash id of modified IP
-   * @param[in] newValueStr  Mask in dot notation as string
-   * @param[in] newValue     Mask as PrefixLength in bitcount
-   * @param[io] asyncResp   Response object that will be returned to client
-   *
-   * @return None
-   */
-  void changeIPv4SubnetMaskProperty(
-      const std::string &ifaceId, int ipIdx, const std::string &ipHash,
-      const std::string &newValueStr, uint8_t &newValue,
-      const std::shared_ptr<AsyncResp> &asyncResp) {
-    auto callback = [
-      asyncResp, ipIdx{std::move(ipIdx)}, newValueStr{std::move(newValueStr)}
-    ](const boost::system::error_code ec) {
-      if (ec) {
-        messages::addMessageToJson(
-            asyncResp->res.jsonValue, messages::internalError(),
-            "/IPv4Addresses/" + std::to_string(ipIdx) + "/SubnetMask");
-      } else {
-        asyncResp->res.jsonValue["IPv4Addresses"][ipIdx]["SubnetMask"] =
-            newValueStr;
-      }
-    };
-
-    crow::connections::systemBus->async_method_call(
-        std::move(callback), "xyz.openbmc_project.Network",
-        "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash,
-        "org.freedesktop.DBus.Properties", "Set",
-        "xyz.openbmc_project.Network.IP", "PrefixLength",
-        sdbusplus::message::variant<uint8_t>(newValue));
-  };
-
-  /**
-   * @brief Disables VLAN with given ifaceId
-   *
-   * @param[in] ifaceId   Id of VLAN interface that should be disabled
-   * @param[in] callback  Function that will be called after the operation
-   *
-   * @return None.
-   */
-  template <typename CallbackFunc>
-  static void disableVlan(const std::string &ifaceId, CallbackFunc &&callback) {
-    crow::connections::systemBus->async_method_call(
-        callback, "xyz.openbmc_project.Network",
-        std::string("/xyz/openbmc_project/network/") + ifaceId,
-        "xyz.openbmc_project.Object.Delete", "Delete");
-  };
-
-  /**
-   * @brief Sets given HostName of the machine through D-Bus
-   *
-   * @param[in] newHostname   New name that HostName will be changed to
-   * @param[in] callback      Function that will be called after the operation
-   *
-   * @return None.
-   */
-  template <typename CallbackFunc>
-  void setHostName(const std::string &newHostname, CallbackFunc &&callback) {
-    crow::connections::systemBus->async_method_call(
-        callback, "xyz.openbmc_project.Network",
-        "/xyz/openbmc_project/network/config",
-        "org.freedesktop.DBus.Properties", "Set",
-        "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
-        sdbusplus::message::variant<std::string>(newHostname));
-  };
-
-  /**
-   * @brief Deletes given IPv4
-   *
-   * @param[in] ifaceId     Id of interface whose IP should be deleted
-   * @param[in] ipIdx       index of IP in input array that should be deleted
-   * @param[in] ipHash      DBus Hash id of IP that should be deleted
-   * @param[io] asyncResp   Response object that will be returned to client
-   *
-   * @return None
-   */
-  void deleteIPv4(const std::string &ifaceId, const std::string &ipHash,
-                  unsigned int ipIdx,
-                  const std::shared_ptr<AsyncResp> &asyncResp) {
-    crow::connections::systemBus->async_method_call(
-        [ ipIdx{std::move(ipIdx)}, asyncResp{std::move(asyncResp)} ](
-            const boost::system::error_code ec) {
-          if (ec) {
-            messages::addMessageToJson(
-                asyncResp->res.jsonValue, messages::internalError(),
-                "/IPv4Addresses/" + std::to_string(ipIdx) + "/");
-          } else {
-            asyncResp->res.jsonValue["IPv4Addresses"][ipIdx] = nullptr;
-          }
-        },
-        "xyz.openbmc_project.Network",
-        "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash,
-        "xyz.openbmc_project.Object.Delete", "Delete");
-  }
-
-  /**
-   * @brief Creates IPv4 with given data
-   *
-   * @param[in] ifaceId     Id of interface whose IP should be deleted
-   * @param[in] ipIdx       index of IP in input array that should be deleted
-   * @param[in] ipHash      DBus Hash id of IP that should be deleted
-   * @param[io] asyncResp   Response object that will be returned to client
-   *
-   * @return None
-   */
-  void createIPv4(const std::string &ifaceId, unsigned int ipIdx,
-                  uint8_t subnetMask, const std::string &gateway,
-                  const std::string &address,
-                  const std::shared_ptr<AsyncResp> &asyncResp) {
-    auto createIpHandler = [
-      ipIdx{std::move(ipIdx)}, asyncResp{std::move(asyncResp)}
-    ](const boost::system::error_code ec) {
-      if (ec) {
-        messages::addMessageToJson(
-            asyncResp->res.jsonValue, messages::internalError(),
-            "/IPv4Addresses/" + std::to_string(ipIdx) + "/");
-      }
-    };
-
-    crow::connections::systemBus->async_method_call(
-        std::move(createIpHandler), "xyz.openbmc_project.Network",
-        "/xyz/openbmc_project/network/" + ifaceId,
-        "xyz.openbmc_project.Network.IP.Create", "IP",
-        "xyz.openbmc_project.Network.IP.Protocol.IPv4", address, subnetMask,
-        gateway);
-  }
-
-  /**
-   * @brief Translates Address Origin value from D-Bus to Redfish format and
-   *        vice-versa
-   *
-   * @param[in] inputOrigin Input value that should be translated
-   * @param[in] isIPv4      True for IPv4 origins, False for IPv6
-   * @param[in] isFromDBus  True for DBus->Redfish conversion, false for reverse
-   *
-   * @return Empty string in case of failure, translated value otherwise
-   */
-  std::string translateAddressOriginBetweenDBusAndRedfish(
-      const std::string *inputOrigin, bool isIPv4, bool isFromDBus) {
-    // Invalid pointer
-    if (inputOrigin == nullptr) {
-      return "";
-    }
-
-    static const constexpr unsigned int firstIPv4OnlyIdx = 1;
-    static const constexpr unsigned int firstIPv6OnlyIdx = 3;
-
-    std::array<std::pair<const char *, const char *>, 6> translationTable{
-        {{"xyz.openbmc_project.Network.IP.AddressOrigin.Static", "Static"},
-         {"xyz.openbmc_project.Network.IP.AddressOrigin.DHCP", "DHCP"},
-         {"xyz.openbmc_project.Network.IP.AddressOrigin.LinkLocal",
-          "IPv4LinkLocal"},
-         {"xyz.openbmc_project.Network.IP.AddressOrigin.DHCP", "DHCPv6"},
-         {"xyz.openbmc_project.Network.IP.AddressOrigin.LinkLocal",
-          "LinkLocal"},
-         {"xyz.openbmc_project.Network.IP.AddressOrigin.SLAAC", "SLAAC"}}};
-
-    for (unsigned int i = 0; i < translationTable.size(); i++) {
-      // Skip unrelated
-      if (isIPv4 && i >= firstIPv6OnlyIdx) break;
-      if (!isIPv4 && i >= firstIPv4OnlyIdx && i < firstIPv6OnlyIdx) continue;
-
-      // When translating D-Bus to Redfish compare input to first element
-      if (isFromDBus && translationTable[i].first == *inputOrigin)
-        return translationTable[i].second;
-
-      // When translating Redfish to D-Bus compare input to second element
-      if (!isFromDBus && translationTable[i].second == *inputOrigin)
-        return translationTable[i].first;
-    }
-
-    // If we are still here, that means that value has not been found
-    return "";
-  }
-
-  /**
-   * Function that retrieves all properties for given Ethernet Interface
-   * Object
-   * from EntityManager Network Manager
-   * @param ethifaceId a eth interface id to query on DBus
-   * @param callback a function that shall be called to convert Dbus output
-   * into JSON
-   */
-  template <typename CallbackFunc>
-  void getEthernetIfaceData(const std::string &ethifaceId,
-                            CallbackFunc &&callback) {
-    crow::connections::systemBus->async_method_call(
-        [
-          this, ethifaceId{std::move(ethifaceId)}, callback{std::move(callback)}
-        ](const boost::system::error_code error_code,
-          const GetManagedObjectsType &resp) {
-          EthernetInterfaceData ethData{};
-          std::vector<IPv4AddressData> ipv4Data;
-          ipv4Data.reserve(maxIpV4AddressesPerInterface);
-
-          if (error_code) {
-            // Something wrong on DBus, the error_code is not important at
-            // this moment, just return success=false, and empty output. Since
-            // size of vector may vary depending on information from Network
-            // Manager, and empty output could not be treated same way as
-            // error.
-            callback(false, ethData, ipv4Data);
-            return;
-          }
-
-          // Find interface
-          if (resp.find("/xyz/openbmc_project/network/" + ethifaceId) ==
-              resp.end()) {
-            // Interface has not been found
-            callback(false, ethData, ipv4Data);
-            return;
-          }
-
-          extractEthernetInterfaceData(ethifaceId, resp, ethData);
-          extractIPv4Data(ethifaceId, resp, ipv4Data);
-
-          // Fix global GW
-          for (IPv4AddressData &ipv4 : ipv4Data) {
-            if ((ipv4.global) &&
-                ((ipv4.gateway == nullptr) || (*ipv4.gateway == "0.0.0.0"))) {
-              ipv4.gateway = ethData.defaultGateway;
+            else
+            {
+                asyncResp->res.jsonValue["IPv4Addresses"][ipIdx][name] =
+                    newValue;
             }
-          }
+        };
 
-          // Finally make a callback with useful data
-          callback(true, ethData, ipv4Data);
-        },
-        "xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
-        "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
-  };
+        crow::connections::systemBus->async_method_call(
+            std::move(callback), "xyz.openbmc_project.Network",
+            "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash,
+            "org.freedesktop.DBus.Properties", "Set",
+            "xyz.openbmc_project.Network.IP", name,
+            sdbusplus::message::variant<std::string>(newValue));
+    };
 
-  /**
-   * Function that retrieves all Ethernet Interfaces available through Network
-   * Manager
-   * @param callback a function that shall be called to convert Dbus output into
-   * JSON.
-   */
-  template <typename CallbackFunc>
-  void getEthernetIfaceList(CallbackFunc &&callback) {
-    crow::connections::systemBus->async_method_call(
-        [ this, callback{std::move(callback)} ](
-            const boost::system::error_code error_code,
-            GetManagedObjectsType &resp) {
-          // Callback requires vector<string> to retrieve all available ethernet
-          // interfaces
-          std::vector<std::string> ifaceList;
-          ifaceList.reserve(resp.size());
-          if (error_code) {
-            // Something wrong on DBus, the error_code is not important at this
-            // moment, just return success=false, and empty output. Since size
-            // of vector may vary depending on information from Network Manager,
-            // and empty output could not be treated same way as error.
-            callback(false, ifaceList);
-            return;
-          }
+    /**
+     * @brief Changes IPv4 address origin property
+     *
+     * @param[in] ifaceId       Id of interface whose IP should be modified
+     * @param[in] ipIdx         index of IP in input array that should be
+     * modified
+     * @param[in] ipHash        DBus Hash id of modified IP
+     * @param[in] newValue      New value in Redfish format
+     * @param[in] newValueDbus  New value in D-Bus format
+     * @param[io] asyncResp     Response object that will be returned to client
+     *
+     * @return true if give IP is valid and has been sent do D-Bus, false
+     * otherwise
+     */
+    void changeIPv4Origin(const std::string &ifaceId, int ipIdx,
+                          const std::string &ipHash,
+                          const std::string &newValue,
+                          const std::string &newValueDbus,
+                          const std::shared_ptr<AsyncResp> &asyncResp)
+    {
+        auto callback = [asyncResp, ipIdx{std::move(ipIdx)},
+                         newValue{std::move(newValue)}](
+                            const boost::system::error_code ec) {
+            if (ec)
+            {
+                messages::addMessageToJson(
+                    asyncResp->res.jsonValue, messages::internalError(),
+                    "/IPv4Addresses/" + std::to_string(ipIdx) +
+                        "/AddressOrigin");
+            }
+            else
+            {
+                asyncResp->res
+                    .jsonValue["IPv4Addresses"][ipIdx]["AddressOrigin"] =
+                    newValue;
+            }
+        };
 
-          // Iterate over all retrieved ObjectPaths.
-          for (auto &objpath : resp) {
-            // And all interfaces available for certain ObjectPath.
-            for (auto &interface : objpath.second) {
-              // If interface is xyz.openbmc_project.Network.EthernetInterface,
-              // this is what we're looking for.
-              if (interface.first ==
-                  "xyz.openbmc_project.Network.EthernetInterface") {
-                // Cut out everything until last "/", ...
-                const std::string &ifaceId =
-                    static_cast<const std::string &>(objpath.first);
-                std::size_t lastPos = ifaceId.rfind("/");
-                if (lastPos != std::string::npos) {
-                  // and put it into output vector.
-                  ifaceList.emplace_back(ifaceId.substr(lastPos + 1));
+        crow::connections::systemBus->async_method_call(
+            std::move(callback), "xyz.openbmc_project.Network",
+            "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash,
+            "org.freedesktop.DBus.Properties", "Set",
+            "xyz.openbmc_project.Network.IP", "Origin",
+            sdbusplus::message::variant<std::string>(newValueDbus));
+    };
+
+    /**
+     * @brief Modifies SubnetMask for given IP
+     *
+     * @param[in] ifaceId      Id of interface whose IP should be modified
+     * @param[in] ipIdx        index of IP in input array that should be
+     * modified
+     * @param[in] ipHash       DBus Hash id of modified IP
+     * @param[in] newValueStr  Mask in dot notation as string
+     * @param[in] newValue     Mask as PrefixLength in bitcount
+     * @param[io] asyncResp   Response object that will be returned to client
+     *
+     * @return None
+     */
+    void changeIPv4SubnetMaskProperty(
+        const std::string &ifaceId, int ipIdx, const std::string &ipHash,
+        const std::string &newValueStr, uint8_t &newValue,
+        const std::shared_ptr<AsyncResp> &asyncResp)
+    {
+        auto callback = [asyncResp, ipIdx{std::move(ipIdx)},
+                         newValueStr{std::move(newValueStr)}](
+                            const boost::system::error_code ec) {
+            if (ec)
+            {
+                messages::addMessageToJson(
+                    asyncResp->res.jsonValue, messages::internalError(),
+                    "/IPv4Addresses/" + std::to_string(ipIdx) + "/SubnetMask");
+            }
+            else
+            {
+                asyncResp->res.jsonValue["IPv4Addresses"][ipIdx]["SubnetMask"] =
+                    newValueStr;
+            }
+        };
+
+        crow::connections::systemBus->async_method_call(
+            std::move(callback), "xyz.openbmc_project.Network",
+            "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash,
+            "org.freedesktop.DBus.Properties", "Set",
+            "xyz.openbmc_project.Network.IP", "PrefixLength",
+            sdbusplus::message::variant<uint8_t>(newValue));
+    };
+
+    /**
+     * @brief Disables VLAN with given ifaceId
+     *
+     * @param[in] ifaceId   Id of VLAN interface that should be disabled
+     * @param[in] callback  Function that will be called after the operation
+     *
+     * @return None.
+     */
+    template <typename CallbackFunc>
+    static void disableVlan(const std::string &ifaceId, CallbackFunc &&callback)
+    {
+        crow::connections::systemBus->async_method_call(
+            callback, "xyz.openbmc_project.Network",
+            std::string("/xyz/openbmc_project/network/") + ifaceId,
+            "xyz.openbmc_project.Object.Delete", "Delete");
+    };
+
+    /**
+     * @brief Sets given HostName of the machine through D-Bus
+     *
+     * @param[in] newHostname   New name that HostName will be changed to
+     * @param[in] callback      Function that will be called after the operation
+     *
+     * @return None.
+     */
+    template <typename CallbackFunc>
+    void setHostName(const std::string &newHostname, CallbackFunc &&callback)
+    {
+        crow::connections::systemBus->async_method_call(
+            callback, "xyz.openbmc_project.Network",
+            "/xyz/openbmc_project/network/config",
+            "org.freedesktop.DBus.Properties", "Set",
+            "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
+            sdbusplus::message::variant<std::string>(newHostname));
+    };
+
+    /**
+     * @brief Deletes given IPv4
+     *
+     * @param[in] ifaceId     Id of interface whose IP should be deleted
+     * @param[in] ipIdx       index of IP in input array that should be deleted
+     * @param[in] ipHash      DBus Hash id of IP that should be deleted
+     * @param[io] asyncResp   Response object that will be returned to client
+     *
+     * @return None
+     */
+    void deleteIPv4(const std::string &ifaceId, const std::string &ipHash,
+                    unsigned int ipIdx,
+                    const std::shared_ptr<AsyncResp> &asyncResp)
+    {
+        crow::connections::systemBus->async_method_call(
+            [ipIdx{std::move(ipIdx)}, asyncResp{std::move(asyncResp)}](
+                const boost::system::error_code ec) {
+                if (ec)
+                {
+                    messages::addMessageToJson(
+                        asyncResp->res.jsonValue, messages::internalError(),
+                        "/IPv4Addresses/" + std::to_string(ipIdx) + "/");
                 }
-              }
+                else
+                {
+                    asyncResp->res.jsonValue["IPv4Addresses"][ipIdx] = nullptr;
+                }
+            },
+            "xyz.openbmc_project.Network",
+            "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash,
+            "xyz.openbmc_project.Object.Delete", "Delete");
+    }
+
+    /**
+     * @brief Creates IPv4 with given data
+     *
+     * @param[in] ifaceId     Id of interface whose IP should be deleted
+     * @param[in] ipIdx       index of IP in input array that should be deleted
+     * @param[in] ipHash      DBus Hash id of IP that should be deleted
+     * @param[io] asyncResp   Response object that will be returned to client
+     *
+     * @return None
+     */
+    void createIPv4(const std::string &ifaceId, unsigned int ipIdx,
+                    uint8_t subnetMask, const std::string &gateway,
+                    const std::string &address,
+                    const std::shared_ptr<AsyncResp> &asyncResp)
+    {
+        auto createIpHandler = [ipIdx{std::move(ipIdx)},
+                                asyncResp{std::move(asyncResp)}](
+                                   const boost::system::error_code ec) {
+            if (ec)
+            {
+                messages::addMessageToJson(
+                    asyncResp->res.jsonValue, messages::internalError(),
+                    "/IPv4Addresses/" + std::to_string(ipIdx) + "/");
             }
-          }
-          // Finally make a callback with useful data
-          callback(true, ifaceList);
-        },
-        "xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
-        "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
-  };
+        };
+
+        crow::connections::systemBus->async_method_call(
+            std::move(createIpHandler), "xyz.openbmc_project.Network",
+            "/xyz/openbmc_project/network/" + ifaceId,
+            "xyz.openbmc_project.Network.IP.Create", "IP",
+            "xyz.openbmc_project.Network.IP.Protocol.IPv4", address, subnetMask,
+            gateway);
+    }
+
+    /**
+     * @brief Translates Address Origin value from D-Bus to Redfish format and
+     *        vice-versa
+     *
+     * @param[in] inputOrigin Input value that should be translated
+     * @param[in] isIPv4      True for IPv4 origins, False for IPv6
+     * @param[in] isFromDBus  True for DBus->Redfish conversion, false for
+     * reverse
+     *
+     * @return Empty string in case of failure, translated value otherwise
+     */
+    std::string translateAddressOriginBetweenDBusAndRedfish(
+        const std::string *inputOrigin, bool isIPv4, bool isFromDBus)
+    {
+        // Invalid pointer
+        if (inputOrigin == nullptr)
+        {
+            return "";
+        }
+
+        static const constexpr unsigned int firstIPv4OnlyIdx = 1;
+        static const constexpr unsigned int firstIPv6OnlyIdx = 3;
+
+        std::array<std::pair<const char *, const char *>, 6> translationTable{
+            {{"xyz.openbmc_project.Network.IP.AddressOrigin.Static", "Static"},
+             {"xyz.openbmc_project.Network.IP.AddressOrigin.DHCP", "DHCP"},
+             {"xyz.openbmc_project.Network.IP.AddressOrigin.LinkLocal",
+              "IPv4LinkLocal"},
+             {"xyz.openbmc_project.Network.IP.AddressOrigin.DHCP", "DHCPv6"},
+             {"xyz.openbmc_project.Network.IP.AddressOrigin.LinkLocal",
+              "LinkLocal"},
+             {"xyz.openbmc_project.Network.IP.AddressOrigin.SLAAC", "SLAAC"}}};
+
+        for (unsigned int i = 0; i < translationTable.size(); i++)
+        {
+            // Skip unrelated
+            if (isIPv4 && i >= firstIPv6OnlyIdx)
+                break;
+            if (!isIPv4 && i >= firstIPv4OnlyIdx && i < firstIPv6OnlyIdx)
+                continue;
+
+            // When translating D-Bus to Redfish compare input to first element
+            if (isFromDBus && translationTable[i].first == *inputOrigin)
+                return translationTable[i].second;
+
+            // When translating Redfish to D-Bus compare input to second element
+            if (!isFromDBus && translationTable[i].second == *inputOrigin)
+                return translationTable[i].first;
+        }
+
+        // If we are still here, that means that value has not been found
+        return "";
+    }
+
+    /**
+     * Function that retrieves all properties for given Ethernet Interface
+     * Object
+     * from EntityManager Network Manager
+     * @param ethifaceId a eth interface id to query on DBus
+     * @param callback a function that shall be called to convert Dbus output
+     * into JSON
+     */
+    template <typename CallbackFunc>
+    void getEthernetIfaceData(const std::string &ethifaceId,
+                              CallbackFunc &&callback)
+    {
+        crow::connections::systemBus->async_method_call(
+            [this, ethifaceId{std::move(ethifaceId)},
+             callback{std::move(callback)}](
+                const boost::system::error_code error_code,
+                const GetManagedObjectsType &resp) {
+                EthernetInterfaceData ethData{};
+                std::vector<IPv4AddressData> ipv4Data;
+                ipv4Data.reserve(maxIpV4AddressesPerInterface);
+
+                if (error_code)
+                {
+                    // Something wrong on DBus, the error_code is not important
+                    // at this moment, just return success=false, and empty
+                    // output. Since size of vector may vary depending on
+                    // information from Network Manager, and empty output could
+                    // not be treated same way as error.
+                    callback(false, ethData, ipv4Data);
+                    return;
+                }
+
+                // Find interface
+                if (resp.find("/xyz/openbmc_project/network/" + ethifaceId) ==
+                    resp.end())
+                {
+                    // Interface has not been found
+                    callback(false, ethData, ipv4Data);
+                    return;
+                }
+
+                extractEthernetInterfaceData(ethifaceId, resp, ethData);
+                extractIPv4Data(ethifaceId, resp, ipv4Data);
+
+                // Fix global GW
+                for (IPv4AddressData &ipv4 : ipv4Data)
+                {
+                    if ((ipv4.global) && ((ipv4.gateway == nullptr) ||
+                                          (*ipv4.gateway == "0.0.0.0")))
+                    {
+                        ipv4.gateway = ethData.defaultGateway;
+                    }
+                }
+
+                // Finally make a callback with useful data
+                callback(true, ethData, ipv4Data);
+            },
+            "xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
+            "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+    };
+
+    /**
+     * Function that retrieves all Ethernet Interfaces available through Network
+     * Manager
+     * @param callback a function that shall be called to convert Dbus output
+     * into JSON.
+     */
+    template <typename CallbackFunc>
+    void getEthernetIfaceList(CallbackFunc &&callback)
+    {
+        crow::connections::systemBus->async_method_call(
+            [this, callback{std::move(callback)}](
+                const boost::system::error_code error_code,
+                GetManagedObjectsType &resp) {
+                // Callback requires vector<string> to retrieve all available
+                // ethernet interfaces
+                std::vector<std::string> ifaceList;
+                ifaceList.reserve(resp.size());
+                if (error_code)
+                {
+                    // Something wrong on DBus, the error_code is not important
+                    // at this moment, just return success=false, and empty
+                    // output. Since size of vector may vary depending on
+                    // information from Network Manager, and empty output could
+                    // not be treated same way as error.
+                    callback(false, ifaceList);
+                    return;
+                }
+
+                // Iterate over all retrieved ObjectPaths.
+                for (auto &objpath : resp)
+                {
+                    // And all interfaces available for certain ObjectPath.
+                    for (auto &interface : objpath.second)
+                    {
+                        // If interface is
+                        // xyz.openbmc_project.Network.EthernetInterface, this
+                        // is what we're looking for.
+                        if (interface.first ==
+                            "xyz.openbmc_project.Network.EthernetInterface")
+                        {
+                            // Cut out everything until last "/", ...
+                            const std::string &ifaceId =
+                                static_cast<const std::string &>(objpath.first);
+                            std::size_t lastPos = ifaceId.rfind("/");
+                            if (lastPos != std::string::npos)
+                            {
+                                // and put it into output vector.
+                                ifaceList.emplace_back(
+                                    ifaceId.substr(lastPos + 1));
+                            }
+                        }
+                    }
+                }
+                // Finally make a callback with useful data
+                callback(true, ifaceList);
+            },
+            "xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
+            "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+    };
 };
 
 /**
  * EthernetCollection derived class for delivering Ethernet Collection Schema
  */
-class EthernetCollection : public Node {
- public:
-  // TODO(Pawel) Remove line from below, where we assume that there is only one
-  // manager called openbmc This shall be generic, but requires to update
-  // GetSubroutes method
-  EthernetCollection(CrowApp &app)
-      : Node(app, "/redfish/v1/Managers/openbmc/EthernetInterfaces/") {
-    Node::json["@odata.type"] =
-        "#EthernetInterfaceCollection.EthernetInterfaceCollection";
-    Node::json["@odata.context"] =
-        "/redfish/v1/"
-        "$metadata#EthernetInterfaceCollection.EthernetInterfaceCollection";
-    Node::json["@odata.id"] = "/redfish/v1/Managers/openbmc/EthernetInterfaces";
-    Node::json["Name"] = "Ethernet Network Interface Collection";
-    Node::json["Description"] =
-        "Collection of EthernetInterfaces for this Manager";
-
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-  }
-
- private:
-  /**
-   * Functions triggers appropriate requests on DBus
-   */
-  void doGet(crow::Response &res, const crow::Request &req,
-             const std::vector<std::string> &params) override {
-    // TODO(Pawel) this shall be parametrized call to get EthernetInterfaces for
-    // any Manager, not only hardcoded 'openbmc'.
-    std::string managerId = "openbmc";
-
-    // get eth interface list, and call the below callback for JSON preparation
-    ethernetProvider.getEthernetIfaceList([&, managerId{std::move(managerId)} ](
-        const bool &success, const std::vector<std::string> &iface_list) {
-      if (success) {
-        nlohmann::json ifaceArray = nlohmann::json::array();
-        for (const std::string &ifaceItem : iface_list) {
-          ifaceArray.push_back(
-              {{"@odata.id", "/redfish/v1/Managers/" + managerId +
-                                 "/EthernetInterfaces/" + ifaceItem}});
-        }
-        Node::json["Members"] = ifaceArray;
-        Node::json["Members@odata.count"] = ifaceArray.size();
+class EthernetCollection : public Node
+{
+  public:
+    // TODO(Pawel) Remove line from below, where we assume that there is only
+    // one manager called openbmc This shall be generic, but requires to update
+    // GetSubroutes method
+    EthernetCollection(CrowApp &app) :
+        Node(app, "/redfish/v1/Managers/openbmc/EthernetInterfaces/")
+    {
+        Node::json["@odata.type"] =
+            "#EthernetInterfaceCollection.EthernetInterfaceCollection";
+        Node::json["@odata.context"] =
+            "/redfish/v1/"
+            "$metadata#EthernetInterfaceCollection.EthernetInterfaceCollection";
         Node::json["@odata.id"] =
-            "/redfish/v1/Managers/" + managerId + "/EthernetInterfaces";
-        res.jsonValue = Node::json;
-      } else {
-        // No success, best what we can do is return INTERNALL ERROR
-        res.result(boost::beast::http::status::internal_server_error);
-      }
-      res.end();
-    });
-  }
+            "/redfish/v1/Managers/openbmc/EthernetInterfaces";
+        Node::json["Name"] = "Ethernet Network Interface Collection";
+        Node::json["Description"] =
+            "Collection of EthernetInterfaces for this Manager";
 
-  // Ethernet Provider object
-  // TODO(Pawel) consider move it to singleton
-  OnDemandEthernetProvider ethernetProvider;
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
+    }
+
+  private:
+    /**
+     * Functions triggers appropriate requests on DBus
+     */
+    void doGet(crow::Response &res, const crow::Request &req,
+               const std::vector<std::string> &params) override
+    {
+        // TODO(Pawel) this shall be parametrized call to get EthernetInterfaces
+        // for any Manager, not only hardcoded 'openbmc'.
+        std::string managerId = "openbmc";
+
+        // get eth interface list, and call the below callback for JSON
+        // preparation
+        ethernetProvider.getEthernetIfaceList(
+            [&, managerId{std::move(managerId)}](
+                const bool &success,
+                const std::vector<std::string> &iface_list) {
+                if (success)
+                {
+                    nlohmann::json ifaceArray = nlohmann::json::array();
+                    for (const std::string &ifaceItem : iface_list)
+                    {
+                        ifaceArray.push_back(
+                            {{"@odata.id", "/redfish/v1/Managers/" + managerId +
+                                               "/EthernetInterfaces/" +
+                                               ifaceItem}});
+                    }
+                    Node::json["Members"] = ifaceArray;
+                    Node::json["Members@odata.count"] = ifaceArray.size();
+                    Node::json["@odata.id"] = "/redfish/v1/Managers/" +
+                                              managerId + "/EthernetInterfaces";
+                    res.jsonValue = Node::json;
+                }
+                else
+                {
+                    // No success, best what we can do is return INTERNALL ERROR
+                    res.result(
+                        boost::beast::http::status::internal_server_error);
+                }
+                res.end();
+            });
+    }
+
+    // Ethernet Provider object
+    // TODO(Pawel) consider move it to singleton
+    OnDemandEthernetProvider ethernetProvider;
 };
 
 /**
  * EthernetInterface derived class for delivering Ethernet Schema
  */
-class EthernetInterface : public Node {
- public:
-  /*
-   * Default Constructor
-   */
-  // TODO(Pawel) Remove line from below, where we assume that there is only one
-  // manager called openbmc This shall be generic, but requires to update
-  // GetSubroutes method
-  EthernetInterface(CrowApp &app)
-      : Node(app, "/redfish/v1/Managers/openbmc/EthernetInterfaces/<str>/",
-             std::string()) {
-    Node::json["@odata.type"] = "#EthernetInterface.v1_2_0.EthernetInterface";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata#EthernetInterface.EthernetInterface";
-    Node::json["Name"] = "Manager Ethernet Interface";
-    Node::json["Description"] = "Management Network Interface";
+class EthernetInterface : public Node
+{
+  public:
+    /*
+     * Default Constructor
+     */
+    // TODO(Pawel) Remove line from below, where we assume that there is only
+    // one manager called openbmc This shall be generic, but requires to update
+    // GetSubroutes method
+    EthernetInterface(CrowApp &app) :
+        Node(app, "/redfish/v1/Managers/openbmc/EthernetInterfaces/<str>/",
+             std::string())
+    {
+        Node::json["@odata.type"] =
+            "#EthernetInterface.v1_2_0.EthernetInterface";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata#EthernetInterface.EthernetInterface";
+        Node::json["Name"] = "Manager Ethernet Interface";
+        Node::json["Description"] = "Management Network Interface";
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-  }
-
-  // TODO(kkowalsk) Find a suitable class/namespace for this
-  static void handleVlanPatch(const std::string &ifaceId,
-                              const nlohmann::json &input,
-                              const EthernetInterfaceData &eth_data,
-                              const std::string &pathPrefix,
-                              const std::shared_ptr<AsyncResp> &asyncResp) {
-    if (!input.is_object()) {
-      messages::addMessageToJson(
-          asyncResp->res.jsonValue,
-          messages::propertyValueTypeError(input.dump(), "VLAN"), pathPrefix);
-      return;
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
     }
 
-    const std::string pathStart = (pathPrefix == "/") ? "" : pathPrefix;
-    nlohmann::json &paramsJson =
-        (pathPrefix == "/")
-            ? asyncResp->res.jsonValue
-            : asyncResp->res.jsonValue[nlohmann::json_pointer<nlohmann::json>(
-                  pathPrefix)];
-    bool inputVlanEnabled;
-    uint64_t inputVlanId;
-
-    json_util::Result inputVlanEnabledState = json_util::getBool(
-        "VLANEnable", input, inputVlanEnabled,
-        static_cast<int>(json_util::MessageSetting::TYPE_ERROR),
-        asyncResp->res.jsonValue, std::string(pathStart + "/VLANEnable"));
-    json_util::Result inputVlanIdState = json_util::getUnsigned(
-        "VLANId", input, inputVlanId,
-        static_cast<int>(json_util::MessageSetting::TYPE_ERROR),
-        asyncResp->res.jsonValue, std::string(pathStart + "/VLANId"));
-    bool inputInvalid = false;
-
-    // Do not proceed if fields in VLAN object were of wrong type
-    if (inputVlanEnabledState == json_util::Result::WRONG_TYPE ||
-        inputVlanIdState == json_util::Result::WRONG_TYPE) {
-      return;
-    }
-
-    // Verify input
-    if (eth_data.vlanId == nullptr) {
-      // This interface is not a VLAN. Cannot do anything with it
-      // TODO(kkowalsk) Change this message
-      messages::addMessageToJson(asyncResp->res.jsonValue,
-                                 messages::propertyMissing("VLANEnable"),
-                                 pathPrefix);
-
-      inputInvalid = true;
-    } else {
-      // Load actual data into field values if they were not provided
-      if (inputVlanEnabledState == json_util::Result::NOT_EXIST) {
-        inputVlanEnabled = true;
-      }
-
-      if (inputVlanIdState == json_util::Result::NOT_EXIST) {
-        inputVlanId = *eth_data.vlanId;
-      }
-    }
-
-    // Do not proceed if input has not been valid
-    if (inputInvalid) {
-      return;
-    }
-
-    // VLAN is configured on the interface
-    if (inputVlanEnabled == true && inputVlanId != *eth_data.vlanId) {
-      // Change VLAN Id
-      paramsJson["VLANId"] = inputVlanId;
-      OnDemandEthernetProvider::changeVlanId(
-          ifaceId, static_cast<uint32_t>(inputVlanId),
-          [&, asyncResp, pathPrefx{std::move(pathPrefix)} ](
-              const boost::system::error_code ec) {
-            if (ec) {
-              messages::addMessageToJson(asyncResp->res.jsonValue,
-                                         messages::internalError(), pathPrefix);
-            } else {
-              paramsJson["VLANEnable"] = true;
-            }
-          });
-    } else if (inputVlanEnabled == false) {
-      // Disable VLAN
-      OnDemandEthernetProvider::disableVlan(
-          ifaceId, [&, asyncResp, pathPrefx{std::move(pathPrefix)} ](
-                       const boost::system::error_code ec) {
-            if (ec) {
-              messages::addMessageToJson(asyncResp->res.jsonValue,
-                                         messages::internalError(), pathPrefix);
-            } else {
-              paramsJson["VLANEnable"] = false;
-            }
-          });
-    }
-  }
-
- private:
-  void handleHostnamePatch(const nlohmann::json &input,
-                           const EthernetInterfaceData &eth_data,
-                           const std::shared_ptr<AsyncResp> &asyncResp) {
-    if (input.is_string()) {
-      std::string newHostname = input.get<std::string>();
-
-      if (eth_data.hostname == nullptr || newHostname != *eth_data.hostname) {
-        // Change hostname
-        ethernetProvider.setHostName(
-            newHostname,
-            [asyncResp, newHostname](const boost::system::error_code ec) {
-              if (ec) {
-                messages::addMessageToJson(asyncResp->res.jsonValue,
-                                           messages::internalError(),
-                                           "/HostName");
-              } else {
-                asyncResp->res.jsonValue["HostName"] = newHostname;
-              }
-            });
-      }
-    } else {
-      messages::addMessageToJson(
-          asyncResp->res.jsonValue,
-          messages::propertyValueTypeError(input.dump(), "HostName"),
-          "/HostName");
-    }
-  }
-
-  void handleIPv4Patch(const std::string &ifaceId, const nlohmann::json &input,
-                       const std::vector<IPv4AddressData> &ipv4_data,
-                       const std::shared_ptr<AsyncResp> &asyncResp) {
-    if (!input.is_array()) {
-      messages::addMessageToJson(
-          asyncResp->res.jsonValue,
-          messages::propertyValueTypeError(input.dump(), "IPv4Addresses"),
-          "/IPv4Addresses");
-      return;
-    }
-
-    // According to Redfish PATCH definition, size must be at least equal
-    if (input.size() < ipv4_data.size()) {
-      // TODO(kkowalsk) This should be a message indicating that not enough
-      // data has been provided
-      messages::addMessageToJson(asyncResp->res.jsonValue,
-                                 messages::internalError(), "/IPv4Addresses");
-      return;
-    }
-
-    json_util::Result addressFieldState;
-    json_util::Result subnetMaskFieldState;
-    json_util::Result addressOriginFieldState;
-    json_util::Result gatewayFieldState;
-    const std::string *addressFieldValue;
-    const std::string *subnetMaskFieldValue;
-    const std::string *addressOriginFieldValue = nullptr;
-    const std::string *gatewayFieldValue;
-    uint8_t subnetMaskAsPrefixLength;
-    std::string addressOriginInDBusFormat;
-
-    bool errorDetected = false;
-    for (unsigned int entryIdx = 0; entryIdx < input.size(); entryIdx++) {
-      // Check that entry is not of some unexpected type
-      if (!input[entryIdx].is_object() && !input[entryIdx].is_null()) {
-        // Invalid object type
-        messages::addMessageToJson(
-            asyncResp->res.jsonValue,
-            messages::propertyValueTypeError(input[entryIdx].dump(),
-                                             "IPv4Address"),
-            "/IPv4Addresses/" + std::to_string(entryIdx));
-
-        continue;
-      }
-
-      // Try to load fields
-      addressFieldState = json_util::getString(
-          "Address", input[entryIdx], addressFieldValue,
-          static_cast<uint8_t>(json_util::MessageSetting::TYPE_ERROR),
-          asyncResp->res.jsonValue,
-          "/IPv4Addresses/" + std::to_string(entryIdx) + "/Address");
-      subnetMaskFieldState = json_util::getString(
-          "SubnetMask", input[entryIdx], subnetMaskFieldValue,
-          static_cast<uint8_t>(json_util::MessageSetting::TYPE_ERROR),
-          asyncResp->res.jsonValue,
-          "/IPv4Addresses/" + std::to_string(entryIdx) + "/SubnetMask");
-      addressOriginFieldState = json_util::getString(
-          "AddressOrigin", input[entryIdx], addressOriginFieldValue,
-          static_cast<uint8_t>(json_util::MessageSetting::TYPE_ERROR),
-          asyncResp->res.jsonValue,
-          "/IPv4Addresses/" + std::to_string(entryIdx) + "/AddressOrigin");
-      gatewayFieldState = json_util::getString(
-          "Gateway", input[entryIdx], gatewayFieldValue,
-          static_cast<uint8_t>(json_util::MessageSetting::TYPE_ERROR),
-          asyncResp->res.jsonValue,
-          "/IPv4Addresses/" + std::to_string(entryIdx) + "/Gateway");
-
-      if (addressFieldState == json_util::Result::WRONG_TYPE ||
-          subnetMaskFieldState == json_util::Result::WRONG_TYPE ||
-          addressOriginFieldState == json_util::Result::WRONG_TYPE ||
-          gatewayFieldState == json_util::Result::WRONG_TYPE) {
-        return;
-      }
-
-      if (addressFieldState == json_util::Result::SUCCESS &&
-          !ethernetProvider.ipv4VerifyIpAndGetBitcount(*addressFieldValue)) {
-        errorDetected = true;
-        messages::addMessageToJson(
-            asyncResp->res.jsonValue,
-            messages::propertyValueFormatError(*addressFieldValue, "Address"),
-            "/IPv4Addresses/" + std::to_string(entryIdx) + "/Address");
-      }
-
-      if (subnetMaskFieldState == json_util::Result::SUCCESS &&
-          !ethernetProvider.ipv4VerifyIpAndGetBitcount(
-              *subnetMaskFieldValue, &subnetMaskAsPrefixLength)) {
-        errorDetected = true;
-        messages::addMessageToJson(
-            asyncResp->res.jsonValue,
-            messages::propertyValueFormatError(*subnetMaskFieldValue,
-                                               "SubnetMask"),
-            "/IPv4Addresses/" + std::to_string(entryIdx) + "/SubnetMask");
-      }
-
-      // get Address origin in proper format
-      addressOriginInDBusFormat =
-          ethernetProvider.translateAddressOriginBetweenDBusAndRedfish(
-              addressOriginFieldValue, true, false);
-
-      if (addressOriginFieldState == json_util::Result::SUCCESS &&
-          addressOriginInDBusFormat.empty()) {
-        errorDetected = true;
-        messages::addMessageToJson(
-            asyncResp->res.jsonValue,
-            messages::propertyValueNotInList(*addressOriginFieldValue,
-                                             "AddressOrigin"),
-            "/IPv4Addresses/" + std::to_string(entryIdx) + "/AddressOrigin");
-      }
-
-      if (gatewayFieldState == json_util::Result::SUCCESS &&
-          !ethernetProvider.ipv4VerifyIpAndGetBitcount(*gatewayFieldValue)) {
-        errorDetected = true;
-        messages::addMessageToJson(
-            asyncResp->res.jsonValue,
-            messages::propertyValueFormatError(*gatewayFieldValue, "Gateway"),
-            "/IPv4Addresses/" + std::to_string(entryIdx) + "/Gateway");
-      }
-
-      // If any error occured do not proceed with current entry, but do not
-      // end loop
-      if (errorDetected) {
-        errorDetected = false;
-        continue;
-      }
-
-      if (entryIdx >= ipv4_data.size()) {
-        asyncResp->res.jsonValue["IPv4Addresses"][entryIdx] = input[entryIdx];
-
-        // Verify that all field were provided
-        if (addressFieldState == json_util::Result::NOT_EXIST) {
-          errorDetected = true;
-          messages::addMessageToJson(
-              asyncResp->res.jsonValue, messages::propertyMissing("Address"),
-              "/IPv4Addresses/" + std::to_string(entryIdx) + "/Address");
-        }
-
-        if (subnetMaskFieldState == json_util::Result::NOT_EXIST) {
-          errorDetected = true;
-          messages::addMessageToJson(
-              asyncResp->res.jsonValue, messages::propertyMissing("SubnetMask"),
-              "/IPv4Addresses/" + std::to_string(entryIdx) + "/SubnetMask");
-        }
-
-        if (addressOriginFieldState == json_util::Result::NOT_EXIST) {
-          errorDetected = true;
-          messages::addMessageToJson(
-              asyncResp->res.jsonValue,
-              messages::propertyMissing("AddressOrigin"),
-              "/IPv4Addresses/" + std::to_string(entryIdx) + "/AddressOrigin");
-        }
-
-        if (gatewayFieldState == json_util::Result::NOT_EXIST) {
-          errorDetected = true;
-          messages::addMessageToJson(
-              asyncResp->res.jsonValue, messages::propertyMissing("Gateway"),
-              "/IPv4Addresses/" + std::to_string(entryIdx) + "/Gateway");
-        }
-
-        // If any error occured do not proceed with current entry, but do not
-        // end loop
-        if (errorDetected) {
-          errorDetected = false;
-          continue;
-        }
-
-        // Create IPv4 with provided data
-        ethernetProvider.createIPv4(ifaceId, entryIdx, subnetMaskAsPrefixLength,
-                                    *gatewayFieldValue, *addressFieldValue,
-                                    asyncResp);
-      } else {
-        // Existing object that should be modified/deleted/remain unchanged
-        if (input[entryIdx].is_null()) {
-          // Object should be deleted
-          ethernetProvider.deleteIPv4(ifaceId, ipv4_data[entryIdx].id, entryIdx,
-                                      asyncResp);
-        } else if (input[entryIdx].is_object()) {
-          if (input[entryIdx].size() == 0) {
-            // Object shall remain unchanged
-            continue;
-          }
-
-          // Apply changes
-          if (addressFieldState == json_util::Result::SUCCESS &&
-              ipv4_data[entryIdx].address != nullptr &&
-              *ipv4_data[entryIdx].address != *addressFieldValue) {
-            ethernetProvider.changeIPv4AddressProperty(
-                ifaceId, entryIdx, ipv4_data[entryIdx].id, "Address",
-                *addressFieldValue, asyncResp);
-          }
-
-          if (subnetMaskFieldState == json_util::Result::SUCCESS &&
-              ipv4_data[entryIdx].netmask != *subnetMaskFieldValue) {
-            ethernetProvider.changeIPv4SubnetMaskProperty(
-                ifaceId, entryIdx, ipv4_data[entryIdx].id,
-                *subnetMaskFieldValue, subnetMaskAsPrefixLength, asyncResp);
-          }
-
-          if (addressOriginFieldState == json_util::Result::SUCCESS &&
-              ipv4_data[entryIdx].origin != *addressFieldValue) {
-            ethernetProvider.changeIPv4Origin(
-                ifaceId, entryIdx, ipv4_data[entryIdx].id,
-                *addressOriginFieldValue, addressOriginInDBusFormat, asyncResp);
-          }
-
-          if (gatewayFieldState == json_util::Result::SUCCESS &&
-              ipv4_data[entryIdx].gateway != nullptr &&
-              *ipv4_data[entryIdx].gateway != *gatewayFieldValue) {
-            ethernetProvider.changeIPv4AddressProperty(
-                ifaceId, entryIdx, ipv4_data[entryIdx].id, "Gateway",
-                *gatewayFieldValue, asyncResp);
-          }
-        }
-      }
-    }
-  }
-
-  nlohmann::json parseInterfaceData(
-      const std::string &ifaceId, const EthernetInterfaceData &eth_data,
-      const std::vector<IPv4AddressData> &ipv4_data) {
-    // Copy JSON object to avoid race condition
-    nlohmann::json jsonResponse(Node::json);
-
-    // Fill out obvious data...
-    jsonResponse["Id"] = ifaceId;
-    jsonResponse["@odata.id"] =
-        "/redfish/v1/Managers/openbmc/EthernetInterfaces/" + ifaceId;
-
-    // ... then the one from DBus, regarding eth iface...
-    if (eth_data.speed != nullptr) jsonResponse["SpeedMbps"] = *eth_data.speed;
-
-    if (eth_data.macAddress != nullptr)
-      jsonResponse["MACAddress"] = *eth_data.macAddress;
-
-    if (eth_data.hostname != nullptr)
-      jsonResponse["HostName"] = *eth_data.hostname;
-
-    if (eth_data.vlanId != nullptr) {
-      nlohmann::json &vlanObj = jsonResponse["VLAN"];
-      vlanObj["VLANEnable"] = true;
-      vlanObj["VLANId"] = *eth_data.vlanId;
-    } else {
-      nlohmann::json &vlanObj = jsonResponse["VLANs"];
-      vlanObj["@odata.id"] =
-          "/redfish/v1/Managers/openbmc/EthernetInterfaces/" + ifaceId +
-          "/VLANs";
-    }
-
-    // ... at last, check if there are IPv4 data and prepare appropriate
-    // collection
-    if (ipv4_data.size() > 0) {
-      nlohmann::json ipv4Array = nlohmann::json::array();
-      for (auto &ipv4Config : ipv4_data) {
-        nlohmann::json jsonIpv4;
-        if (ipv4Config.address != nullptr) {
-          jsonIpv4["Address"] = *ipv4Config.address;
-          if (ipv4Config.gateway != nullptr)
-            jsonIpv4["Gateway"] = *ipv4Config.gateway;
-
-          jsonIpv4["AddressOrigin"] = ipv4Config.origin;
-          jsonIpv4["SubnetMask"] = ipv4Config.netmask;
-
-          ipv4Array.push_back(std::move(jsonIpv4));
-        }
-      }
-      jsonResponse["IPv4Addresses"] = std::move(ipv4Array);
-    }
-
-    return jsonResponse;
-  }
-
-  /**
-   * Functions triggers appropriate requests on DBus
-   */
-  void doGet(crow::Response &res, const crow::Request &req,
-             const std::vector<std::string> &params) override {
-    // TODO(Pawel) this shall be parametrized call (two params) to get
-    // EthernetInterfaces for any Manager, not only hardcoded 'openbmc'.
-    // Check if there is required param, truly entering this shall be
-    // impossible.
-    if (params.size() != 1) {
-      res.result(boost::beast::http::status::internal_server_error);
-      res.end();
-      return;
-    }
-
-    const std::string &ifaceId = params[0];
-
-    // get single eth interface data, and call the below callback for JSON
-    // preparation
-    ethernetProvider.getEthernetIfaceData(
-        ifaceId,
-        [&, ifaceId](const bool &success, const EthernetInterfaceData &eth_data,
-                     const std::vector<IPv4AddressData> &ipv4_data) {
-          if (success) {
-            res.jsonValue = parseInterfaceData(ifaceId, eth_data, ipv4_data);
-          } else {
-            // ... otherwise return error
-            // TODO(Pawel)consider distinguish between non existing object, and
-            // other errors
-            messages::addMessageToErrorJson(
-                res.jsonValue,
-                messages::resourceNotFound("EthernetInterface", ifaceId));
-            res.result(boost::beast::http::status::not_found);
-          }
-          res.end();
-        });
-  }
-
-  void doPatch(crow::Response &res, const crow::Request &req,
-               const std::vector<std::string> &params) override {
-    // TODO(Pawel) this shall be parametrized call (two params) to get
-    // EthernetInterfaces for any Manager, not only hardcoded 'openbmc'.
-    // Check if there is required param, truly entering this shall be
-    // impossible.
-    if (params.size() != 1) {
-      res.result(boost::beast::http::status::internal_server_error);
-      res.end();
-      return;
-    }
-
-    const std::string &ifaceId = params[0];
-
-    nlohmann::json patchReq;
-
-    if (!json_util::processJsonFromRequest(res, req, patchReq)) {
-      return;
-    }
-
-    // get single eth interface data, and call the below callback for JSON
-    // preparation
-    ethernetProvider.getEthernetIfaceData(
-        ifaceId, [&, ifaceId, patchReq = std::move(patchReq) ](
-                     const bool &success, const EthernetInterfaceData &eth_data,
-                     const std::vector<IPv4AddressData> &ipv4_data) {
-          if (!success) {
-            // ... otherwise return error
-            // TODO(Pawel)consider distinguish between non existing object, and
-            // other errors
-            messages::addMessageToErrorJson(
-                res.jsonValue,
-                messages::resourceNotFound("VLAN Network Interface", ifaceId));
-            res.result(boost::beast::http::status::not_found);
-            res.end();
-
+    // TODO(kkowalsk) Find a suitable class/namespace for this
+    static void handleVlanPatch(const std::string &ifaceId,
+                                const nlohmann::json &input,
+                                const EthernetInterfaceData &eth_data,
+                                const std::string &pathPrefix,
+                                const std::shared_ptr<AsyncResp> &asyncResp)
+    {
+        if (!input.is_object())
+        {
+            messages::addMessageToJson(
+                asyncResp->res.jsonValue,
+                messages::propertyValueTypeError(input.dump(), "VLAN"),
+                pathPrefix);
             return;
-          }
+        }
 
-          res.jsonValue = parseInterfaceData(ifaceId, eth_data, ipv4_data);
+        const std::string pathStart = (pathPrefix == "/") ? "" : pathPrefix;
+        nlohmann::json &paramsJson =
+            (pathPrefix == "/")
+                ? asyncResp->res.jsonValue
+                : asyncResp->res
+                      .jsonValue[nlohmann::json_pointer<nlohmann::json>(
+                          pathPrefix)];
+        bool inputVlanEnabled;
+        uint64_t inputVlanId;
 
-          std::shared_ptr<AsyncResp> asyncResp =
-              std::make_shared<AsyncResp>(res);
+        json_util::Result inputVlanEnabledState = json_util::getBool(
+            "VLANEnable", input, inputVlanEnabled,
+            static_cast<int>(json_util::MessageSetting::TYPE_ERROR),
+            asyncResp->res.jsonValue, std::string(pathStart + "/VLANEnable"));
+        json_util::Result inputVlanIdState = json_util::getUnsigned(
+            "VLANId", input, inputVlanId,
+            static_cast<int>(json_util::MessageSetting::TYPE_ERROR),
+            asyncResp->res.jsonValue, std::string(pathStart + "/VLANId"));
+        bool inputInvalid = false;
 
-          for (auto propertyIt = patchReq.begin(); propertyIt != patchReq.end();
-               ++propertyIt) {
-            if (propertyIt.key() == "VLAN") {
-              handleVlanPatch(ifaceId, propertyIt.value(), eth_data, "/VLAN",
-                              asyncResp);
-            } else if (propertyIt.key() == "HostName") {
-              handleHostnamePatch(propertyIt.value(), eth_data, asyncResp);
-            } else if (propertyIt.key() == "IPv4Addresses") {
-              handleIPv4Patch(ifaceId, propertyIt.value(), ipv4_data,
-                              asyncResp);
-            } else if (propertyIt.key() == "IPv6Addresses") {
-              // TODO(kkowalsk) IPv6 Not supported on D-Bus yet
-              messages::addMessageToJsonRoot(
-                  res.jsonValue,
-                  messages::propertyNotWritable(propertyIt.key()));
-            } else {
-              auto fieldInJsonIt = res.jsonValue.find(propertyIt.key());
+        // Do not proceed if fields in VLAN object were of wrong type
+        if (inputVlanEnabledState == json_util::Result::WRONG_TYPE ||
+            inputVlanIdState == json_util::Result::WRONG_TYPE)
+        {
+            return;
+        }
 
-              if (fieldInJsonIt == res.jsonValue.end()) {
-                // Field not in scope of defined fields
-                messages::addMessageToJsonRoot(
-                    res.jsonValue, messages::propertyUnknown(propertyIt.key()));
-              } else if (*fieldInJsonIt != *propertyIt) {
-                // User attempted to modify non-writable field
-                messages::addMessageToJsonRoot(
-                    res.jsonValue,
-                    messages::propertyNotWritable(propertyIt.key()));
-              }
+        // Verify input
+        if (eth_data.vlanId == nullptr)
+        {
+            // This interface is not a VLAN. Cannot do anything with it
+            // TODO(kkowalsk) Change this message
+            messages::addMessageToJson(asyncResp->res.jsonValue,
+                                       messages::propertyMissing("VLANEnable"),
+                                       pathPrefix);
+
+            inputInvalid = true;
+        }
+        else
+        {
+            // Load actual data into field values if they were not provided
+            if (inputVlanEnabledState == json_util::Result::NOT_EXIST)
+            {
+                inputVlanEnabled = true;
             }
-          }
-        });
-  }
 
-  // Ethernet Provider object
-  // TODO(Pawel) consider move it to singleton
-  OnDemandEthernetProvider ethernetProvider;
+            if (inputVlanIdState == json_util::Result::NOT_EXIST)
+            {
+                inputVlanId = *eth_data.vlanId;
+            }
+        }
+
+        // Do not proceed if input has not been valid
+        if (inputInvalid)
+        {
+            return;
+        }
+
+        // VLAN is configured on the interface
+        if (inputVlanEnabled == true && inputVlanId != *eth_data.vlanId)
+        {
+            // Change VLAN Id
+            paramsJson["VLANId"] = inputVlanId;
+            OnDemandEthernetProvider::changeVlanId(
+                ifaceId, static_cast<uint32_t>(inputVlanId),
+                [&, asyncResp, pathPrefx{std::move(pathPrefix)}](
+                    const boost::system::error_code ec) {
+                    if (ec)
+                    {
+                        messages::addMessageToJson(asyncResp->res.jsonValue,
+                                                   messages::internalError(),
+                                                   pathPrefix);
+                    }
+                    else
+                    {
+                        paramsJson["VLANEnable"] = true;
+                    }
+                });
+        }
+        else if (inputVlanEnabled == false)
+        {
+            // Disable VLAN
+            OnDemandEthernetProvider::disableVlan(
+                ifaceId, [&, asyncResp, pathPrefx{std::move(pathPrefix)}](
+                             const boost::system::error_code ec) {
+                    if (ec)
+                    {
+                        messages::addMessageToJson(asyncResp->res.jsonValue,
+                                                   messages::internalError(),
+                                                   pathPrefix);
+                    }
+                    else
+                    {
+                        paramsJson["VLANEnable"] = false;
+                    }
+                });
+        }
+    }
+
+  private:
+    void handleHostnamePatch(const nlohmann::json &input,
+                             const EthernetInterfaceData &eth_data,
+                             const std::shared_ptr<AsyncResp> &asyncResp)
+    {
+        if (input.is_string())
+        {
+            std::string newHostname = input.get<std::string>();
+
+            if (eth_data.hostname == nullptr ||
+                newHostname != *eth_data.hostname)
+            {
+                // Change hostname
+                ethernetProvider.setHostName(
+                    newHostname, [asyncResp, newHostname](
+                                     const boost::system::error_code ec) {
+                        if (ec)
+                        {
+                            messages::addMessageToJson(
+                                asyncResp->res.jsonValue,
+                                messages::internalError(), "/HostName");
+                        }
+                        else
+                        {
+                            asyncResp->res.jsonValue["HostName"] = newHostname;
+                        }
+                    });
+            }
+        }
+        else
+        {
+            messages::addMessageToJson(
+                asyncResp->res.jsonValue,
+                messages::propertyValueTypeError(input.dump(), "HostName"),
+                "/HostName");
+        }
+    }
+
+    void handleIPv4Patch(const std::string &ifaceId,
+                         const nlohmann::json &input,
+                         const std::vector<IPv4AddressData> &ipv4_data,
+                         const std::shared_ptr<AsyncResp> &asyncResp)
+    {
+        if (!input.is_array())
+        {
+            messages::addMessageToJson(
+                asyncResp->res.jsonValue,
+                messages::propertyValueTypeError(input.dump(), "IPv4Addresses"),
+                "/IPv4Addresses");
+            return;
+        }
+
+        // According to Redfish PATCH definition, size must be at least equal
+        if (input.size() < ipv4_data.size())
+        {
+            // TODO(kkowalsk) This should be a message indicating that not
+            // enough data has been provided
+            messages::addMessageToJson(asyncResp->res.jsonValue,
+                                       messages::internalError(),
+                                       "/IPv4Addresses");
+            return;
+        }
+
+        json_util::Result addressFieldState;
+        json_util::Result subnetMaskFieldState;
+        json_util::Result addressOriginFieldState;
+        json_util::Result gatewayFieldState;
+        const std::string *addressFieldValue;
+        const std::string *subnetMaskFieldValue;
+        const std::string *addressOriginFieldValue = nullptr;
+        const std::string *gatewayFieldValue;
+        uint8_t subnetMaskAsPrefixLength;
+        std::string addressOriginInDBusFormat;
+
+        bool errorDetected = false;
+        for (unsigned int entryIdx = 0; entryIdx < input.size(); entryIdx++)
+        {
+            // Check that entry is not of some unexpected type
+            if (!input[entryIdx].is_object() && !input[entryIdx].is_null())
+            {
+                // Invalid object type
+                messages::addMessageToJson(
+                    asyncResp->res.jsonValue,
+                    messages::propertyValueTypeError(input[entryIdx].dump(),
+                                                     "IPv4Address"),
+                    "/IPv4Addresses/" + std::to_string(entryIdx));
+
+                continue;
+            }
+
+            // Try to load fields
+            addressFieldState = json_util::getString(
+                "Address", input[entryIdx], addressFieldValue,
+                static_cast<uint8_t>(json_util::MessageSetting::TYPE_ERROR),
+                asyncResp->res.jsonValue,
+                "/IPv4Addresses/" + std::to_string(entryIdx) + "/Address");
+            subnetMaskFieldState = json_util::getString(
+                "SubnetMask", input[entryIdx], subnetMaskFieldValue,
+                static_cast<uint8_t>(json_util::MessageSetting::TYPE_ERROR),
+                asyncResp->res.jsonValue,
+                "/IPv4Addresses/" + std::to_string(entryIdx) + "/SubnetMask");
+            addressOriginFieldState = json_util::getString(
+                "AddressOrigin", input[entryIdx], addressOriginFieldValue,
+                static_cast<uint8_t>(json_util::MessageSetting::TYPE_ERROR),
+                asyncResp->res.jsonValue,
+                "/IPv4Addresses/" + std::to_string(entryIdx) +
+                    "/AddressOrigin");
+            gatewayFieldState = json_util::getString(
+                "Gateway", input[entryIdx], gatewayFieldValue,
+                static_cast<uint8_t>(json_util::MessageSetting::TYPE_ERROR),
+                asyncResp->res.jsonValue,
+                "/IPv4Addresses/" + std::to_string(entryIdx) + "/Gateway");
+
+            if (addressFieldState == json_util::Result::WRONG_TYPE ||
+                subnetMaskFieldState == json_util::Result::WRONG_TYPE ||
+                addressOriginFieldState == json_util::Result::WRONG_TYPE ||
+                gatewayFieldState == json_util::Result::WRONG_TYPE)
+            {
+                return;
+            }
+
+            if (addressFieldState == json_util::Result::SUCCESS &&
+                !ethernetProvider.ipv4VerifyIpAndGetBitcount(
+                    *addressFieldValue))
+            {
+                errorDetected = true;
+                messages::addMessageToJson(
+                    asyncResp->res.jsonValue,
+                    messages::propertyValueFormatError(*addressFieldValue,
+                                                       "Address"),
+                    "/IPv4Addresses/" + std::to_string(entryIdx) + "/Address");
+            }
+
+            if (subnetMaskFieldState == json_util::Result::SUCCESS &&
+                !ethernetProvider.ipv4VerifyIpAndGetBitcount(
+                    *subnetMaskFieldValue, &subnetMaskAsPrefixLength))
+            {
+                errorDetected = true;
+                messages::addMessageToJson(
+                    asyncResp->res.jsonValue,
+                    messages::propertyValueFormatError(*subnetMaskFieldValue,
+                                                       "SubnetMask"),
+                    "/IPv4Addresses/" + std::to_string(entryIdx) +
+                        "/SubnetMask");
+            }
+
+            // get Address origin in proper format
+            addressOriginInDBusFormat =
+                ethernetProvider.translateAddressOriginBetweenDBusAndRedfish(
+                    addressOriginFieldValue, true, false);
+
+            if (addressOriginFieldState == json_util::Result::SUCCESS &&
+                addressOriginInDBusFormat.empty())
+            {
+                errorDetected = true;
+                messages::addMessageToJson(
+                    asyncResp->res.jsonValue,
+                    messages::propertyValueNotInList(*addressOriginFieldValue,
+                                                     "AddressOrigin"),
+                    "/IPv4Addresses/" + std::to_string(entryIdx) +
+                        "/AddressOrigin");
+            }
+
+            if (gatewayFieldState == json_util::Result::SUCCESS &&
+                !ethernetProvider.ipv4VerifyIpAndGetBitcount(
+                    *gatewayFieldValue))
+            {
+                errorDetected = true;
+                messages::addMessageToJson(
+                    asyncResp->res.jsonValue,
+                    messages::propertyValueFormatError(*gatewayFieldValue,
+                                                       "Gateway"),
+                    "/IPv4Addresses/" + std::to_string(entryIdx) + "/Gateway");
+            }
+
+            // If any error occured do not proceed with current entry, but do
+            // not end loop
+            if (errorDetected)
+            {
+                errorDetected = false;
+                continue;
+            }
+
+            if (entryIdx >= ipv4_data.size())
+            {
+                asyncResp->res.jsonValue["IPv4Addresses"][entryIdx] =
+                    input[entryIdx];
+
+                // Verify that all field were provided
+                if (addressFieldState == json_util::Result::NOT_EXIST)
+                {
+                    errorDetected = true;
+                    messages::addMessageToJson(
+                        asyncResp->res.jsonValue,
+                        messages::propertyMissing("Address"),
+                        "/IPv4Addresses/" + std::to_string(entryIdx) +
+                            "/Address");
+                }
+
+                if (subnetMaskFieldState == json_util::Result::NOT_EXIST)
+                {
+                    errorDetected = true;
+                    messages::addMessageToJson(
+                        asyncResp->res.jsonValue,
+                        messages::propertyMissing("SubnetMask"),
+                        "/IPv4Addresses/" + std::to_string(entryIdx) +
+                            "/SubnetMask");
+                }
+
+                if (addressOriginFieldState == json_util::Result::NOT_EXIST)
+                {
+                    errorDetected = true;
+                    messages::addMessageToJson(
+                        asyncResp->res.jsonValue,
+                        messages::propertyMissing("AddressOrigin"),
+                        "/IPv4Addresses/" + std::to_string(entryIdx) +
+                            "/AddressOrigin");
+                }
+
+                if (gatewayFieldState == json_util::Result::NOT_EXIST)
+                {
+                    errorDetected = true;
+                    messages::addMessageToJson(
+                        asyncResp->res.jsonValue,
+                        messages::propertyMissing("Gateway"),
+                        "/IPv4Addresses/" + std::to_string(entryIdx) +
+                            "/Gateway");
+                }
+
+                // If any error occured do not proceed with current entry, but
+                // do not end loop
+                if (errorDetected)
+                {
+                    errorDetected = false;
+                    continue;
+                }
+
+                // Create IPv4 with provided data
+                ethernetProvider.createIPv4(
+                    ifaceId, entryIdx, subnetMaskAsPrefixLength,
+                    *gatewayFieldValue, *addressFieldValue, asyncResp);
+            }
+            else
+            {
+                // Existing object that should be modified/deleted/remain
+                // unchanged
+                if (input[entryIdx].is_null())
+                {
+                    // Object should be deleted
+                    ethernetProvider.deleteIPv4(ifaceId, ipv4_data[entryIdx].id,
+                                                entryIdx, asyncResp);
+                }
+                else if (input[entryIdx].is_object())
+                {
+                    if (input[entryIdx].size() == 0)
+                    {
+                        // Object shall remain unchanged
+                        continue;
+                    }
+
+                    // Apply changes
+                    if (addressFieldState == json_util::Result::SUCCESS &&
+                        ipv4_data[entryIdx].address != nullptr &&
+                        *ipv4_data[entryIdx].address != *addressFieldValue)
+                    {
+                        ethernetProvider.changeIPv4AddressProperty(
+                            ifaceId, entryIdx, ipv4_data[entryIdx].id,
+                            "Address", *addressFieldValue, asyncResp);
+                    }
+
+                    if (subnetMaskFieldState == json_util::Result::SUCCESS &&
+                        ipv4_data[entryIdx].netmask != *subnetMaskFieldValue)
+                    {
+                        ethernetProvider.changeIPv4SubnetMaskProperty(
+                            ifaceId, entryIdx, ipv4_data[entryIdx].id,
+                            *subnetMaskFieldValue, subnetMaskAsPrefixLength,
+                            asyncResp);
+                    }
+
+                    if (addressOriginFieldState == json_util::Result::SUCCESS &&
+                        ipv4_data[entryIdx].origin != *addressFieldValue)
+                    {
+                        ethernetProvider.changeIPv4Origin(
+                            ifaceId, entryIdx, ipv4_data[entryIdx].id,
+                            *addressOriginFieldValue, addressOriginInDBusFormat,
+                            asyncResp);
+                    }
+
+                    if (gatewayFieldState == json_util::Result::SUCCESS &&
+                        ipv4_data[entryIdx].gateway != nullptr &&
+                        *ipv4_data[entryIdx].gateway != *gatewayFieldValue)
+                    {
+                        ethernetProvider.changeIPv4AddressProperty(
+                            ifaceId, entryIdx, ipv4_data[entryIdx].id,
+                            "Gateway", *gatewayFieldValue, asyncResp);
+                    }
+                }
+            }
+        }
+    }
+
+    nlohmann::json
+        parseInterfaceData(const std::string &ifaceId,
+                           const EthernetInterfaceData &eth_data,
+                           const std::vector<IPv4AddressData> &ipv4_data)
+    {
+        // Copy JSON object to avoid race condition
+        nlohmann::json jsonResponse(Node::json);
+
+        // Fill out obvious data...
+        jsonResponse["Id"] = ifaceId;
+        jsonResponse["@odata.id"] =
+            "/redfish/v1/Managers/openbmc/EthernetInterfaces/" + ifaceId;
+
+        // ... then the one from DBus, regarding eth iface...
+        if (eth_data.speed != nullptr)
+            jsonResponse["SpeedMbps"] = *eth_data.speed;
+
+        if (eth_data.macAddress != nullptr)
+            jsonResponse["MACAddress"] = *eth_data.macAddress;
+
+        if (eth_data.hostname != nullptr)
+            jsonResponse["HostName"] = *eth_data.hostname;
+
+        if (eth_data.vlanId != nullptr)
+        {
+            nlohmann::json &vlanObj = jsonResponse["VLAN"];
+            vlanObj["VLANEnable"] = true;
+            vlanObj["VLANId"] = *eth_data.vlanId;
+        }
+        else
+        {
+            nlohmann::json &vlanObj = jsonResponse["VLANs"];
+            vlanObj["@odata.id"] =
+                "/redfish/v1/Managers/openbmc/EthernetInterfaces/" + ifaceId +
+                "/VLANs";
+        }
+
+        // ... at last, check if there are IPv4 data and prepare appropriate
+        // collection
+        if (ipv4_data.size() > 0)
+        {
+            nlohmann::json ipv4Array = nlohmann::json::array();
+            for (auto &ipv4Config : ipv4_data)
+            {
+                nlohmann::json jsonIpv4;
+                if (ipv4Config.address != nullptr)
+                {
+                    jsonIpv4["Address"] = *ipv4Config.address;
+                    if (ipv4Config.gateway != nullptr)
+                        jsonIpv4["Gateway"] = *ipv4Config.gateway;
+
+                    jsonIpv4["AddressOrigin"] = ipv4Config.origin;
+                    jsonIpv4["SubnetMask"] = ipv4Config.netmask;
+
+                    ipv4Array.push_back(std::move(jsonIpv4));
+                }
+            }
+            jsonResponse["IPv4Addresses"] = std::move(ipv4Array);
+        }
+
+        return jsonResponse;
+    }
+
+    /**
+     * Functions triggers appropriate requests on DBus
+     */
+    void doGet(crow::Response &res, const crow::Request &req,
+               const std::vector<std::string> &params) override
+    {
+        // TODO(Pawel) this shall be parametrized call (two params) to get
+        // EthernetInterfaces for any Manager, not only hardcoded 'openbmc'.
+        // Check if there is required param, truly entering this shall be
+        // impossible.
+        if (params.size() != 1)
+        {
+            res.result(boost::beast::http::status::internal_server_error);
+            res.end();
+            return;
+        }
+
+        const std::string &ifaceId = params[0];
+
+        // get single eth interface data, and call the below callback for JSON
+        // preparation
+        ethernetProvider.getEthernetIfaceData(
+            ifaceId,
+            [&, ifaceId](const bool &success,
+                         const EthernetInterfaceData &eth_data,
+                         const std::vector<IPv4AddressData> &ipv4_data) {
+                if (success)
+                {
+                    res.jsonValue =
+                        parseInterfaceData(ifaceId, eth_data, ipv4_data);
+                }
+                else
+                {
+                    // ... otherwise return error
+                    // TODO(Pawel)consider distinguish between non existing
+                    // object, and other errors
+                    messages::addMessageToErrorJson(
+                        res.jsonValue, messages::resourceNotFound(
+                                           "EthernetInterface", ifaceId));
+                    res.result(boost::beast::http::status::not_found);
+                }
+                res.end();
+            });
+    }
+
+    void doPatch(crow::Response &res, const crow::Request &req,
+                 const std::vector<std::string> &params) override
+    {
+        // TODO(Pawel) this shall be parametrized call (two params) to get
+        // EthernetInterfaces for any Manager, not only hardcoded 'openbmc'.
+        // Check if there is required param, truly entering this shall be
+        // impossible.
+        if (params.size() != 1)
+        {
+            res.result(boost::beast::http::status::internal_server_error);
+            res.end();
+            return;
+        }
+
+        const std::string &ifaceId = params[0];
+
+        nlohmann::json patchReq;
+
+        if (!json_util::processJsonFromRequest(res, req, patchReq))
+        {
+            return;
+        }
+
+        // get single eth interface data, and call the below callback for JSON
+        // preparation
+        ethernetProvider.getEthernetIfaceData(
+            ifaceId,
+            [&, ifaceId, patchReq = std::move(patchReq)](
+                const bool &success, const EthernetInterfaceData &eth_data,
+                const std::vector<IPv4AddressData> &ipv4_data) {
+                if (!success)
+                {
+                    // ... otherwise return error
+                    // TODO(Pawel)consider distinguish between non existing
+                    // object, and other errors
+                    messages::addMessageToErrorJson(
+                        res.jsonValue, messages::resourceNotFound(
+                                           "VLAN Network Interface", ifaceId));
+                    res.result(boost::beast::http::status::not_found);
+                    res.end();
+
+                    return;
+                }
+
+                res.jsonValue =
+                    parseInterfaceData(ifaceId, eth_data, ipv4_data);
+
+                std::shared_ptr<AsyncResp> asyncResp =
+                    std::make_shared<AsyncResp>(res);
+
+                for (auto propertyIt = patchReq.begin();
+                     propertyIt != patchReq.end(); ++propertyIt)
+                {
+                    if (propertyIt.key() == "VLAN")
+                    {
+                        handleVlanPatch(ifaceId, propertyIt.value(), eth_data,
+                                        "/VLAN", asyncResp);
+                    }
+                    else if (propertyIt.key() == "HostName")
+                    {
+                        handleHostnamePatch(propertyIt.value(), eth_data,
+                                            asyncResp);
+                    }
+                    else if (propertyIt.key() == "IPv4Addresses")
+                    {
+                        handleIPv4Patch(ifaceId, propertyIt.value(), ipv4_data,
+                                        asyncResp);
+                    }
+                    else if (propertyIt.key() == "IPv6Addresses")
+                    {
+                        // TODO(kkowalsk) IPv6 Not supported on D-Bus yet
+                        messages::addMessageToJsonRoot(
+                            res.jsonValue,
+                            messages::propertyNotWritable(propertyIt.key()));
+                    }
+                    else
+                    {
+                        auto fieldInJsonIt =
+                            res.jsonValue.find(propertyIt.key());
+
+                        if (fieldInJsonIt == res.jsonValue.end())
+                        {
+                            // Field not in scope of defined fields
+                            messages::addMessageToJsonRoot(
+                                res.jsonValue,
+                                messages::propertyUnknown(propertyIt.key()));
+                        }
+                        else if (*fieldInJsonIt != *propertyIt)
+                        {
+                            // User attempted to modify non-writable field
+                            messages::addMessageToJsonRoot(
+                                res.jsonValue, messages::propertyNotWritable(
+                                                   propertyIt.key()));
+                        }
+                    }
+                }
+            });
+    }
+
+    // Ethernet Provider object
+    // TODO(Pawel) consider move it to singleton
+    OnDemandEthernetProvider ethernetProvider;
 };
 
 class VlanNetworkInterfaceCollection;
@@ -1350,422 +1585,499 @@
 /**
  * VlanNetworkInterface derived class for delivering VLANNetworkInterface Schema
  */
-class VlanNetworkInterface : public Node {
- public:
-  /*
-   * Default Constructor
-   */
-  template <typename CrowApp>
-  // TODO(Pawel) Remove line from below, where we assume that there is only one
-  // manager called openbmc This shall be generic, but requires to update
-  // GetSubroutes method
-  VlanNetworkInterface(CrowApp &app)
-      : Node(
+class VlanNetworkInterface : public Node
+{
+  public:
+    /*
+     * Default Constructor
+     */
+    template <typename CrowApp>
+    // TODO(Pawel) Remove line from below, where we assume that there is only
+    // one manager called openbmc This shall be generic, but requires to update
+    // GetSubroutes method
+    VlanNetworkInterface(CrowApp &app) :
+        Node(
             app,
             "/redfish/v1/Managers/openbmc/EthernetInterfaces/<str>/VLANs/<str>",
-            std::string(), std::string()) {
-    Node::json["@odata.type"] =
-        "#VLanNetworkInterface.v1_1_0.VLanNetworkInterface";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata#VLanNetworkInterface.VLanNetworkInterface";
-    Node::json["Name"] = "VLAN Network Interface";
+            std::string(), std::string())
+    {
+        Node::json["@odata.type"] =
+            "#VLanNetworkInterface.v1_1_0.VLanNetworkInterface";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata#VLanNetworkInterface.VLanNetworkInterface";
+        Node::json["Name"] = "VLAN Network Interface";
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-  }
-
- private:
-  nlohmann::json parseInterfaceData(
-      const std::string &parent_ifaceId, const std::string &ifaceId,
-      const EthernetInterfaceData &eth_data,
-      const std::vector<IPv4AddressData> &ipv4_data) {
-    // Copy JSON object to avoid race condition
-    nlohmann::json jsonResponse(Node::json);
-
-    // Fill out obvious data...
-    jsonResponse["Id"] = ifaceId;
-    jsonResponse["@odata.id"] =
-        "/redfish/v1/Managers/openbmc/EthernetInterfaces/" + parent_ifaceId +
-        "/VLANs/" + ifaceId;
-
-    jsonResponse["VLANEnable"] = true;
-    jsonResponse["VLANId"] = *eth_data.vlanId;
-
-    return jsonResponse;
-  }
-
-  bool verifyNames(crow::Response &res, const std::string &parent,
-                   const std::string &iface) {
-    if (!boost::starts_with(iface, parent + "_")) {
-      messages::addMessageToErrorJson(
-          res.jsonValue,
-          messages::resourceNotFound("VLAN Network Interface", iface));
-      res.result(boost::beast::http::status::not_found);
-      res.end();
-
-      return false;
-    } else {
-      return true;
-    }
-  }
-
-  /**
-   * Functions triggers appropriate requests on DBus
-   */
-  void doGet(crow::Response &res, const crow::Request &req,
-             const std::vector<std::string> &params) override {
-    // TODO(Pawel) this shall be parametrized call (two params) to get
-    // EthernetInterfaces for any Manager, not only hardcoded 'openbmc'.
-    // Check if there is required param, truly entering this shall be
-    // impossible.
-    if (params.size() != 2) {
-      res.result(boost::beast::http::status::internal_server_error);
-      res.end();
-      return;
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
     }
 
-    const std::string &parentIfaceId = params[0];
-    const std::string &ifaceId = params[1];
+  private:
+    nlohmann::json
+        parseInterfaceData(const std::string &parent_ifaceId,
+                           const std::string &ifaceId,
+                           const EthernetInterfaceData &eth_data,
+                           const std::vector<IPv4AddressData> &ipv4_data)
+    {
+        // Copy JSON object to avoid race condition
+        nlohmann::json jsonResponse(Node::json);
 
-    if (!verifyNames(res, parentIfaceId, ifaceId)) {
-      return;
+        // Fill out obvious data...
+        jsonResponse["Id"] = ifaceId;
+        jsonResponse["@odata.id"] =
+            "/redfish/v1/Managers/openbmc/EthernetInterfaces/" +
+            parent_ifaceId + "/VLANs/" + ifaceId;
+
+        jsonResponse["VLANEnable"] = true;
+        jsonResponse["VLANId"] = *eth_data.vlanId;
+
+        return jsonResponse;
     }
 
-    // Get single eth interface data, and call the below callback for JSON
-    // preparation
-    ethernetProvider.getEthernetIfaceData(
-        ifaceId, [&, parentIfaceId, ifaceId](
-                     const bool &success, const EthernetInterfaceData &eth_data,
-                     const std::vector<IPv4AddressData> &ipv4_data) {
-          if (success && eth_data.vlanId != nullptr) {
-            res.jsonValue =
-                parseInterfaceData(parentIfaceId, ifaceId, eth_data, ipv4_data);
-          } else {
-            // ... otherwise return error
-            // TODO(Pawel)consider distinguish between non existing object, and
-            // other errors
+    bool verifyNames(crow::Response &res, const std::string &parent,
+                     const std::string &iface)
+    {
+        if (!boost::starts_with(iface, parent + "_"))
+        {
             messages::addMessageToErrorJson(
                 res.jsonValue,
-                messages::resourceNotFound("VLAN Network Interface", ifaceId));
-            res.result(boost::beast::http::status::not_found);
-          }
-          res.end();
-        });
-  }
-
-  void doPatch(crow::Response &res, const crow::Request &req,
-               const std::vector<std::string> &params) override {
-    if (params.size() != 2) {
-      res.result(boost::beast::http::status::internal_server_error);
-      res.end();
-      return;
-    }
-
-    const std::string &parentIfaceId = params[0];
-    const std::string &ifaceId = params[1];
-
-    if (!verifyNames(res, parentIfaceId, ifaceId)) {
-      return;
-    }
-
-    nlohmann::json patchReq;
-
-    if (!json_util::processJsonFromRequest(res, req, patchReq)) {
-      return;
-    }
-
-    // Get single eth interface data, and call the below callback for JSON
-    // preparation
-    ethernetProvider.getEthernetIfaceData(
-        ifaceId, [&, parentIfaceId, ifaceId, patchReq = std::move(patchReq) ](
-                     const bool &success, const EthernetInterfaceData &eth_data,
-                     const std::vector<IPv4AddressData> &ipv4_data) {
-          if (!success) {
-            // ... otherwise return error
-            // TODO(Pawel)consider distinguish between non existing object,
-            // and
-            // other errors
-            messages::addMessageToErrorJson(
-                res.jsonValue,
-                messages::resourceNotFound("VLAN Network Interface", ifaceId));
+                messages::resourceNotFound("VLAN Network Interface", iface));
             res.result(boost::beast::http::status::not_found);
             res.end();
 
+            return false;
+        }
+        else
+        {
+            return true;
+        }
+    }
+
+    /**
+     * Functions triggers appropriate requests on DBus
+     */
+    void doGet(crow::Response &res, const crow::Request &req,
+               const std::vector<std::string> &params) override
+    {
+        // TODO(Pawel) this shall be parametrized call (two params) to get
+        // EthernetInterfaces for any Manager, not only hardcoded 'openbmc'.
+        // Check if there is required param, truly entering this shall be
+        // impossible.
+        if (params.size() != 2)
+        {
+            res.result(boost::beast::http::status::internal_server_error);
+            res.end();
             return;
-          }
+        }
 
-          res.jsonValue =
-              parseInterfaceData(parentIfaceId, ifaceId, eth_data, ipv4_data);
+        const std::string &parentIfaceId = params[0];
+        const std::string &ifaceId = params[1];
 
-          std::shared_ptr<AsyncResp> asyncResp =
-              std::make_shared<AsyncResp>(res);
+        if (!verifyNames(res, parentIfaceId, ifaceId))
+        {
+            return;
+        }
 
-          for (auto propertyIt = patchReq.begin(); propertyIt != patchReq.end();
-               ++propertyIt) {
-            if (propertyIt.key() != "VLANEnable" &&
-                propertyIt.key() != "VLANId") {
-              auto fieldInJsonIt = res.jsonValue.find(propertyIt.key());
-
-              if (fieldInJsonIt == res.jsonValue.end()) {
-                // Field not in scope of defined fields
-                messages::addMessageToJsonRoot(
-                    res.jsonValue, messages::propertyUnknown(propertyIt.key()));
-              } else if (*fieldInJsonIt != *propertyIt) {
-                // User attempted to modify non-writable field
-                messages::addMessageToJsonRoot(
-                    res.jsonValue,
-                    messages::propertyNotWritable(propertyIt.key()));
-              }
-            }
-          }
-
-          EthernetInterface::handleVlanPatch(ifaceId, patchReq, eth_data, "/",
-                                             asyncResp);
-        });
-  }
-
-  void doDelete(crow::Response &res, const crow::Request &req,
-                const std::vector<std::string> &params) override {
-    if (params.size() != 2) {
-      res.result(boost::beast::http::status::internal_server_error);
-      res.end();
-      return;
+        // Get single eth interface data, and call the below callback for JSON
+        // preparation
+        ethernetProvider.getEthernetIfaceData(
+            ifaceId, [&, parentIfaceId,
+                      ifaceId](const bool &success,
+                               const EthernetInterfaceData &eth_data,
+                               const std::vector<IPv4AddressData> &ipv4_data) {
+                if (success && eth_data.vlanId != nullptr)
+                {
+                    res.jsonValue = parseInterfaceData(parentIfaceId, ifaceId,
+                                                       eth_data, ipv4_data);
+                }
+                else
+                {
+                    // ... otherwise return error
+                    // TODO(Pawel)consider distinguish between non existing
+                    // object, and other errors
+                    messages::addMessageToErrorJson(
+                        res.jsonValue, messages::resourceNotFound(
+                                           "VLAN Network Interface", ifaceId));
+                    res.result(boost::beast::http::status::not_found);
+                }
+                res.end();
+            });
     }
 
-    const std::string &parentIfaceId = params[0];
-    const std::string &ifaceId = params[1];
-
-    if (!verifyNames(res, parentIfaceId, ifaceId)) {
-      return;
-    }
-
-    // Get single eth interface data, and call the below callback for JSON
-    // preparation
-    ethernetProvider.getEthernetIfaceData(
-        ifaceId, [&, parentIfaceId, ifaceId](
-                     const bool &success, const EthernetInterfaceData &eth_data,
-                     const std::vector<IPv4AddressData> &ipv4_data) {
-          if (success && eth_data.vlanId != nullptr) {
-            res.jsonValue =
-                parseInterfaceData(parentIfaceId, ifaceId, eth_data, ipv4_data);
-
-            // Disable VLAN
-            OnDemandEthernetProvider::disableVlan(
-                ifaceId, [&](const boost::system::error_code ec) {
-                  if (ec) {
-                    res.jsonValue = nlohmann::json::object();
-                    messages::addMessageToErrorJson(res.jsonValue,
-                                                    messages::internalError());
-                    res.result(
-                        boost::beast::http::status::internal_server_error);
-                  }
-                  res.end();
-                });
-          } else {
-            // ... otherwise return error
-            // TODO(Pawel)consider distinguish between non existing object,
-            // and
-            // other errors
-            messages::addMessageToErrorJson(
-                res.jsonValue,
-                messages::resourceNotFound("VLAN Network Interface", ifaceId));
-            res.result(boost::beast::http::status::not_found);
+    void doPatch(crow::Response &res, const crow::Request &req,
+                 const std::vector<std::string> &params) override
+    {
+        if (params.size() != 2)
+        {
+            res.result(boost::beast::http::status::internal_server_error);
             res.end();
-          }
-        });
-  }
+            return;
+        }
 
-  /**
-   * This allows VlanNetworkInterfaceCollection to reuse this class' doGet
-   * method, to maintain consistency of returned data, as Collection's doPost
-   * should return data for created member which should match member's doGet
-   * result in 100%.
-   */
-  friend VlanNetworkInterfaceCollection;
+        const std::string &parentIfaceId = params[0];
+        const std::string &ifaceId = params[1];
 
-  // Ethernet Provider object
-  // TODO(Pawel) consider move it to singleton
-  OnDemandEthernetProvider ethernetProvider;
+        if (!verifyNames(res, parentIfaceId, ifaceId))
+        {
+            return;
+        }
+
+        nlohmann::json patchReq;
+
+        if (!json_util::processJsonFromRequest(res, req, patchReq))
+        {
+            return;
+        }
+
+        // Get single eth interface data, and call the below callback for JSON
+        // preparation
+        ethernetProvider.getEthernetIfaceData(
+            ifaceId,
+            [&, parentIfaceId, ifaceId, patchReq = std::move(patchReq)](
+                const bool &success, const EthernetInterfaceData &eth_data,
+                const std::vector<IPv4AddressData> &ipv4_data) {
+                if (!success)
+                {
+                    // ... otherwise return error
+                    // TODO(Pawel)consider distinguish between non existing
+                    // object, and other errors
+                    messages::addMessageToErrorJson(
+                        res.jsonValue, messages::resourceNotFound(
+                                           "VLAN Network Interface", ifaceId));
+                    res.result(boost::beast::http::status::not_found);
+                    res.end();
+
+                    return;
+                }
+
+                res.jsonValue = parseInterfaceData(parentIfaceId, ifaceId,
+                                                   eth_data, ipv4_data);
+
+                std::shared_ptr<AsyncResp> asyncResp =
+                    std::make_shared<AsyncResp>(res);
+
+                for (auto propertyIt = patchReq.begin();
+                     propertyIt != patchReq.end(); ++propertyIt)
+                {
+                    if (propertyIt.key() != "VLANEnable" &&
+                        propertyIt.key() != "VLANId")
+                    {
+                        auto fieldInJsonIt =
+                            res.jsonValue.find(propertyIt.key());
+
+                        if (fieldInJsonIt == res.jsonValue.end())
+                        {
+                            // Field not in scope of defined fields
+                            messages::addMessageToJsonRoot(
+                                res.jsonValue,
+                                messages::propertyUnknown(propertyIt.key()));
+                        }
+                        else if (*fieldInJsonIt != *propertyIt)
+                        {
+                            // User attempted to modify non-writable field
+                            messages::addMessageToJsonRoot(
+                                res.jsonValue, messages::propertyNotWritable(
+                                                   propertyIt.key()));
+                        }
+                    }
+                }
+
+                EthernetInterface::handleVlanPatch(ifaceId, patchReq, eth_data,
+                                                   "/", asyncResp);
+            });
+    }
+
+    void doDelete(crow::Response &res, const crow::Request &req,
+                  const std::vector<std::string> &params) override
+    {
+        if (params.size() != 2)
+        {
+            res.result(boost::beast::http::status::internal_server_error);
+            res.end();
+            return;
+        }
+
+        const std::string &parentIfaceId = params[0];
+        const std::string &ifaceId = params[1];
+
+        if (!verifyNames(res, parentIfaceId, ifaceId))
+        {
+            return;
+        }
+
+        // Get single eth interface data, and call the below callback for JSON
+        // preparation
+        ethernetProvider.getEthernetIfaceData(
+            ifaceId, [&, parentIfaceId,
+                      ifaceId](const bool &success,
+                               const EthernetInterfaceData &eth_data,
+                               const std::vector<IPv4AddressData> &ipv4_data) {
+                if (success && eth_data.vlanId != nullptr)
+                {
+                    res.jsonValue = parseInterfaceData(parentIfaceId, ifaceId,
+                                                       eth_data, ipv4_data);
+
+                    // Disable VLAN
+                    OnDemandEthernetProvider::disableVlan(
+                        ifaceId, [&](const boost::system::error_code ec) {
+                            if (ec)
+                            {
+                                res.jsonValue = nlohmann::json::object();
+                                messages::addMessageToErrorJson(
+                                    res.jsonValue, messages::internalError());
+                                res.result(boost::beast::http::status::
+                                               internal_server_error);
+                            }
+                            res.end();
+                        });
+                }
+                else
+                {
+                    // ... otherwise return error
+                    // TODO(Pawel)consider distinguish between non existing
+                    // object, and other errors
+                    messages::addMessageToErrorJson(
+                        res.jsonValue, messages::resourceNotFound(
+                                           "VLAN Network Interface", ifaceId));
+                    res.result(boost::beast::http::status::not_found);
+                    res.end();
+                }
+            });
+    }
+
+    /**
+     * This allows VlanNetworkInterfaceCollection to reuse this class' doGet
+     * method, to maintain consistency of returned data, as Collection's doPost
+     * should return data for created member which should match member's doGet
+     * result in 100%.
+     */
+    friend VlanNetworkInterfaceCollection;
+
+    // Ethernet Provider object
+    // TODO(Pawel) consider move it to singleton
+    OnDemandEthernetProvider ethernetProvider;
 };
 
 /**
  * VlanNetworkInterfaceCollection derived class for delivering
  * VLANNetworkInterface Collection Schema
  */
-class VlanNetworkInterfaceCollection : public Node {
- public:
-  template <typename CrowApp>
-  // TODO(Pawel) Remove line from below, where we assume that there is only one
-  // manager called openbmc This shall be generic, but requires to update
-  // GetSubroutes method
-  VlanNetworkInterfaceCollection(CrowApp &app)
-      : Node(app,
+class VlanNetworkInterfaceCollection : public Node
+{
+  public:
+    template <typename CrowApp>
+    // TODO(Pawel) Remove line from below, where we assume that there is only
+    // one manager called openbmc This shall be generic, but requires to update
+    // GetSubroutes method
+    VlanNetworkInterfaceCollection(CrowApp &app) :
+        Node(app,
              "/redfish/v1/Managers/openbmc/EthernetInterfaces/<str>/VLANs/",
              std::string()),
-        memberVlan(app) {
-    Node::json["@odata.type"] =
-        "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata"
-        "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection";
-    Node::json["Name"] = "VLAN Network Interface Collection";
+        memberVlan(app)
+    {
+        Node::json["@odata.type"] =
+            "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata"
+            "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection";
+        Node::json["Name"] = "VLAN Network Interface Collection";
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-  }
-
- private:
-  /**
-   * Functions triggers appropriate requests on DBus
-   */
-  void doGet(crow::Response &res, const crow::Request &req,
-             const std::vector<std::string> &params) override {
-    if (params.size() != 1) {
-      // This means there is a problem with the router
-      res.result(boost::beast::http::status::internal_server_error);
-      res.end();
-
-      return;
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
     }
 
-    // TODO(Pawel) this shall be parametrized call to get EthernetInterfaces for
-    // any Manager, not only hardcoded 'openbmc'.
-    std::string managerId = "openbmc";
-    std::string rootInterfaceName = params[0];
+  private:
+    /**
+     * Functions triggers appropriate requests on DBus
+     */
+    void doGet(crow::Response &res, const crow::Request &req,
+               const std::vector<std::string> &params) override
+    {
+        if (params.size() != 1)
+        {
+            // This means there is a problem with the router
+            res.result(boost::beast::http::status::internal_server_error);
+            res.end();
 
-    // get eth interface list, and call the below callback for JSON preparation
-    ethernetProvider.getEthernetIfaceList([
-          &, managerId{std::move(managerId)},
-          rootInterfaceName{std::move(rootInterfaceName)}
-    ](const bool &success, const std::vector<std::string> &iface_list) {
-      if (success) {
-        bool rootInterfaceFound = false;
-        nlohmann::json ifaceArray = nlohmann::json::array();
-
-        for (const std::string &ifaceItem : iface_list) {
-          if (ifaceItem == rootInterfaceName) {
-            rootInterfaceFound = true;
-          } else if (boost::starts_with(ifaceItem, rootInterfaceName + "_")) {
-            ifaceArray.push_back(
-                {{"@odata.id", "/redfish/v1/Managers/" + managerId +
-                                   "/EthernetInterfaces/" + rootInterfaceName +
-                                   "/VLANs/" + ifaceItem}});
-          }
+            return;
         }
 
-        if (rootInterfaceFound) {
-          Node::json["Members"] = ifaceArray;
-          Node::json["Members@odata.count"] = ifaceArray.size();
-          Node::json["@odata.id"] = "/redfish/v1/Managers/" + managerId +
-                                    "/EthernetInterfaces/" + rootInterfaceName +
-                                    "/VLANs";
-          res.jsonValue = Node::json;
-        } else {
-          messages::addMessageToErrorJson(
-              res.jsonValue, messages::resourceNotFound("EthernetInterface",
-                                                        rootInterfaceName));
-          res.result(boost::beast::http::status::not_found);
-          res.end();
-        }
-      } else {
-        // No success, best what we can do is return INTERNALL ERROR
-        res.result(boost::beast::http::status::internal_server_error);
-      }
-      res.end();
-    });
-  }
+        // TODO(Pawel) this shall be parametrized call to get EthernetInterfaces
+        // for any Manager, not only hardcoded 'openbmc'.
+        std::string managerId = "openbmc";
+        std::string rootInterfaceName = params[0];
 
-  void doPost(crow::Response &res, const crow::Request &req,
-              const std::vector<std::string> &params) override {
-    if (params.size() != 1) {
-      // This means there is a problem with the router
-      res.result(boost::beast::http::status::internal_server_error);
-      res.end();
-      return;
-    }
+        // get eth interface list, and call the below callback for JSON
+        // preparation
+        ethernetProvider.getEthernetIfaceList(
+            [&, managerId{std::move(managerId)},
+             rootInterfaceName{std::move(rootInterfaceName)}](
+                const bool &success,
+                const std::vector<std::string> &iface_list) {
+                if (success)
+                {
+                    bool rootInterfaceFound = false;
+                    nlohmann::json ifaceArray = nlohmann::json::array();
 
-    nlohmann::json postReq;
+                    for (const std::string &ifaceItem : iface_list)
+                    {
+                        if (ifaceItem == rootInterfaceName)
+                        {
+                            rootInterfaceFound = true;
+                        }
+                        else if (boost::starts_with(ifaceItem,
+                                                    rootInterfaceName + "_"))
+                        {
+                            ifaceArray.push_back(
+                                {{"@odata.id", "/redfish/v1/Managers/" +
+                                                   managerId +
+                                                   "/EthernetInterfaces/" +
+                                                   rootInterfaceName +
+                                                   "/VLANs/" + ifaceItem}});
+                        }
+                    }
 
-    if (!json_util::processJsonFromRequest(res, req, postReq)) {
-      return;
-    }
-
-    // TODO(Pawel) this shall be parametrized call to get EthernetInterfaces for
-    // any Manager, not only hardcoded 'openbmc'.
-    std::string managerId = "openbmc";
-    std::string rootInterfaceName = params[0];
-    uint64_t vlanId;
-    bool errorDetected;
-
-    if (json_util::getUnsigned(
-            "VLANId", postReq, vlanId,
-            static_cast<uint8_t>(json_util::MessageSetting::MISSING) |
-                static_cast<uint8_t>(json_util::MessageSetting::TYPE_ERROR),
-            res.jsonValue, "/VLANId") != json_util::Result::SUCCESS) {
-      res.end();
-      return;
-    }
-
-    // get eth interface list, and call the below callback for JSON preparation
-    ethernetProvider.getEthernetIfaceList([
-          &, managerId{std::move(managerId)},
-          rootInterfaceName{std::move(rootInterfaceName)}
-    ](const bool &success, const std::vector<std::string> &iface_list) {
-      if (success) {
-        bool rootInterfaceFound = false;
-
-        for (const std::string &ifaceItem : iface_list) {
-          if (ifaceItem == rootInterfaceName) {
-            rootInterfaceFound = true;
-            break;
-          }
-        }
-
-        if (rootInterfaceFound) {
-          ethernetProvider.createVlan(
-              rootInterfaceName, vlanId,
-              [&, vlanId, rootInterfaceName,
-               req{std::move(req)} ](const boost::system::error_code ec) {
-                if (ec) {
-                  messages::addMessageToErrorJson(res.jsonValue,
-                                                  messages::internalError());
-                  res.end();
-                } else {
-                  memberVlan.doGet(
-                      res, req,
-                      {rootInterfaceName,
-                       rootInterfaceName + "_" + std::to_string(vlanId)});
+                    if (rootInterfaceFound)
+                    {
+                        Node::json["Members"] = ifaceArray;
+                        Node::json["Members@odata.count"] = ifaceArray.size();
+                        Node::json["@odata.id"] = "/redfish/v1/Managers/" +
+                                                  managerId +
+                                                  "/EthernetInterfaces/" +
+                                                  rootInterfaceName + "/VLANs";
+                        res.jsonValue = Node::json;
+                    }
+                    else
+                    {
+                        messages::addMessageToErrorJson(
+                            res.jsonValue,
+                            messages::resourceNotFound("EthernetInterface",
+                                                       rootInterfaceName));
+                        res.result(boost::beast::http::status::not_found);
+                        res.end();
+                    }
                 }
-              });
-        } else {
-          messages::addMessageToErrorJson(
-              res.jsonValue, messages::resourceNotFound("EthernetInterface",
-                                                        rootInterfaceName));
-          res.result(boost::beast::http::status::not_found);
-          res.end();
-        }
-      } else {
-        // No success, best what we can do is return INTERNALL ERROR
-        res.result(boost::beast::http::status::internal_server_error);
-        res.end();
-      }
-    });
-  }
+                else
+                {
+                    // No success, best what we can do is return INTERNALL ERROR
+                    res.result(
+                        boost::beast::http::status::internal_server_error);
+                }
+                res.end();
+            });
+    }
 
-  // Ethernet Provider object
-  // TODO(Pawel) consider move it to singleton
-  OnDemandEthernetProvider ethernetProvider;
-  VlanNetworkInterface memberVlan;
+    void doPost(crow::Response &res, const crow::Request &req,
+                const std::vector<std::string> &params) override
+    {
+        if (params.size() != 1)
+        {
+            // This means there is a problem with the router
+            res.result(boost::beast::http::status::internal_server_error);
+            res.end();
+            return;
+        }
+
+        nlohmann::json postReq;
+
+        if (!json_util::processJsonFromRequest(res, req, postReq))
+        {
+            return;
+        }
+
+        // TODO(Pawel) this shall be parametrized call to get EthernetInterfaces
+        // for any Manager, not only hardcoded 'openbmc'.
+        std::string managerId = "openbmc";
+        std::string rootInterfaceName = params[0];
+        uint64_t vlanId;
+        bool errorDetected;
+
+        if (json_util::getUnsigned(
+                "VLANId", postReq, vlanId,
+                static_cast<uint8_t>(json_util::MessageSetting::MISSING) |
+                    static_cast<uint8_t>(json_util::MessageSetting::TYPE_ERROR),
+                res.jsonValue, "/VLANId") != json_util::Result::SUCCESS)
+        {
+            res.end();
+            return;
+        }
+
+        // get eth interface list, and call the below callback for JSON
+        // preparation
+        ethernetProvider.getEthernetIfaceList(
+            [&, managerId{std::move(managerId)},
+             rootInterfaceName{std::move(rootInterfaceName)}](
+                const bool &success,
+                const std::vector<std::string> &iface_list) {
+                if (success)
+                {
+                    bool rootInterfaceFound = false;
+
+                    for (const std::string &ifaceItem : iface_list)
+                    {
+                        if (ifaceItem == rootInterfaceName)
+                        {
+                            rootInterfaceFound = true;
+                            break;
+                        }
+                    }
+
+                    if (rootInterfaceFound)
+                    {
+                        ethernetProvider.createVlan(
+                            rootInterfaceName, vlanId,
+                            [&, vlanId, rootInterfaceName, req{std::move(req)}](
+                                const boost::system::error_code ec) {
+                                if (ec)
+                                {
+                                    messages::addMessageToErrorJson(
+                                        res.jsonValue,
+                                        messages::internalError());
+                                    res.end();
+                                }
+                                else
+                                {
+                                    memberVlan.doGet(
+                                        res, req,
+                                        {rootInterfaceName,
+                                         rootInterfaceName + "_" +
+                                             std::to_string(vlanId)});
+                                }
+                            });
+                    }
+                    else
+                    {
+                        messages::addMessageToErrorJson(
+                            res.jsonValue,
+                            messages::resourceNotFound("EthernetInterface",
+                                                       rootInterfaceName));
+                        res.result(boost::beast::http::status::not_found);
+                        res.end();
+                    }
+                }
+                else
+                {
+                    // No success, best what we can do is return INTERNALL ERROR
+                    res.result(
+                        boost::beast::http::status::internal_server_error);
+                    res.end();
+                }
+            });
+    }
+
+    // Ethernet Provider object
+    // TODO(Pawel) consider move it to singleton
+    OnDemandEthernetProvider ethernetProvider;
+    VlanNetworkInterface memberVlan;
 };
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/lib/managers.hpp b/redfish-core/lib/managers.hpp
index 7a861b4..86fe567 100644
--- a/redfish-core/lib/managers.hpp
+++ b/redfish-core/lib/managers.hpp
@@ -17,101 +17,111 @@
 
 #include "node.hpp"
 
-namespace redfish {
+namespace redfish
+{
 
-class Manager : public Node {
- public:
-  Manager(CrowApp& app) : Node(app, "/redfish/v1/Managers/openbmc/") {
-    Node::json["@odata.id"] = "/redfish/v1/Managers/openbmc";
-    Node::json["@odata.type"] = "#Manager.v1_3_0.Manager";
-    Node::json["@odata.context"] = "/redfish/v1/$metadata#Manager.Manager";
-    Node::json["Id"] = "openbmc";
-    Node::json["Name"] = "OpenBmc Manager";
-    Node::json["Description"] = "Baseboard Management Controller";
-    Node::json["PowerState"] = "On";
-    Node::json["UUID"] =
-        app.template getMiddleware<crow::persistent_data::Middleware>()
-            .systemUuid;
-    Node::json["Model"] = "OpenBmc";               // TODO(ed), get model
-    Node::json["FirmwareVersion"] = "1234456789";  // TODO(ed), get fwversion
-    Node::json["EthernetInterfaces"] = nlohmann::json(
-        {{"@odata.id",
-          "/redfish/v1/Managers/openbmc/EthernetInterfaces"}});  // TODO(Pawel),
-                                                                 // remove this
-                                                                 // when
-                                                                 // subroutes
-                                                                 // will work
-                                                                 // correctly
+class Manager : public Node
+{
+  public:
+    Manager(CrowApp& app) : Node(app, "/redfish/v1/Managers/openbmc/")
+    {
+        Node::json["@odata.id"] = "/redfish/v1/Managers/openbmc";
+        Node::json["@odata.type"] = "#Manager.v1_3_0.Manager";
+        Node::json["@odata.context"] = "/redfish/v1/$metadata#Manager.Manager";
+        Node::json["Id"] = "openbmc";
+        Node::json["Name"] = "OpenBmc Manager";
+        Node::json["Description"] = "Baseboard Management Controller";
+        Node::json["PowerState"] = "On";
+        Node::json["UUID"] =
+            app.template getMiddleware<crow::persistent_data::Middleware>()
+                .systemUuid;
+        Node::json["Model"] = "OpenBmc";              // TODO(ed), get model
+        Node::json["FirmwareVersion"] = "1234456789"; // TODO(ed), get fwversion
+        Node::json["EthernetInterfaces"] = nlohmann::json(
+            {{"@odata.id", "/redfish/v1/Managers/openbmc/"
+                           "EthernetInterfaces"}}); // TODO(Pawel),
+                                                    // remove this
+                                                    // when
+                                                    // subroutes
+                                                    // will work
+                                                    // correctly
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-  }
-
- private:
-  void doGet(crow::Response& res, const crow::Request& req,
-             const std::vector<std::string>& params) override {
-    Node::json["DateTime"] = getDateTime();
-    // Copy over the static data to include the entries added by SubRoute
-    res.jsonValue = Node::json;
-    res.end();
-  }
-
-  std::string getDateTime() const {
-    std::array<char, 128> dateTime;
-    std::string redfishDateTime("0000-00-00T00:00:00Z00:00");
-    std::time_t time = std::time(nullptr);
-
-    if (std::strftime(dateTime.begin(), dateTime.size(), "%FT%T%z",
-                      std::localtime(&time))) {
-      // insert the colon required by the ISO 8601 standard
-      redfishDateTime = std::string(dateTime.data());
-      redfishDateTime.insert(redfishDateTime.end() - 2, ':');
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
     }
 
-    return redfishDateTime;
-  }
+  private:
+    void doGet(crow::Response& res, const crow::Request& req,
+               const std::vector<std::string>& params) override
+    {
+        Node::json["DateTime"] = getDateTime();
+        // Copy over the static data to include the entries added by SubRoute
+        res.jsonValue = Node::json;
+        res.end();
+    }
+
+    std::string getDateTime() const
+    {
+        std::array<char, 128> dateTime;
+        std::string redfishDateTime("0000-00-00T00:00:00Z00:00");
+        std::time_t time = std::time(nullptr);
+
+        if (std::strftime(dateTime.begin(), dateTime.size(), "%FT%T%z",
+                          std::localtime(&time)))
+        {
+            // insert the colon required by the ISO 8601 standard
+            redfishDateTime = std::string(dateTime.data());
+            redfishDateTime.insert(redfishDateTime.end() - 2, ':');
+        }
+
+        return redfishDateTime;
+    }
 };
 
-class ManagerCollection : public Node {
- public:
-  ManagerCollection(CrowApp& app) : Node(app, "/redfish/v1/Managers/") {
-    Node::json["@odata.id"] = "/redfish/v1/Managers";
-    Node::json["@odata.type"] = "#ManagerCollection.ManagerCollection";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata#ManagerCollection.ManagerCollection";
-    Node::json["Name"] = "Manager Collection";
-    Node::json["Members@odata.count"] = 1;
-    Node::json["Members"] = {{{"@odata.id", "/redfish/v1/Managers/openbmc"}}};
+class ManagerCollection : public Node
+{
+  public:
+    ManagerCollection(CrowApp& app) : Node(app, "/redfish/v1/Managers/")
+    {
+        Node::json["@odata.id"] = "/redfish/v1/Managers";
+        Node::json["@odata.type"] = "#ManagerCollection.ManagerCollection";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata#ManagerCollection.ManagerCollection";
+        Node::json["Name"] = "Manager Collection";
+        Node::json["Members@odata.count"] = 1;
+        Node::json["Members"] = {
+            {{"@odata.id", "/redfish/v1/Managers/openbmc"}}};
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-  }
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
+    }
 
- private:
-  void doGet(crow::Response& res, const crow::Request& req,
-             const std::vector<std::string>& params) override {
-    // Collections don't include the static data added by SubRoute because it
-    // has a duplicate entry for members
-    res.jsonValue["@odata.id"] = "/redfish/v1/Managers";
-    res.jsonValue["@odata.type"] = "#ManagerCollection.ManagerCollection";
-    res.jsonValue["@odata.context"] =
-        "/redfish/v1/$metadata#ManagerCollection.ManagerCollection";
-    res.jsonValue["Name"] = "Manager Collection";
-    res.jsonValue["Members@odata.count"] = 1;
-    res.jsonValue["Members"] = {
-        {{"@odata.id", "/redfish/v1/Managers/openbmc"}}};
-    res.end();
-  }
+  private:
+    void doGet(crow::Response& res, const crow::Request& req,
+               const std::vector<std::string>& params) override
+    {
+        // Collections don't include the static data added by SubRoute because
+        // it has a duplicate entry for members
+        res.jsonValue["@odata.id"] = "/redfish/v1/Managers";
+        res.jsonValue["@odata.type"] = "#ManagerCollection.ManagerCollection";
+        res.jsonValue["@odata.context"] =
+            "/redfish/v1/$metadata#ManagerCollection.ManagerCollection";
+        res.jsonValue["Name"] = "Manager Collection";
+        res.jsonValue["Members@odata.count"] = 1;
+        res.jsonValue["Members"] = {
+            {{"@odata.id", "/redfish/v1/Managers/openbmc"}}};
+        res.end();
+    }
 };
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/lib/network_protocol.hpp b/redfish-core/lib/network_protocol.hpp
index ae29df0..bb021f5 100644
--- a/redfish-core/lib/network_protocol.hpp
+++ b/redfish-core/lib/network_protocol.hpp
@@ -18,24 +18,27 @@
 #include "error_messages.hpp"
 #include "node.hpp"
 
-namespace redfish {
+namespace redfish
+{
 
-enum NetworkProtocolUnitStructFields {
-  NET_PROTO_UNIT_NAME,
-  NET_PROTO_UNIT_DESC,
-  NET_PROTO_UNIT_LOAD_STATE,
-  NET_PROTO_UNIT_ACTIVE_STATE,
-  NET_PROTO_UNIT_SUB_STATE,
-  NET_PROTO_UNIT_DEVICE,
-  NET_PROTO_UNIT_OBJ_PATH,
-  NET_PROTO_UNIT_ALWAYS_0,
-  NET_PROTO_UNIT_ALWAYS_EMPTY,
-  NET_PROTO_UNIT_ALWAYS_ROOT_PATH
+enum NetworkProtocolUnitStructFields
+{
+    NET_PROTO_UNIT_NAME,
+    NET_PROTO_UNIT_DESC,
+    NET_PROTO_UNIT_LOAD_STATE,
+    NET_PROTO_UNIT_ACTIVE_STATE,
+    NET_PROTO_UNIT_SUB_STATE,
+    NET_PROTO_UNIT_DEVICE,
+    NET_PROTO_UNIT_OBJ_PATH,
+    NET_PROTO_UNIT_ALWAYS_0,
+    NET_PROTO_UNIT_ALWAYS_EMPTY,
+    NET_PROTO_UNIT_ALWAYS_ROOT_PATH
 };
 
-enum NetworkProtocolListenResponseElements {
-  NET_PROTO_LISTEN_TYPE,
-  NET_PROTO_LISTEN_STREAM
+enum NetworkProtocolListenResponseElements
+{
+    NET_PROTO_LISTEN_TYPE,
+    NET_PROTO_LISTEN_STREAM
 };
 
 /**
@@ -46,9 +49,10 @@
                std::string, sdbusplus::message::object_path, uint32_t,
                std::string, sdbusplus::message::object_path>;
 
-struct ServiceConfiguration {
-  const char* serviceName;
-  const char* socketPath;
+struct ServiceConfiguration
+{
+    const char* serviceName;
+    const char* socketPath;
 };
 
 const static boost::container::flat_map<const char*, ServiceConfiguration>
@@ -63,128 +67,161 @@
          {"phosphor-ipmi-net.service",
           "/org/freedesktop/systemd1/unit/phosphor_2dipmi_2dnet_2esocket"}}};
 
-class NetworkProtocol : public Node {
- public:
-  NetworkProtocol(CrowApp& app)
-      : Node(app, "/redfish/v1/Managers/openbmc/NetworkProtocol") {
-    Node::json["@odata.type"] =
-        "#ManagerNetworkProtocol.v1_1_0.ManagerNetworkProtocol";
-    Node::json["@odata.id"] = "/redfish/v1/Managers/openbmc/NetworkProtocol";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata#ManagerNetworkProtocol.ManagerNetworkProtocol";
-    Node::json["Id"] = "NetworkProtocol";
-    Node::json["Name"] = "Manager Network Protocol";
-    Node::json["Description"] = "Manager Network Service";
-    Node::json["Status"]["Health"] = "OK";
-    Node::json["Status"]["HealthRollup"] = "OK";
-    Node::json["Status"]["State"] = "Enabled";
+class NetworkProtocol : public Node
+{
+  public:
+    NetworkProtocol(CrowApp& app) :
+        Node(app, "/redfish/v1/Managers/openbmc/NetworkProtocol")
+    {
+        Node::json["@odata.type"] =
+            "#ManagerNetworkProtocol.v1_1_0.ManagerNetworkProtocol";
+        Node::json["@odata.id"] =
+            "/redfish/v1/Managers/openbmc/NetworkProtocol";
+        Node::json["@odata.context"] =
+            "/redfish/v1/"
+            "$metadata#ManagerNetworkProtocol.ManagerNetworkProtocol";
+        Node::json["Id"] = "NetworkProtocol";
+        Node::json["Name"] = "Manager Network Protocol";
+        Node::json["Description"] = "Manager Network Service";
+        Node::json["Status"]["Health"] = "OK";
+        Node::json["Status"]["HealthRollup"] = "OK";
+        Node::json["Status"]["State"] = "Enabled";
 
-    for (auto& protocol : protocolToDBus) {
-      Node::json[protocol.first]["ProtocolEnabled"] = false;
+        for (auto& protocol : protocolToDBus)
+        {
+            Node::json[protocol.first]["ProtocolEnabled"] = false;
+        }
+
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
     }
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-  }
+  private:
+    void doGet(crow::Response& res, const crow::Request& req,
+               const std::vector<std::string>& params) override
+    {
+        std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
 
- private:
-  void doGet(crow::Response& res, const crow::Request& req,
-             const std::vector<std::string>& params) override {
-    std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
-
-    getData(asyncResp);
-  }
-
-  std::string getHostName() const {
-    std::string hostName;
-
-    std::array<char, HOST_NAME_MAX> hostNameCStr;
-    if (gethostname(hostNameCStr.data(), hostNameCStr.size()) == 0) {
-      hostName = hostNameCStr.data();
+        getData(asyncResp);
     }
-    return hostName;
-  }
 
-  void getData(const std::shared_ptr<AsyncResp>& asyncResp) {
-    Node::json["HostName"] = getHostName();
-    asyncResp->res.jsonValue = Node::json;
+    std::string getHostName() const
+    {
+        std::string hostName;
 
-    crow::connections::systemBus->async_method_call(
-        [asyncResp](const boost::system::error_code ec,
-                    const std::vector<UnitStruct>& resp) {
-          if (ec) {
-            asyncResp->res.jsonValue = nlohmann::json::object();
-            messages::addMessageToErrorJson(asyncResp->res.jsonValue,
-                                            messages::internalError());
-            asyncResp->res.result(
-                boost::beast::http::status::internal_server_error);
-            return;
-          }
+        std::array<char, HOST_NAME_MAX> hostNameCStr;
+        if (gethostname(hostNameCStr.data(), hostNameCStr.size()) == 0)
+        {
+            hostName = hostNameCStr.data();
+        }
+        return hostName;
+    }
 
-          for (auto& unit : resp) {
-            for (auto& kv : protocolToDBus) {
-              if (kv.second.serviceName ==
-                  std::get<NET_PROTO_UNIT_NAME>(unit)) {
-                continue;
-              }
-              const char* service = kv.first;
-              const char* socketPath = kv.second.socketPath;
+    void getData(const std::shared_ptr<AsyncResp>& asyncResp)
+    {
+        Node::json["HostName"] = getHostName();
+        asyncResp->res.jsonValue = Node::json;
 
-              asyncResp->res.jsonValue[service]["ProtocolEnabled"] =
-                  std::get<NET_PROTO_UNIT_SUB_STATE>(unit) == "running";
+        crow::connections::systemBus->async_method_call(
+            [asyncResp](const boost::system::error_code ec,
+                        const std::vector<UnitStruct>& resp) {
+                if (ec)
+                {
+                    asyncResp->res.jsonValue = nlohmann::json::object();
+                    messages::addMessageToErrorJson(asyncResp->res.jsonValue,
+                                                    messages::internalError());
+                    asyncResp->res.result(
+                        boost::beast::http::status::internal_server_error);
+                    return;
+                }
 
-              crow::connections::systemBus->async_method_call(
-                  [ asyncResp, service{std::string(service)}, socketPath ](
-                      const boost::system::error_code ec,
-                      const sdbusplus::message::variant<std::vector<
-                          std::tuple<std::string, std::string>>>& resp) {
-                    if (ec) {
-                      messages::addMessageToJson(asyncResp->res.jsonValue,
-                                                 messages::internalError(),
-                                                 "/" + service);
-                      return;
+                for (auto& unit : resp)
+                {
+                    for (auto& kv : protocolToDBus)
+                    {
+                        if (kv.second.serviceName ==
+                            std::get<NET_PROTO_UNIT_NAME>(unit))
+                        {
+                            continue;
+                        }
+                        const char* service = kv.first;
+                        const char* socketPath = kv.second.socketPath;
+
+                        asyncResp->res.jsonValue[service]["ProtocolEnabled"] =
+                            std::get<NET_PROTO_UNIT_SUB_STATE>(unit) ==
+                            "running";
+
+                        crow::connections::systemBus->async_method_call(
+                            [asyncResp, service{std::string(service)},
+                             socketPath](
+                                const boost::system::error_code ec,
+                                const sdbusplus::message::variant<std::vector<
+                                    std::tuple<std::string, std::string>>>&
+                                    resp) {
+                                if (ec)
+                                {
+                                    messages::addMessageToJson(
+                                        asyncResp->res.jsonValue,
+                                        messages::internalError(),
+                                        "/" + service);
+                                    return;
+                                }
+                                const std::vector<std::tuple<
+                                    std::string, std::string>>* responsePtr =
+                                    mapbox::getPtr<const std::vector<
+                                        std::tuple<std::string, std::string>>>(
+                                        resp);
+                                if (responsePtr == nullptr ||
+                                    responsePtr->size() < 1)
+                                {
+                                    return;
+                                }
+
+                                const std::string& listenStream =
+                                    std::get<NET_PROTO_LISTEN_STREAM>(
+                                        (*responsePtr)[0]);
+                                std::size_t lastColonPos =
+                                    listenStream.rfind(":");
+                                if (lastColonPos == std::string::npos)
+                                {
+                                    // Not a port
+                                    return;
+                                }
+                                std::string portStr =
+                                    listenStream.substr(lastColonPos + 1);
+                                char* endPtr = nullptr;
+                                // Use strtol instead of stroi to avoid
+                                // exceptions
+                                long port =
+                                    std::strtol(portStr.c_str(), &endPtr, 10);
+
+                                if (*endPtr != '\0' || portStr.empty())
+                                {
+                                    // Invalid value
+                                    asyncResp->res.jsonValue[service]["Port"] =
+                                        nullptr;
+                                }
+                                else
+                                {
+                                    // Everything OK
+                                    asyncResp->res.jsonValue[service]["Port"] =
+                                        port;
+                                }
+                            },
+                            "org.freedesktop.systemd1", socketPath,
+                            "org.freedesktop.DBus.Properties", "Get",
+                            "org.freedesktop.systemd1.Socket", "Listen");
                     }
-                    const std::vector<std::tuple<std::string, std::string>>*
-                        responsePtr = mapbox::getPtr<const std::vector<
-                            std::tuple<std::string, std::string>>>(resp);
-                    if (responsePtr == nullptr || responsePtr->size() < 1) {
-                      return;
-                    }
-
-                    const std::string& listenStream =
-                        std::get<NET_PROTO_LISTEN_STREAM>((*responsePtr)[0]);
-                    std::size_t lastColonPos = listenStream.rfind(":");
-                    if (lastColonPos == std::string::npos) {
-                      // Not a port
-                      return;
-                    }
-                    std::string portStr = listenStream.substr(lastColonPos + 1);
-                    char* endPtr = nullptr;
-                    // Use strtol instead of stroi to avoid exceptions
-                    long port = std::strtol(portStr.c_str(), &endPtr, 10);
-
-                    if (*endPtr != '\0' || portStr.empty()) {
-                      // Invalid value
-                      asyncResp->res.jsonValue[service]["Port"] = nullptr;
-                    } else {
-                      // Everything OK
-                      asyncResp->res.jsonValue[service]["Port"] = port;
-                    }
-                  },
-                  "org.freedesktop.systemd1", socketPath,
-                  "org.freedesktop.DBus.Properties", "Get",
-                  "org.freedesktop.systemd1.Socket", "Listen");
-            }
-          }
-        },
-        "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
-        "org.freedesktop.systemd1.Manager", "ListUnits");
-  }
+                }
+            },
+            "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
+            "org.freedesktop.systemd1.Manager", "ListUnits");
+    }
 };
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/lib/redfish_sessions.hpp b/redfish-core/lib/redfish_sessions.hpp
index ca1c375..2406250 100644
--- a/redfish-core/lib/redfish_sessions.hpp
+++ b/redfish-core/lib/redfish_sessions.hpp
@@ -19,312 +19,348 @@
 #include "node.hpp"
 #include "persistent_data_middleware.hpp"
 
-namespace redfish {
+namespace redfish
+{
 
 class SessionCollection;
 
-class Sessions : public Node {
- public:
-  Sessions(CrowApp& app)
-      : Node(app, "/redfish/v1/SessionService/Sessions/<str>/", std::string()) {
-    Node::json["@odata.type"] = "#Session.v1_0_2.Session";
-    Node::json["@odata.context"] = "/redfish/v1/$metadata#Session.Session";
-    Node::json["Name"] = "User Session";
-    Node::json["Description"] = "Manager User Session";
+class Sessions : public Node
+{
+  public:
+    Sessions(CrowApp& app) :
+        Node(app, "/redfish/v1/SessionService/Sessions/<str>/", std::string())
+    {
+        Node::json["@odata.type"] = "#Session.v1_0_2.Session";
+        Node::json["@odata.context"] = "/redfish/v1/$metadata#Session.Session";
+        Node::json["Name"] = "User Session";
+        Node::json["Description"] = "Manager User Session";
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-  }
-
- private:
-  void doGet(crow::Response& res, const crow::Request& req,
-             const std::vector<std::string>& params) override {
-    auto session =
-        crow::persistent_data::SessionStore::getInstance().getSessionByUid(
-            params[0]);
-
-    if (session == nullptr) {
-      messages::addMessageToErrorJson(
-          res.jsonValue, messages::resourceNotFound("Session", params[0]));
-
-      res.result(boost::beast::http::status::not_found);
-      res.end();
-      return;
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
     }
 
-    Node::json["Id"] = session->uniqueId;
-    Node::json["UserName"] = session->username;
-    Node::json["@odata.id"] =
-        "/redfish/v1/SessionService/Sessions/" + session->uniqueId;
+  private:
+    void doGet(crow::Response& res, const crow::Request& req,
+               const std::vector<std::string>& params) override
+    {
+        auto session =
+            crow::persistent_data::SessionStore::getInstance().getSessionByUid(
+                params[0]);
 
-    res.jsonValue = Node::json;
-    res.end();
-  }
+        if (session == nullptr)
+        {
+            messages::addMessageToErrorJson(
+                res.jsonValue,
+                messages::resourceNotFound("Session", params[0]));
 
-  void doDelete(crow::Response& res, const crow::Request& req,
-                const std::vector<std::string>& params) override {
-    // Need only 1 param which should be id of session to be deleted
-    if (params.size() != 1) {
-      // This should be handled by crow and never happen
-      BMCWEB_LOG_ERROR
-          << "Session DELETE has been called with invalid number of params";
+            res.result(boost::beast::http::status::not_found);
+            res.end();
+            return;
+        }
 
-      res.result(boost::beast::http::status::bad_request);
-      messages::addMessageToErrorJson(res.jsonValue, messages::generalError());
+        Node::json["Id"] = session->uniqueId;
+        Node::json["UserName"] = session->username;
+        Node::json["@odata.id"] =
+            "/redfish/v1/SessionService/Sessions/" + session->uniqueId;
 
-      res.end();
-      return;
+        res.jsonValue = Node::json;
+        res.end();
     }
 
-    auto session =
-        crow::persistent_data::SessionStore::getInstance().getSessionByUid(
-            params[0]);
+    void doDelete(crow::Response& res, const crow::Request& req,
+                  const std::vector<std::string>& params) override
+    {
+        // Need only 1 param which should be id of session to be deleted
+        if (params.size() != 1)
+        {
+            // This should be handled by crow and never happen
+            BMCWEB_LOG_ERROR << "Session DELETE has been called with invalid "
+                                "number of params";
 
-    if (session == nullptr) {
-      messages::addMessageToErrorJson(
-          res.jsonValue, messages::resourceNotFound("Session", params[0]));
+            res.result(boost::beast::http::status::bad_request);
+            messages::addMessageToErrorJson(res.jsonValue,
+                                            messages::generalError());
 
-      res.result(boost::beast::http::status::not_found);
-      res.end();
-      return;
+            res.end();
+            return;
+        }
+
+        auto session =
+            crow::persistent_data::SessionStore::getInstance().getSessionByUid(
+                params[0]);
+
+        if (session == nullptr)
+        {
+            messages::addMessageToErrorJson(
+                res.jsonValue,
+                messages::resourceNotFound("Session", params[0]));
+
+            res.result(boost::beast::http::status::not_found);
+            res.end();
+            return;
+        }
+
+        // DELETE should return representation of object that will be removed
+        doGet(res, req, params);
+
+        crow::persistent_data::SessionStore::getInstance().removeSession(
+            session);
     }
 
-    // DELETE should return representation of object that will be removed
-    doGet(res, req, params);
-
-    crow::persistent_data::SessionStore::getInstance().removeSession(session);
-  }
-
-  /**
-   * This allows SessionCollection to reuse this class' doGet method, to
-   * maintain consistency of returned data, as Collection's doPost should return
-   * data for created member which should match member's doGet result in 100%
-   */
-  friend SessionCollection;
+    /**
+     * This allows SessionCollection to reuse this class' doGet method, to
+     * maintain consistency of returned data, as Collection's doPost should
+     * return data for created member which should match member's doGet result
+     * in 100%
+     */
+    friend SessionCollection;
 };
 
-class SessionCollection : public Node {
- public:
-  SessionCollection(CrowApp& app)
-      : Node(app, "/redfish/v1/SessionService/Sessions/"), memberSession(app) {
-    Node::json["@odata.type"] = "#SessionCollection.SessionCollection";
-    Node::json["@odata.id"] = "/redfish/v1/SessionService/Sessions/";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata#SessionCollection.SessionCollection";
-    Node::json["Name"] = "Session Collection";
-    Node::json["Description"] = "Session Collection";
-    Node::json["Members@odata.count"] = 0;
-    Node::json["Members"] = nlohmann::json::array();
+class SessionCollection : public Node
+{
+  public:
+    SessionCollection(CrowApp& app) :
+        Node(app, "/redfish/v1/SessionService/Sessions/"), memberSession(app)
+    {
+        Node::json["@odata.type"] = "#SessionCollection.SessionCollection";
+        Node::json["@odata.id"] = "/redfish/v1/SessionService/Sessions/";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata#SessionCollection.SessionCollection";
+        Node::json["Name"] = "Session Collection";
+        Node::json["Description"] = "Session Collection";
+        Node::json["Members@odata.count"] = 0;
+        Node::json["Members"] = nlohmann::json::array();
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::post, {}}};
-  }
-
- private:
-  void doGet(crow::Response& res, const crow::Request& req,
-             const std::vector<std::string>& params) override {
-    std::vector<const std::string*> sessionIds =
-        crow::persistent_data::SessionStore::getInstance().getUniqueIds(
-            false, crow::persistent_data::PersistenceType::TIMEOUT);
-
-    Node::json["Members@odata.count"] = sessionIds.size();
-    Node::json["Members"] = nlohmann::json::array();
-    for (const std::string* uid : sessionIds) {
-      Node::json["Members"].push_back(
-          {{"@odata.id", "/redfish/v1/SessionService/Sessions/" + *uid}});
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::post, {}}};
     }
 
-    res.jsonValue = Node::json;
-    res.end();
-  }
+  private:
+    void doGet(crow::Response& res, const crow::Request& req,
+               const std::vector<std::string>& params) override
+    {
+        std::vector<const std::string*> sessionIds =
+            crow::persistent_data::SessionStore::getInstance().getUniqueIds(
+                false, crow::persistent_data::PersistenceType::TIMEOUT);
 
-  void doPost(crow::Response& res, const crow::Request& req,
-              const std::vector<std::string>& params) override {
-    boost::beast::http::status status;
-    std::string username;
-    bool userAuthSuccessful =
-        authenticateUser(req, status, username, res.jsonValue);
-    res.result(status);
+        Node::json["Members@odata.count"] = sessionIds.size();
+        Node::json["Members"] = nlohmann::json::array();
+        for (const std::string* uid : sessionIds)
+        {
+            Node::json["Members"].push_back(
+                {{"@odata.id", "/redfish/v1/SessionService/Sessions/" + *uid}});
+        }
 
-    if (!userAuthSuccessful) {
-      res.end();
-      return;
+        res.jsonValue = Node::json;
+        res.end();
     }
 
-    // User is authenticated - create session for him
-    auto session =
-        crow::persistent_data::SessionStore::getInstance().generateUserSession(
-            username);
-    res.addHeader("X-Auth-Token", session->sessionToken);
+    void doPost(crow::Response& res, const crow::Request& req,
+                const std::vector<std::string>& params) override
+    {
+        boost::beast::http::status status;
+        std::string username;
+        bool userAuthSuccessful =
+            authenticateUser(req, status, username, res.jsonValue);
+        res.result(status);
 
-    res.addHeader("Location",
-                  "/redfish/v1/SessionService/Sessions/" + session->uniqueId);
+        if (!userAuthSuccessful)
+        {
+            res.end();
+            return;
+        }
 
-    // Return data for created session
-    memberSession.doGet(res, req, {session->uniqueId});
+        // User is authenticated - create session for him
+        auto session = crow::persistent_data::SessionStore::getInstance()
+                           .generateUserSession(username);
+        res.addHeader("X-Auth-Token", session->sessionToken);
 
-    // No need for res.end(), as it is called by doGet()
-  }
+        res.addHeader("Location", "/redfish/v1/SessionService/Sessions/" +
+                                      session->uniqueId);
 
-  /**
-   * @brief Verifies data provided in request and tries to authenticate user
-   *
-   * @param[in]  req            Crow request containing authentication data
-   * @param[out] httpRespCode   HTTP Code that should be returned in response
-   * @param[out] user           Retrieved username - not filled on failure
-   * @param[out] errJson        JSON to which error messages will be written
-   *
-   * @return true if authentication was successful, false otherwise
-   */
-  bool authenticateUser(const crow::Request& req,
-                        boost::beast::http::status& httpRespCode,
-                        std::string& user, nlohmann::json& errJson) {
-    // We need only UserName and Password - nothing more, nothing less
-    static constexpr const unsigned int numberOfRequiredFieldsInReq = 2;
+        // Return data for created session
+        memberSession.doGet(res, req, {session->uniqueId});
 
-    // call with exceptions disabled
-    auto loginCredentials = nlohmann::json::parse(req.body, nullptr, false);
-    if (loginCredentials.is_discarded()) {
-      httpRespCode = boost::beast::http::status::bad_request;
-
-      messages::addMessageToErrorJson(errJson, messages::malformedJSON());
-
-      return false;
+        // No need for res.end(), as it is called by doGet()
     }
 
-    // Check that there are only as many fields as there should be
-    if (loginCredentials.size() != numberOfRequiredFieldsInReq) {
-      httpRespCode = boost::beast::http::status::bad_request;
+    /**
+     * @brief Verifies data provided in request and tries to authenticate user
+     *
+     * @param[in]  req            Crow request containing authentication data
+     * @param[out] httpRespCode   HTTP Code that should be returned in response
+     * @param[out] user           Retrieved username - not filled on failure
+     * @param[out] errJson        JSON to which error messages will be written
+     *
+     * @return true if authentication was successful, false otherwise
+     */
+    bool authenticateUser(const crow::Request& req,
+                          boost::beast::http::status& httpRespCode,
+                          std::string& user, nlohmann::json& errJson)
+    {
+        // We need only UserName and Password - nothing more, nothing less
+        static constexpr const unsigned int numberOfRequiredFieldsInReq = 2;
 
-      messages::addMessageToErrorJson(errJson, messages::malformedJSON());
+        // call with exceptions disabled
+        auto loginCredentials = nlohmann::json::parse(req.body, nullptr, false);
+        if (loginCredentials.is_discarded())
+        {
+            httpRespCode = boost::beast::http::status::bad_request;
 
-      return false;
+            messages::addMessageToErrorJson(errJson, messages::malformedJSON());
+
+            return false;
+        }
+
+        // Check that there are only as many fields as there should be
+        if (loginCredentials.size() != numberOfRequiredFieldsInReq)
+        {
+            httpRespCode = boost::beast::http::status::bad_request;
+
+            messages::addMessageToErrorJson(errJson, messages::malformedJSON());
+
+            return false;
+        }
+
+        // Find fields that we need - UserName and Password
+        auto userIt = loginCredentials.find("UserName");
+        auto passIt = loginCredentials.find("Password");
+        if (userIt == loginCredentials.end() ||
+            passIt == loginCredentials.end())
+        {
+            httpRespCode = boost::beast::http::status::bad_request;
+
+            if (userIt == loginCredentials.end())
+            {
+                messages::addMessageToErrorJson(
+                    errJson, messages::propertyMissing("UserName"));
+            }
+
+            if (passIt == loginCredentials.end())
+            {
+                messages::addMessageToErrorJson(
+                    errJson, messages::propertyMissing("Password"));
+            }
+
+            return false;
+        }
+
+        // Check that given data is of valid type (string)
+        if (!userIt->is_string() || !passIt->is_string())
+        {
+            httpRespCode = boost::beast::http::status::bad_request;
+
+            if (!userIt->is_string())
+            {
+                messages::addMessageToErrorJson(
+                    errJson, messages::propertyValueTypeError(userIt->dump(),
+                                                              "UserName"));
+            }
+
+            if (!passIt->is_string())
+            {
+                messages::addMessageToErrorJson(
+                    errJson, messages::propertyValueTypeError(userIt->dump(),
+                                                              "Password"));
+            }
+
+            return false;
+        }
+
+        // Extract username and password
+        std::string username = userIt->get<const std::string>();
+        std::string password = passIt->get<const std::string>();
+
+        // Verify that required fields are not empty
+        if (username.empty() || password.empty())
+        {
+            httpRespCode = boost::beast::http::status::bad_request;
+
+            if (username.empty())
+            {
+                messages::addMessageToErrorJson(
+                    errJson, messages::propertyMissing("UserName"));
+            }
+
+            if (password.empty())
+            {
+                messages::addMessageToErrorJson(
+                    errJson, messages::propertyMissing("Password"));
+            }
+
+            return false;
+        }
+
+        // Finally - try to authenticate user
+        if (!pamAuthenticateUser(username, password))
+        {
+            httpRespCode = boost::beast::http::status::unauthorized;
+
+            messages::addMessageToErrorJson(
+                errJson,
+                messages::resourceAtUriUnauthorized(
+                    std::string(req.url), "Invalid username or password"));
+
+            return false;
+        }
+
+        // User authenticated successfully
+        httpRespCode = boost::beast::http::status::ok;
+        user = username;
+
+        return true;
     }
 
-    // Find fields that we need - UserName and Password
-    auto userIt = loginCredentials.find("UserName");
-    auto passIt = loginCredentials.find("Password");
-    if (userIt == loginCredentials.end() || passIt == loginCredentials.end()) {
-      httpRespCode = boost::beast::http::status::bad_request;
-
-      if (userIt == loginCredentials.end()) {
-        messages::addMessageToErrorJson(errJson,
-                                        messages::propertyMissing("UserName"));
-      }
-
-      if (passIt == loginCredentials.end()) {
-        messages::addMessageToErrorJson(errJson,
-                                        messages::propertyMissing("Password"));
-      }
-
-      return false;
-    }
-
-    // Check that given data is of valid type (string)
-    if (!userIt->is_string() || !passIt->is_string()) {
-      httpRespCode = boost::beast::http::status::bad_request;
-
-      if (!userIt->is_string()) {
-        messages::addMessageToErrorJson(
-            errJson,
-            messages::propertyValueTypeError(userIt->dump(), "UserName"));
-      }
-
-      if (!passIt->is_string()) {
-        messages::addMessageToErrorJson(
-            errJson,
-            messages::propertyValueTypeError(userIt->dump(), "Password"));
-      }
-
-      return false;
-    }
-
-    // Extract username and password
-    std::string username = userIt->get<const std::string>();
-    std::string password = passIt->get<const std::string>();
-
-    // Verify that required fields are not empty
-    if (username.empty() || password.empty()) {
-      httpRespCode = boost::beast::http::status::bad_request;
-
-      if (username.empty()) {
-        messages::addMessageToErrorJson(errJson,
-                                        messages::propertyMissing("UserName"));
-      }
-
-      if (password.empty()) {
-        messages::addMessageToErrorJson(errJson,
-                                        messages::propertyMissing("Password"));
-      }
-
-      return false;
-    }
-
-    // Finally - try to authenticate user
-    if (!pamAuthenticateUser(username, password)) {
-      httpRespCode = boost::beast::http::status::unauthorized;
-
-      messages::addMessageToErrorJson(
-          errJson, messages::resourceAtUriUnauthorized(
-                       std::string(req.url), "Invalid username or password"));
-
-      return false;
-    }
-
-    // User authenticated successfully
-    httpRespCode = boost::beast::http::status::ok;
-    user = username;
-
-    return true;
-  }
-
-  /**
-   * Member session to ensure consistency between collection's doPost and
-   * member's doGet, as they should return 100% matching data
-   */
-  Sessions memberSession;
+    /**
+     * Member session to ensure consistency between collection's doPost and
+     * member's doGet, as they should return 100% matching data
+     */
+    Sessions memberSession;
 };
 
-class SessionService : public Node {
- public:
-  SessionService(CrowApp& app) : Node(app, "/redfish/v1/SessionService/") {
-    Node::json["@odata.type"] = "#SessionService.v1_0_2.SessionService";
-    Node::json["@odata.id"] = "/redfish/v1/SessionService/";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata#SessionService.SessionService";
-    Node::json["Name"] = "Session Service";
-    Node::json["Id"] = "SessionService";
-    Node::json["Description"] = "Session Service";
-    Node::json["SessionTimeout"] =
-        crow::persistent_data::SessionStore::getInstance()
-            .getTimeoutInSeconds();
-    Node::json["ServiceEnabled"] = true;
+class SessionService : public Node
+{
+  public:
+    SessionService(CrowApp& app) : Node(app, "/redfish/v1/SessionService/")
+    {
+        Node::json["@odata.type"] = "#SessionService.v1_0_2.SessionService";
+        Node::json["@odata.id"] = "/redfish/v1/SessionService/";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata#SessionService.SessionService";
+        Node::json["Name"] = "Session Service";
+        Node::json["Id"] = "SessionService";
+        Node::json["Description"] = "Session Service";
+        Node::json["SessionTimeout"] =
+            crow::persistent_data::SessionStore::getInstance()
+                .getTimeoutInSeconds();
+        Node::json["ServiceEnabled"] = true;
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-  }
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
+    }
 
- private:
-  void doGet(crow::Response& res, const crow::Request& req,
-             const std::vector<std::string>& params) override {
-    res.jsonValue = Node::json;
-    res.end();
-  }
+  private:
+    void doGet(crow::Response& res, const crow::Request& req,
+               const std::vector<std::string>& params) override
+    {
+        res.jsonValue = Node::json;
+        res.end();
+    }
 };
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/lib/roles.hpp b/redfish-core/lib/roles.hpp
index 72d7948..258eed3 100644
--- a/redfish-core/lib/roles.hpp
+++ b/redfish-core/lib/roles.hpp
@@ -17,74 +17,82 @@
 
 #include "node.hpp"
 
-namespace redfish {
+namespace redfish
+{
 
-class Roles : public Node {
- public:
-  Roles(CrowApp& app)
-      : Node(app, "/redfish/v1/AccountService/Roles/Administrator/") {
-    Node::json["@odata.id"] = "/redfish/v1/AccountService/Roles/Administrator";
-    Node::json["@odata.type"] = "#Role.v1_0_2.Role";
-    Node::json["@odata.context"] = "/redfish/v1/$metadata#Role.Role";
-    Node::json["Id"] = "Administrator";
-    Node::json["Name"] = "User Role";
-    Node::json["Description"] = "Administrator User Role";
-    Node::json["IsPredefined"] = true;
-    Node::json["AssignedPrivileges"] = {"Login", "ConfigureManager",
-                                        "ConfigureUsers", "ConfigureSelf",
-                                        "ConfigureComponents"};
-    Node::json["OemPrivileges"] = nlohmann::json::array();
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-  }
+class Roles : public Node
+{
+  public:
+    Roles(CrowApp& app) :
+        Node(app, "/redfish/v1/AccountService/Roles/Administrator/")
+    {
+        Node::json["@odata.id"] =
+            "/redfish/v1/AccountService/Roles/Administrator";
+        Node::json["@odata.type"] = "#Role.v1_0_2.Role";
+        Node::json["@odata.context"] = "/redfish/v1/$metadata#Role.Role";
+        Node::json["Id"] = "Administrator";
+        Node::json["Name"] = "User Role";
+        Node::json["Description"] = "Administrator User Role";
+        Node::json["IsPredefined"] = true;
+        Node::json["AssignedPrivileges"] = {"Login", "ConfigureManager",
+                                            "ConfigureUsers", "ConfigureSelf",
+                                            "ConfigureComponents"};
+        Node::json["OemPrivileges"] = nlohmann::json::array();
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
+    }
 
- private:
-  void doGet(crow::Response& res, const crow::Request& req,
-             const std::vector<std::string>& params) override {
-    res.jsonValue = Node::json;
-    res.end();
-  }
+  private:
+    void doGet(crow::Response& res, const crow::Request& req,
+               const std::vector<std::string>& params) override
+    {
+        res.jsonValue = Node::json;
+        res.end();
+    }
 };
 
-class RoleCollection : public Node {
- public:
-  RoleCollection(CrowApp& app)
-      : Node(app, "/redfish/v1/AccountService/Roles/") {
-    Node::json["@odata.id"] = "/redfish/v1/AccountService/Roles";
-    Node::json["@odata.type"] = "#RoleCollection.RoleCollection";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata#RoleCollection.RoleCollection";
-    Node::json["Name"] = "Roles Collection";
-    Node::json["Description"] = "BMC User Roles";
-    Node::json["Members@odata.count"] = 1;
-    Node::json["Members"] = {
-        {{"@odata.id", "/redfish/v1/AccountService/Roles/Administrator"}}};
+class RoleCollection : public Node
+{
+  public:
+    RoleCollection(CrowApp& app) :
+        Node(app, "/redfish/v1/AccountService/Roles/")
+    {
+        Node::json["@odata.id"] = "/redfish/v1/AccountService/Roles";
+        Node::json["@odata.type"] = "#RoleCollection.RoleCollection";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata#RoleCollection.RoleCollection";
+        Node::json["Name"] = "Roles Collection";
+        Node::json["Description"] = "BMC User Roles";
+        Node::json["Members@odata.count"] = 1;
+        Node::json["Members"] = {
+            {{"@odata.id", "/redfish/v1/AccountService/Roles/Administrator"}}};
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-  }
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
+    }
 
- private:
-  void doGet(crow::Response& res, const crow::Request& req,
-             const std::vector<std::string>& params) override {
-    res.jsonValue = Node::json;
-    // This is a short term solution to work around a bug.  GetSubroutes
-    // accidentally recognizes the Roles/Administrator route as a subroute
-    // (because it's hardcoded to a single entity).  Remove this line when that
-    // is resolved
-    res.jsonValue.erase("Administrator");
-    res.end();
-  }
+  private:
+    void doGet(crow::Response& res, const crow::Request& req,
+               const std::vector<std::string>& params) override
+    {
+        res.jsonValue = Node::json;
+        // This is a short term solution to work around a bug.  GetSubroutes
+        // accidentally recognizes the Roles/Administrator route as a subroute
+        // (because it's hardcoded to a single entity).  Remove this line when
+        // that is resolved
+        res.jsonValue.erase("Administrator");
+        res.end();
+    }
 };
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/lib/sensors.hpp b/redfish-core/lib/sensors.hpp
index 7f9fa68..c390cd7 100644
--- a/redfish-core/lib/sensors.hpp
+++ b/redfish-core/lib/sensors.hpp
@@ -16,13 +16,15 @@
 #pragma once
 
 #include <math.h>
-#include <dbus_singleton.hpp>
+
 #include <boost/algorithm/string/predicate.hpp>
 #include <boost/algorithm/string/split.hpp>
 #include <boost/container/flat_map.hpp>
 #include <boost/range/algorithm/replace_copy_if.hpp>
+#include <dbus_singleton.hpp>
 
-namespace redfish {
+namespace redfish
+{
 
 constexpr const char* dbusSensorPrefix = "/xyz/openbmc_project/sensors/";
 
@@ -41,32 +43,38 @@
  * SensorsAsyncResp
  * Gathers data needed for response processing after async calls are done
  */
-class SensorsAsyncResp {
- public:
-  SensorsAsyncResp(crow::Response& response, const std::string& chassisId,
-                   const std::initializer_list<const char*> types)
-      : res(response), chassisId(chassisId), types(types) {
-    res.jsonValue["@odata.id"] =
-        "/redfish/v1/Chassis/" + chassisId + "/Thermal";
-  }
-
-  ~SensorsAsyncResp() {
-    if (res.result() == boost::beast::http::status::internal_server_error) {
-      // Reset the json object to clear out any data that made it in before the
-      // error happened
-      // todo(ed) handle error condition with proper code
-      res.jsonValue = nlohmann::json::object();
+class SensorsAsyncResp
+{
+  public:
+    SensorsAsyncResp(crow::Response& response, const std::string& chassisId,
+                     const std::initializer_list<const char*> types) :
+        res(response),
+        chassisId(chassisId), types(types)
+    {
+        res.jsonValue["@odata.id"] =
+            "/redfish/v1/Chassis/" + chassisId + "/Thermal";
     }
-    res.end();
-  }
 
-  void setErrorStatus() {
-    res.result(boost::beast::http::status::internal_server_error);
-  }
+    ~SensorsAsyncResp()
+    {
+        if (res.result() == boost::beast::http::status::internal_server_error)
+        {
+            // Reset the json object to clear out any data that made it in
+            // before the error happened todo(ed) handle error condition with
+            // proper code
+            res.jsonValue = nlohmann::json::object();
+        }
+        res.end();
+    }
 
-  crow::Response& res;
-  std::string chassisId{};
-  const std::vector<const char*> types;
+    void setErrorStatus()
+    {
+        res.result(boost::beast::http::status::internal_server_error);
+    }
+
+    crow::Response& res;
+    std::string chassisId{};
+    const std::vector<const char*> types;
 };
 
 /**
@@ -78,70 +86,84 @@
 template <typename Callback>
 void getConnections(std::shared_ptr<SensorsAsyncResp> SensorsAsyncResp,
                     const boost::container::flat_set<std::string>& sensorNames,
-                    Callback&& callback) {
-  BMCWEB_LOG_DEBUG << "getConnections enter";
-  const std::string path = "/xyz/openbmc_project/sensors";
-  const std::array<std::string, 1> interfaces = {
-      "xyz.openbmc_project.Sensor.Value"};
+                    Callback&& callback)
+{
+    BMCWEB_LOG_DEBUG << "getConnections enter";
+    const std::string path = "/xyz/openbmc_project/sensors";
+    const std::array<std::string, 1> interfaces = {
+        "xyz.openbmc_project.Sensor.Value"};
 
-  // Response handler for parsing objects subtree
-  auto respHandler =
-      [ callback{std::move(callback)}, SensorsAsyncResp, sensorNames ](
-          const boost::system::error_code ec, const GetSubTreeType& subtree) {
-    BMCWEB_LOG_DEBUG << "getConnections resp_handler enter";
-    if (ec) {
-      SensorsAsyncResp->setErrorStatus();
-      BMCWEB_LOG_ERROR << "getConnections resp_handler: Dbus error " << ec;
-      return;
-    }
-
-    BMCWEB_LOG_DEBUG << "Found " << subtree.size() << " subtrees";
-
-    // Make unique list of connections only for requested sensor types and
-    // found in the chassis
-    boost::container::flat_set<std::string> connections;
-    // Intrinsic to avoid malloc.  Most systems will have < 8 sensor producers
-    connections.reserve(8);
-
-    BMCWEB_LOG_DEBUG << "sensorNames list count: " << sensorNames.size();
-    for (const std::string& tsensor : sensorNames) {
-      BMCWEB_LOG_DEBUG << "Sensor to find: " << tsensor;
-    }
-
-    for (const std::pair<
-             std::string,
-             std::vector<std::pair<std::string, std::vector<std::string>>>>&
-             object : subtree) {
-      for (const char* type : SensorsAsyncResp->types) {
-        if (boost::starts_with(object.first, type)) {
-          auto lastPos = object.first.rfind('/');
-          if (lastPos != std::string::npos) {
-            std::string sensorName = object.first.substr(lastPos + 1);
-
-            if (sensorNames.find(sensorName) != sensorNames.end()) {
-              // For each Connection name
-              for (const std::pair<std::string, std::vector<std::string>>&
-                       objData : object.second) {
-                BMCWEB_LOG_DEBUG << "Adding connection: " << objData.first;
-                connections.insert(objData.first);
-              }
-            }
-          }
-          break;
+    // Response handler for parsing objects subtree
+    auto respHandler = [callback{std::move(callback)}, SensorsAsyncResp,
+                        sensorNames](const boost::system::error_code ec,
+                                     const GetSubTreeType& subtree) {
+        BMCWEB_LOG_DEBUG << "getConnections resp_handler enter";
+        if (ec)
+        {
+            SensorsAsyncResp->setErrorStatus();
+            BMCWEB_LOG_ERROR << "getConnections resp_handler: Dbus error "
+                             << ec;
+            return;
         }
-      }
-    }
-    BMCWEB_LOG_DEBUG << "Found " << connections.size() << " connections";
-    callback(std::move(connections));
-    BMCWEB_LOG_DEBUG << "getConnections resp_handler exit";
-  };
 
-  // Make call to ObjectMapper to find all sensors objects
-  crow::connections::systemBus->async_method_call(
-      std::move(respHandler), "xyz.openbmc_project.ObjectMapper",
-      "/xyz/openbmc_project/object_mapper", "xyz.openbmc_project.ObjectMapper",
-      "GetSubTree", path, 2, interfaces);
-  BMCWEB_LOG_DEBUG << "getConnections exit";
+        BMCWEB_LOG_DEBUG << "Found " << subtree.size() << " subtrees";
+
+        // Make unique list of connections only for requested sensor types and
+        // found in the chassis
+        boost::container::flat_set<std::string> connections;
+        // Intrinsic to avoid malloc.  Most systems will have < 8 sensor
+        // producers
+        connections.reserve(8);
+
+        BMCWEB_LOG_DEBUG << "sensorNames list count: " << sensorNames.size();
+        for (const std::string& tsensor : sensorNames)
+        {
+            BMCWEB_LOG_DEBUG << "Sensor to find: " << tsensor;
+        }
+
+        for (const std::pair<
+                 std::string,
+                 std::vector<std::pair<std::string, std::vector<std::string>>>>&
+                 object : subtree)
+        {
+            for (const char* type : SensorsAsyncResp->types)
+            {
+                if (boost::starts_with(object.first, type))
+                {
+                    auto lastPos = object.first.rfind('/');
+                    if (lastPos != std::string::npos)
+                    {
+                        std::string sensorName =
+                            object.first.substr(lastPos + 1);
+
+                        if (sensorNames.find(sensorName) != sensorNames.end())
+                        {
+                            // For each Connection name
+                            for (const std::pair<std::string,
+                                                 std::vector<std::string>>&
+                                     objData : object.second)
+                            {
+                                BMCWEB_LOG_DEBUG << "Adding connection: "
+                                                 << objData.first;
+                                connections.insert(objData.first);
+                            }
+                        }
+                    }
+                    break;
+                }
+            }
+        }
+        BMCWEB_LOG_DEBUG << "Found " << connections.size() << " connections";
+        callback(std::move(connections));
+        BMCWEB_LOG_DEBUG << "getConnections resp_handler exit";
+    };
+
+    // Make call to ObjectMapper to find all sensors objects
+    crow::connections::systemBus->async_method_call(
+        std::move(respHandler), "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetSubTree", path, 2, interfaces);
+    BMCWEB_LOG_DEBUG << "getConnections exit";
 }
 
 /**
@@ -151,64 +173,74 @@
  */
 template <typename Callback>
 void getChassis(std::shared_ptr<SensorsAsyncResp> SensorsAsyncResp,
-                Callback&& callback) {
-  BMCWEB_LOG_DEBUG << "getChassis enter";
-  // Process response from EntityManager and extract chassis data
-  auto respHandler = [ callback{std::move(callback)}, SensorsAsyncResp ](
-      const boost::system::error_code ec, ManagedObjectsVectorType& resp) {
-    BMCWEB_LOG_DEBUG << "getChassis respHandler enter";
-    if (ec) {
-      BMCWEB_LOG_ERROR << "getChassis respHandler DBUS error: " << ec;
-      SensorsAsyncResp->setErrorStatus();
-      return;
-    }
-    boost::container::flat_set<std::string> sensorNames;
+                Callback&& callback)
+{
+    BMCWEB_LOG_DEBUG << "getChassis enter";
+    // Process response from EntityManager and extract chassis data
+    auto respHandler = [callback{std::move(callback)},
+                        SensorsAsyncResp](const boost::system::error_code ec,
+                                          ManagedObjectsVectorType& resp) {
+        BMCWEB_LOG_DEBUG << "getChassis respHandler enter";
+        if (ec)
+        {
+            BMCWEB_LOG_ERROR << "getChassis respHandler DBUS error: " << ec;
+            SensorsAsyncResp->setErrorStatus();
+            return;
+        }
+        boost::container::flat_set<std::string> sensorNames;
 
-    //   SensorsAsyncResp->chassisId
-    bool foundChassis = false;
-    std::vector<std::string> split;
-    // Reserve space for
-    // /xyz/openbmc_project/inventory/<name>/<subname> + 3 subnames
-    split.reserve(8);
+        //   SensorsAsyncResp->chassisId
+        bool foundChassis = false;
+        std::vector<std::string> split;
+        // Reserve space for
+        // /xyz/openbmc_project/inventory/<name>/<subname> + 3 subnames
+        split.reserve(8);
 
-    for (const auto& objDictEntry : resp) {
-      const std::string& objectPath =
-          static_cast<const std::string&>(objDictEntry.first);
-      boost::algorithm::split(split, objectPath, boost::is_any_of("/"));
-      if (split.size() < 2) {
-        BMCWEB_LOG_ERROR << "Got path that isn't long enough " << objectPath;
-        split.clear();
-        continue;
-      }
-      const std::string& sensorName = split.end()[-1];
-      const std::string& chassisName = split.end()[-2];
+        for (const auto& objDictEntry : resp)
+        {
+            const std::string& objectPath =
+                static_cast<const std::string&>(objDictEntry.first);
+            boost::algorithm::split(split, objectPath, boost::is_any_of("/"));
+            if (split.size() < 2)
+            {
+                BMCWEB_LOG_ERROR << "Got path that isn't long enough "
+                                 << objectPath;
+                split.clear();
+                continue;
+            }
+            const std::string& sensorName = split.end()[-1];
+            const std::string& chassisName = split.end()[-2];
 
-      if (chassisName != SensorsAsyncResp->chassisId) {
-        split.clear();
-        continue;
-      }
-      BMCWEB_LOG_DEBUG << "New sensor: " << sensorName;
-      foundChassis = true;
-      sensorNames.emplace(sensorName);
-      split.clear();
+            if (chassisName != SensorsAsyncResp->chassisId)
+            {
+                split.clear();
+                continue;
+            }
+            BMCWEB_LOG_DEBUG << "New sensor: " << sensorName;
+            foundChassis = true;
+            sensorNames.emplace(sensorName);
+            split.clear();
+        };
+        BMCWEB_LOG_DEBUG << "Found " << sensorNames.size() << " Sensor names";
+
+        if (!foundChassis)
+        {
+            BMCWEB_LOG_INFO << "Unable to find chassis named "
+                            << SensorsAsyncResp->chassisId;
+            SensorsAsyncResp->res.result(boost::beast::http::status::not_found);
+        }
+        else
+        {
+            callback(sensorNames);
+        }
+        BMCWEB_LOG_DEBUG << "getChassis respHandler exit";
     };
-    BMCWEB_LOG_DEBUG << "Found " << sensorNames.size() << " Sensor names";
 
-    if (!foundChassis) {
-      BMCWEB_LOG_INFO << "Unable to find chassis named "
-                      << SensorsAsyncResp->chassisId;
-      SensorsAsyncResp->res.result(boost::beast::http::status::not_found);
-    } else {
-      callback(sensorNames);
-    }
-    BMCWEB_LOG_DEBUG << "getChassis respHandler exit";
-  };
-
-  // Make call to EntityManager to find all chassis objects
-  crow::connections::systemBus->async_method_call(
-      respHandler, "xyz.openbmc_project.EntityManager", "/",
-      "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
-  BMCWEB_LOG_DEBUG << "getChassis exit";
+    // Make call to EntityManager to find all chassis objects
+    crow::connections::systemBus->async_method_call(
+        respHandler, "xyz.openbmc_project.EntityManager", "/",
+        "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+    BMCWEB_LOG_DEBUG << "getChassis exit";
 }
 
 /**
@@ -225,116 +257,146 @@
     const boost::container::flat_map<
         std::string, boost::container::flat_map<std::string, SensorVariant>>&
         interfacesDict,
-    nlohmann::json& sensor_json) {
-  // We need a value interface before we can do anything with it
-  auto valueIt = interfacesDict.find("xyz.openbmc_project.Sensor.Value");
-  if (valueIt == interfacesDict.end()) {
-    BMCWEB_LOG_ERROR << "Sensor doesn't have a value interface";
-    return;
-  }
-
-  // Assume values exist as is (10^0 == 1) if no scale exists
-  int64_t scaleMultiplier = 0;
-
-  auto scaleIt = valueIt->second.find("Scale");
-  // If a scale exists, pull value as int64, and use the scaling.
-  if (scaleIt != valueIt->second.end()) {
-    const int64_t* int64Value = mapbox::getPtr<const int64_t>(scaleIt->second);
-    if (int64Value != nullptr) {
-      scaleMultiplier = *int64Value;
+    nlohmann::json& sensor_json)
+{
+    // We need a value interface before we can do anything with it
+    auto valueIt = interfacesDict.find("xyz.openbmc_project.Sensor.Value");
+    if (valueIt == interfacesDict.end())
+    {
+        BMCWEB_LOG_ERROR << "Sensor doesn't have a value interface";
+        return;
     }
-  }
 
-  sensor_json["MemberId"] = sensorName;
-  sensor_json["Name"] = sensorName;
-  sensor_json["Status"]["State"] = "Enabled";
-  sensor_json["Status"]["Health"] = "OK";
+    // Assume values exist as is (10^0 == 1) if no scale exists
+    int64_t scaleMultiplier = 0;
 
-  // Parameter to set to override the type we get from dbus, and force it to
-  // int, regardless of what is available.  This is used for schemas like fan,
-  // that require integers, not floats.
-  bool forceToInt = false;
-
-  const char* unit = "Reading";
-  if (sensorType == "temperature") {
-    unit = "ReadingCelsius";
-    sensor_json["@odata.type"] = "#Thermal.v1_3_0.Temperature";
-    // TODO(ed) Documentation says that path should be type fan_tach,
-    // implementation seems to implement fan
-  } else if (sensorType == "fan" || sensorType == "fan_tach") {
-    unit = "Reading";
-    sensor_json["ReadingUnits"] = "RPM";
-    sensor_json["@odata.type"] = "#Thermal.v1_3_0.Fan";
-    forceToInt = true;
-  } else if (sensorType == "voltage") {
-    unit = "ReadingVolts";
-    sensor_json["@odata.type"] = "#Power.v1_0_0.Voltage";
-  } else {
-    BMCWEB_LOG_ERROR << "Redfish cannot map object type for " << sensorName;
-    return;
-  }
-  // Map of dbus interface name, dbus property name and redfish property_name
-  std::vector<std::tuple<const char*, const char*, const char*>> properties;
-  properties.reserve(7);
-
-  properties.emplace_back("xyz.openbmc_project.Sensor.Value", "Value", unit);
-  properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Warning",
-                          "WarningHigh", "UpperThresholdNonCritical");
-  properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Warning",
-                          "WarningLow", "LowerThresholdNonCritical");
-  properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Critical",
-                          "CriticalHigh", "UpperThresholdCritical");
-  properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Critical",
-                          "CriticalLow", "LowerThresholdCritical");
-
-  if (sensorType == "temperature") {
-    properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue",
-                            "MinReadingRangeTemp");
-    properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue",
-                            "MaxReadingRangeTemp");
-  } else {
-    properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue",
-                            "MinReadingRange");
-    properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue",
-                            "MaxReadingRange");
-  }
-
-  for (const std::tuple<const char*, const char*, const char*>& p :
-       properties) {
-    auto interfaceProperties = interfacesDict.find(std::get<0>(p));
-    if (interfaceProperties != interfacesDict.end()) {
-      auto valueIt = interfaceProperties->second.find(std::get<1>(p));
-      if (valueIt != interfaceProperties->second.end()) {
-        const SensorVariant& valueVariant = valueIt->second;
-        nlohmann::json& valueIt = sensor_json[std::get<2>(p)];
-
-        // Attempt to pull the int64 directly
-        const int64_t* int64Value = mapbox::getPtr<const int64_t>(valueVariant);
-
-        if (int64Value != nullptr) {
-          if (forceToInt || scaleMultiplier >= 0) {
-            valueIt = *int64Value * std::pow(10, scaleMultiplier);
-          } else {
-            valueIt = *int64Value *
-                      std::pow(10, static_cast<double>(scaleMultiplier));
-          }
+    auto scaleIt = valueIt->second.find("Scale");
+    // If a scale exists, pull value as int64, and use the scaling.
+    if (scaleIt != valueIt->second.end())
+    {
+        const int64_t* int64Value =
+            mapbox::getPtr<const int64_t>(scaleIt->second);
+        if (int64Value != nullptr)
+        {
+            scaleMultiplier = *int64Value;
         }
-        // Attempt to pull the float directly
-        const double* doubleValue = mapbox::getPtr<const double>(valueVariant);
-
-        if (doubleValue != nullptr) {
-          if (!forceToInt) {
-            valueIt = *doubleValue *
-                      std::pow(10, static_cast<double>(scaleMultiplier));
-          } else {
-            valueIt = static_cast<int64_t>(*doubleValue *
-                                           std::pow(10, scaleMultiplier));
-          }
-        }
-      }
     }
-  }
-  BMCWEB_LOG_DEBUG << "Added sensor " << sensorName;
+
+    sensor_json["MemberId"] = sensorName;
+    sensor_json["Name"] = sensorName;
+    sensor_json["Status"]["State"] = "Enabled";
+    sensor_json["Status"]["Health"] = "OK";
+
+    // Parameter to set to override the type we get from dbus, and force it to
+    // int, regardless of what is available.  This is used for schemas like fan,
+    // that require integers, not floats.
+    bool forceToInt = false;
+
+    const char* unit = "Reading";
+    if (sensorType == "temperature")
+    {
+        unit = "ReadingCelsius";
+        sensor_json["@odata.type"] = "#Thermal.v1_3_0.Temperature";
+        // TODO(ed) Documentation says that path should be type fan_tach,
+        // implementation seems to implement fan
+    }
+    else if (sensorType == "fan" || sensorType == "fan_tach")
+    {
+        unit = "Reading";
+        sensor_json["ReadingUnits"] = "RPM";
+        sensor_json["@odata.type"] = "#Thermal.v1_3_0.Fan";
+        forceToInt = true;
+    }
+    else if (sensorType == "voltage")
+    {
+        unit = "ReadingVolts";
+        sensor_json["@odata.type"] = "#Power.v1_0_0.Voltage";
+    }
+    else
+    {
+        BMCWEB_LOG_ERROR << "Redfish cannot map object type for " << sensorName;
+        return;
+    }
+    // Map of dbus interface name, dbus property name and redfish property_name
+    std::vector<std::tuple<const char*, const char*, const char*>> properties;
+    properties.reserve(7);
+
+    properties.emplace_back("xyz.openbmc_project.Sensor.Value", "Value", unit);
+    properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Warning",
+                            "WarningHigh", "UpperThresholdNonCritical");
+    properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Warning",
+                            "WarningLow", "LowerThresholdNonCritical");
+    properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Critical",
+                            "CriticalHigh", "UpperThresholdCritical");
+    properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Critical",
+                            "CriticalLow", "LowerThresholdCritical");
+
+    if (sensorType == "temperature")
+    {
+        properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue",
+                                "MinReadingRangeTemp");
+        properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue",
+                                "MaxReadingRangeTemp");
+    }
+    else
+    {
+        properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue",
+                                "MinReadingRange");
+        properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue",
+                                "MaxReadingRange");
+    }
+
+    for (const std::tuple<const char*, const char*, const char*>& p :
+         properties)
+    {
+        auto interfaceProperties = interfacesDict.find(std::get<0>(p));
+        if (interfaceProperties != interfacesDict.end())
+        {
+            auto valueIt = interfaceProperties->second.find(std::get<1>(p));
+            if (valueIt != interfaceProperties->second.end())
+            {
+                const SensorVariant& valueVariant = valueIt->second;
+                nlohmann::json& valueIt = sensor_json[std::get<2>(p)];
+
+                // Attempt to pull the int64 directly
+                const int64_t* int64Value =
+                    mapbox::getPtr<const int64_t>(valueVariant);
+
+                if (int64Value != nullptr)
+                {
+                    if (forceToInt || scaleMultiplier >= 0)
+                    {
+                        valueIt = *int64Value * std::pow(10, scaleMultiplier);
+                    }
+                    else
+                    {
+                        valueIt =
+                            *int64Value *
+                            std::pow(10, static_cast<double>(scaleMultiplier));
+                    }
+                }
+                // Attempt to pull the float directly
+                const double* doubleValue =
+                    mapbox::getPtr<const double>(valueVariant);
+
+                if (doubleValue != nullptr)
+                {
+                    if (!forceToInt)
+                    {
+                        valueIt =
+                            *doubleValue *
+                            std::pow(10, static_cast<double>(scaleMultiplier));
+                    }
+                    else
+                    {
+                        valueIt = static_cast<int64_t>(
+                            *doubleValue * std::pow(10, scaleMultiplier));
+                    }
+                }
+            }
+        }
+    }
+    BMCWEB_LOG_DEBUG << "Added sensor " << sensorName;
 }
 
 /**
@@ -342,106 +404,140 @@
  *        chassis.
  * @param SensorsAsyncResp   Pointer to object holding response data
  */
-void getChassisData(std::shared_ptr<SensorsAsyncResp> SensorsAsyncResp) {
-  BMCWEB_LOG_DEBUG << "getChassisData enter";
-  auto getChassisCb = [&, SensorsAsyncResp](
-                          boost::container::flat_set<std::string>&
-                              sensorNames) {
-    BMCWEB_LOG_DEBUG << "getChassisCb enter";
-    auto getConnectionCb =
-        [&, SensorsAsyncResp, sensorNames](
-            const boost::container::flat_set<std::string>& connections) {
-          BMCWEB_LOG_DEBUG << "getConnectionCb enter";
-          // Get managed objects from all services exposing sensors
-          for (const std::string& connection : connections) {
-            // Response handler to process managed objects
-            auto getManagedObjectsCb = [&, SensorsAsyncResp, sensorNames](
-                                           const boost::system::error_code ec,
-                                           ManagedObjectsVectorType& resp) {
-              BMCWEB_LOG_DEBUG << "getManagedObjectsCb enter";
-              if (ec) {
-                BMCWEB_LOG_ERROR << "getManagedObjectsCb DBUS error: " << ec;
-                SensorsAsyncResp->setErrorStatus();
-                return;
-              }
-              // Go through all objects and update response with
-              // sensor data
-              for (const auto& objDictEntry : resp) {
-                const std::string& objPath =
-                    static_cast<const std::string&>(objDictEntry.first);
-                BMCWEB_LOG_DEBUG << "getManagedObjectsCb parsing object "
-                                 << objPath;
+void getChassisData(std::shared_ptr<SensorsAsyncResp> SensorsAsyncResp)
+{
+    BMCWEB_LOG_DEBUG << "getChassisData enter";
+    auto getChassisCb = [&, SensorsAsyncResp](
+                            boost::container::flat_set<std::string>&
+                                sensorNames) {
+        BMCWEB_LOG_DEBUG << "getChassisCb enter";
+        auto getConnectionCb =
+            [&, SensorsAsyncResp, sensorNames](
+                const boost::container::flat_set<std::string>& connections) {
+                BMCWEB_LOG_DEBUG << "getConnectionCb enter";
+                // Get managed objects from all services exposing sensors
+                for (const std::string& connection : connections)
+                {
+                    // Response handler to process managed objects
+                    auto getManagedObjectsCb =
+                        [&, SensorsAsyncResp,
+                         sensorNames](const boost::system::error_code ec,
+                                      ManagedObjectsVectorType& resp) {
+                            BMCWEB_LOG_DEBUG << "getManagedObjectsCb enter";
+                            if (ec)
+                            {
+                                BMCWEB_LOG_ERROR
+                                    << "getManagedObjectsCb DBUS error: " << ec;
+                                SensorsAsyncResp->setErrorStatus();
+                                return;
+                            }
+                            // Go through all objects and update response with
+                            // sensor data
+                            for (const auto& objDictEntry : resp)
+                            {
+                                const std::string& objPath =
+                                    static_cast<const std::string&>(
+                                        objDictEntry.first);
+                                BMCWEB_LOG_DEBUG
+                                    << "getManagedObjectsCb parsing object "
+                                    << objPath;
 
-                std::vector<std::string> split;
-                // Reserve space for
-                // /xyz/openbmc_project/sensors/<name>/<subname>
-                split.reserve(6);
-                boost::algorithm::split(split, objPath, boost::is_any_of("/"));
-                if (split.size() < 6) {
-                  BMCWEB_LOG_ERROR << "Got path that isn't long enough "
-                                   << objPath;
-                  continue;
-                }
-                // These indexes aren't intuitive, as boost::split puts an empty
-                // string at the beggining
-                const std::string& sensorType = split[4];
-                const std::string& sensorName = split[5];
-                BMCWEB_LOG_DEBUG << "sensorName " << sensorName
-                                 << " sensorType " << sensorType;
-                if (sensorNames.find(sensorName) == sensorNames.end()) {
-                  BMCWEB_LOG_ERROR << sensorName << " not in sensor list ";
-                  continue;
-                }
+                                std::vector<std::string> split;
+                                // Reserve space for
+                                // /xyz/openbmc_project/sensors/<name>/<subname>
+                                split.reserve(6);
+                                boost::algorithm::split(split, objPath,
+                                                        boost::is_any_of("/"));
+                                if (split.size() < 6)
+                                {
+                                    BMCWEB_LOG_ERROR
+                                        << "Got path that isn't long enough "
+                                        << objPath;
+                                    continue;
+                                }
+                                // These indexes aren't intuitive, as
+                                // boost::split puts an empty string at the
+                                // beggining
+                                const std::string& sensorType = split[4];
+                                const std::string& sensorName = split[5];
+                                BMCWEB_LOG_DEBUG << "sensorName " << sensorName
+                                                 << " sensorType "
+                                                 << sensorType;
+                                if (sensorNames.find(sensorName) ==
+                                    sensorNames.end())
+                                {
+                                    BMCWEB_LOG_ERROR << sensorName
+                                                     << " not in sensor list ";
+                                    continue;
+                                }
 
-                const char* fieldName = nullptr;
-                if (sensorType == "temperature") {
-                  fieldName = "Temperatures";
-                } else if (sensorType == "fan" || sensorType == "fan_tach") {
-                  fieldName = "Fans";
-                } else if (sensorType == "voltage") {
-                  fieldName = "Voltages";
-                } else if (sensorType == "current") {
-                  fieldName = "PowerSupply";
-                } else if (sensorType == "power") {
-                  fieldName = "PowerSupply";
-                } else {
-                  BMCWEB_LOG_ERROR << "Unsure how to handle sensorType "
-                                   << sensorType;
-                  continue;
-                }
+                                const char* fieldName = nullptr;
+                                if (sensorType == "temperature")
+                                {
+                                    fieldName = "Temperatures";
+                                }
+                                else if (sensorType == "fan" ||
+                                         sensorType == "fan_tach")
+                                {
+                                    fieldName = "Fans";
+                                }
+                                else if (sensorType == "voltage")
+                                {
+                                    fieldName = "Voltages";
+                                }
+                                else if (sensorType == "current")
+                                {
+                                    fieldName = "PowerSupply";
+                                }
+                                else if (sensorType == "power")
+                                {
+                                    fieldName = "PowerSupply";
+                                }
+                                else
+                                {
+                                    BMCWEB_LOG_ERROR
+                                        << "Unsure how to handle sensorType "
+                                        << sensorType;
+                                    continue;
+                                }
 
-                nlohmann::json& tempArray =
-                    SensorsAsyncResp->res.jsonValue[fieldName];
+                                nlohmann::json& tempArray =
+                                    SensorsAsyncResp->res.jsonValue[fieldName];
 
-                // Create the array if it doesn't yet exist
-                if (tempArray.is_array() == false) {
-                  tempArray = nlohmann::json::array();
-                }
+                                // Create the array if it doesn't yet exist
+                                if (tempArray.is_array() == false)
+                                {
+                                    tempArray = nlohmann::json::array();
+                                }
 
-                tempArray.push_back(
-                    {{"@odata.id", "/redfish/v1/Chassis/" +
-                                       SensorsAsyncResp->chassisId +
-                                       "/Thermal#/" + sensorName}});
-                nlohmann::json& sensorJson = tempArray.back();
-                objectInterfacesToJson(sensorName, sensorType,
-                                       objDictEntry.second, sensorJson);
-              }
-              BMCWEB_LOG_DEBUG << "getManagedObjectsCb exit";
+                                tempArray.push_back(
+                                    {{"@odata.id",
+                                      "/redfish/v1/Chassis/" +
+                                          SensorsAsyncResp->chassisId +
+                                          "/Thermal#/" + sensorName}});
+                                nlohmann::json& sensorJson = tempArray.back();
+                                objectInterfacesToJson(sensorName, sensorType,
+                                                       objDictEntry.second,
+                                                       sensorJson);
+                            }
+                            BMCWEB_LOG_DEBUG << "getManagedObjectsCb exit";
+                        };
+                    crow::connections::systemBus->async_method_call(
+                        getManagedObjectsCb, connection, "/",
+                        "org.freedesktop.DBus.ObjectManager",
+                        "GetManagedObjects");
+                };
+                BMCWEB_LOG_DEBUG << "getConnectionCb exit";
             };
-            crow::connections::systemBus->async_method_call(
-                getManagedObjectsCb, connection, "/",
-                "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
-          };
-          BMCWEB_LOG_DEBUG << "getConnectionCb exit";
-        };
-    // get connections and then pass it to get sensors
-    getConnections(SensorsAsyncResp, sensorNames, std::move(getConnectionCb));
-    BMCWEB_LOG_DEBUG << "getChassisCb exit";
-  };
+        // get connections and then pass it to get sensors
+        getConnections(SensorsAsyncResp, sensorNames,
+                       std::move(getConnectionCb));
+        BMCWEB_LOG_DEBUG << "getChassisCb exit";
+    };
 
-  // get chassis information related to sensors
-  getChassis(SensorsAsyncResp, std::move(getChassisCb));
-  BMCWEB_LOG_DEBUG << "getChassisData exit";
+    // get chassis information related to sensors
+    getChassis(SensorsAsyncResp, std::move(getChassisCb));
+    BMCWEB_LOG_DEBUG << "getChassisData exit";
 };
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/lib/service_root.hpp b/redfish-core/lib/service_root.hpp
index 6fa9632..d2c5163 100644
--- a/redfish-core/lib/service_root.hpp
+++ b/redfish-core/lib/service_root.hpp
@@ -15,62 +15,69 @@
 */
 #pragma once
 
-#include <systemd/sd-id128.h>
 #include "node.hpp"
 
-namespace redfish {
+#include <systemd/sd-id128.h>
 
-class ServiceRoot : public Node {
- public:
-  ServiceRoot(CrowApp& app) : Node(app, "/redfish/v1/") {
-    Node::json["@odata.type"] = "#ServiceRoot.v1_1_1.ServiceRoot";
-    Node::json["@odata.id"] = "/redfish/v1/";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata#ServiceRoot.ServiceRoot";
-    Node::json["Id"] = "RootService";
-    Node::json["Name"] = "Root Service";
-    Node::json["RedfishVersion"] = "1.1.0";
-    Node::json["Links"]["Sessions"] = {
-        {"@odata.id", "/redfish/v1/SessionService/Sessions"}};
+namespace redfish
+{
 
-    Node::json["UUID"] = getUuid();
+class ServiceRoot : public Node
+{
+  public:
+    ServiceRoot(CrowApp& app) : Node(app, "/redfish/v1/")
+    {
+        Node::json["@odata.type"] = "#ServiceRoot.v1_1_1.ServiceRoot";
+        Node::json["@odata.id"] = "/redfish/v1/";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata#ServiceRoot.ServiceRoot";
+        Node::json["Id"] = "RootService";
+        Node::json["Name"] = "Root Service";
+        Node::json["RedfishVersion"] = "1.1.0";
+        Node::json["Links"]["Sessions"] = {
+            {"@odata.id", "/redfish/v1/SessionService/Sessions"}};
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {}},
-        {boost::beast::http::verb::head, {}},
-        {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-  }
+        Node::json["UUID"] = getUuid();
 
- private:
-  void doGet(crow::Response& res, const crow::Request& req,
-             const std::vector<std::string>& params) override {
-    res.jsonValue = Node::json;
-    res.end();
-  }
-
-  const std::string getUuid() {
-  // If we are using a version of systemd that can get the app specific uuid,
-  // use that
-#ifdef sd_id128_get_machine_app_specific
-    std::array<char, SD_ID128_STRING_MAX> string;
-    sd_id128_t id = SD_ID128_NULL;
-
-    // This ID needs to match the one in ipmid
-    int r = sd_id128_get_machine_app_specific(
-        SD_ID128_MAKE(e0, e1, 73, 76, 64, 61, 47, da, a5, 0c, d0, cc, 64, 12,
-                      45, 78),
-        &id);
-    if (r < 0) {
-      return "00000000-0000-0000-0000-000000000000";
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {}},
+            {boost::beast::http::verb::head, {}},
+            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
     }
-    return string.data();
+
+  private:
+    void doGet(crow::Response& res, const crow::Request& req,
+               const std::vector<std::string>& params) override
+    {
+        res.jsonValue = Node::json;
+        res.end();
+    }
+
+    const std::string getUuid()
+    {
+        // If we are using a version of systemd that can get the app specific
+        // uuid, use that
+#ifdef sd_id128_get_machine_app_specific
+        std::array<char, SD_ID128_STRING_MAX> string;
+        sd_id128_t id = SD_ID128_NULL;
+
+        // This ID needs to match the one in ipmid
+        int r = sd_id128_get_machine_app_specific(
+            SD_ID128_MAKE(e0, e1, 73, 76, 64, 61, 47, da, a5, 0c, d0, cc, 64,
+                          12, 45, 78),
+            &id);
+        if (r < 0)
+        {
+            return "00000000-0000-0000-0000-000000000000";
+        }
+        return string.data();
 #else
-    return "00000000-0000-0000-0000-000000000000";
+        return "00000000-0000-0000-0000-000000000000";
 #endif
-  }
+    }
 };
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/lib/systems.hpp b/redfish-core/lib/systems.hpp
index b7f91b9..cd49883 100644
--- a/redfish-core/lib/systems.hpp
+++ b/redfish-core/lib/systems.hpp
@@ -15,36 +15,44 @@
 */
 #pragma once
 
+#include "boost/container/flat_map.hpp"
+#include "node.hpp"
+
 #include <error_messages.hpp>
 #include <utils/json_utils.hpp>
-#include "node.hpp"
-#include "boost/container/flat_map.hpp"
 
-namespace redfish {
+namespace redfish
+{
 
 /**
  * SystemAsyncResp
  * Gathers data needed for response processing after async calls are done
  */
-class SystemAsyncResp {
- public:
-  SystemAsyncResp(crow::Response &response) : res(response) {}
-
-  ~SystemAsyncResp() {
-    if (res.result() != (boost::beast::http::status::ok)) {
-      // Reset the json object to clear out any data that made it in before the
-      // error happened
-      // todo(ed) handle error condition with proper code
-      res.jsonValue = messages::internalError();
+class SystemAsyncResp
+{
+  public:
+    SystemAsyncResp(crow::Response &response) : res(response)
+    {
     }
-    res.end();
-  }
 
-  void setErrorStatus() {
-    res.result(boost::beast::http::status::internal_server_error);
-  }
+    ~SystemAsyncResp()
+    {
+        if (res.result() != (boost::beast::http::status::ok))
+        {
+            // Reset the json object to clear out any data that made it in
+            // before the error happened todo(ed) handle error condition with
+            // proper code
+            res.jsonValue = messages::internalError();
+        }
+        res.end();
+    }
 
-  crow::Response &res;
+    void setErrorStatus()
+    {
+        res.result(boost::beast::http::status::internal_server_error);
+    }
+
+    crow::Response &res;
 };
 
 /**
@@ -59,628 +67,853 @@
  * This perhaps shall be different file, which has to be chosen on compile time
  * depending on OEM needs
  */
-class OnDemandSystemsProvider {
- public:
-  template <typename CallbackFunc>
-  void getBaseboardList(CallbackFunc &&callback) {
-    BMCWEB_LOG_DEBUG << "Get list of available boards.";
-    crow::connections::systemBus->async_method_call(
-        [callback{std::move(callback)}](const boost::system::error_code ec,
-                                        const std::vector<std::string> &resp) {
-          // Callback requires vector<string> to retrieve all available board
-          // list.
-          std::vector<std::string> boardList;
-          if (ec) {
-            // Something wrong on DBus, the error_code is not important at this
-            // moment, just return success=false, and empty output. Since size
-            // of vector may vary depending on information from Entity Manager,
-            // and empty output could not be treated same way as error.
-            callback(false, boardList);
-            return;
-          }
-          BMCWEB_LOG_DEBUG << "Got " << resp.size() << " boards.";
-          // Iterate over all retrieved ObjectPaths.
-          for (const std::string &objpath : resp) {
-            std::size_t lastPos = objpath.rfind("/");
-            if (lastPos != std::string::npos) {
-              boardList.emplace_back(objpath.substr(lastPos + 1));
-            }
-          }
-          // Finally make a callback with useful data
-          callback(true, boardList);
-        },
-        "xyz.openbmc_project.ObjectMapper",
-        "/xyz/openbmc_project/object_mapper",
-        "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
-        "/xyz/openbmc_project/inventory", int32_t(0),
-        std::array<const char *, 1>{
-            "xyz.openbmc_project.Inventory.Item.Board"});
-  };
-
-  /**
-   * @brief Retrieves computer system properties over dbus
-   *
-   * @param[in] aResp Shared pointer for completing asynchronous calls
-   * @param[in] name  Computer system name from request
-   *
-   * @return None.
-   */
-  void getComputerSystem(std::shared_ptr<SystemAsyncResp> aResp,
-                         const std::string &name) {
-    const std::array<const char *, 5> interfaces = {
-        "xyz.openbmc_project.Inventory.Decorator.Asset",
-        "xyz.openbmc_project.Inventory.Item.Cpu",
-        "xyz.openbmc_project.Inventory.Item.Dimm",
-        "xyz.openbmc_project.Inventory.Item.System",
-        "xyz.openbmc_project.Common.UUID",
+class OnDemandSystemsProvider
+{
+  public:
+    template <typename CallbackFunc>
+    void getBaseboardList(CallbackFunc &&callback)
+    {
+        BMCWEB_LOG_DEBUG << "Get list of available boards.";
+        crow::connections::systemBus->async_method_call(
+            [callback{std::move(callback)}](
+                const boost::system::error_code ec,
+                const std::vector<std::string> &resp) {
+                // Callback requires vector<string> to retrieve all available
+                // board list.
+                std::vector<std::string> boardList;
+                if (ec)
+                {
+                    // Something wrong on DBus, the error_code is not important
+                    // at this moment, just return success=false, and empty
+                    // output. Since size of vector may vary depending on
+                    // information from Entity Manager, and empty output could
+                    // not be treated same way as error.
+                    callback(false, boardList);
+                    return;
+                }
+                BMCWEB_LOG_DEBUG << "Got " << resp.size() << " boards.";
+                // Iterate over all retrieved ObjectPaths.
+                for (const std::string &objpath : resp)
+                {
+                    std::size_t lastPos = objpath.rfind("/");
+                    if (lastPos != std::string::npos)
+                    {
+                        boardList.emplace_back(objpath.substr(lastPos + 1));
+                    }
+                }
+                // Finally make a callback with useful data
+                callback(true, boardList);
+            },
+            "xyz.openbmc_project.ObjectMapper",
+            "/xyz/openbmc_project/object_mapper",
+            "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
+            "/xyz/openbmc_project/inventory", int32_t(0),
+            std::array<const char *, 1>{
+                "xyz.openbmc_project.Inventory.Item.Board"});
     };
-    BMCWEB_LOG_DEBUG << "Get available system components.";
-    crow::connections::systemBus->async_method_call(
-        [ name, aResp{std::move(aResp)} ](
-            const boost::system::error_code ec,
-            const std::vector<std::pair<
-                std::string,
-                std::vector<std::pair<std::string, std::vector<std::string>>>>>
-                &subtree) {
-          if (ec) {
-            BMCWEB_LOG_DEBUG << "DBUS response error";
-            aResp->setErrorStatus();
-            return;
-          }
-          bool foundName = false;
-          // Iterate over all retrieved ObjectPaths.
-          for (const std::pair<std::string,
-                               std::vector<std::pair<std::string,
-                                                     std::vector<std::string>>>>
-                   &object : subtree) {
-            const std::string &path = object.first;
-            BMCWEB_LOG_DEBUG << "Got path: " << path;
-            const std::vector<std::pair<std::string, std::vector<std::string>>>
-                &connectionNames = object.second;
-            if (connectionNames.size() < 1) {
-              continue;
-            }
-            // Check if computer system exist
-            if (boost::ends_with(path, name)) {
-              foundName = true;
-              BMCWEB_LOG_DEBUG << "Found name: " << name;
-              const std::string connectionName = connectionNames[0].first;
-              crow::connections::systemBus->async_method_call(
-                  [ aResp, name(std::string(name)) ](
-                      const boost::system::error_code ec,
-                      const std::vector<std::pair<std::string, VariantType>>
-                          &propertiesList) {
-                    if (ec) {
-                      BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
-                      aResp->setErrorStatus();
-                      return;
+
+    /**
+     * @brief Retrieves computer system properties over dbus
+     *
+     * @param[in] aResp Shared pointer for completing asynchronous calls
+     * @param[in] name  Computer system name from request
+     *
+     * @return None.
+     */
+    void getComputerSystem(std::shared_ptr<SystemAsyncResp> aResp,
+                           const std::string &name)
+    {
+        const std::array<const char *, 5> interfaces = {
+            "xyz.openbmc_project.Inventory.Decorator.Asset",
+            "xyz.openbmc_project.Inventory.Item.Cpu",
+            "xyz.openbmc_project.Inventory.Item.Dimm",
+            "xyz.openbmc_project.Inventory.Item.System",
+            "xyz.openbmc_project.Common.UUID",
+        };
+        BMCWEB_LOG_DEBUG << "Get available system components.";
+        crow::connections::systemBus->async_method_call(
+            [name, aResp{std::move(aResp)}](
+                const boost::system::error_code ec,
+                const std::vector<std::pair<
+                    std::string, std::vector<std::pair<
+                                     std::string, std::vector<std::string>>>>>
+                    &subtree) {
+                if (ec)
+                {
+                    BMCWEB_LOG_DEBUG << "DBUS response error";
+                    aResp->setErrorStatus();
+                    return;
+                }
+                bool foundName = false;
+                // Iterate over all retrieved ObjectPaths.
+                for (const std::pair<
+                         std::string,
+                         std::vector<
+                             std::pair<std::string, std::vector<std::string>>>>
+                         &object : subtree)
+                {
+                    const std::string &path = object.first;
+                    BMCWEB_LOG_DEBUG << "Got path: " << path;
+                    const std::vector<
+                        std::pair<std::string, std::vector<std::string>>>
+                        &connectionNames = object.second;
+                    if (connectionNames.size() < 1)
+                    {
+                        continue;
                     }
-                    BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
-                                     << "properties for system";
-                    for (const std::pair<std::string, VariantType> &property :
-                         propertiesList) {
-                      const std::string *value =
-                          mapbox::getPtr<const std::string>(property.second);
-                      if (value != nullptr) {
-                        aResp->res.jsonValue[property.first] = *value;
-                      }
-                    }
-                    aResp->res.jsonValue["Name"] = name;
-                    aResp->res.jsonValue["Id"] =
-                        aResp->res.jsonValue["SerialNumber"];
-                  },
-                  connectionName, path, "org.freedesktop.DBus.Properties",
-                  "GetAll", "xyz.openbmc_project.Inventory.Decorator.Asset");
-            } else {
-              // This is not system, so check if it's cpu, dimm, UUID or BiosVer
-              for (auto const &s : connectionNames) {
-                for (auto const &i : s.second) {
-                  if (boost::ends_with(i, "Dimm")) {
-                    BMCWEB_LOG_DEBUG << "Found Dimm, now get it properties.";
-                    crow::connections::systemBus->async_method_call(
-                        [&, aResp](const boost::system::error_code ec,
-                                   const std::vector<std::pair<
-                                       std::string, VariantType>> &properties) {
-                          if (ec) {
-                            BMCWEB_LOG_ERROR << "DBUS response error " << ec;
-                            aResp->setErrorStatus();
-                            return;
-                          }
-                          BMCWEB_LOG_DEBUG << "Got " << properties.size()
-                                           << "Dimm properties.";
-                          for (const auto &p : properties) {
-                            if (p.first == "MemorySize") {
-                              const std::string *value =
-                                  mapbox::getPtr<const std::string>(p.second);
-                              if ((value != nullptr) && (*value != "NULL")) {
-                                // Remove units char
-                                int32_t unitCoeff;
-                                if (boost::ends_with(*value, "MB")) {
-                                  unitCoeff = 1000;
-                                } else if (boost::ends_with(*value, "KB")) {
-                                  unitCoeff = 1000000;
-                                } else {
-                                  BMCWEB_LOG_ERROR
-                                      << "Unsupported memory units";
-                                  aResp->setErrorStatus();
-                                  return;
+                    // Check if computer system exist
+                    if (boost::ends_with(path, name))
+                    {
+                        foundName = true;
+                        BMCWEB_LOG_DEBUG << "Found name: " << name;
+                        const std::string connectionName =
+                            connectionNames[0].first;
+                        crow::connections::systemBus->async_method_call(
+                            [aResp, name(std::string(name))](
+                                const boost::system::error_code ec,
+                                const std::vector<
+                                    std::pair<std::string, VariantType>>
+                                    &propertiesList) {
+                                if (ec)
+                                {
+                                    BMCWEB_LOG_ERROR << "DBUS response error: "
+                                                     << ec;
+                                    aResp->setErrorStatus();
+                                    return;
                                 }
-
-                                auto memSize = boost::lexical_cast<int>(
-                                    value->substr(0, value->length() - 2));
-                                aResp->res.jsonValue["TotalSystemMemoryGiB"] +=
-                                    memSize * unitCoeff;
-                                aResp->res.jsonValue["MemorySummary"]["Status"]
-                                                    ["State"] = "Enabled";
-                              }
-                            }
-                          }
-                        },
-                        s.first, path, "org.freedesktop.DBus.Properties",
-                        "GetAll", "xyz.openbmc_project.Inventory.Item.Dimm");
-                  } else if (boost::ends_with(i, "Cpu")) {
-                    BMCWEB_LOG_DEBUG << "Found Cpu, now get it properties.";
-                    crow::connections::systemBus->async_method_call(
-                        [&, aResp](const boost::system::error_code ec,
-                                   const std::vector<std::pair<
-                                       std::string, VariantType>> &properties) {
-                          if (ec) {
-                            BMCWEB_LOG_ERROR << "DBUS response error " << ec;
-                            aResp->setErrorStatus();
-                            return;
-                          }
-                          BMCWEB_LOG_DEBUG << "Got " << properties.size()
-                                           << "Cpu properties.";
-                          for (const auto &p : properties) {
-                            if (p.first == "ProcessorFamily") {
-                              const std::string *value =
-                                  mapbox::getPtr<const std::string>(p.second);
-                              if (value != nullptr) {
-                                aResp->res
-                                    .jsonValue["ProcessorSummary"]["Count"] =
-                                    aResp->res
-                                        .jsonValue["ProcessorSummary"]["Count"]
-                                        .get<int>() +
-                                    1;
-                                aResp->res.jsonValue["ProcessorSummary"]
-                                                    ["Status"]["State"] =
-                                    "Enabled";
-                                aResp->res
-                                    .jsonValue["ProcessorSummary"]["Model"] =
-                                    *value;
-                              }
-                            }
-                          }
-                        },
-                        s.first, path, "org.freedesktop.DBus.Properties",
-                        "GetAll", "xyz.openbmc_project.Inventory.Item.Cpu");
-                  } else if (boost::ends_with(i, "UUID")) {
-                    BMCWEB_LOG_DEBUG << "Found UUID, now get it properties.";
-                    crow::connections::systemBus->async_method_call(
-                        [aResp](const boost::system::error_code ec,
-                                const std::vector<std::pair<
-                                    std::string, VariantType>> &properties) {
-                          if (ec) {
-                            BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
-                            aResp->setErrorStatus();
-                            return;
-                          }
-                          BMCWEB_LOG_DEBUG << "Got " << properties.size()
-                                           << "UUID properties.";
-                          for (const std::pair<std::string, VariantType> &p :
-                               properties) {
-                            if (p.first == "BIOSVer") {
-                              const std::string *value =
-                                  mapbox::getPtr<const std::string>(p.second);
-                              if (value != nullptr) {
-                                aResp->res.jsonValue["BiosVersion"] = *value;
-                              }
-                            }
-                            if (p.first == "UUID") {
-                              const std::string *value =
-                                  mapbox::getPtr<const std::string>(p.second);
-                              BMCWEB_LOG_DEBUG << "UUID = " << *value
-                                               << " length " << value->length();
-                              if (value != nullptr) {
-                                // Workaround for to short return str in smbios
-                                // demo app, 32 bytes are described by spec
-                                if (value->length() > 0 &&
-                                    value->length() < 32) {
-                                  std::string correctedValue = *value;
-                                  correctedValue.append(32 - value->length(),
-                                                        '0');
-                                  value = &correctedValue;
-                                } else if (value->length() == 32) {
-                                  aResp->res.jsonValue["UUID"] =
-                                      value->substr(0, 8) + "-" +
-                                      value->substr(8, 4) + "-" +
-                                      value->substr(12, 4) + "-" +
-                                      value->substr(16, 4) + "-" +
-                                      value->substr(20, 12);
+                                BMCWEB_LOG_DEBUG << "Got "
+                                                 << propertiesList.size()
+                                                 << "properties for system";
+                                for (const std::pair<std::string, VariantType>
+                                         &property : propertiesList)
+                                {
+                                    const std::string *value =
+                                        mapbox::getPtr<const std::string>(
+                                            property.second);
+                                    if (value != nullptr)
+                                    {
+                                        aResp->res.jsonValue[property.first] =
+                                            *value;
+                                    }
                                 }
-                              }
+                                aResp->res.jsonValue["Name"] = name;
+                                aResp->res.jsonValue["Id"] =
+                                    aResp->res.jsonValue["SerialNumber"];
+                            },
+                            connectionName, path,
+                            "org.freedesktop.DBus.Properties", "GetAll",
+                            "xyz.openbmc_project.Inventory.Decorator.Asset");
+                    }
+                    else
+                    {
+                        // This is not system, so check if it's cpu, dimm, UUID
+                        // or BiosVer
+                        for (auto const &s : connectionNames)
+                        {
+                            for (auto const &i : s.second)
+                            {
+                                if (boost::ends_with(i, "Dimm"))
+                                {
+                                    BMCWEB_LOG_DEBUG
+                                        << "Found Dimm, now get it properties.";
+                                    crow::connections::systemBus->async_method_call(
+                                        [&, aResp](
+                                            const boost::system::error_code ec,
+                                            const std::vector<std::pair<
+                                                std::string, VariantType>>
+                                                &properties) {
+                                            if (ec)
+                                            {
+                                                BMCWEB_LOG_ERROR
+                                                    << "DBUS response error "
+                                                    << ec;
+                                                aResp->setErrorStatus();
+                                                return;
+                                            }
+                                            BMCWEB_LOG_DEBUG
+                                                << "Got " << properties.size()
+                                                << "Dimm properties.";
+                                            for (const auto &p : properties)
+                                            {
+                                                if (p.first == "MemorySize")
+                                                {
+                                                    const std::string *value =
+                                                        mapbox::getPtr<
+                                                            const std::string>(
+                                                            p.second);
+                                                    if ((value != nullptr) &&
+                                                        (*value != "NULL"))
+                                                    {
+                                                        // Remove units char
+                                                        int32_t unitCoeff;
+                                                        if (boost::ends_with(
+                                                                *value, "MB"))
+                                                        {
+                                                            unitCoeff = 1000;
+                                                        }
+                                                        else if (boost::
+                                                                     ends_with(
+                                                                         *value,
+                                                                         "KB"))
+                                                        {
+                                                            unitCoeff = 1000000;
+                                                        }
+                                                        else
+                                                        {
+                                                            BMCWEB_LOG_ERROR
+                                                                << "Unsupported"
+                                                                   " memory "
+                                                                   "units";
+                                                            aResp
+                                                                ->setErrorStatus();
+                                                            return;
+                                                        }
+
+                                                        auto memSize =
+                                                            boost::lexical_cast<
+                                                                int>(value->substr(
+                                                                0,
+                                                                value->length() -
+                                                                    2));
+                                                        aResp->res.jsonValue
+                                                            ["TotalSystemMemory"
+                                                             "GiB"] +=
+                                                            memSize * unitCoeff;
+                                                        aResp->res.jsonValue
+                                                            ["MemorySummary"]
+                                                            ["Status"]
+                                                            ["State"] =
+                                                            "Enabled";
+                                                    }
+                                                }
+                                            }
+                                        },
+                                        s.first, path,
+                                        "org.freedesktop.DBus.Properties",
+                                        "GetAll",
+                                        "xyz.openbmc_project.Inventory.Item."
+                                        "Dimm");
+                                }
+                                else if (boost::ends_with(i, "Cpu"))
+                                {
+                                    BMCWEB_LOG_DEBUG
+                                        << "Found Cpu, now get it properties.";
+                                    crow::connections::systemBus
+                                        ->async_method_call(
+                                            [&, aResp](
+                                                const boost::system::error_code
+                                                    ec,
+                                                const std::vector<std::pair<
+                                                    std::string, VariantType>>
+                                                    &properties) {
+                                                if (ec)
+                                                {
+                                                    BMCWEB_LOG_ERROR
+                                                        << "DBUS response "
+                                                           "error "
+                                                        << ec;
+                                                    aResp->setErrorStatus();
+                                                    return;
+                                                }
+                                                BMCWEB_LOG_DEBUG
+                                                    << "Got "
+                                                    << properties.size()
+                                                    << "Cpu properties.";
+                                                for (const auto &p : properties)
+                                                {
+                                                    if (p.first ==
+                                                        "ProcessorFamily")
+                                                    {
+                                                        const std::string
+                                                            *value =
+                                                                mapbox::getPtr<
+                                                                    const std::
+                                                                        string>(
+                                                                    p.second);
+                                                        if (value != nullptr)
+                                                        {
+                                                            aResp->res.jsonValue
+                                                                ["ProcessorSumm"
+                                                                 "ary"]
+                                                                ["Count"] =
+                                                                aResp->res
+                                                                    .jsonValue
+                                                                        ["Proce"
+                                                                         "ssorS"
+                                                                         "ummar"
+                                                                         "y"]
+                                                                        ["Coun"
+                                                                         "t"]
+                                                                    .get<
+                                                                        int>() +
+                                                                1;
+                                                            aResp->res.jsonValue
+                                                                ["ProcessorSumm"
+                                                                 "ary"]
+                                                                ["Status"]
+                                                                ["State"] =
+                                                                "Enabled";
+                                                            aResp->res.jsonValue
+                                                                ["ProcessorSumm"
+                                                                 "ary"]
+                                                                ["Model"] =
+                                                                *value;
+                                                        }
+                                                    }
+                                                }
+                                            },
+                                            s.first, path,
+                                            "org.freedesktop.DBus.Properties",
+                                            "GetAll",
+                                            "xyz.openbmc_project.Inventory."
+                                            "Item.Cpu");
+                                }
+                                else if (boost::ends_with(i, "UUID"))
+                                {
+                                    BMCWEB_LOG_DEBUG
+                                        << "Found UUID, now get it properties.";
+                                    crow::connections::systemBus->async_method_call(
+                                        [aResp](
+                                            const boost::system::error_code ec,
+                                            const std::vector<std::pair<
+                                                std::string, VariantType>>
+                                                &properties) {
+                                            if (ec)
+                                            {
+                                                BMCWEB_LOG_DEBUG
+                                                    << "DBUS response error "
+                                                    << ec;
+                                                aResp->setErrorStatus();
+                                                return;
+                                            }
+                                            BMCWEB_LOG_DEBUG
+                                                << "Got " << properties.size()
+                                                << "UUID properties.";
+                                            for (const std::pair<std::string,
+                                                                 VariantType>
+                                                     &p : properties)
+                                            {
+                                                if (p.first == "BIOSVer")
+                                                {
+                                                    const std::string *value =
+                                                        mapbox::getPtr<
+                                                            const std::string>(
+                                                            p.second);
+                                                    if (value != nullptr)
+                                                    {
+                                                        aResp->res.jsonValue
+                                                            ["BiosVersion"] =
+                                                            *value;
+                                                    }
+                                                }
+                                                if (p.first == "UUID")
+                                                {
+                                                    const std::string *value =
+                                                        mapbox::getPtr<
+                                                            const std::string>(
+                                                            p.second);
+                                                    BMCWEB_LOG_DEBUG
+                                                        << "UUID = " << *value
+                                                        << " length "
+                                                        << value->length();
+                                                    if (value != nullptr)
+                                                    {
+                                                        // Workaround for to
+                                                        // short return str in
+                                                        // smbios demo app, 32
+                                                        // bytes are described
+                                                        // by spec
+                                                        if (value->length() >
+                                                                0 &&
+                                                            value->length() <
+                                                                32)
+                                                        {
+                                                            std::string
+                                                                correctedValue =
+                                                                    *value;
+                                                            correctedValue.append(
+                                                                32 -
+                                                                    value
+                                                                        ->length(),
+                                                                '0');
+                                                            value =
+                                                                &correctedValue;
+                                                        }
+                                                        else if (
+                                                            value->length() ==
+                                                            32)
+                                                        {
+                                                            aResp->res.jsonValue
+                                                                ["UUID"] =
+                                                                value->substr(
+                                                                    0, 8) +
+                                                                "-" +
+                                                                value->substr(
+                                                                    8, 4) +
+                                                                "-" +
+                                                                value->substr(
+                                                                    12, 4) +
+                                                                "-" +
+                                                                value->substr(
+                                                                    16, 4) +
+                                                                "-" +
+                                                                value->substr(
+                                                                    20, 12);
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        },
+                                        s.first, path,
+                                        "org.freedesktop.DBus.Properties",
+                                        "GetAll",
+                                        "xyz.openbmc_project.Common.UUID");
+                                }
                             }
-                          }
-                        },
-                        s.first, path, "org.freedesktop.DBus.Properties",
-                        "GetAll", "xyz.openbmc_project.Common.UUID");
-                  }
-                }
-              }
-            }
-          }
-          if (foundName == false) {
-            aResp->setErrorStatus();
-          }
-        },
-        "xyz.openbmc_project.ObjectMapper",
-        "/xyz/openbmc_project/object_mapper",
-        "xyz.openbmc_project.ObjectMapper", "GetSubTree",
-        "/xyz/openbmc_project/inventory", int32_t(0), interfaces);
-  }
-
-  /**
-   * @brief Retrieves identify led group properties over dbus
-   *
-   * @param[in] aResp     Shared pointer for completing asynchronous calls.
-   * @param[in] callback  Callback for process retrieved data.
-   *
-   * @return None.
-   */
-  template <typename CallbackFunc>
-  void getLedGroupIdentify(std::shared_ptr<SystemAsyncResp> aResp,
-                           CallbackFunc &&callback) {
-    BMCWEB_LOG_DEBUG << "Get led groups";
-    crow::connections::systemBus->async_method_call(
-        [
-          aResp{std::move(aResp)}, &callback
-        ](const boost::system::error_code &ec, const ManagedObjectsType &resp) {
-          if (ec) {
-            BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
-            aResp->setErrorStatus();
-            return;
-          }
-          BMCWEB_LOG_DEBUG << "Got " << resp.size() << "led group objects.";
-          for (const auto &objPath : resp) {
-            const std::string &path = objPath.first;
-            if (path.rfind("enclosure_identify") != std::string::npos) {
-              for (const auto &interface : objPath.second) {
-                if (interface.first == "xyz.openbmc_project.Led.Group") {
-                  for (const auto &property : interface.second) {
-                    if (property.first == "Asserted") {
-                      const bool *asserted =
-                          mapbox::getPtr<const bool>(property.second);
-                      if (nullptr != asserted) {
-                        callback(*asserted, aResp);
-                      } else {
-                        callback(false, aResp);
-                      }
+                        }
                     }
-                  }
                 }
-              }
-            }
-          }
-        },
-        "xyz.openbmc_project.LED.GroupManager",
-        "/xyz/openbmc_project/led/groups", "org.freedesktop.DBus.ObjectManager",
-        "GetManagedObjects");
-  }
+                if (foundName == false)
+                {
+                    aResp->setErrorStatus();
+                }
+            },
+            "xyz.openbmc_project.ObjectMapper",
+            "/xyz/openbmc_project/object_mapper",
+            "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+            "/xyz/openbmc_project/inventory", int32_t(0), interfaces);
+    }
 
-  template <typename CallbackFunc>
-  void getLedIdentify(std::shared_ptr<SystemAsyncResp> aResp,
-                      CallbackFunc &&callback) {
-    BMCWEB_LOG_DEBUG << "Get identify led properties";
-    crow::connections::systemBus->async_method_call(
-        [ aResp{std::move(aResp)}, &callback ](
-            const boost::system::error_code ec,
-            const PropertiesType &properties) {
-          if (ec) {
-            BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
-            aResp->setErrorStatus();
-            return;
-          }
-          BMCWEB_LOG_DEBUG << "Got " << properties.size() << "led properties.";
-          std::string output;
-          for (const auto &property : properties) {
-            if (property.first == "State") {
-              const std::string *s =
-                  mapbox::getPtr<std::string>(property.second);
-              if (nullptr != s) {
-                BMCWEB_LOG_DEBUG << "Identify Led State: " << *s;
-                const auto pos = s->rfind('.');
-                if (pos != std::string::npos) {
-                  auto led = s->substr(pos + 1);
-                  for (const std::pair<const char *, const char *> &p :
-                       std::array<std::pair<const char *, const char *>, 3>{
-                           {{"On", "Lit"},
-                            {"Blink", "Blinking"},
-                            {"Off", "Off"}}}) {
-                    if (led == p.first) {
-                      output = p.second;
+    /**
+     * @brief Retrieves identify led group properties over dbus
+     *
+     * @param[in] aResp     Shared pointer for completing asynchronous calls.
+     * @param[in] callback  Callback for process retrieved data.
+     *
+     * @return None.
+     */
+    template <typename CallbackFunc>
+    void getLedGroupIdentify(std::shared_ptr<SystemAsyncResp> aResp,
+                             CallbackFunc &&callback)
+    {
+        BMCWEB_LOG_DEBUG << "Get led groups";
+        crow::connections::systemBus->async_method_call(
+            [aResp{std::move(aResp)},
+             &callback](const boost::system::error_code &ec,
+                        const ManagedObjectsType &resp) {
+                if (ec)
+                {
+                    BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
+                    aResp->setErrorStatus();
+                    return;
+                }
+                BMCWEB_LOG_DEBUG << "Got " << resp.size()
+                                 << "led group objects.";
+                for (const auto &objPath : resp)
+                {
+                    const std::string &path = objPath.first;
+                    if (path.rfind("enclosure_identify") != std::string::npos)
+                    {
+                        for (const auto &interface : objPath.second)
+                        {
+                            if (interface.first ==
+                                "xyz.openbmc_project.Led.Group")
+                            {
+                                for (const auto &property : interface.second)
+                                {
+                                    if (property.first == "Asserted")
+                                    {
+                                        const bool *asserted =
+                                            mapbox::getPtr<const bool>(
+                                                property.second);
+                                        if (nullptr != asserted)
+                                        {
+                                            callback(*asserted, aResp);
+                                        }
+                                        else
+                                        {
+                                            callback(false, aResp);
+                                        }
+                                    }
+                                }
+                            }
+                        }
                     }
-                  }
                 }
-              }
-            }
-          }
-          callback(output, aResp);
-        },
-        "xyz.openbmc_project.LED.Controller.identify",
-        "/xyz/openbmc_project/led/physical/identify",
-        "org.freedesktop.DBus.Properties", "GetAll",
-        "xyz.openbmc_project.Led.Physical");
-  }
+            },
+            "xyz.openbmc_project.LED.GroupManager",
+            "/xyz/openbmc_project/led/groups",
+            "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+    }
 
-  /**
-   * @brief Retrieves host state properties over dbus
-   *
-   * @param[in] aResp     Shared pointer for completing asynchronous calls.
-   *
-   * @return None.
-   */
-  void getHostState(std::shared_ptr<SystemAsyncResp> aResp) {
-    BMCWEB_LOG_DEBUG << "Get host information.";
-    crow::connections::systemBus->async_method_call(
-        [aResp{std::move(aResp)}](const boost::system::error_code ec,
-                                  const PropertiesType &properties) {
-          if (ec) {
-            BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
-            aResp->setErrorStatus();
-            return;
-          }
-          BMCWEB_LOG_DEBUG << "Got " << properties.size() << "host properties.";
-          for (const auto &property : properties) {
-            if (property.first == "CurrentHostState") {
-              const std::string *s =
-                  mapbox::getPtr<const std::string>(property.second);
-              BMCWEB_LOG_DEBUG << "Host state: " << *s;
-              if (nullptr != s) {
-                const auto pos = s->rfind('.');
-                if (pos != std::string::npos) {
-                  // Verify Host State
-                  if (s->substr(pos + 1) == "Running") {
-                    aResp->res.jsonValue["PowerState"] = "On";
-                    aResp->res.jsonValue["Status"]["State"] = "Enabled";
-                  } else {
-                    aResp->res.jsonValue["PowerState"] = "Off";
-                    aResp->res.jsonValue["Status"]["State"] = "Disabled";
-                  }
+    template <typename CallbackFunc>
+    void getLedIdentify(std::shared_ptr<SystemAsyncResp> aResp,
+                        CallbackFunc &&callback)
+    {
+        BMCWEB_LOG_DEBUG << "Get identify led properties";
+        crow::connections::systemBus->async_method_call(
+            [aResp{std::move(aResp)},
+             &callback](const boost::system::error_code ec,
+                        const PropertiesType &properties) {
+                if (ec)
+                {
+                    BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
+                    aResp->setErrorStatus();
+                    return;
                 }
-              }
-            }
-          }
-        },
-        "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
-        "org.freedesktop.DBus.Properties", "GetAll",
-        "xyz.openbmc_project.State.Host");
-  }
+                BMCWEB_LOG_DEBUG << "Got " << properties.size()
+                                 << "led properties.";
+                std::string output;
+                for (const auto &property : properties)
+                {
+                    if (property.first == "State")
+                    {
+                        const std::string *s =
+                            mapbox::getPtr<std::string>(property.second);
+                        if (nullptr != s)
+                        {
+                            BMCWEB_LOG_DEBUG << "Identify Led State: " << *s;
+                            const auto pos = s->rfind('.');
+                            if (pos != std::string::npos)
+                            {
+                                auto led = s->substr(pos + 1);
+                                for (const std::pair<const char *, const char *>
+                                         &p :
+                                     std::array<
+                                         std::pair<const char *, const char *>,
+                                         3>{{{"On", "Lit"},
+                                             {"Blink", "Blinking"},
+                                             {"Off", "Off"}}})
+                                {
+                                    if (led == p.first)
+                                    {
+                                        output = p.second;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+                callback(output, aResp);
+            },
+            "xyz.openbmc_project.LED.Controller.identify",
+            "/xyz/openbmc_project/led/physical/identify",
+            "org.freedesktop.DBus.Properties", "GetAll",
+            "xyz.openbmc_project.Led.Physical");
+    }
+
+    /**
+     * @brief Retrieves host state properties over dbus
+     *
+     * @param[in] aResp     Shared pointer for completing asynchronous calls.
+     *
+     * @return None.
+     */
+    void getHostState(std::shared_ptr<SystemAsyncResp> aResp)
+    {
+        BMCWEB_LOG_DEBUG << "Get host information.";
+        crow::connections::systemBus->async_method_call(
+            [aResp{std::move(aResp)}](const boost::system::error_code ec,
+                                      const PropertiesType &properties) {
+                if (ec)
+                {
+                    BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
+                    aResp->setErrorStatus();
+                    return;
+                }
+                BMCWEB_LOG_DEBUG << "Got " << properties.size()
+                                 << "host properties.";
+                for (const auto &property : properties)
+                {
+                    if (property.first == "CurrentHostState")
+                    {
+                        const std::string *s =
+                            mapbox::getPtr<const std::string>(property.second);
+                        BMCWEB_LOG_DEBUG << "Host state: " << *s;
+                        if (nullptr != s)
+                        {
+                            const auto pos = s->rfind('.');
+                            if (pos != std::string::npos)
+                            {
+                                // Verify Host State
+                                if (s->substr(pos + 1) == "Running")
+                                {
+                                    aResp->res.jsonValue["PowerState"] = "On";
+                                    aResp->res.jsonValue["Status"]["State"] =
+                                        "Enabled";
+                                }
+                                else
+                                {
+                                    aResp->res.jsonValue["PowerState"] = "Off";
+                                    aResp->res.jsonValue["Status"]["State"] =
+                                        "Disabled";
+                                }
+                            }
+                        }
+                    }
+                }
+            },
+            "xyz.openbmc_project.State.Host",
+            "/xyz/openbmc_project/state/host0",
+            "org.freedesktop.DBus.Properties", "GetAll",
+            "xyz.openbmc_project.State.Host");
+    }
 };
 
 /**
  * SystemsCollection derived class for delivering ComputerSystems Collection
  * Schema
  */
-class SystemsCollection : public Node {
- public:
-  SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/") {
-    Node::json["@odata.type"] =
-        "#ComputerSystemCollection.ComputerSystemCollection";
-    Node::json["@odata.id"] = "/redfish/v1/Systems";
-    Node::json["@odata.context"] =
-        "/redfish/v1/"
-        "$metadata#ComputerSystemCollection.ComputerSystemCollection";
-    Node::json["Name"] = "Computer System Collection";
+class SystemsCollection : public Node
+{
+  public:
+    SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
+    {
+        Node::json["@odata.type"] =
+            "#ComputerSystemCollection.ComputerSystemCollection";
+        Node::json["@odata.id"] = "/redfish/v1/Systems";
+        Node::json["@odata.context"] =
+            "/redfish/v1/"
+            "$metadata#ComputerSystemCollection.ComputerSystemCollection";
+        Node::json["Name"] = "Computer System Collection";
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-  }
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
+    }
 
- private:
-  /**
-   * Functions triggers appropriate requests on DBus
-   */
-  void doGet(crow::Response &res, const crow::Request &req,
-             const std::vector<std::string> &params) override {
-    // Get board list, and call the below callback for JSON preparation
-    provider.getBaseboardList(
-        [&](const bool &success, const std::vector<std::string> &output) {
-          if (success) {
-            // ... prepare json array with appropriate @odata.id links
-            nlohmann::json boardArray = nlohmann::json::array();
-            for (const std::string &boardItem : output) {
-              boardArray.push_back(
-                  {{"@odata.id", "/redfish/v1/Systems/" + boardItem}});
+  private:
+    /**
+     * Functions triggers appropriate requests on DBus
+     */
+    void doGet(crow::Response &res, const crow::Request &req,
+               const std::vector<std::string> &params) override
+    {
+        // Get board list, and call the below callback for JSON preparation
+        provider.getBaseboardList([&](const bool &success,
+                                      const std::vector<std::string> &output) {
+            if (success)
+            {
+                // ... prepare json array with appropriate @odata.id links
+                nlohmann::json boardArray = nlohmann::json::array();
+                for (const std::string &boardItem : output)
+                {
+                    boardArray.push_back(
+                        {{"@odata.id", "/redfish/v1/Systems/" + boardItem}});
+                }
+                // Then attach members, count size and return,
+                Node::json["Members"] = boardArray;
+                Node::json["Members@odata.count"] = boardArray.size();
+                res.jsonValue = Node::json;
             }
-            // Then attach members, count size and return,
-            Node::json["Members"] = boardArray;
-            Node::json["Members@odata.count"] = boardArray.size();
-            res.jsonValue = Node::json;
-          } else {
-            // ... otherwise, return INTERNALL ERROR
-            res.result(boost::beast::http::status::internal_server_error);
-          }
-          res.end();
+            else
+            {
+                // ... otherwise, return INTERNALL ERROR
+                res.result(boost::beast::http::status::internal_server_error);
+            }
+            res.end();
         });
-  }
+    }
 
-  OnDemandSystemsProvider provider;
+    OnDemandSystemsProvider provider;
 };
 
 /**
  * Systems override class for delivering ComputerSystems Schema
  */
-class Systems : public Node {
- public:
-  /*
-   * Default Constructor
-   */
-  Systems(CrowApp &app)
-      : Node(app, "/redfish/v1/Systems/<str>/", std::string()) {
-    Node::json["@odata.type"] = "#ComputerSystem.v1_3_0.ComputerSystem";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata#ComputerSystem.ComputerSystem";
-    Node::json["SystemType"] = "Physical";
-    Node::json["Description"] = "Computer System";
-    Node::json["Boot"]["BootSourceOverrideEnabled"] =
-        "Disabled";  // TODO(Dawid), get real boot data
-    Node::json["Boot"]["BootSourceOverrideTarget"] =
-        "None";  // TODO(Dawid), get real boot data
-    Node::json["Boot"]["BootSourceOverrideMode"] =
-        "Legacy";  // TODO(Dawid), get real boot data
-    Node::json["Boot"]["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
-        "None",      "Pxe",       "Hdd", "Cd",
-        "BiosSetup", "UefiShell", "Usb"};  // TODO(Dawid), get real boot data
-    Node::json["ProcessorSummary"]["Count"] = int(0);
-    Node::json["ProcessorSummary"]["Status"]["State"] = "Disabled";
-    Node::json["MemorySummary"]["TotalSystemMemoryGiB"] = int(0);
-    Node::json["MemorySummary"]["Status"]["State"] = "Disabled";
+class Systems : public Node
+{
+  public:
+    /*
+     * Default Constructor
+     */
+    Systems(CrowApp &app) :
+        Node(app, "/redfish/v1/Systems/<str>/", std::string())
+    {
+        Node::json["@odata.type"] = "#ComputerSystem.v1_3_0.ComputerSystem";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata#ComputerSystem.ComputerSystem";
+        Node::json["SystemType"] = "Physical";
+        Node::json["Description"] = "Computer System";
+        Node::json["Boot"]["BootSourceOverrideEnabled"] =
+            "Disabled"; // TODO(Dawid), get real boot data
+        Node::json["Boot"]["BootSourceOverrideTarget"] =
+            "None"; // TODO(Dawid), get real boot data
+        Node::json["Boot"]["BootSourceOverrideMode"] =
+            "Legacy"; // TODO(Dawid), get real boot data
+        Node::json["Boot"]["BootSourceOverrideTarget@Redfish.AllowableValues"] =
+            {"None",      "Pxe",       "Hdd", "Cd",
+             "BiosSetup", "UefiShell", "Usb"}; // TODO(Dawid), get real boot
+                                               // data
+        Node::json["ProcessorSummary"]["Count"] = int(0);
+        Node::json["ProcessorSummary"]["Status"]["State"] = "Disabled";
+        Node::json["MemorySummary"]["TotalSystemMemoryGiB"] = int(0);
+        Node::json["MemorySummary"]["Status"]["State"] = "Disabled";
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-  }
-
- private:
-  OnDemandSystemsProvider provider;
-
-  /**
-   * Functions triggers appropriate requests on DBus
-   */
-  void doGet(crow::Response &res, const crow::Request &req,
-             const std::vector<std::string> &params) override {
-    // Check if there is required param, truly entering this shall be
-    // impossible
-    if (params.size() != 1) {
-      res.result(boost::beast::http::status::internal_server_error);
-      res.end();
-      return;
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
     }
 
-    const std::string &name = params[0];
+  private:
+    OnDemandSystemsProvider provider;
 
-    res.jsonValue = Node::json;
-    res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name;
+    /**
+     * Functions triggers appropriate requests on DBus
+     */
+    void doGet(crow::Response &res, const crow::Request &req,
+               const std::vector<std::string> &params) override
+    {
+        // Check if there is required param, truly entering this shall be
+        // impossible
+        if (params.size() != 1)
+        {
+            res.result(boost::beast::http::status::internal_server_error);
+            res.end();
+            return;
+        }
 
-    auto asyncResp = std::make_shared<SystemAsyncResp>(res);
+        const std::string &name = params[0];
 
-    provider.getLedGroupIdentify(
-        asyncResp, [&](const bool &asserted,
-                       const std::shared_ptr<SystemAsyncResp> &aResp) {
-          if (asserted) {
-            // If led group is asserted, then another call is needed to
-            // get led status
-            provider.getLedIdentify(
-                aResp, [](const std::string &ledStatus,
-                          const std::shared_ptr<SystemAsyncResp> &aResp) {
-                  if (!ledStatus.empty()) {
-                    aResp->res.jsonValue["IndicatorLED"] = ledStatus;
-                  }
-                });
-          } else {
-            aResp->res.jsonValue["IndicatorLED"] = "Off";
-          }
-        });
-    provider.getComputerSystem(asyncResp, name);
-    provider.getHostState(asyncResp);
-  }
+        res.jsonValue = Node::json;
+        res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name;
 
-  void doPatch(crow::Response &res, const crow::Request &req,
-               const std::vector<std::string> &params) override {
-    // Check if there is required param, truly entering this shall be
-    // impossible
-    if (params.size() != 1) {
-      res.result(boost::beast::http::status::internal_server_error);
-      res.end();
-      return;
-    }
-    // Parse JSON request body
-    nlohmann::json patch;
-    if (!json_util::processJsonFromRequest(res, req, patch)) {
-      return;
-    }
-    // Find key with new led value
-    const std::string &name = params[0];
-    const std::string *reqLedState = nullptr;
-    json_util::Result r = json_util::getString(
-        "IndicatorLED", patch, reqLedState,
-        static_cast<int>(json_util::MessageSetting::TYPE_ERROR) |
-            static_cast<int>(json_util::MessageSetting::MISSING),
-        res.jsonValue, std::string("/" + name + "/IndicatorLED"));
-    if ((r != json_util::Result::SUCCESS) || (reqLedState == nullptr)) {
-      res.result(boost::beast::http::status::bad_request);
-      res.end();
-      return;
-    }
-    // Verify key value
-    std::string dbusLedState;
-    for (const auto &p : boost::container::flat_map<const char *, const char *>{
-             {"On", "Lit"}, {"Blink", "Blinking"}, {"Off", "Off"}}) {
-      if (*reqLedState == p.second) {
-        dbusLedState = p.first;
-      }
+        auto asyncResp = std::make_shared<SystemAsyncResp>(res);
+
+        provider.getLedGroupIdentify(
+            asyncResp, [&](const bool &asserted,
+                           const std::shared_ptr<SystemAsyncResp> &aResp) {
+                if (asserted)
+                {
+                    // If led group is asserted, then another call is needed to
+                    // get led status
+                    provider.getLedIdentify(
+                        aResp,
+                        [](const std::string &ledStatus,
+                           const std::shared_ptr<SystemAsyncResp> &aResp) {
+                            if (!ledStatus.empty())
+                            {
+                                aResp->res.jsonValue["IndicatorLED"] =
+                                    ledStatus;
+                            }
+                        });
+                }
+                else
+                {
+                    aResp->res.jsonValue["IndicatorLED"] = "Off";
+                }
+            });
+        provider.getComputerSystem(asyncResp, name);
+        provider.getHostState(asyncResp);
     }
 
-    // Update led status
-    auto asyncResp = std::make_shared<SystemAsyncResp>(res);
-    res.jsonValue = Node::json;
-    res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name;
-
-    provider.getHostState(asyncResp);
-    provider.getComputerSystem(asyncResp, name);
-
-    if (dbusLedState.empty()) {
-      messages::addMessageToJsonRoot(
-          res.jsonValue,
-          messages::propertyValueNotInList(*reqLedState, "IndicatorLED"));
-    } else {
-      // Update led group
-      BMCWEB_LOG_DEBUG << "Update led group.";
-      crow::connections::systemBus->async_method_call(
-          [&, asyncResp{std::move(asyncResp)} ](
-              const boost::system::error_code ec) {
-            if (ec) {
-              BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
-              asyncResp->setErrorStatus();
-              return;
+    void doPatch(crow::Response &res, const crow::Request &req,
+                 const std::vector<std::string> &params) override
+    {
+        // Check if there is required param, truly entering this shall be
+        // impossible
+        if (params.size() != 1)
+        {
+            res.result(boost::beast::http::status::internal_server_error);
+            res.end();
+            return;
+        }
+        // Parse JSON request body
+        nlohmann::json patch;
+        if (!json_util::processJsonFromRequest(res, req, patch))
+        {
+            return;
+        }
+        // Find key with new led value
+        const std::string &name = params[0];
+        const std::string *reqLedState = nullptr;
+        json_util::Result r = json_util::getString(
+            "IndicatorLED", patch, reqLedState,
+            static_cast<int>(json_util::MessageSetting::TYPE_ERROR) |
+                static_cast<int>(json_util::MessageSetting::MISSING),
+            res.jsonValue, std::string("/" + name + "/IndicatorLED"));
+        if ((r != json_util::Result::SUCCESS) || (reqLedState == nullptr))
+        {
+            res.result(boost::beast::http::status::bad_request);
+            res.end();
+            return;
+        }
+        // Verify key value
+        std::string dbusLedState;
+        for (const auto &p :
+             boost::container::flat_map<const char *, const char *>{
+                 {"On", "Lit"}, {"Blink", "Blinking"}, {"Off", "Off"}})
+        {
+            if (*reqLedState == p.second)
+            {
+                dbusLedState = p.first;
             }
-            BMCWEB_LOG_DEBUG << "Led group update done.";
-          },
-          "xyz.openbmc_project.LED.GroupManager",
-          "/xyz/openbmc_project/led/groups/enclosure_identify",
-          "org.freedesktop.DBus.Properties", "Set",
-          "xyz.openbmc_project.Led.Group", "Asserted",
-          sdbusplus::message::variant<bool>(
-              (dbusLedState == "Off" ? false : true)));
-      // Update identify led status
-      BMCWEB_LOG_DEBUG << "Update led SoftwareInventoryCollection.";
-      crow::connections::systemBus->async_method_call(
-          [&, asyncResp{std::move(asyncResp)} ](
-              const boost::system::error_code ec) {
-            if (ec) {
-              BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
-              asyncResp->setErrorStatus();
-              return;
-            }
-            BMCWEB_LOG_DEBUG << "Led state update done.";
-            res.jsonValue["IndicatorLED"] = *reqLedState;
-          },
-          "xyz.openbmc_project.LED.Controller.identify",
-          "/xyz/openbmc_project/led/physical/identify",
-          "org.freedesktop.DBus.Properties", "Set",
-          "xyz.openbmc_project.Led.Physical", "State",
-          sdbusplus::message::variant<std::string>(
-              "xyz.openbmc_project.Led.Physical.Action." + dbusLedState));
+        }
+
+        // Update led status
+        auto asyncResp = std::make_shared<SystemAsyncResp>(res);
+        res.jsonValue = Node::json;
+        res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name;
+
+        provider.getHostState(asyncResp);
+        provider.getComputerSystem(asyncResp, name);
+
+        if (dbusLedState.empty())
+        {
+            messages::addMessageToJsonRoot(
+                res.jsonValue,
+                messages::propertyValueNotInList(*reqLedState, "IndicatorLED"));
+        }
+        else
+        {
+            // Update led group
+            BMCWEB_LOG_DEBUG << "Update led group.";
+            crow::connections::systemBus->async_method_call(
+                [&, asyncResp{std::move(asyncResp)}](
+                    const boost::system::error_code ec) {
+                    if (ec)
+                    {
+                        BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
+                        asyncResp->setErrorStatus();
+                        return;
+                    }
+                    BMCWEB_LOG_DEBUG << "Led group update done.";
+                },
+                "xyz.openbmc_project.LED.GroupManager",
+                "/xyz/openbmc_project/led/groups/enclosure_identify",
+                "org.freedesktop.DBus.Properties", "Set",
+                "xyz.openbmc_project.Led.Group", "Asserted",
+                sdbusplus::message::variant<bool>(
+                    (dbusLedState == "Off" ? false : true)));
+            // Update identify led status
+            BMCWEB_LOG_DEBUG << "Update led SoftwareInventoryCollection.";
+            crow::connections::systemBus->async_method_call(
+                [&, asyncResp{std::move(asyncResp)}](
+                    const boost::system::error_code ec) {
+                    if (ec)
+                    {
+                        BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
+                        asyncResp->setErrorStatus();
+                        return;
+                    }
+                    BMCWEB_LOG_DEBUG << "Led state update done.";
+                    res.jsonValue["IndicatorLED"] = *reqLedState;
+                },
+                "xyz.openbmc_project.LED.Controller.identify",
+                "/xyz/openbmc_project/led/physical/identify",
+                "org.freedesktop.DBus.Properties", "Set",
+                "xyz.openbmc_project.Led.Physical", "State",
+                sdbusplus::message::variant<std::string>(
+                    "xyz.openbmc_project.Led.Physical.Action." + dbusLedState));
+        }
     }
-  }
 };
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/lib/thermal.hpp b/redfish-core/lib/thermal.hpp
index 8fb291b..37b0f43 100644
--- a/redfish-core/lib/thermal.hpp
+++ b/redfish-core/lib/thermal.hpp
@@ -18,44 +18,49 @@
 #include "node.hpp"
 #include "sensors.hpp"
 
-namespace redfish {
+namespace redfish
+{
 
-class Thermal : public Node {
- public:
-  Thermal(CrowApp& app)
-      : Node((app), "/redfish/v1/Chassis/<str>/Thermal/", std::string()) {
-    Node::json["@odata.type"] = "#Thermal.v1_4_0.Thermal";
-    Node::json["@odata.context"] = "/redfish/v1/$metadata#Thermal.Thermal";
-    Node::json["Id"] = "Thermal";
-    Node::json["Name"] = "Thermal";
+class Thermal : public Node
+{
+  public:
+    Thermal(CrowApp& app) :
+        Node((app), "/redfish/v1/Chassis/<str>/Thermal/", std::string())
+    {
+        Node::json["@odata.type"] = "#Thermal.v1_4_0.Thermal";
+        Node::json["@odata.context"] = "/redfish/v1/$metadata#Thermal.Thermal";
+        Node::json["Id"] = "Thermal";
+        Node::json["Name"] = "Thermal";
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-  }
-
- private:
-  void doGet(crow::Response& res, const crow::Request& req,
-             const std::vector<std::string>& params) override {
-    if (params.size() != 1) {
-      res.result(boost::beast::http::status::internal_server_error);
-      res.end();
-      return;
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
     }
-    const std::string& chassisName = params[0];
 
-    res.jsonValue = Node::json;
-    auto asyncResp = std::make_shared<SensorsAsyncResp>(
-        res, chassisName,
-        std::initializer_list<const char*>{
-            "/xyz/openbmc_project/sensors/fan",
-            "/xyz/openbmc_project/sensors/temperature"});
-    getChassisData(asyncResp);
-  }
+  private:
+    void doGet(crow::Response& res, const crow::Request& req,
+               const std::vector<std::string>& params) override
+    {
+        if (params.size() != 1)
+        {
+            res.result(boost::beast::http::status::internal_server_error);
+            res.end();
+            return;
+        }
+        const std::string& chassisName = params[0];
+
+        res.jsonValue = Node::json;
+        auto asyncResp = std::make_shared<SensorsAsyncResp>(
+            res, chassisName,
+            std::initializer_list<const char*>{
+                "/xyz/openbmc_project/sensors/fan",
+                "/xyz/openbmc_project/sensors/temperature"});
+        getChassisData(asyncResp);
+    }
 };
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/lib/update_service.hpp b/redfish-core/lib/update_service.hpp
index 677b6d1..658937d 100644
--- a/redfish-core/lib/update_service.hpp
+++ b/redfish-core/lib/update_service.hpp
@@ -16,381 +16,450 @@
 #pragma once
 
 #include "node.hpp"
+
 #include <boost/container/flat_map.hpp>
 
-namespace redfish {
+namespace redfish
+{
 static std::unique_ptr<sdbusplus::bus::match::match> fwUpdateMatcher;
 
-class UpdateService : public Node {
- public:
-  UpdateService(CrowApp &app) : Node(app, "/redfish/v1/UpdateService/") {
-    Node::json["@odata.type"] = "#UpdateService.v1_2_0.UpdateService";
-    Node::json["@odata.id"] = "/redfish/v1/UpdateService";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata#UpdateService.UpdateService";
-    Node::json["Id"] = "UpdateService";
-    Node::json["Description"] = "Service for Software Update";
-    Node::json["Name"] = "Update Service";
-    Node::json["HttpPushUri"] = "/redfish/v1/UpdateService";
-    // UpdateService cannot be disabled
-    Node::json["ServiceEnabled"] = true;
-    Node::json["FirmwareInventory"] = {
-        {"@odata.id", "/redfish/v1/UpdateService/FirmwareInventory"}};
+class UpdateService : public Node
+{
+  public:
+    UpdateService(CrowApp &app) : Node(app, "/redfish/v1/UpdateService/")
+    {
+        Node::json["@odata.type"] = "#UpdateService.v1_2_0.UpdateService";
+        Node::json["@odata.id"] = "/redfish/v1/UpdateService";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata#UpdateService.UpdateService";
+        Node::json["Id"] = "UpdateService";
+        Node::json["Description"] = "Service for Software Update";
+        Node::json["Name"] = "Update Service";
+        Node::json["HttpPushUri"] = "/redfish/v1/UpdateService";
+        // UpdateService cannot be disabled
+        Node::json["ServiceEnabled"] = true;
+        Node::json["FirmwareInventory"] = {
+            {"@odata.id", "/redfish/v1/UpdateService/FirmwareInventory"}};
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-  }
-
- private:
-  void doGet(crow::Response &res, const crow::Request &req,
-             const std::vector<std::string> &params) override {
-    res.jsonValue = Node::json;
-    res.end();
-  }
-  static void activateImage(const std::string &objPath) {
-    crow::connections::systemBus->async_method_call(
-        [objPath](const boost::system::error_code error_code) {
-          if (error_code) {
-            BMCWEB_LOG_DEBUG << "error_code = " << error_code;
-            BMCWEB_LOG_DEBUG << "error msg = " << error_code.message();
-          }
-        },
-        "xyz.openbmc_project.Software.BMC.Updater", objPath,
-        "org.freedesktop.DBus.Properties", "Set",
-        "xyz.openbmc_project.Software.Activation", "RequestedActivation",
-        sdbusplus::message::variant<std::string>(
-            "xyz.openbmc_project.Software.Activation.RequestedActivations."
-            "Active"));
-  }
-  void doPost(crow::Response &res, const crow::Request &req,
-              const std::vector<std::string> &params) override {
-    BMCWEB_LOG_DEBUG << "doPost...";
-
-    // Only allow one FW update at a time
-    if (fwUpdateMatcher != nullptr) {
-      res.addHeader("Retry-After", "30");
-      res.result(boost::beast::http::status::service_unavailable);
-      res.jsonValue = messages::serviceTemporarilyUnavailable("3");
-      res.end();
-      return;
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
     }
-    // Make this const static so it survives outside this method
-    static boost::asio::deadline_timer timeout(*req.ioService,
-                                               boost::posix_time::seconds(5));
 
-    timeout.expires_from_now(boost::posix_time::seconds(5));
-
-    timeout.async_wait([&res](const boost::system::error_code &ec) {
-      fwUpdateMatcher = nullptr;
-      if (ec == boost::asio::error::operation_aborted) {
-        // expected, we were canceled before the timer completed.
-        return;
-      }
-      BMCWEB_LOG_ERROR << "Timed out waiting for firmware object being created";
-      BMCWEB_LOG_ERROR << "FW image may has already been uploaded to server";
-      if (ec) {
-        BMCWEB_LOG_ERROR << "Async_wait failed" << ec;
-        return;
-      }
-
-      res.result(boost::beast::http::status::internal_server_error);
-      res.jsonValue = redfish::messages::internalError();
-      res.end();
-    });
-
-    auto callback = [&res](sdbusplus::message::message &m) {
-      BMCWEB_LOG_DEBUG << "Match fired";
-      bool flag = false;
-
-      if (m.is_method_error()) {
-        BMCWEB_LOG_DEBUG << "Dbus method error!!!";
+  private:
+    void doGet(crow::Response &res, const crow::Request &req,
+               const std::vector<std::string> &params) override
+    {
+        res.jsonValue = Node::json;
         res.end();
-        return;
-      }
-      std::vector<std::pair<
-          std::string,
-          std::vector<std::pair<std::string,
-                                sdbusplus::message::variant<std::string>>>>>
-          interfaces_properties;
+    }
+    static void activateImage(const std::string &objPath)
+    {
+        crow::connections::systemBus->async_method_call(
+            [objPath](const boost::system::error_code error_code) {
+                if (error_code)
+                {
+                    BMCWEB_LOG_DEBUG << "error_code = " << error_code;
+                    BMCWEB_LOG_DEBUG << "error msg = " << error_code.message();
+                }
+            },
+            "xyz.openbmc_project.Software.BMC.Updater", objPath,
+            "org.freedesktop.DBus.Properties", "Set",
+            "xyz.openbmc_project.Software.Activation", "RequestedActivation",
+            sdbusplus::message::variant<std::string>(
+                "xyz.openbmc_project.Software.Activation.RequestedActivations."
+                "Active"));
+    }
+    void doPost(crow::Response &res, const crow::Request &req,
+                const std::vector<std::string> &params) override
+    {
+        BMCWEB_LOG_DEBUG << "doPost...";
 
-      sdbusplus::message::object_path objPath;
-
-      m.read(objPath, interfaces_properties);  // Read in the object path
-                                               // that was just created
-      // std::string str_objpath = objPath.str;  // keep a copy for
-      // constructing response message
-      BMCWEB_LOG_DEBUG << "obj path = " << objPath.str;  // str_objpath;
-      for (auto &interface : interfaces_properties) {
-        BMCWEB_LOG_DEBUG << "interface = " << interface.first;
-
-        if (interface.first == "xyz.openbmc_project.Software.Activation") {
-          // cancel timer only when xyz.openbmc_project.Software.Activation
-          // interface is added
-          boost::system::error_code ec;
-          timeout.cancel(ec);
-          if (ec) {
-            BMCWEB_LOG_ERROR << "error canceling timer " << ec;
-          }
-          UpdateService::activateImage(objPath.str);  // str_objpath);
-          res.jsonValue = redfish::messages::success();
-          BMCWEB_LOG_DEBUG << "ending response";
-          res.end();
-          fwUpdateMatcher = nullptr;
-        }
-      }
-    };
-
-    fwUpdateMatcher = std::make_unique<sdbusplus::bus::match::match>(
-        *crow::connections::systemBus,
-        "interface='org.freedesktop.DBus.ObjectManager',type='signal',"
-        "member='InterfacesAdded',path='/xyz/openbmc_project/software'",
-        callback);
-
-    std::string filepath(
-        "/tmp/images/" +
-        boost::uuids::to_string(boost::uuids::random_generator()()));
-    BMCWEB_LOG_DEBUG << "Writing file to " << filepath;
-    std::ofstream out(filepath, std::ofstream::out | std::ofstream::binary |
-                                    std::ofstream::trunc);
-    out << req.body;
-    out.close();
-    BMCWEB_LOG_DEBUG << "file upload complete!!";
-  }
-};
-
-class SoftwareInventoryCollection : public Node {
- public:
-  template <typename CrowApp>
-  SoftwareInventoryCollection(CrowApp &app)
-      : Node(app, "/redfish/v1/UpdateService/FirmwareInventory/") {
-    Node::json["@odata.type"] =
-        "#SoftwareInventoryCollection.SoftwareInventoryCollection";
-    Node::json["@odata.id"] = "/redfish/v1/UpdateService/FirmwareInventory";
-    Node::json["@odata.context"] =
-        "/redfish/v1/"
-        "$metadata#SoftwareInventoryCollection.SoftwareInventoryCollection";
-    Node::json["Name"] = "Software Inventory Collection";
-
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-  }
-
- private:
-  void doGet(crow::Response &res, const crow::Request &req,
-             const std::vector<std::string> &params) override {
-    std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
-    res.jsonValue = Node::json;
-
-    crow::connections::systemBus->async_method_call(
-        [asyncResp](
-            const boost::system::error_code ec,
-            const std::vector<std::pair<
-                std::string,
-                std::vector<std::pair<std::string, std::vector<std::string>>>>>
-                &subtree) {
-          if (ec) {
-            asyncResp->res.result(
-                boost::beast::http::status::internal_server_error);
+        // Only allow one FW update at a time
+        if (fwUpdateMatcher != nullptr)
+        {
+            res.addHeader("Retry-After", "30");
+            res.result(boost::beast::http::status::service_unavailable);
+            res.jsonValue = messages::serviceTemporarilyUnavailable("3");
+            res.end();
             return;
-          }
-          asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
-          asyncResp->res.jsonValue["Members@odata.count"] = 0;
+        }
+        // Make this const static so it survives outside this method
+        static boost::asio::deadline_timer timeout(
+            *req.ioService, boost::posix_time::seconds(5));
 
-          for (auto &obj : subtree) {
-            const std::vector<std::pair<std::string, std::vector<std::string>>>
-                &connections = obj.second;
+        timeout.expires_from_now(boost::posix_time::seconds(5));
 
-            for (auto &conn : connections) {
-              const std::string &connectionName = conn.first;
-              BMCWEB_LOG_DEBUG << "connectionName = " << connectionName;
-              BMCWEB_LOG_DEBUG << "obj.first = " << obj.first;
-
-              crow::connections::systemBus->async_method_call(
-                  [asyncResp](const boost::system::error_code error_code,
-                              const VariantType &activation) {
-                    BMCWEB_LOG_DEBUG << "safe returned in lambda function";
-                    if (error_code) {
-                      asyncResp->res.result(
-                          boost::beast::http::status::internal_server_error);
-                      return;
-                    }
-
-                    const std::string *sw_inv_purpose =
-                        mapbox::getPtr<const std::string>(activation);
-                    if (sw_inv_purpose == nullptr) {
-                      asyncResp->res.result(
-                          boost::beast::http::status::internal_server_error);
-                      return;
-                    }
-                    std::size_t last_pos = sw_inv_purpose->rfind(".");
-                    if (last_pos == std::string::npos) {
-                      asyncResp->res.result(
-                          boost::beast::http::status::internal_server_error);
-                      return;
-                    }
-                    nlohmann::json &members =
-                        asyncResp->res.jsonValue["Members"];
-                    members.push_back(
-                        {{"@odata.id",
-                          "/redfish/v1/UpdateService/FirmwareInventory/" +
-                              sw_inv_purpose->substr(last_pos + 1)}});
-                    asyncResp->res.jsonValue["Members@odata.count"] =
-                        members.size();
-                  },
-                  connectionName, obj.first, "org.freedesktop.DBus.Properties",
-                  "Get", "xyz.openbmc_project.Software.Activation",
-                  "Activation");
+        timeout.async_wait([&res](const boost::system::error_code &ec) {
+            fwUpdateMatcher = nullptr;
+            if (ec == boost::asio::error::operation_aborted)
+            {
+                // expected, we were canceled before the timer completed.
+                return;
             }
-          }
-        },
-        "xyz.openbmc_project.ObjectMapper",
-        "/xyz/openbmc_project/object_mapper",
-        "xyz.openbmc_project.ObjectMapper", "GetSubTree",
-        "/xyz/openbmc_project/software", int32_t(1),
-        std::array<const char *, 1>{"xyz.openbmc_project.Software.Version"});
-  }
+            BMCWEB_LOG_ERROR
+                << "Timed out waiting for firmware object being created";
+            BMCWEB_LOG_ERROR
+                << "FW image may has already been uploaded to server";
+            if (ec)
+            {
+                BMCWEB_LOG_ERROR << "Async_wait failed" << ec;
+                return;
+            }
+
+            res.result(boost::beast::http::status::internal_server_error);
+            res.jsonValue = redfish::messages::internalError();
+            res.end();
+        });
+
+        auto callback = [&res](sdbusplus::message::message &m) {
+            BMCWEB_LOG_DEBUG << "Match fired";
+            bool flag = false;
+
+            if (m.is_method_error())
+            {
+                BMCWEB_LOG_DEBUG << "Dbus method error!!!";
+                res.end();
+                return;
+            }
+            std::vector<std::pair<
+                std::string,
+                std::vector<std::pair<
+                    std::string, sdbusplus::message::variant<std::string>>>>>
+                interfaces_properties;
+
+            sdbusplus::message::object_path objPath;
+
+            m.read(objPath, interfaces_properties); // Read in the object path
+                                                    // that was just created
+            // std::string str_objpath = objPath.str;  // keep a copy for
+            // constructing response message
+            BMCWEB_LOG_DEBUG << "obj path = " << objPath.str; // str_objpath;
+            for (auto &interface : interfaces_properties)
+            {
+                BMCWEB_LOG_DEBUG << "interface = " << interface.first;
+
+                if (interface.first ==
+                    "xyz.openbmc_project.Software.Activation")
+                {
+                    // cancel timer only when
+                    // xyz.openbmc_project.Software.Activation interface is
+                    // added
+                    boost::system::error_code ec;
+                    timeout.cancel(ec);
+                    if (ec)
+                    {
+                        BMCWEB_LOG_ERROR << "error canceling timer " << ec;
+                    }
+                    UpdateService::activateImage(objPath.str); // str_objpath);
+                    res.jsonValue = redfish::messages::success();
+                    BMCWEB_LOG_DEBUG << "ending response";
+                    res.end();
+                    fwUpdateMatcher = nullptr;
+                }
+            }
+        };
+
+        fwUpdateMatcher = std::make_unique<sdbusplus::bus::match::match>(
+            *crow::connections::systemBus,
+            "interface='org.freedesktop.DBus.ObjectManager',type='signal',"
+            "member='InterfacesAdded',path='/xyz/openbmc_project/software'",
+            callback);
+
+        std::string filepath(
+            "/tmp/images/" +
+            boost::uuids::to_string(boost::uuids::random_generator()()));
+        BMCWEB_LOG_DEBUG << "Writing file to " << filepath;
+        std::ofstream out(filepath, std::ofstream::out | std::ofstream::binary |
+                                        std::ofstream::trunc);
+        out << req.body;
+        out.close();
+        BMCWEB_LOG_DEBUG << "file upload complete!!";
+    }
 };
 
-class SoftwareInventory : public Node {
- public:
-  template <typename CrowApp>
-  SoftwareInventory(CrowApp &app)
-      : Node(app, "/redfish/v1/UpdateService/FirmwareInventory/<str>/",
-             std::string()) {
-    Node::json["@odata.type"] = "#SoftwareInventory.v1_1_0.SoftwareInventory";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata#SoftwareInventory.SoftwareInventory";
-    Node::json["Name"] = "Software Inventory";
-    Node::json["Updateable"] = false;
-    Node::json["Status"]["Health"] = "OK";
-    Node::json["Status"]["HealthRollup"] = "OK";
-    Node::json["Status"]["State"] = "Enabled";
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-  }
+class SoftwareInventoryCollection : public Node
+{
+  public:
+    template <typename CrowApp>
+    SoftwareInventoryCollection(CrowApp &app) :
+        Node(app, "/redfish/v1/UpdateService/FirmwareInventory/")
+    {
+        Node::json["@odata.type"] =
+            "#SoftwareInventoryCollection.SoftwareInventoryCollection";
+        Node::json["@odata.id"] = "/redfish/v1/UpdateService/FirmwareInventory";
+        Node::json["@odata.context"] =
+            "/redfish/v1/"
+            "$metadata#SoftwareInventoryCollection.SoftwareInventoryCollection";
+        Node::json["Name"] = "Software Inventory Collection";
 
- private:
-  void doGet(crow::Response &res, const crow::Request &req,
-             const std::vector<std::string> &params) override {
-    std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
-    res.jsonValue = Node::json;
-
-    if (params.size() != 1) {
-      res.result(boost::beast::http::status::internal_server_error);
-      res.jsonValue = messages::internalError();
-      res.end();
-      return;
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
     }
 
-    std::shared_ptr<std::string> sw_id =
-        std::make_shared<std::string>(params[0]);
+  private:
+    void doGet(crow::Response &res, const crow::Request &req,
+               const std::vector<std::string> &params) override
+    {
+        std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
+        res.jsonValue = Node::json;
 
-    res.jsonValue["@odata.id"] =
-        "/redfish/v1/UpdateService/FirmwareInventory/" + *sw_id;
-
-    crow::connections::systemBus->async_method_call(
-        [asyncResp, sw_id](
-            const boost::system::error_code ec,
-            const std::vector<std::pair<
-                std::string,
-                std::vector<std::pair<std::string, std::vector<std::string>>>>>
-                &subtree) {
-          BMCWEB_LOG_DEBUG << "doGet callback...";
-          if (ec) {
-            asyncResp->res.result(
-                boost::beast::http::status::internal_server_error);
-            return;
-          }
-
-          for (const std::pair<std::string,
-                               std::vector<std::pair<std::string,
-                                                     std::vector<std::string>>>>
-                   &obj : subtree) {
-            if (boost::ends_with(obj.first, *sw_id) != true) {
-              continue;
-            }
-
-            if (obj.second.size() <= 1) {
-              continue;
-            }
-
-            crow::connections::systemBus->async_method_call(
-                [asyncResp, sw_id](
-                    const boost::system::error_code error_code,
-                    const boost::container::flat_map<std::string, VariantType>
-                        &propertiesList) {
-                  if (error_code) {
+        crow::connections::systemBus->async_method_call(
+            [asyncResp](
+                const boost::system::error_code ec,
+                const std::vector<std::pair<
+                    std::string, std::vector<std::pair<
+                                     std::string, std::vector<std::string>>>>>
+                    &subtree) {
+                if (ec)
+                {
                     asyncResp->res.result(
                         boost::beast::http::status::internal_server_error);
                     return;
-                  }
-                  boost::container::flat_map<std::string,
-                                             VariantType>::const_iterator it =
-                      propertiesList.find("Purpose");
-                  if (it == propertiesList.end()) {
-                    BMCWEB_LOG_DEBUG << "Can't find property \"Purpose\"!";
-                    asyncResp->res.result(
-                        boost::beast::http::status::internal_server_error);
-                    return;
-                  }
-                  const std::string *sw_inv_purpose =
-                      mapbox::getPtr<const std::string>(it->second);
-                  if (sw_inv_purpose == nullptr) {
-                    BMCWEB_LOG_DEBUG << "wrong types for property\"Purpose\"!";
-                    asyncResp->res.result(
-                        boost::beast::http::status::internal_server_error);
-                    return;
-                  }
+                }
+                asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
+                asyncResp->res.jsonValue["Members@odata.count"] = 0;
 
-                  BMCWEB_LOG_DEBUG << "sw_inv_purpose = " << *sw_inv_purpose;
-                  if (boost::ends_with(*sw_inv_purpose, "." + *sw_id)) {
-                    it = propertiesList.find("Version");
-                    if (it == propertiesList.end()) {
-                      BMCWEB_LOG_DEBUG << "Can't find property \"Version\"!";
-                      asyncResp->res.result(
-                          boost::beast::http::status::internal_server_error);
-                      return;
+                for (auto &obj : subtree)
+                {
+                    const std::vector<
+                        std::pair<std::string, std::vector<std::string>>>
+                        &connections = obj.second;
+
+                    for (auto &conn : connections)
+                    {
+                        const std::string &connectionName = conn.first;
+                        BMCWEB_LOG_DEBUG << "connectionName = "
+                                         << connectionName;
+                        BMCWEB_LOG_DEBUG << "obj.first = " << obj.first;
+
+                        crow::connections::systemBus->async_method_call(
+                            [asyncResp](
+                                const boost::system::error_code error_code,
+                                const VariantType &activation) {
+                                BMCWEB_LOG_DEBUG
+                                    << "safe returned in lambda function";
+                                if (error_code)
+                                {
+                                    asyncResp->res.result(
+                                        boost::beast::http::status::
+                                            internal_server_error);
+                                    return;
+                                }
+
+                                const std::string *sw_inv_purpose =
+                                    mapbox::getPtr<const std::string>(
+                                        activation);
+                                if (sw_inv_purpose == nullptr)
+                                {
+                                    asyncResp->res.result(
+                                        boost::beast::http::status::
+                                            internal_server_error);
+                                    return;
+                                }
+                                std::size_t last_pos =
+                                    sw_inv_purpose->rfind(".");
+                                if (last_pos == std::string::npos)
+                                {
+                                    asyncResp->res.result(
+                                        boost::beast::http::status::
+                                            internal_server_error);
+                                    return;
+                                }
+                                nlohmann::json &members =
+                                    asyncResp->res.jsonValue["Members"];
+                                members.push_back(
+                                    {{"@odata.id", "/redfish/v1/UpdateService/"
+                                                   "FirmwareInventory/" +
+                                                       sw_inv_purpose->substr(
+                                                           last_pos + 1)}});
+                                asyncResp->res
+                                    .jsonValue["Members@odata.count"] =
+                                    members.size();
+                            },
+                            connectionName, obj.first,
+                            "org.freedesktop.DBus.Properties", "Get",
+                            "xyz.openbmc_project.Software.Activation",
+                            "Activation");
                     }
-
-                    const std::string *version =
-                        mapbox::getPtr<const std::string>(it->second);
-
-                    if (version != nullptr) {
-                      BMCWEB_LOG_DEBUG << "Can't find property \"Version\"!";
-                      asyncResp->res.result(
-                          boost::beast::http::status::internal_server_error);
-                      return;
-                    }
-                    asyncResp->res.jsonValue["Version"] = *version;
-                    asyncResp->res.jsonValue["Id"] = *sw_id;
-                  }
-                },
-                obj.second[0].first, obj.first,
-                "org.freedesktop.DBus.Properties", "GetAll",
-                "xyz.openbmc_project.Software.Version");
-          }
-        },
-        "xyz.openbmc_project.ObjectMapper",
-        "/xyz/openbmc_project/object_mapper",
-        "xyz.openbmc_project.ObjectMapper", "GetSubTree",
-        "/xyz/openbmc_project/software", int32_t(1),
-        std::array<const char *, 1>{"xyz.openbmc_project.Software.Version"});
-  }
+                }
+            },
+            "xyz.openbmc_project.ObjectMapper",
+            "/xyz/openbmc_project/object_mapper",
+            "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+            "/xyz/openbmc_project/software", int32_t(1),
+            std::array<const char *, 1>{
+                "xyz.openbmc_project.Software.Version"});
+    }
 };
 
-}  // namespace redfish
+class SoftwareInventory : public Node
+{
+  public:
+    template <typename CrowApp>
+    SoftwareInventory(CrowApp &app) :
+        Node(app, "/redfish/v1/UpdateService/FirmwareInventory/<str>/",
+             std::string())
+    {
+        Node::json["@odata.type"] =
+            "#SoftwareInventory.v1_1_0.SoftwareInventory";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata#SoftwareInventory.SoftwareInventory";
+        Node::json["Name"] = "Software Inventory";
+        Node::json["Updateable"] = false;
+        Node::json["Status"]["Health"] = "OK";
+        Node::json["Status"]["HealthRollup"] = "OK";
+        Node::json["Status"]["State"] = "Enabled";
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
+    }
+
+  private:
+    void doGet(crow::Response &res, const crow::Request &req,
+               const std::vector<std::string> &params) override
+    {
+        std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
+        res.jsonValue = Node::json;
+
+        if (params.size() != 1)
+        {
+            res.result(boost::beast::http::status::internal_server_error);
+            res.jsonValue = messages::internalError();
+            res.end();
+            return;
+        }
+
+        std::shared_ptr<std::string> sw_id =
+            std::make_shared<std::string>(params[0]);
+
+        res.jsonValue["@odata.id"] =
+            "/redfish/v1/UpdateService/FirmwareInventory/" + *sw_id;
+
+        crow::connections::systemBus->async_method_call(
+            [asyncResp, sw_id](
+                const boost::system::error_code ec,
+                const std::vector<std::pair<
+                    std::string, std::vector<std::pair<
+                                     std::string, std::vector<std::string>>>>>
+                    &subtree) {
+                BMCWEB_LOG_DEBUG << "doGet callback...";
+                if (ec)
+                {
+                    asyncResp->res.result(
+                        boost::beast::http::status::internal_server_error);
+                    return;
+                }
+
+                for (const std::pair<
+                         std::string,
+                         std::vector<
+                             std::pair<std::string, std::vector<std::string>>>>
+                         &obj : subtree)
+                {
+                    if (boost::ends_with(obj.first, *sw_id) != true)
+                    {
+                        continue;
+                    }
+
+                    if (obj.second.size() <= 1)
+                    {
+                        continue;
+                    }
+
+                    crow::connections::systemBus->async_method_call(
+                        [asyncResp,
+                         sw_id](const boost::system::error_code error_code,
+                                const boost::container::flat_map<
+                                    std::string, VariantType> &propertiesList) {
+                            if (error_code)
+                            {
+                                asyncResp->res.result(
+                                    boost::beast::http::status::
+                                        internal_server_error);
+                                return;
+                            }
+                            boost::container::flat_map<
+                                std::string, VariantType>::const_iterator it =
+                                propertiesList.find("Purpose");
+                            if (it == propertiesList.end())
+                            {
+                                BMCWEB_LOG_DEBUG
+                                    << "Can't find property \"Purpose\"!";
+                                asyncResp->res.result(
+                                    boost::beast::http::status::
+                                        internal_server_error);
+                                return;
+                            }
+                            const std::string *sw_inv_purpose =
+                                mapbox::getPtr<const std::string>(it->second);
+                            if (sw_inv_purpose == nullptr)
+                            {
+                                BMCWEB_LOG_DEBUG
+                                    << "wrong types for property\"Purpose\"!";
+                                asyncResp->res.result(
+                                    boost::beast::http::status::
+                                        internal_server_error);
+                                return;
+                            }
+
+                            BMCWEB_LOG_DEBUG << "sw_inv_purpose = "
+                                             << *sw_inv_purpose;
+                            if (boost::ends_with(*sw_inv_purpose, "." + *sw_id))
+                            {
+                                it = propertiesList.find("Version");
+                                if (it == propertiesList.end())
+                                {
+                                    BMCWEB_LOG_DEBUG
+                                        << "Can't find property \"Version\"!";
+                                    asyncResp->res.result(
+                                        boost::beast::http::status::
+                                            internal_server_error);
+                                    return;
+                                }
+
+                                const std::string *version =
+                                    mapbox::getPtr<const std::string>(
+                                        it->second);
+
+                                if (version != nullptr)
+                                {
+                                    BMCWEB_LOG_DEBUG
+                                        << "Can't find property \"Version\"!";
+                                    asyncResp->res.result(
+                                        boost::beast::http::status::
+                                            internal_server_error);
+                                    return;
+                                }
+                                asyncResp->res.jsonValue["Version"] = *version;
+                                asyncResp->res.jsonValue["Id"] = *sw_id;
+                            }
+                        },
+                        obj.second[0].first, obj.first,
+                        "org.freedesktop.DBus.Properties", "GetAll",
+                        "xyz.openbmc_project.Software.Version");
+                }
+            },
+            "xyz.openbmc_project.ObjectMapper",
+            "/xyz/openbmc_project/object_mapper",
+            "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+            "/xyz/openbmc_project/software", int32_t(1),
+            std::array<const char *, 1>{
+                "xyz.openbmc_project.Software.Version"});
+    }
+};
+
+} // namespace redfish
diff --git a/redfish-core/src/error_messages.cpp b/redfish-core/src/error_messages.cpp
index 4773e3d..a807762 100644
--- a/redfish-core/src/error_messages.cpp
+++ b/redfish-core/src/error_messages.cpp
@@ -13,78 +13,93 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 */
-#include <error_messages.hpp>
 #include <crow/logging.h>
 
-namespace redfish {
+#include <error_messages.hpp>
 
-namespace messages {
+namespace redfish
+{
+
+namespace messages
+{
 
 void addMessageToErrorJson(nlohmann::json& target,
-                           const nlohmann::json& message) {
-  auto& error = target["error"];
+                           const nlohmann::json& message)
+{
+    auto& error = target["error"];
 
-  // If this is the first error message, fill in the information from the first
-  // error message to the top level struct
-  if (!error.is_object()) {
-    auto message_id_iterator = message.find("MessageId");
-    if (message_id_iterator == message.end()) {
-      BMCWEB_LOG_CRITICAL << "Attempt to add error message without MessageId";
-      return;
-    }
+    // If this is the first error message, fill in the information from the
+    // first error message to the top level struct
+    if (!error.is_object())
+    {
+        auto message_id_iterator = message.find("MessageId");
+        if (message_id_iterator == message.end())
+        {
+            BMCWEB_LOG_CRITICAL
+                << "Attempt to add error message without MessageId";
+            return;
+        }
 
-    auto message_field_iterator = message.find("Message");
-    if (message_field_iterator == message.end()) {
-      BMCWEB_LOG_CRITICAL << "Attempt to add error message without Message";
-      return;
-    }
-    // clang-format off
+        auto message_field_iterator = message.find("Message");
+        if (message_field_iterator == message.end())
+        {
+            BMCWEB_LOG_CRITICAL
+                << "Attempt to add error message without Message";
+            return;
+        }
+        // clang-format off
     error = {
         {"code", *message_id_iterator},
         {"message", *message_field_iterator}
     };
-    // clang-format on
-  } else {
-    // More than 1 error occurred, so the message has to be generic
-    error["code"] = std::string(messageVersionPrefix) + "GeneralError";
-    error["message"] =
-        "A general error has occurred. See ExtendedInfo for more"
-        "information.";
-  }
+        // clang-format on
+    }
+    else
+    {
+        // More than 1 error occurred, so the message has to be generic
+        error["code"] = std::string(messageVersionPrefix) + "GeneralError";
+        error["message"] =
+            "A general error has occurred. See ExtendedInfo for more"
+            "information.";
+    }
 
-  // This check could technically be done in in the default construction
-  // branch above, but because we need the pointer to the extended info field
-  // anyway, it's more efficient to do it here.
-  auto& extended_info = error[messages::messageAnnotation];
-  if (!extended_info.is_array()) {
-    extended_info = nlohmann::json::array();
-  }
+    // This check could technically be done in in the default construction
+    // branch above, but because we need the pointer to the extended info field
+    // anyway, it's more efficient to do it here.
+    auto& extended_info = error[messages::messageAnnotation];
+    if (!extended_info.is_array())
+    {
+        extended_info = nlohmann::json::array();
+    }
 
-  extended_info.push_back(message);
+    extended_info.push_back(message);
 }
 
-void addMessageToJsonRoot(nlohmann::json& target,
-                          const nlohmann::json& message) {
-  if (!target[messages::messageAnnotation].is_array()) {
-    // Force object to be an array
-    target[messages::messageAnnotation] = nlohmann::json::array();
-  }
+void addMessageToJsonRoot(nlohmann::json& target, const nlohmann::json& message)
+{
+    if (!target[messages::messageAnnotation].is_array())
+    {
+        // Force object to be an array
+        target[messages::messageAnnotation] = nlohmann::json::array();
+    }
 
-  target[messages::messageAnnotation].push_back(message);
+    target[messages::messageAnnotation].push_back(message);
 }
 
 void addMessageToJson(nlohmann::json& target, const nlohmann::json& message,
-                      const std::string& fieldPath) {
-  nlohmann::json_pointer<nlohmann::json> extendedInfo(
-      fieldPath + messages::messageAnnotation);
+                      const std::string& fieldPath)
+{
+    nlohmann::json_pointer<nlohmann::json> extendedInfo(
+        fieldPath + messages::messageAnnotation);
 
-  if (!target[extendedInfo].is_array()) {
-    // Force object to be an array
-    target[extendedInfo] = nlohmann::json::array();
-  }
+    if (!target[extendedInfo].is_array())
+    {
+        // Force object to be an array
+        target[extendedInfo] = nlohmann::json::array();
+    }
 
-  // Object exists and it is an array so we can just push in the message
-  target[extendedInfo].push_back(message);
+    // Object exists and it is an array so we can just push in the message
+    target[extendedInfo].push_back(message);
 }
 
 /*********************************
@@ -98,17 +113,18 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json resourceInUse() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ResourceInUse"},
-      {"Message",
-       "The change to the requested resource failed because the resource is in "
-       "use or in transition."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Remove the condition and resubmit the request if the operation "
-       "failed."}};
+nlohmann::json resourceInUse()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ResourceInUse"},
+        {"Message", "The change to the requested resource failed because the "
+                    "resource is in "
+                    "use or in transition."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Remove the condition and resubmit the request if the operation "
+         "failed."}};
 }
 
 /**
@@ -118,16 +134,17 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json malformedJSON() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.MalformedJSON"},
-      {"Message",
-       "The request body submitted was malformed JSON and could not be parsed "
-       "by the receiving service."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Ensure that the request body is valid JSON and resubmit the request."}};
+nlohmann::json malformedJSON()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.MalformedJSON"},
+        {"Message", "The request body submitted was malformed JSON and could "
+                    "not be parsed "
+                    "by the receiving service."},
+        {"Severity", "Critical"},
+        {"Resolution", "Ensure that the request body is valid JSON and "
+                       "resubmit the request."}};
 }
 
 /**
@@ -137,15 +154,16 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json resourceMissingAtURI(const std::string& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ResourceMissingAtURI"},
-      {"Message", "The resource at the URI " + arg1 + " was not found."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Place a valid resource at the URI or correct the URI and resubmit the "
-       "request."}};
+nlohmann::json resourceMissingAtURI(const std::string& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ResourceMissingAtURI"},
+        {"Message", "The resource at the URI " + arg1 + " was not found."},
+        {"Severity", "Critical"},
+        {"Resolution", "Place a valid resource at the URI or correct the URI "
+                       "and resubmit the "
+                       "request."}};
 }
 
 /**
@@ -157,17 +175,19 @@
  */
 nlohmann::json actionParameterValueFormatError(const std::string& arg1,
                                                const std::string& arg2,
-                                               const std::string& arg3) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ActionParameterValueFormatError"},
-      {"Message",
-       "The value " + arg1 + " for the parameter " + arg2 + " in the action " +
-           arg3 + " is of a different format than the parameter can accept."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Correct the value for the parameter in the request body and resubmit "
-       "the request if the operation failed."}};
+                                               const std::string& arg3)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ActionParameterValueFormatError"},
+        {"Message",
+         "The value " + arg1 + " for the parameter " + arg2 +
+             " in the action " + arg3 +
+             " is of a different format than the parameter can accept."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Correct the value for the parameter in the request body and resubmit "
+         "the request if the operation failed."}};
 }
 
 /**
@@ -177,17 +197,18 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json internalError() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.InternalError"},
-      {"Message",
-       "The request failed due to an internal service error.  The service is "
-       "still operational."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Resubmit the request.  If the problem persists, consider resetting the "
-       "service."}};
+nlohmann::json internalError()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.InternalError"},
+        {"Message",
+         "The request failed due to an internal service error.  The service is "
+         "still operational."},
+        {"Severity", "Critical"},
+        {"Resolution", "Resubmit the request.  If the problem persists, "
+                       "consider resetting the "
+                       "service."}};
 }
 
 /**
@@ -197,16 +218,17 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json unrecognizedRequestBody() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.UnrecognizedRequestBody"},
-      {"Message",
-       "The service detected a malformed request body that it was unable to "
-       "interpret."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Correct the request body and resubmit the request if it failed."}};
+nlohmann::json unrecognizedRequestBody()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.UnrecognizedRequestBody"},
+        {"Message",
+         "The service detected a malformed request body that it was unable to "
+         "interpret."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Correct the request body and resubmit the request if it failed."}};
 }
 
 /**
@@ -217,17 +239,18 @@
  * @endinternal
  */
 nlohmann::json resourceAtUriUnauthorized(const std::string& arg1,
-                                         const std::string& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ResourceAtUriUnauthorized"},
-      {"Message", "While accessing the resource at " + arg1 +
-                      ", the service received an authorization error " + arg2 +
-                      "."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Ensure that the appropriate access is provided for the service in "
-       "order for it to access the URI."}};
+                                         const std::string& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ResourceAtUriUnauthorized"},
+        {"Message", "While accessing the resource at " + arg1 +
+                        ", the service received an authorization error " +
+                        arg2 + "."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Ensure that the appropriate access is provided for the service in "
+         "order for it to access the URI."}};
 }
 
 /**
@@ -238,17 +261,18 @@
  * @endinternal
  */
 nlohmann::json actionParameterUnknown(const std::string& arg1,
-                                      const std::string& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ActionParameterUnknown"},
-      {"Message", "The action " + arg1 +
-                      " was submitted with the invalid parameter " + arg2 +
-                      "."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Correct the invalid parameter and resubmit the request if the "
-       "operation failed."}};
+                                      const std::string& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ActionParameterUnknown"},
+        {"Message", "The action " + arg1 +
+                        " was submitted with the invalid parameter " + arg2 +
+                        "."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Correct the invalid parameter and resubmit the request if the "
+         "operation failed."}};
 }
 
 /**
@@ -258,15 +282,16 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json resourceCannotBeDeleted() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ResourceCannotBeDeleted"},
-      {"Message",
-       "The delete request failed because the resource requested cannot be "
-       "deleted."},
-      {"Severity", "Critical"},
-      {"Resolution", "Do not attempt to delete a non-deletable resource."}};
+nlohmann::json resourceCannotBeDeleted()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ResourceCannotBeDeleted"},
+        {"Message",
+         "The delete request failed because the resource requested cannot be "
+         "deleted."},
+        {"Severity", "Critical"},
+        {"Resolution", "Do not attempt to delete a non-deletable resource."}};
 }
 
 /**
@@ -276,15 +301,16 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json propertyDuplicate(const std::string& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.PropertyDuplicate"},
-      {"Message", "The property " + arg1 + " was duplicated in the request."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Remove the duplicate property from the request body and resubmit the "
-       "request if the operation failed."}};
+nlohmann::json propertyDuplicate(const std::string& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.PropertyDuplicate"},
+        {"Message", "The property " + arg1 + " was duplicated in the request."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Remove the duplicate property from the request body and resubmit the "
+         "request if the operation failed."}};
 }
 
 /**
@@ -294,15 +320,16 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json serviceTemporarilyUnavailable(const std::string& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ServiceTemporarilyUnavailable"},
-      {"Message", "The service is temporarily unavailable.  Retry in " + arg1 +
-                      " seconds."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Wait for the indicated retry duration and retry the operation."}};
+nlohmann::json serviceTemporarilyUnavailable(const std::string& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ServiceTemporarilyUnavailable"},
+        {"Message", "The service is temporarily unavailable.  Retry in " +
+                        arg1 + " seconds."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Wait for the indicated retry duration and retry the operation."}};
 }
 
 /**
@@ -314,17 +341,18 @@
  */
 nlohmann::json resourceAlreadyExists(const std::string& arg1,
                                      const std::string& arg2,
-                                     const std::string& arg3) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ResourceAlreadyExists"},
-      {"Message", "The requested resource of type " + arg1 +
-                      " with the property " + arg2 + " with the value " + arg3 +
-                      " already exists."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Do not repeat the create operation as the resource has already been "
-       "created."}};
+                                     const std::string& arg3)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ResourceAlreadyExists"},
+        {"Message", "The requested resource of type " + arg1 +
+                        " with the property " + arg2 + " with the value " +
+                        arg3 + " already exists."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Do not repeat the create operation as the resource has already been "
+         "created."}};
 }
 
 /**
@@ -334,15 +362,16 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json accountForSessionNoLongerExists() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.AccountForSessionNoLongerExists"},
-      {"Message",
-       "The account for the current session has been removed, thus the current "
-       "session has been removed as well."},
-      {"Severity", "OK"},
-      {"Resolution", "Attempt to connect with a valid account."}};
+nlohmann::json accountForSessionNoLongerExists()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.AccountForSessionNoLongerExists"},
+        {"Message", "The account for the current session has been removed, "
+                    "thus the current "
+                    "session has been removed as well."},
+        {"Severity", "OK"},
+        {"Resolution", "Attempt to connect with a valid account."}};
 }
 
 /**
@@ -352,16 +381,18 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json createFailedMissingReqProperties(const std::string& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.CreateFailedMissingReqProperties"},
-      {"Message", "The create operation failed because the required property " +
-                      arg1 + " was missing from the request."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Correct the body to include the required property with a valid value "
-       "and resubmit the request if the operation failed."}};
+nlohmann::json createFailedMissingReqProperties(const std::string& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.CreateFailedMissingReqProperties"},
+        {"Message",
+         "The create operation failed because the required property " + arg1 +
+             " was missing from the request."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Correct the body to include the required property with a valid value "
+         "and resubmit the request if the operation failed."}};
 }
 
 /**
@@ -372,17 +403,18 @@
  * @endinternal
  */
 nlohmann::json propertyValueFormatError(const std::string& arg1,
-                                        const std::string& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.PropertyValueFormatError"},
-      {"Message",
-       "The value " + arg1 + " for the property " + arg2 +
-           " is of a different format than the property can accept."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Correct the value for the property in the request body and resubmit "
-       "the request if the operation failed."}};
+                                        const std::string& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.PropertyValueFormatError"},
+        {"Message",
+         "The value " + arg1 + " for the property " + arg2 +
+             " is of a different format than the property can accept."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Correct the value for the property in the request body and resubmit "
+         "the request if the operation failed."}};
 }
 
 /**
@@ -393,16 +425,17 @@
  * @endinternal
  */
 nlohmann::json propertyValueNotInList(const std::string& arg1,
-                                      const std::string& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.PropertyValueNotInList"},
-      {"Message", "The value " + arg1 + " for the property " + arg2 +
-                      " is not in the list of acceptable values."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Choose a value from the enumeration list that the implementation can "
-       "support and resubmit the request if the operation failed."}};
+                                      const std::string& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.PropertyValueNotInList"},
+        {"Message", "The value " + arg1 + " for the property " + arg2 +
+                        " is not in the list of acceptable values."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Choose a value from the enumeration list that the implementation can "
+         "support and resubmit the request if the operation failed."}};
 }
 
 /**
@@ -412,16 +445,17 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json resourceAtUriInUnknownFormat(const std::string& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ResourceAtUriInUnknownFormat"},
-      {"Message", "The resource at " + arg1 +
-                      " is in a format not recognized by the service."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Place an image or resource or file that is recognized by the service "
-       "at the URI."}};
+nlohmann::json resourceAtUriInUnknownFormat(const std::string& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ResourceAtUriInUnknownFormat"},
+        {"Message", "The resource at " + arg1 +
+                        " is in a format not recognized by the service."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Place an image or resource or file that is recognized by the service "
+         "at the URI."}};
 }
 
 /**
@@ -431,17 +465,18 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json serviceInUnknownState() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ServiceInUnknownState"},
-      {"Message",
-       "The operation failed because the service is in an unknown state and "
-       "can no longer take incoming requests."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Restart the service and resubmit the request if the operation "
-       "failed."}};
+nlohmann::json serviceInUnknownState()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ServiceInUnknownState"},
+        {"Message",
+         "The operation failed because the service is in an unknown state and "
+         "can no longer take incoming requests."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Restart the service and resubmit the request if the operation "
+         "failed."}};
 }
 
 /**
@@ -451,18 +486,19 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json eventSubscriptionLimitExceeded() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.EventSubscriptionLimitExceeded"},
-      {"Message",
-       "The event subscription failed due to the number of simultaneous "
-       "subscriptions exceeding the limit of the implementation."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Reduce the number of other subscriptions before trying to establish "
-       "the event subscription or increase the limit of simultaneous "
-       "subscriptions (if supported)."}};
+nlohmann::json eventSubscriptionLimitExceeded()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.EventSubscriptionLimitExceeded"},
+        {"Message",
+         "The event subscription failed due to the number of simultaneous "
+         "subscriptions exceeding the limit of the implementation."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Reduce the number of other subscriptions before trying to establish "
+         "the event subscription or increase the limit of simultaneous "
+         "subscriptions (if supported)."}};
 }
 
 /**
@@ -473,16 +509,17 @@
  * @endinternal
  */
 nlohmann::json actionParameterMissing(const std::string& arg1,
-                                      const std::string& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ActionParameterMissing"},
-      {"Message", "The action " + arg1 + " requires the parameter " + arg2 +
-                      " to be present in the request body."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Supply the action with the required parameter in the request body when "
-       "the request is resubmitted."}};
+                                      const std::string& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ActionParameterMissing"},
+        {"Message", "The action " + arg1 + " requires the parameter " + arg2 +
+                        " to be present in the request body."},
+        {"Severity", "Critical"},
+        {"Resolution", "Supply the action with the required parameter in the "
+                       "request body when "
+                       "the request is resubmitted."}};
 }
 
 /**
@@ -492,15 +529,16 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json stringValueTooLong(const std::string& arg1, const int& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.StringValueTooLong"},
-      {"Message", "The string " + arg1 + " exceeds the length limit " +
-                      std::to_string(arg2) + "."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Resubmit the request with an appropriate string length."}};
+nlohmann::json stringValueTooLong(const std::string& arg1, const int& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.StringValueTooLong"},
+        {"Message", "The string " + arg1 + " exceeds the length limit " +
+                        std::to_string(arg2) + "."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Resubmit the request with an appropriate string length."}};
 }
 
 /**
@@ -511,16 +549,18 @@
  * @endinternal
  */
 nlohmann::json propertyValueTypeError(const std::string& arg1,
-                                      const std::string& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.PropertyValueTypeError"},
-      {"Message", "The value " + arg1 + " for the property " + arg2 +
-                      " is of a different type than the property can accept."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Correct the value for the property in the request body and resubmit "
-       "the request if the operation failed."}};
+                                      const std::string& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.PropertyValueTypeError"},
+        {"Message",
+         "The value " + arg1 + " for the property " + arg2 +
+             " is of a different type than the property can accept."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Correct the value for the property in the request body and resubmit "
+         "the request if the operation failed."}};
 }
 
 /**
@@ -531,15 +571,16 @@
  * @endinternal
  */
 nlohmann::json resourceNotFound(const std::string& arg1,
-                                const std::string& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ResourceNotFound"},
-      {"Message", "The requested resource of type " + arg1 + " named " + arg2 +
-                      " was not found."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Provide a valid resource identifier and resubmit the request."}};
+                                const std::string& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ResourceNotFound"},
+        {"Message", "The requested resource of type " + arg1 + " named " +
+                        arg2 + " was not found."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Provide a valid resource identifier and resubmit the request."}};
 }
 
 /**
@@ -549,16 +590,18 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json couldNotEstablishConnection(const std::string& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.CouldNotEstablishConnection"},
-      {"Message", "The service failed to establish a Connection with the URI " +
-                      arg1 + "."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Ensure that the URI contains a valid and reachable node name, protocol "
-       "information and other URI components."}};
+nlohmann::json couldNotEstablishConnection(const std::string& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.CouldNotEstablishConnection"},
+        {"Message",
+         "The service failed to establish a Connection with the URI " + arg1 +
+             "."},
+        {"Severity", "Critical"},
+        {"Resolution", "Ensure that the URI contains a valid and reachable "
+                       "node name, protocol "
+                       "information and other URI components."}};
 }
 
 /**
@@ -568,17 +611,18 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json propertyNotWritable(const std::string& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.PropertyNotWritable"},
-      {"Message",
-       "The property " + arg1 +
-           " is a read only property and cannot be assigned a value."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Remove the property from the request body and resubmit the request if "
-       "the operation failed."}};
+nlohmann::json propertyNotWritable(const std::string& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.PropertyNotWritable"},
+        {"Message",
+         "The property " + arg1 +
+             " is a read only property and cannot be assigned a value."},
+        {"Severity", "Warning"},
+        {"Resolution", "Remove the property from the request body and resubmit "
+                       "the request if "
+                       "the operation failed."}};
 }
 
 /**
@@ -589,16 +633,18 @@
  * @endinternal
  */
 nlohmann::json queryParameterValueTypeError(const std::string& arg1,
-                                            const std::string& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.QueryParameterValueTypeError"},
-      {"Message", "The value " + arg1 + " for the query parameter " + arg2 +
-                      " is of a different type than the parameter can accept."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Correct the value for the query parameter in the request and resubmit "
-       "the request if the operation failed."}};
+                                            const std::string& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.QueryParameterValueTypeError"},
+        {"Message",
+         "The value " + arg1 + " for the query parameter " + arg2 +
+             " is of a different type than the parameter can accept."},
+        {"Severity", "Warning"},
+        {"Resolution", "Correct the value for the query parameter in the "
+                       "request and resubmit "
+                       "the request if the operation failed."}};
 }
 
 /**
@@ -608,17 +654,18 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json serviceShuttingDown() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ServiceShuttingDown"},
-      {"Message",
-       "The operation failed because the service is shutting down and can no "
-       "longer take incoming requests."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "When the service becomes available, resubmit the request if the "
-       "operation failed."}};
+nlohmann::json serviceShuttingDown()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ServiceShuttingDown"},
+        {"Message",
+         "The operation failed because the service is shutting down and can no "
+         "longer take incoming requests."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "When the service becomes available, resubmit the request if the "
+         "operation failed."}};
 }
 
 /**
@@ -629,18 +676,19 @@
  * @endinternal
  */
 nlohmann::json actionParameterDuplicate(const std::string& arg1,
-                                        const std::string& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ActionParameterDuplicate"},
-      {"Message",
-       "The action " + arg1 +
-           " was submitted with more than one value for the parameter " + arg2 +
-           "."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Resubmit the action with only one instance of the parameter in the "
-       "request body if the operation failed."}};
+                                        const std::string& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ActionParameterDuplicate"},
+        {"Message",
+         "The action " + arg1 +
+             " was submitted with more than one value for the parameter " +
+             arg2 + "."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Resubmit the action with only one instance of the parameter in the "
+         "request body if the operation failed."}};
 }
 
 /**
@@ -651,16 +699,17 @@
  * @endinternal
  */
 nlohmann::json actionParameterNotSupported(const std::string& arg1,
-                                           const std::string& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ActionParameterNotSupported"},
-      {"Message", "The parameter " + arg1 + " for the action " + arg2 +
-                      " is not supported on the target resource."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Remove the parameter supplied and resubmit the request if the "
-       "operation failed."}};
+                                           const std::string& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ActionParameterNotSupported"},
+        {"Message", "The parameter " + arg1 + " for the action " + arg2 +
+                        " is not supported on the target resource."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Remove the parameter supplied and resubmit the request if the "
+         "operation failed."}};
 }
 
 /**
@@ -671,14 +720,16 @@
  * @endinternal
  */
 nlohmann::json sourceDoesNotSupportProtocol(const std::string& arg1,
-                                            const std::string& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.SourceDoesNotSupportProtocol"},
-      {"Message", "The other end of the Connection at " + arg1 +
-                      " does not support the specified protocol " + arg2 + "."},
-      {"Severity", "Critical"},
-      {"Resolution", "Change protocols or URIs. "}};
+                                            const std::string& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.SourceDoesNotSupportProtocol"},
+        {"Message", "The other end of the Connection at " + arg1 +
+                        " does not support the specified protocol " + arg2 +
+                        "."},
+        {"Severity", "Critical"},
+        {"Resolution", "Change protocols or URIs. "}};
 }
 
 /**
@@ -688,13 +739,14 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json accountRemoved() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.AccountRemoved"},
-      {"Message", "The account was successfully removed."},
-      {"Severity", "OK"},
-      {"Resolution", "No resolution is required."}};
+nlohmann::json accountRemoved()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.AccountRemoved"},
+        {"Message", "The account was successfully removed."},
+        {"Severity", "OK"},
+        {"Resolution", "No resolution is required."}};
 }
 
 /**
@@ -704,16 +756,17 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json accessDenied(const std::string& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.AccessDenied"},
-      {"Message", "While attempting to establish a Connection to " + arg1 +
-                      ", the service denied access."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Attempt to ensure that the URI is correct and that the service has the "
-       "appropriate credentials."}};
+nlohmann::json accessDenied(const std::string& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.AccessDenied"},
+        {"Message", "While attempting to establish a Connection to " + arg1 +
+                        ", the service denied access."},
+        {"Severity", "Critical"},
+        {"Resolution", "Attempt to ensure that the URI is correct and that the "
+                       "service has the "
+                       "appropriate credentials."}};
 }
 
 /**
@@ -723,15 +776,16 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json queryNotSupported() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.QueryNotSupported"},
-      {"Message", "Querying is not supported by the implementation."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Remove the query parameters and resubmit the request if the operation "
-       "failed."}};
+nlohmann::json queryNotSupported()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.QueryNotSupported"},
+        {"Message", "Querying is not supported by the implementation."},
+        {"Severity", "Warning"},
+        {"Resolution", "Remove the query parameters and resubmit the request "
+                       "if the operation "
+                       "failed."}};
 }
 
 /**
@@ -741,17 +795,18 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json createLimitReachedForResource() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.CreateLimitReachedForResource"},
-      {"Message",
-       "The create operation failed because the resource has reached the limit "
-       "of possible resources."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Either delete resources and resubmit the request if the operation "
-       "failed or do not resubmit the request."}};
+nlohmann::json createLimitReachedForResource()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.CreateLimitReachedForResource"},
+        {"Message", "The create operation failed because the resource has "
+                    "reached the limit "
+                    "of possible resources."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Either delete resources and resubmit the request if the operation "
+         "failed or do not resubmit the request."}};
 }
 
 /**
@@ -761,14 +816,15 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json generalError() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.GeneralError"},
-      {"Message",
-       "A general error has occurred. See ExtendedInfo for more information."},
-      {"Severity", "Critical"},
-      {"Resolution", "See ExtendedInfo for more information."}};
+nlohmann::json generalError()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.GeneralError"},
+        {"Message", "A general error has occurred. See ExtendedInfo for more "
+                    "information."},
+        {"Severity", "Critical"},
+        {"Resolution", "See ExtendedInfo for more information."}};
 }
 
 /**
@@ -778,13 +834,14 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json success() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.Success"},
-      {"Message", "Successfully Completed Request"},
-      {"Severity", "OK"},
-      {"Resolution", "None"}};
+nlohmann::json success()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.Success"},
+        {"Message", "Successfully Completed Request"},
+        {"Severity", "OK"},
+        {"Resolution", "None"}};
 }
 
 /**
@@ -794,13 +851,14 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json created() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.Created"},
-      {"Message", "The resource has been created successfully"},
-      {"Severity", "OK"},
-      {"Resolution", "None"}};
+nlohmann::json created()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.Created"},
+        {"Message", "The resource has been created successfully"},
+        {"Severity", "OK"},
+        {"Resolution", "None"}};
 }
 
 /**
@@ -810,17 +868,18 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json propertyUnknown(const std::string& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.PropertyUnknown"},
-      {"Message",
-       "The property " + arg1 +
-           " is not in the list of valid properties for the resource."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Remove the unknown property from the request body and resubmit the "
-       "request if the operation failed."}};
+nlohmann::json propertyUnknown(const std::string& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.PropertyUnknown"},
+        {"Message",
+         "The property " + arg1 +
+             " is not in the list of valid properties for the resource."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Remove the unknown property from the request body and resubmit the "
+         "request if the operation failed."}};
 }
 
 /**
@@ -830,14 +889,16 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json noValidSession() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.NoValidSession"},
-      {"Message",
-       "There is no valid session established with the implementation."},
-      {"Severity", "Critical"},
-      {"Resolution", "Establish as session before attempting any operations."}};
+nlohmann::json noValidSession()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.NoValidSession"},
+        {"Message",
+         "There is no valid session established with the implementation."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Establish as session before attempting any operations."}};
 }
 
 /**
@@ -847,15 +908,16 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json invalidObject(const std::string& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.InvalidObject"},
-      {"Message", "The object at " + arg1 + " is invalid."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Either the object is malformed or the URI is not correct.  Correct the "
-       "condition and resubmit the request if it failed."}};
+nlohmann::json invalidObject(const std::string& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.InvalidObject"},
+        {"Message", "The object at " + arg1 + " is invalid."},
+        {"Severity", "Critical"},
+        {"Resolution", "Either the object is malformed or the URI is not "
+                       "correct.  Correct the "
+                       "condition and resubmit the request if it failed."}};
 }
 
 /**
@@ -865,17 +927,18 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json resourceInStandby() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ResourceInStandby"},
-      {"Message",
-       "The request could not be performed because the resource is in "
-       "standby."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Ensure that the resource is in the correct power state and resubmit "
-       "the request."}};
+nlohmann::json resourceInStandby()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ResourceInStandby"},
+        {"Message",
+         "The request could not be performed because the resource is in "
+         "standby."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Ensure that the resource is in the correct power state and resubmit "
+         "the request."}};
 }
 
 /**
@@ -887,17 +950,19 @@
  */
 nlohmann::json actionParameterValueTypeError(const std::string& arg1,
                                              const std::string& arg2,
-                                             const std::string& arg3) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ActionParameterValueTypeError"},
-      {"Message", "The value " + arg1 + " for the parameter " + arg2 +
-                      " in the action " + arg3 +
-                      " is of a different type than the parameter can accept."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Correct the value for the parameter in the request body and resubmit "
-       "the request if the operation failed."}};
+                                             const std::string& arg3)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ActionParameterValueTypeError"},
+        {"Message",
+         "The value " + arg1 + " for the parameter " + arg2 +
+             " in the action " + arg3 +
+             " is of a different type than the parameter can accept."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Correct the value for the parameter in the request body and resubmit "
+         "the request if the operation failed."}};
 }
 
 /**
@@ -907,18 +972,19 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json sessionLimitExceeded() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.SessionLimitExceeded"},
-      {"Message",
-       "The session establishment failed due to the number of simultaneous "
-       "sessions exceeding the limit of the implementation."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Reduce the number of other sessions before trying to establish the "
-       "session or increase the limit of simultaneous sessions (if "
-       "supported)."}};
+nlohmann::json sessionLimitExceeded()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.SessionLimitExceeded"},
+        {"Message",
+         "The session establishment failed due to the number of simultaneous "
+         "sessions exceeding the limit of the implementation."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Reduce the number of other sessions before trying to establish the "
+         "session or increase the limit of simultaneous sessions (if "
+         "supported)."}};
 }
 
 /**
@@ -928,16 +994,18 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json actionNotSupported(const std::string& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ActionNotSupported"},
-      {"Message", "The action " + arg1 + " is not supported by the resource."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "The action supplied cannot be resubmitted to the implementation.  "
-       "Perhaps the action was invalid, the wrong resource was the target or "
-       "the implementation documentation may be of assistance."}};
+nlohmann::json actionNotSupported(const std::string& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ActionNotSupported"},
+        {"Message",
+         "The action " + arg1 + " is not supported by the resource."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "The action supplied cannot be resubmitted to the implementation.  "
+         "Perhaps the action was invalid, the wrong resource was the target or "
+         "the implementation documentation may be of assistance."}};
 }
 
 /**
@@ -947,15 +1015,16 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json invalidIndex(const int& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.InvalidIndex"},
-      {"Message", "The index " + std::to_string(arg1) +
-                      " is not a valid offset into the array."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Verify the index value provided is within the bounds of the array."}};
+nlohmann::json invalidIndex(const int& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.InvalidIndex"},
+        {"Message", "The index " + std::to_string(arg1) +
+                        " is not a valid offset into the array."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Verify the index value provided is within the bounds of the array."}};
 }
 
 /**
@@ -965,16 +1034,17 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json emptyJSON() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.EmptyJSON"},
-      {"Message",
-       "The request body submitted contained an empty JSON object and the "
-       "service is unable to process it."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Add properties in the JSON object and resubmit the request."}};
+nlohmann::json emptyJSON()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.EmptyJSON"},
+        {"Message",
+         "The request body submitted contained an empty JSON object and the "
+         "service is unable to process it."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Add properties in the JSON object and resubmit the request."}};
 }
 
 /**
@@ -984,15 +1054,16 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json queryNotSupportedOnResource() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.QueryNotSupportedOnResource"},
-      {"Message", "Querying is not supported on the requested resource."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Remove the query parameters and resubmit the request if the operation "
-       "failed."}};
+nlohmann::json queryNotSupportedOnResource()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.QueryNotSupportedOnResource"},
+        {"Message", "Querying is not supported on the requested resource."},
+        {"Severity", "Warning"},
+        {"Resolution", "Remove the query parameters and resubmit the request "
+                       "if the operation "
+                       "failed."}};
 }
 
 /**
@@ -1002,18 +1073,19 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json insufficientPrivilege() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.InsufficientPrivilege"},
-      {"Message",
-       "There are insufficient privileges for the account or credentials "
-       "associated with the current session to perform the requested "
-       "operation."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Either abandon the operation or change the associated access rights "
-       "and resubmit the request if the operation failed."}};
+nlohmann::json insufficientPrivilege()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.InsufficientPrivilege"},
+        {"Message",
+         "There are insufficient privileges for the account or credentials "
+         "associated with the current session to perform the requested "
+         "operation."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Either abandon the operation or change the associated access rights "
+         "and resubmit the request if the operation failed."}};
 }
 
 /**
@@ -1024,14 +1096,15 @@
  * @endinternal
  */
 nlohmann::json propertyValueModified(const std::string& arg1,
-                                     const std::string& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.PropertyValueModified"},
-      {"Message", "The property " + arg1 + " was assigned the value " + arg2 +
-                      " due to modification by the service."},
-      {"Severity", "Warning"},
-      {"Resolution", "No resolution is required."}};
+                                     const std::string& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.PropertyValueModified"},
+        {"Message", "The property " + arg1 + " was assigned the value " + arg2 +
+                        " due to modification by the service."},
+        {"Severity", "Warning"},
+        {"Resolution", "No resolution is required."}};
 }
 
 /**
@@ -1041,15 +1114,16 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json accountNotModified() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.AccountNotModified"},
-      {"Message", "The account modification request failed."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "The modification may have failed due to permission issues or issues "
-       "with the request body."}};
+nlohmann::json accountNotModified()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.AccountNotModified"},
+        {"Message", "The account modification request failed."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "The modification may have failed due to permission issues or issues "
+         "with the request body."}};
 }
 
 /**
@@ -1060,17 +1134,18 @@
  * @endinternal
  */
 nlohmann::json queryParameterValueFormatError(const std::string& arg1,
-                                              const std::string& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.QueryParameterValueFormatError"},
-      {"Message",
-       "The value " + arg1 + " for the parameter " + arg2 +
-           " is of a different format than the parameter can accept."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Correct the value for the query parameter in the request and resubmit "
-       "the request if the operation failed."}};
+                                              const std::string& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.QueryParameterValueFormatError"},
+        {"Message",
+         "The value " + arg1 + " for the parameter " + arg2 +
+             " is of a different format than the parameter can accept."},
+        {"Severity", "Warning"},
+        {"Resolution", "Correct the value for the query parameter in the "
+                       "request and resubmit "
+                       "the request if the operation failed."}};
 }
 
 /**
@@ -1080,17 +1155,18 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json propertyMissing(const std::string& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.PropertyMissing"},
-      {"Message",
-       "The property " + arg1 +
-           " is a required property and must be included in the request."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Ensure that the property is in the request body and has a valid value "
-       "and resubmit the request if the operation failed."}};
+nlohmann::json propertyMissing(const std::string& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.PropertyMissing"},
+        {"Message",
+         "The property " + arg1 +
+             " is a required property and must be included in the request."},
+        {"Severity", "Warning"},
+        {"Resolution", "Ensure that the property is in the request body and "
+                       "has a valid value "
+                       "and resubmit the request if the operation failed."}};
 }
 
 /**
@@ -1100,17 +1176,18 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json resourceExhaustion(const std::string& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ResourceExhaustion"},
-      {"Message", "The resource " + arg1 +
-                      " was unable to satisfy the request "
-                      "due to unavailability of "
-                      "resources."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Ensure that the resources are available and resubmit the request."}};
+nlohmann::json resourceExhaustion(const std::string& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ResourceExhaustion"},
+        {"Message", "The resource " + arg1 +
+                        " was unable to satisfy the request "
+                        "due to unavailability of "
+                        "resources."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Ensure that the resources are available and resubmit the request."}};
 }
 
 /**
@@ -1120,13 +1197,14 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json accountModified() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.AccountModified"},
-      {"Message", "The account was successfully modified."},
-      {"Severity", "OK"},
-      {"Resolution", "No resolution is required."}};
+nlohmann::json accountModified()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.AccountModified"},
+        {"Message", "The account was successfully modified."},
+        {"Severity", "OK"},
+        {"Resolution", "No resolution is required."}};
 }
 
 /**
@@ -1138,24 +1216,26 @@
  */
 nlohmann::json queryParameterOutOfRange(const std::string& arg1,
                                         const std::string& arg2,
-                                        const std::string& arg3) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.QueryParameterOutOfRange"},
-      {"Message", "The value " + arg1 + " for the query parameter " + arg2 +
-                      " is out of range " + arg3 + "."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Reduce the value for the query parameter to a value that is within "
-       "range, such as a start or count value that is within bounds of the "
-       "number of resources in a collection or a page that is within the range "
-       "of valid pages."}};
+                                        const std::string& arg3)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.QueryParameterOutOfRange"},
+        {"Message", "The value " + arg1 + " for the query parameter " + arg2 +
+                        " is out of range " + arg3 + "."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Reduce the value for the query parameter to a value that is within "
+         "range, such as a start or count value that is within bounds of the "
+         "number of resources in a collection or a page that is within the "
+         "range "
+         "of valid pages."}};
 }
 
 /*********************************
  * AUTOGENERATED FUNCTIONS END *
  *********************************/
 
-}  // namespace messages
+} // namespace messages
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/src/utils/json_utils.cpp b/redfish-core/src/utils/json_utils.cpp
index 5d81c21..868601f 100644
--- a/redfish-core/src/utils/json_utils.cpp
+++ b/redfish-core/src/utils/json_utils.cpp
@@ -14,440 +14,512 @@
 // limitations under the License.
 */
 #include "utils/json_utils.hpp"
+
 #include <error_messages.hpp>
 
-namespace redfish {
+namespace redfish
+{
 
-namespace json_util {
+namespace json_util
+{
 
 Result getString(const char* fieldName, const nlohmann::json& json,
-                 const std::string*& output) {
-  // Find field
-  auto fieldIt = json.find(fieldName);
+                 const std::string*& output)
+{
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify existence
-  if (fieldIt == json.end()) {
-    return Result::NOT_EXIST;
-  }
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        return Result::NOT_EXIST;
+    }
 
-  output = fieldIt->get_ptr<const std::string*>();
+    output = fieldIt->get_ptr<const std::string*>();
 
-  // Verify type - we know that it exists, so nullptr means wrong type
-  if (output == nullptr) {
-    return Result::WRONG_TYPE;
-  }
+    // Verify type - we know that it exists, so nullptr means wrong type
+    if (output == nullptr)
+    {
+        return Result::WRONG_TYPE;
+    }
 
-  return Result::SUCCESS;
+    return Result::SUCCESS;
 }
 
 Result getObject(const char* fieldName, const nlohmann::json& json,
-                 nlohmann::json* output) {
-  // Verify input pointer
-  if (output == nullptr) {
-    return Result::NULL_POINTER;
-  }
+                 nlohmann::json* output)
+{
+    // Verify input pointer
+    if (output == nullptr)
+    {
+        return Result::NULL_POINTER;
+    }
 
-  // Find field
-  auto fieldIt = json.find(fieldName);
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify existence
-  if (fieldIt == json.end()) {
-    return Result::NOT_EXIST;
-  }
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        return Result::NOT_EXIST;
+    }
 
-  // Verify type
-  if (!fieldIt->is_object()) {
-    return Result::WRONG_TYPE;
-  }
+    // Verify type
+    if (!fieldIt->is_object())
+    {
+        return Result::WRONG_TYPE;
+    }
 
-  // Extract value
-  *output = *fieldIt;
+    // Extract value
+    *output = *fieldIt;
 
-  return Result::SUCCESS;
+    return Result::SUCCESS;
 }
 
 Result getArray(const char* fieldName, const nlohmann::json& json,
-                nlohmann::json* output) {
-  // Verify input pointer
-  if (output == nullptr) {
-    return Result::NULL_POINTER;
-  }
+                nlohmann::json* output)
+{
+    // Verify input pointer
+    if (output == nullptr)
+    {
+        return Result::NULL_POINTER;
+    }
 
-  // Find field
-  auto fieldIt = json.find(fieldName);
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify existence
-  if (fieldIt == json.end()) {
-    return Result::NOT_EXIST;
-  }
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        return Result::NOT_EXIST;
+    }
 
-  // Verify type
-  if (!fieldIt->is_array()) {
-    return Result::WRONG_TYPE;
-  }
+    // Verify type
+    if (!fieldIt->is_array())
+    {
+        return Result::WRONG_TYPE;
+    }
 
-  // Extract value
-  *output = *fieldIt;
+    // Extract value
+    *output = *fieldIt;
 
-  return Result::SUCCESS;
+    return Result::SUCCESS;
 }
 
 Result getInt(const char* fieldName, const nlohmann::json& json,
-              int64_t& output) {
-  // Find field
-  auto fieldIt = json.find(fieldName);
+              int64_t& output)
+{
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify existence
-  if (fieldIt == json.end()) {
-    return Result::NOT_EXIST;
-  }
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        return Result::NOT_EXIST;
+    }
 
-  const int64_t* retVal = fieldIt->get_ptr<const int64_t*>();
+    const int64_t* retVal = fieldIt->get_ptr<const int64_t*>();
 
-  // Verify type - we know that it exists, so nullptr means wrong type
-  if (retVal == nullptr) {
-    return Result::WRONG_TYPE;
-  }
+    // Verify type - we know that it exists, so nullptr means wrong type
+    if (retVal == nullptr)
+    {
+        return Result::WRONG_TYPE;
+    }
 
-  // Extract value
-  output = *retVal;
+    // Extract value
+    output = *retVal;
 
-  return Result::SUCCESS;
+    return Result::SUCCESS;
 }
 
 Result getUnsigned(const char* fieldName, const nlohmann::json& json,
-                   uint64_t& output) {
-  // Find field
-  auto fieldIt = json.find(fieldName);
+                   uint64_t& output)
+{
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify existence
-  if (fieldIt == json.end()) {
-    return Result::NOT_EXIST;
-  }
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        return Result::NOT_EXIST;
+    }
 
-  const uint64_t* retVal = fieldIt->get_ptr<const uint64_t*>();
+    const uint64_t* retVal = fieldIt->get_ptr<const uint64_t*>();
 
-  // Verify type - we know that it exists, so nullptr means wrong type
-  if (retVal == nullptr) {
-    return Result::WRONG_TYPE;
-  }
+    // Verify type - we know that it exists, so nullptr means wrong type
+    if (retVal == nullptr)
+    {
+        return Result::WRONG_TYPE;
+    }
 
-  // Extract value
-  output = *retVal;
+    // Extract value
+    output = *retVal;
 
-  return Result::SUCCESS;
+    return Result::SUCCESS;
 }
 
-Result getBool(const char* fieldName, const nlohmann::json& json,
-               bool& output) {
-  // Find field
-  auto fieldIt = json.find(fieldName);
+Result getBool(const char* fieldName, const nlohmann::json& json, bool& output)
+{
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify existence
-  if (fieldIt == json.end()) {
-    return Result::NOT_EXIST;
-  }
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        return Result::NOT_EXIST;
+    }
 
-  const bool* retVal = fieldIt->get_ptr<const bool*>();
+    const bool* retVal = fieldIt->get_ptr<const bool*>();
 
-  // Verify type - we know that it exists, so nullptr means wrong type
-  if (retVal == nullptr) {
-    return Result::WRONG_TYPE;
-  }
+    // Verify type - we know that it exists, so nullptr means wrong type
+    if (retVal == nullptr)
+    {
+        return Result::WRONG_TYPE;
+    }
 
-  // Extract value
-  output = *retVal;
+    // Extract value
+    output = *retVal;
 
-  return Result::SUCCESS;
+    return Result::SUCCESS;
 }
 
 Result getDouble(const char* fieldName, const nlohmann::json& json,
-                 double& output) {
-  // Find field
-  auto fieldIt = json.find(fieldName);
+                 double& output)
+{
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify existence
-  if (fieldIt == json.end()) {
-    return Result::NOT_EXIST;
-  }
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        return Result::NOT_EXIST;
+    }
 
-  const double* retVal = fieldIt->get_ptr<const double*>();
+    const double* retVal = fieldIt->get_ptr<const double*>();
 
-  // Verify type - we know that it exists, so nullptr means wrong type
-  if (retVal == nullptr) {
-    return Result::WRONG_TYPE;
-  }
+    // Verify type - we know that it exists, so nullptr means wrong type
+    if (retVal == nullptr)
+    {
+        return Result::WRONG_TYPE;
+    }
 
-  // Extract value
-  output = *retVal;
+    // Extract value
+    output = *retVal;
 
-  return Result::SUCCESS;
+    return Result::SUCCESS;
 }
 
 Result getString(const char* fieldName, const nlohmann::json& json,
                  const std::string*& output, uint8_t msgCfgMap,
-                 nlohmann::json& msgJson, const std::string&& fieldPath) {
-  // Find field
-  auto fieldIt = json.find(fieldName);
+                 nlohmann::json& msgJson, const std::string&& fieldPath)
+{
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify existence
-  if (fieldIt == json.end()) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::MISSING)) {
-      messages::addMessageToJson(msgJson, messages::propertyMissing(fieldName),
-                                 fieldPath);
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::MISSING))
+        {
+            messages::addMessageToJson(
+                msgJson, messages::propertyMissing(fieldName), fieldPath);
+        }
+
+        return Result::NOT_EXIST;
     }
 
-    return Result::NOT_EXIST;
-  }
+    output = fieldIt->get_ptr<const std::string*>();
 
-  output = fieldIt->get_ptr<const std::string*>();
+    // Verify type - we know that it exists, so nullptr means wrong type
+    if (output == nullptr)
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR))
+        {
+            messages::addMessageToJson(
+                msgJson,
+                messages::propertyValueTypeError(fieldIt->dump(), fieldName),
+                fieldPath);
+        }
 
-  // Verify type - we know that it exists, so nullptr means wrong type
-  if (output == nullptr) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR)) {
-      messages::addMessageToJson(
-          msgJson, messages::propertyValueTypeError(fieldIt->dump(), fieldName),
-          fieldPath);
+        return Result::WRONG_TYPE;
     }
 
-    return Result::WRONG_TYPE;
-  }
-
-  return Result::SUCCESS;
+    return Result::SUCCESS;
 }
 
 Result getObject(const char* fieldName, const nlohmann::json& json,
                  nlohmann::json* output, uint8_t msgCfgMap,
-                 nlohmann::json& msgJson, const std::string&& fieldPath) {
-  // Verify input pointer
-  if (output == nullptr) {
-    return Result::NULL_POINTER;
-  }
-
-  // Find field
-  auto fieldIt = json.find(fieldName);
-
-  // Verify existence
-  if (fieldIt == json.end()) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::MISSING)) {
-      messages::addMessageToJson(msgJson, messages::propertyMissing(fieldName),
-                                 fieldPath);
+                 nlohmann::json& msgJson, const std::string&& fieldPath)
+{
+    // Verify input pointer
+    if (output == nullptr)
+    {
+        return Result::NULL_POINTER;
     }
 
-    return Result::NOT_EXIST;
-  }
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify type
-  if (!fieldIt->is_object()) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR)) {
-      messages::addMessageToJson(
-          msgJson, messages::propertyValueTypeError(fieldIt->dump(), fieldName),
-          fieldPath);
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::MISSING))
+        {
+            messages::addMessageToJson(
+                msgJson, messages::propertyMissing(fieldName), fieldPath);
+        }
+
+        return Result::NOT_EXIST;
     }
 
-    return Result::WRONG_TYPE;
-  }
+    // Verify type
+    if (!fieldIt->is_object())
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR))
+        {
+            messages::addMessageToJson(
+                msgJson,
+                messages::propertyValueTypeError(fieldIt->dump(), fieldName),
+                fieldPath);
+        }
 
-  // Extract value
-  *output = *fieldIt;
+        return Result::WRONG_TYPE;
+    }
 
-  return Result::SUCCESS;
+    // Extract value
+    *output = *fieldIt;
+
+    return Result::SUCCESS;
 }
 
 Result getArray(const char* fieldName, const nlohmann::json& json,
                 nlohmann::json* output, uint8_t msgCfgMap,
-                nlohmann::json& msgJson, const std::string&& fieldPath) {
-  // Verify input pointer
-  if (output == nullptr) {
-    return Result::NULL_POINTER;
-  }
-
-  // Find field
-  auto fieldIt = json.find(fieldName);
-
-  // Verify existence
-  if (fieldIt == json.end()) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::MISSING)) {
-      messages::addMessageToJson(msgJson, messages::propertyMissing(fieldName),
-                                 fieldPath);
+                nlohmann::json& msgJson, const std::string&& fieldPath)
+{
+    // Verify input pointer
+    if (output == nullptr)
+    {
+        return Result::NULL_POINTER;
     }
 
-    return Result::NOT_EXIST;
-  }
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify type
-  if (!fieldIt->is_array()) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR)) {
-      messages::addMessageToJson(
-          msgJson, messages::propertyValueTypeError(fieldIt->dump(), fieldName),
-          fieldPath);
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::MISSING))
+        {
+            messages::addMessageToJson(
+                msgJson, messages::propertyMissing(fieldName), fieldPath);
+        }
+
+        return Result::NOT_EXIST;
     }
 
-    return Result::WRONG_TYPE;
-  }
+    // Verify type
+    if (!fieldIt->is_array())
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR))
+        {
+            messages::addMessageToJson(
+                msgJson,
+                messages::propertyValueTypeError(fieldIt->dump(), fieldName),
+                fieldPath);
+        }
 
-  // Extract value
-  *output = *fieldIt;
+        return Result::WRONG_TYPE;
+    }
 
-  return Result::SUCCESS;
+    // Extract value
+    *output = *fieldIt;
+
+    return Result::SUCCESS;
 }
 
 Result getInt(const char* fieldName, const nlohmann::json& json,
               int64_t& output, uint8_t msgCfgMap, nlohmann::json& msgJson,
-              const std::string&& fieldPath) {
-  // Find field
-  auto fieldIt = json.find(fieldName);
+              const std::string&& fieldPath)
+{
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify existence
-  if (fieldIt == json.end()) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::MISSING)) {
-      messages::addMessageToJson(msgJson, messages::propertyMissing(fieldName),
-                                 fieldPath);
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::MISSING))
+        {
+            messages::addMessageToJson(
+                msgJson, messages::propertyMissing(fieldName), fieldPath);
+        }
+
+        return Result::NOT_EXIST;
     }
 
-    return Result::NOT_EXIST;
-  }
+    const int64_t* retVal = fieldIt->get_ptr<const int64_t*>();
 
-  const int64_t* retVal = fieldIt->get_ptr<const int64_t*>();
+    // Verify type - we know that it exists, so nullptr means wrong type
+    if (retVal == nullptr)
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR))
+        {
+            messages::addMessageToJson(
+                msgJson,
+                messages::propertyValueTypeError(fieldIt->dump(), fieldName),
+                fieldPath);
+        }
 
-  // Verify type - we know that it exists, so nullptr means wrong type
-  if (retVal == nullptr) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR)) {
-      messages::addMessageToJson(
-          msgJson, messages::propertyValueTypeError(fieldIt->dump(), fieldName),
-          fieldPath);
+        return Result::WRONG_TYPE;
     }
 
-    return Result::WRONG_TYPE;
-  }
+    // Extract value
+    output = *retVal;
 
-  // Extract value
-  output = *retVal;
-
-  return Result::SUCCESS;
+    return Result::SUCCESS;
 }
 
 Result getUnsigned(const char* fieldName, const nlohmann::json& json,
                    uint64_t& output, uint8_t msgCfgMap, nlohmann::json& msgJson,
-                   const std::string&& fieldPath) {
-  // Find field
-  auto fieldIt = json.find(fieldName);
+                   const std::string&& fieldPath)
+{
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify existence
-  if (fieldIt == json.end()) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::MISSING)) {
-      messages::addMessageToJson(msgJson, messages::propertyMissing(fieldName),
-                                 fieldPath);
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::MISSING))
+        {
+            messages::addMessageToJson(
+                msgJson, messages::propertyMissing(fieldName), fieldPath);
+        }
+
+        return Result::NOT_EXIST;
     }
 
-    return Result::NOT_EXIST;
-  }
+    const uint64_t* retVal = fieldIt->get_ptr<const uint64_t*>();
 
-  const uint64_t* retVal = fieldIt->get_ptr<const uint64_t*>();
+    // Verify type - we know that it exists, so nullptr means wrong type
+    if (retVal == nullptr)
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR))
+        {
+            messages::addMessageToJson(
+                msgJson,
+                messages::propertyValueTypeError(fieldIt->dump(), fieldName),
+                fieldPath);
+        }
 
-  // Verify type - we know that it exists, so nullptr means wrong type
-  if (retVal == nullptr) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR)) {
-      messages::addMessageToJson(
-          msgJson, messages::propertyValueTypeError(fieldIt->dump(), fieldName),
-          fieldPath);
+        return Result::WRONG_TYPE;
     }
 
-    return Result::WRONG_TYPE;
-  }
+    // Extract value
+    output = *retVal;
 
-  // Extract value
-  output = *retVal;
-
-  return Result::SUCCESS;
+    return Result::SUCCESS;
 }
 
 Result getBool(const char* fieldName, const nlohmann::json& json, bool& output,
                uint8_t msgCfgMap, nlohmann::json& msgJson,
-               const std::string&& fieldPath) {
-  // Find field
-  auto fieldIt = json.find(fieldName);
+               const std::string&& fieldPath)
+{
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify existence
-  if (fieldIt == json.end()) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::MISSING)) {
-      messages::addMessageToJson(msgJson, messages::propertyMissing(fieldName),
-                                 fieldPath);
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::MISSING))
+        {
+            messages::addMessageToJson(
+                msgJson, messages::propertyMissing(fieldName), fieldPath);
+        }
+
+        return Result::NOT_EXIST;
     }
 
-    return Result::NOT_EXIST;
-  }
+    const bool* retVal = fieldIt->get_ptr<const bool*>();
 
-  const bool* retVal = fieldIt->get_ptr<const bool*>();
+    // Verify type - we know that it exists, so nullptr means wrong type
+    if (retVal == nullptr)
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR))
+        {
+            messages::addMessageToJson(
+                msgJson,
+                messages::propertyValueTypeError(fieldIt->dump(), fieldName),
+                fieldPath);
+        }
 
-  // Verify type - we know that it exists, so nullptr means wrong type
-  if (retVal == nullptr) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR)) {
-      messages::addMessageToJson(
-          msgJson, messages::propertyValueTypeError(fieldIt->dump(), fieldName),
-          fieldPath);
+        return Result::WRONG_TYPE;
     }
 
-    return Result::WRONG_TYPE;
-  }
+    // Extract value
+    output = *retVal;
 
-  // Extract value
-  output = *retVal;
-
-  return Result::SUCCESS;
+    return Result::SUCCESS;
 }
 
 Result getDouble(const char* fieldName, const nlohmann::json& json,
                  double& output, uint8_t msgCfgMap, nlohmann::json& msgJson,
-                 const std::string&& fieldPath) {
-  // Find field
-  auto fieldIt = json.find(fieldName);
+                 const std::string&& fieldPath)
+{
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify existence
-  if (fieldIt == json.end()) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::MISSING)) {
-      messages::addMessageToJson(msgJson, messages::propertyMissing(fieldName),
-                                 fieldPath);
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::MISSING))
+        {
+            messages::addMessageToJson(
+                msgJson, messages::propertyMissing(fieldName), fieldPath);
+        }
+
+        return Result::NOT_EXIST;
     }
 
-    return Result::NOT_EXIST;
-  }
+    const double* retVal = fieldIt->get_ptr<const double*>();
 
-  const double* retVal = fieldIt->get_ptr<const double*>();
+    // Verify type - we know that it exists, so nullptr means wrong type
+    if (retVal == nullptr)
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR))
+        {
+            messages::addMessageToJson(
+                msgJson,
+                messages::propertyValueTypeError(fieldIt->dump(), fieldName),
+                fieldPath);
+        }
 
-  // Verify type - we know that it exists, so nullptr means wrong type
-  if (retVal == nullptr) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR)) {
-      messages::addMessageToJson(
-          msgJson, messages::propertyValueTypeError(fieldIt->dump(), fieldName),
-          fieldPath);
+        return Result::WRONG_TYPE;
     }
 
-    return Result::WRONG_TYPE;
-  }
+    // Extract value
+    output = *retVal;
 
-  // Extract value
-  output = *retVal;
-
-  return Result::SUCCESS;
+    return Result::SUCCESS;
 }
 
 bool processJsonFromRequest(crow::Response& res, const crow::Request& req,
-                            nlohmann::json& reqJson) {
-  reqJson = nlohmann::json::parse(req.body, nullptr, false);
+                            nlohmann::json& reqJson)
+{
+    reqJson = nlohmann::json::parse(req.body, nullptr, false);
 
-  if (reqJson.is_discarded()) {
-    messages::addMessageToErrorJson(res.jsonValue, messages::malformedJSON());
+    if (reqJson.is_discarded())
+    {
+        messages::addMessageToErrorJson(res.jsonValue,
+                                        messages::malformedJSON());
 
-    res.result(boost::beast::http::status::bad_request);
-    res.end();
+        res.result(boost::beast::http::status::bad_request);
+        res.end();
 
-    return false;
-  }
+        return false;
+    }
 
-  return true;
+    return true;
 }
 
-}  // namespace json_util
+} // namespace json_util
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/ut/privileges_test.cpp b/redfish-core/ut/privileges_test.cpp
index 92cd6c4..d857290 100644
--- a/redfish-core/ut/privileges_test.cpp
+++ b/redfish-core/ut/privileges_test.cpp
@@ -1,114 +1,127 @@
+#include "nlohmann/json.hpp"
 #include "privileges.hpp"
+
 #include <fstream>
 #include <string>
-#include "nlohmann/json.hpp"
+
 #include "gmock/gmock.h"
 
 using namespace redfish;
 
-TEST(PrivilegeTest, PrivilegeConstructor) {
-  Privileges privileges{"Login", "ConfigureManager"};
+TEST(PrivilegeTest, PrivilegeConstructor)
+{
+    Privileges privileges{"Login", "ConfigureManager"};
 
-  EXPECT_THAT(privileges.getActivePrivilegeNames(PrivilegeType::BASE),
-              ::testing::UnorderedElementsAre(
-                  ::testing::Pointee(&"Login"[0]),
-                  ::testing::Pointee(&"ConfigureManager"[0])));
+    EXPECT_THAT(privileges.getActivePrivilegeNames(PrivilegeType::BASE),
+                ::testing::UnorderedElementsAre(
+                    ::testing::Pointee(&"Login"[0]),
+                    ::testing::Pointee(&"ConfigureManager"[0])));
 }
 
-TEST(PrivilegeTest, PrivilegeCheckForNoPrivilegesRequired) {
-  Privileges userPrivileges{"Login"};
+TEST(PrivilegeTest, PrivilegeCheckForNoPrivilegesRequired)
+{
+    Privileges userPrivileges{"Login"};
 
-  OperationMap entityPrivileges{{boost::beast::http::verb::get, {{"Login"}}}};
+    OperationMap entityPrivileges{{boost::beast::http::verb::get, {{"Login"}}}};
 
-  EXPECT_TRUE(isMethodAllowedWithPrivileges(boost::beast::http::verb::get,
-                                            entityPrivileges, userPrivileges));
+    EXPECT_TRUE(isMethodAllowedWithPrivileges(
+        boost::beast::http::verb::get, entityPrivileges, userPrivileges));
 }
 
-TEST(PrivilegeTest, PrivilegeCheckForSingleCaseSuccess) {
-  auto userPrivileges = Privileges{"Login"};
-  OperationMap entityPrivileges{{boost::beast::http::verb::get, {}}};
+TEST(PrivilegeTest, PrivilegeCheckForSingleCaseSuccess)
+{
+    auto userPrivileges = Privileges{"Login"};
+    OperationMap entityPrivileges{{boost::beast::http::verb::get, {}}};
 
-  EXPECT_TRUE(isMethodAllowedWithPrivileges(boost::beast::http::verb::get,
-                                            entityPrivileges, userPrivileges));
+    EXPECT_TRUE(isMethodAllowedWithPrivileges(
+        boost::beast::http::verb::get, entityPrivileges, userPrivileges));
 }
 
-TEST(PrivilegeTest, PrivilegeCheckForSingleCaseFailure) {
-  auto userPrivileges = Privileges{"Login"};
-  OperationMap entityPrivileges{
-      {boost::beast::http::verb::get, {{"ConfigureManager"}}}};
+TEST(PrivilegeTest, PrivilegeCheckForSingleCaseFailure)
+{
+    auto userPrivileges = Privileges{"Login"};
+    OperationMap entityPrivileges{
+        {boost::beast::http::verb::get, {{"ConfigureManager"}}}};
 
-  EXPECT_FALSE(isMethodAllowedWithPrivileges(boost::beast::http::verb::get,
-                                             entityPrivileges, userPrivileges));
+    EXPECT_FALSE(isMethodAllowedWithPrivileges(
+        boost::beast::http::verb::get, entityPrivileges, userPrivileges));
 }
 
-TEST(PrivilegeTest, PrivilegeCheckForANDCaseSuccess) {
-  auto userPrivileges =
-      Privileges{"Login", "ConfigureManager", "ConfigureSelf"};
-  OperationMap entityPrivileges{
-      {boost::beast::http::verb::get,
-       {{"Login", "ConfigureManager", "ConfigureSelf"}}}};
+TEST(PrivilegeTest, PrivilegeCheckForANDCaseSuccess)
+{
+    auto userPrivileges =
+        Privileges{"Login", "ConfigureManager", "ConfigureSelf"};
+    OperationMap entityPrivileges{
+        {boost::beast::http::verb::get,
+         {{"Login", "ConfigureManager", "ConfigureSelf"}}}};
 
-  EXPECT_TRUE(isMethodAllowedWithPrivileges(boost::beast::http::verb::get,
-                                            entityPrivileges, userPrivileges));
+    EXPECT_TRUE(isMethodAllowedWithPrivileges(
+        boost::beast::http::verb::get, entityPrivileges, userPrivileges));
 }
 
-TEST(PrivilegeTest, PrivilegeCheckForANDCaseFailure) {
-  auto userPrivileges = Privileges{"Login", "ConfigureManager"};
-  OperationMap entityPrivileges{
-      {boost::beast::http::verb::get,
-       {{"Login", "ConfigureManager", "ConfigureSelf"}}}};
+TEST(PrivilegeTest, PrivilegeCheckForANDCaseFailure)
+{
+    auto userPrivileges = Privileges{"Login", "ConfigureManager"};
+    OperationMap entityPrivileges{
+        {boost::beast::http::verb::get,
+         {{"Login", "ConfigureManager", "ConfigureSelf"}}}};
 
-  EXPECT_FALSE(isMethodAllowedWithPrivileges(boost::beast::http::verb::get,
-                                             entityPrivileges, userPrivileges));
+    EXPECT_FALSE(isMethodAllowedWithPrivileges(
+        boost::beast::http::verb::get, entityPrivileges, userPrivileges));
 }
 
-TEST(PrivilegeTest, PrivilegeCheckForORCaseSuccess) {
-  auto userPrivileges = Privileges{"ConfigureManager"};
-  OperationMap entityPrivileges{
-      {boost::beast::http::verb::get, {{"Login"}, {"ConfigureManager"}}}};
+TEST(PrivilegeTest, PrivilegeCheckForORCaseSuccess)
+{
+    auto userPrivileges = Privileges{"ConfigureManager"};
+    OperationMap entityPrivileges{
+        {boost::beast::http::verb::get, {{"Login"}, {"ConfigureManager"}}}};
 
-  EXPECT_TRUE(isMethodAllowedWithPrivileges(boost::beast::http::verb::get,
-                                            entityPrivileges, userPrivileges));
+    EXPECT_TRUE(isMethodAllowedWithPrivileges(
+        boost::beast::http::verb::get, entityPrivileges, userPrivileges));
 }
 
-TEST(PrivilegeTest, PrivilegeCheckForORCaseFailure) {
-  auto userPrivileges = Privileges{"ConfigureComponents"};
-  OperationMap entityPrivileges = OperationMap(
-      {{boost::beast::http::verb::get, {{"Login"}, {"ConfigureManager"}}}});
+TEST(PrivilegeTest, PrivilegeCheckForORCaseFailure)
+{
+    auto userPrivileges = Privileges{"ConfigureComponents"};
+    OperationMap entityPrivileges = OperationMap(
+        {{boost::beast::http::verb::get, {{"Login"}, {"ConfigureManager"}}}});
 
-  EXPECT_FALSE(isMethodAllowedWithPrivileges(boost::beast::http::verb::get,
-                                             entityPrivileges, userPrivileges));
+    EXPECT_FALSE(isMethodAllowedWithPrivileges(
+        boost::beast::http::verb::get, entityPrivileges, userPrivileges));
 }
 
-TEST(PrivilegeTest, DefaultPrivilegeBitsetsAreEmpty) {
-  Privileges privileges;
+TEST(PrivilegeTest, DefaultPrivilegeBitsetsAreEmpty)
+{
+    Privileges privileges;
 
-  EXPECT_THAT(privileges.getActivePrivilegeNames(PrivilegeType::BASE),
-              ::testing::IsEmpty());
+    EXPECT_THAT(privileges.getActivePrivilegeNames(PrivilegeType::BASE),
+                ::testing::IsEmpty());
 
-  EXPECT_THAT(privileges.getActivePrivilegeNames(PrivilegeType::OEM),
-              ::testing::IsEmpty());
+    EXPECT_THAT(privileges.getActivePrivilegeNames(PrivilegeType::OEM),
+                ::testing::IsEmpty());
 }
 
-TEST(PrivilegeTest, GetActivePrivilegeNames) {
-  Privileges privileges;
+TEST(PrivilegeTest, GetActivePrivilegeNames)
+{
+    Privileges privileges;
 
-  EXPECT_THAT(privileges.getActivePrivilegeNames(PrivilegeType::BASE),
-              ::testing::IsEmpty());
+    EXPECT_THAT(privileges.getActivePrivilegeNames(PrivilegeType::BASE),
+                ::testing::IsEmpty());
 
-  std::array<const char*, 5> expectedPrivileges{
-      "Login", "ConfigureManager", "ConfigureUsers", "ConfigureComponents",
-      "ConfigureSelf"};
+    std::array<const char*, 5> expectedPrivileges{
+        "Login", "ConfigureManager", "ConfigureUsers", "ConfigureComponents",
+        "ConfigureSelf"};
 
-  for (const auto& privilege : expectedPrivileges) {
-    EXPECT_TRUE(privileges.setSinglePrivilege(privilege));
-  }
+    for (const auto& privilege : expectedPrivileges)
+    {
+        EXPECT_TRUE(privileges.setSinglePrivilege(privilege));
+    }
 
-  EXPECT_THAT(privileges.getActivePrivilegeNames(PrivilegeType::BASE),
-              ::testing::UnorderedElementsAre(
-                  ::testing::Pointee(expectedPrivileges[0]),
-                  ::testing::Pointee(expectedPrivileges[1]),
-                  ::testing::Pointee(expectedPrivileges[2]),
-                  ::testing::Pointee(expectedPrivileges[3]),
-                  ::testing::Pointee(expectedPrivileges[4])));
+    EXPECT_THAT(privileges.getActivePrivilegeNames(PrivilegeType::BASE),
+                ::testing::UnorderedElementsAre(
+                    ::testing::Pointee(expectedPrivileges[0]),
+                    ::testing::Pointee(expectedPrivileges[1]),
+                    ::testing::Pointee(expectedPrivileges[2]),
+                    ::testing::Pointee(expectedPrivileges[3]),
+                    ::testing::Pointee(expectedPrivileges[4])));
 }
diff --git a/src/ast_jpeg_decoder_test.cpp b/src/ast_jpeg_decoder_test.cpp
index 277ba2c..1552f46 100644
--- a/src/ast_jpeg_decoder_test.cpp
+++ b/src/ast_jpeg_decoder_test.cpp
@@ -1,4 +1,5 @@
 #include "ast_jpeg_decoder.hpp"
+
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
@@ -10,150 +11,160 @@
 using namespace testing;
 MATCHER_P2(IsBetween, a, b,
            std::string(negation ? "isn't" : "is") + " between " +
-               PrintToString(a) + " and " + PrintToString(b)) {
-  return a <= arg && arg <= b;
+               PrintToString(a) + " and " + PrintToString(b))
+{
+    return a <= arg && arg <= b;
 };
 
-TEST(AstJpegDecoder, AllBlue) {
-  ast_video::RawVideoBuffer out;
+TEST(AstJpegDecoder, AllBlue)
+{
+    ast_video::RawVideoBuffer out;
 
-  // This binary blog was created on the aspeed hardware using a blue screen
-  // consisting of the color 0x8EFFFA in a web browser window
-  FILE *fp = fopen("test_resources/aspeedbluescreen.bin", "rb");
-  EXPECT_NE(fp, nullptr);
-  size_t bufferlen =
-      fread(out.buffer.data(), sizeof(decltype(out.buffer)::value_type),
-            out.buffer.size(), fp);
-  fclose(fp);
+    // This binary blog was created on the aspeed hardware using a blue screen
+    // consisting of the color 0x8EFFFA in a web browser window
+    FILE *fp = fopen("test_resources/aspeedbluescreen.bin", "rb");
+    EXPECT_NE(fp, nullptr);
+    size_t bufferlen =
+        fread(out.buffer.data(), sizeof(decltype(out.buffer)::value_type),
+              out.buffer.size(), fp);
+    fclose(fp);
 
-  ASSERT_GT(bufferlen, 0);
+    ASSERT_GT(bufferlen, 0);
 
-  out.ySelector = 0;
-  out.uvSelector = 0;
-  out.mode = ast_video::YuvMode::YUV444;
-  out.width = 800;
-  out.height = 600;
+    out.ySelector = 0;
+    out.uvSelector = 0;
+    out.mode = ast_video::YuvMode::YUV444;
+    out.width = 800;
+    out.height = 600;
 
-  ast_video::AstJpegDecoder d;
-  d.decode(out.buffer, out.width, out.height, out.mode, out.ySelector,
-           out.uvSelector);
+    ast_video::AstJpegDecoder d;
+    d.decode(out.buffer, out.width, out.height, out.mode, out.ySelector,
+             out.uvSelector);
 
-  int tolerance = 16;
+    int tolerance = 16;
 
-  // All pixels should be blue (0x8EFFFA) to within a tolerance (due to jpeg
-  // compression artifacts and quanitization)
-  for (int i = 0; i < out.width * out.height; i++) {
-    ast_video::RGB &pixel = d.outBuffer[i];
-    EXPECT_GT(pixel.r, 0x8E - tolerance);
-    EXPECT_LT(pixel.r, 0x8E + tolerance);
-    EXPECT_GT(pixel.g, 0xFF - tolerance);
-    EXPECT_LT(pixel.g, 0xFF + tolerance);
-    EXPECT_GT(pixel.b, 0xF1 - tolerance);
-    EXPECT_LT(pixel.b, 0xF1 + tolerance);
-  }
-}
-
-TEST(AstJpegDecoder, AllBlack) {
-  ast_video::RawVideoBuffer out;
-
-  // This binary blog was created on the aspeed hardware using a black screen
-  FILE *fp = fopen("test_resources/aspeedblackscreen.bin", "rb");
-  EXPECT_NE(fp, nullptr);
-  size_t bufferlen = fread(out.buffer.data(), sizeof(char),
-                           out.buffer.size() * sizeof(long), fp);
-  fclose(fp);
-
-  ASSERT_GT(bufferlen, 0);
-
-  out.ySelector = 0;
-  out.uvSelector = 0;
-  out.mode = ast_video::YuvMode::YUV444;
-  out.width = 800;
-  out.height = 600;
-
-  ast_video::AstJpegDecoder d;
-  d.decode(out.buffer, out.width, out.height, out.mode, out.ySelector,
-           out.uvSelector);
-
-  // All pixels should be blue (0x8EFFFA) to within a tolerance (due to jpeg
-  // compression artifacts and quanitization)
-  for (int x = 0; x < out.width; x++) {
-    for (int y = 0; y < out.height; y++) {
-      ast_video::RGB pixel = d.outBuffer[x + (y * out.width)];
-      ASSERT_EQ(pixel.r, 0x00) << "X:" << x << " Y: " << y;
-      ASSERT_EQ(pixel.g, 0x00) << "X:" << x << " Y: " << y;
-      ASSERT_EQ(pixel.b, 0x00) << "X:" << x << " Y: " << y;
+    // All pixels should be blue (0x8EFFFA) to within a tolerance (due to jpeg
+    // compression artifacts and quanitization)
+    for (int i = 0; i < out.width * out.height; i++)
+    {
+        ast_video::RGB &pixel = d.outBuffer[i];
+        EXPECT_GT(pixel.r, 0x8E - tolerance);
+        EXPECT_LT(pixel.r, 0x8E + tolerance);
+        EXPECT_GT(pixel.g, 0xFF - tolerance);
+        EXPECT_LT(pixel.g, 0xFF + tolerance);
+        EXPECT_GT(pixel.b, 0xF1 - tolerance);
+        EXPECT_LT(pixel.b, 0xF1 + tolerance);
     }
-  }
 }
 
-TEST(AstJpegDecoder, TestColors) {
-  ast_video::RawVideoBuffer out;
+TEST(AstJpegDecoder, AllBlack)
+{
+    ast_video::RawVideoBuffer out;
 
-  // This binary blog was created on the aspeed hardware using a blue screen
-  // consisting of the color 0x8EFFFA in a web browser window
-  FILE *fp = fopen("test_resources/ubuntu_444_800x600_0chrom_0lum.bin", "rb");
-  EXPECT_NE(fp, nullptr);
-  size_t bufferlen = fread(out.buffer.data(), sizeof(char),
-                           out.buffer.size() * sizeof(long), fp);
-  fclose(fp);
+    // This binary blog was created on the aspeed hardware using a black screen
+    FILE *fp = fopen("test_resources/aspeedblackscreen.bin", "rb");
+    EXPECT_NE(fp, nullptr);
+    size_t bufferlen = fread(out.buffer.data(), sizeof(char),
+                             out.buffer.size() * sizeof(long), fp);
+    fclose(fp);
 
-  ASSERT_GT(bufferlen, 0);
+    ASSERT_GT(bufferlen, 0);
 
-  out.ySelector = 0;
-  out.uvSelector = 0;
-  out.mode = ast_video::YuvMode::YUV444;
-  out.width = 800;
-  out.height = 600;
+    out.ySelector = 0;
+    out.uvSelector = 0;
+    out.mode = ast_video::YuvMode::YUV444;
+    out.width = 800;
+    out.height = 600;
 
-  ast_video::AstJpegDecoder d;
-  d.decode(out.buffer, out.width, out.height, out.mode, out.ySelector,
-           out.uvSelector);
+    ast_video::AstJpegDecoder d;
+    d.decode(out.buffer, out.width, out.height, out.mode, out.ySelector,
+             out.uvSelector);
 
-  int tolerance = 16;
-  /*
-  for (int i = 0; i < out.width * out.height; i++) {
-    ast_video::RGB &pixel = d.outBuffer[i];
-    EXPECT_GT(pixel.r, 0x8E - tolerance);
-    EXPECT_LT(pixel.r, 0x8E + tolerance);
-    EXPECT_GT(pixel.g, 0xFF - tolerance);
-    EXPECT_LT(pixel.g, 0xFF + tolerance);
-    EXPECT_GT(pixel.b, 0xF1 - tolerance);
-    EXPECT_LT(pixel.b, 0xF1 + tolerance);
-  }
-  */
+    // All pixels should be blue (0x8EFFFA) to within a tolerance (due to jpeg
+    // compression artifacts and quanitization)
+    for (int x = 0; x < out.width; x++)
+    {
+        for (int y = 0; y < out.height; y++)
+        {
+            ast_video::RGB pixel = d.outBuffer[x + (y * out.width)];
+            ASSERT_EQ(pixel.r, 0x00) << "X:" << x << " Y: " << y;
+            ASSERT_EQ(pixel.g, 0x00) << "X:" << x << " Y: " << y;
+            ASSERT_EQ(pixel.b, 0x00) << "X:" << x << " Y: " << y;
+        }
+    }
+}
+
+TEST(AstJpegDecoder, TestColors)
+{
+    ast_video::RawVideoBuffer out;
+
+    // This binary blog was created on the aspeed hardware using a blue screen
+    // consisting of the color 0x8EFFFA in a web browser window
+    FILE *fp = fopen("test_resources/ubuntu_444_800x600_0chrom_0lum.bin", "rb");
+    EXPECT_NE(fp, nullptr);
+    size_t bufferlen = fread(out.buffer.data(), sizeof(char),
+                             out.buffer.size() * sizeof(long), fp);
+    fclose(fp);
+
+    ASSERT_GT(bufferlen, 0);
+
+    out.ySelector = 0;
+    out.uvSelector = 0;
+    out.mode = ast_video::YuvMode::YUV444;
+    out.width = 800;
+    out.height = 600;
+
+    ast_video::AstJpegDecoder d;
+    d.decode(out.buffer, out.width, out.height, out.mode, out.ySelector,
+             out.uvSelector);
+
+    int tolerance = 16;
+    /*
+    for (int i = 0; i < out.width * out.height; i++) {
+      ast_video::RGB &pixel = d.outBuffer[i];
+      EXPECT_GT(pixel.r, 0x8E - tolerance);
+      EXPECT_LT(pixel.r, 0x8E + tolerance);
+      EXPECT_GT(pixel.g, 0xFF - tolerance);
+      EXPECT_LT(pixel.g, 0xFF + tolerance);
+      EXPECT_GT(pixel.b, 0xF1 - tolerance);
+      EXPECT_LT(pixel.b, 0xF1 + tolerance);
+    }
+    */
 }
 
 // Tests the buffers around the screen aren't written to
-TEST(AstJpegDecoder, BufferLimits) {
-  ast_video::RawVideoBuffer out;
+TEST(AstJpegDecoder, BufferLimits)
+{
+    ast_video::RawVideoBuffer out;
 
-  // This binary blog was created on the aspeed hardware using a black screen
-  FILE *fp = fopen("test_resources/aspeedblackscreen.bin", "rb");
-  EXPECT_NE(fp, nullptr);
-  size_t bufferlen = fread(out.buffer.data(), sizeof(char),
-                           out.buffer.size() * sizeof(long), fp);
-  fclose(fp);
+    // This binary blog was created on the aspeed hardware using a black screen
+    FILE *fp = fopen("test_resources/aspeedblackscreen.bin", "rb");
+    EXPECT_NE(fp, nullptr);
+    size_t bufferlen = fread(out.buffer.data(), sizeof(char),
+                             out.buffer.size() * sizeof(long), fp);
+    fclose(fp);
 
-  ASSERT_GT(bufferlen, 0);
+    ASSERT_GT(bufferlen, 0);
 
-  out.ySelector = 0;
-  out.uvSelector = 0;
-  out.mode = ast_video::YuvMode::YUV444;
-  out.width = 800;
-  out.height = 600;
+    out.ySelector = 0;
+    out.uvSelector = 0;
+    out.mode = ast_video::YuvMode::YUV444;
+    out.width = 800;
+    out.height = 600;
 
-  ast_video::AstJpegDecoder d;
-  d.decode(out.buffer, out.width, out.height, out.mode, out.ySelector,
-           out.uvSelector);
-  // reserved pixel should be default value
-  for (auto &pixel : d.outBuffer) {
-    EXPECT_EQ(pixel.reserved, 0xAA);
-  }
-  // All pixels beyond the buffer should be zero
-  for (int i = out.width * out.height; i < d.outBuffer.size(); i++) {
-    EXPECT_EQ(d.outBuffer[i].r, 0x00) << "index:" << i;
-    EXPECT_EQ(d.outBuffer[i].b, 0x00) << "index:" << i;
-    EXPECT_EQ(d.outBuffer[i].g, 0x00) << "index:" << i;
-  }
+    ast_video::AstJpegDecoder d;
+    d.decode(out.buffer, out.width, out.height, out.mode, out.ySelector,
+             out.uvSelector);
+    // reserved pixel should be default value
+    for (auto &pixel : d.outBuffer)
+    {
+        EXPECT_EQ(pixel.reserved, 0xAA);
+    }
+    // All pixels beyond the buffer should be zero
+    for (int i = out.width * out.height; i < d.outBuffer.size(); i++)
+    {
+        EXPECT_EQ(d.outBuffer[i].r, 0x00) << "index:" << i;
+        EXPECT_EQ(d.outBuffer[i].b, 0x00) << "index:" << i;
+        EXPECT_EQ(d.outBuffer[i].g, 0x00) << "index:" << i;
+    }
 }
\ No newline at end of file
diff --git a/src/ast_video_puller_test.cpp b/src/ast_video_puller_test.cpp
index 58adda9..4fa3dcc 100644
--- a/src/ast_video_puller_test.cpp
+++ b/src/ast_video_puller_test.cpp
@@ -2,6 +2,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+
 #include <ast_jpeg_decoder.hpp>
 #include <ast_video_puller.hpp>
 #include <chrono>
@@ -10,38 +11,46 @@
 #include <iostream>
 #include <thread>
 #include <vector>
+
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
-TEST(AstvideoPuller, BasicRead) {
-  ast_video::RawVideoBuffer out;
-  bool have_hardware = false;
-  if (access("/dev/video", F_OK) != -1) {
-    ast_video::SimpleVideoPuller p;
-    p.initialize();
-    out = p.readVideo();
-  } else {
-    FILE *fp = fopen("test_resources/ubuntu_444_800x600_0chrom_0lum.bin", "rb");
-    if (fp) {
-      size_t newLen = fread(out.buffer.data(), sizeof(char),
-                            out.buffer.size() * sizeof(long), fp);
-      if (ferror(fp) != 0) {
-        fputs("Error reading file", stderr);
-      }
-      fclose(fp);
-      out.buffer.resize(newLen);
-      out.mode = ast_video::YuvMode::YUV444;
-      out.width = 800;
-      out.height = 600;
-      out.ySelector = 0;
-      out.uvSelector = 0;
+TEST(AstvideoPuller, BasicRead)
+{
+    ast_video::RawVideoBuffer out;
+    bool have_hardware = false;
+    if (access("/dev/video", F_OK) != -1)
+    {
+        ast_video::SimpleVideoPuller p;
+        p.initialize();
+        out = p.readVideo();
     }
-  }
+    else
+    {
+        FILE *fp =
+            fopen("test_resources/ubuntu_444_800x600_0chrom_0lum.bin", "rb");
+        if (fp)
+        {
+            size_t newLen = fread(out.buffer.data(), sizeof(char),
+                                  out.buffer.size() * sizeof(long), fp);
+            if (ferror(fp) != 0)
+            {
+                fputs("Error reading file", stderr);
+            }
+            fclose(fp);
+            out.buffer.resize(newLen);
+            out.mode = ast_video::YuvMode::YUV444;
+            out.width = 800;
+            out.height = 600;
+            out.ySelector = 0;
+            out.uvSelector = 0;
+        }
+    }
 
-  FILE *fp = fopen("/tmp/screendata.bin", "wb");
-  fwrite(out.buffer.data(), sizeof(char), out.buffer.size(), fp);
+    FILE *fp = fopen("/tmp/screendata.bin", "wb");
+    fwrite(out.buffer.data(), sizeof(char), out.buffer.size(), fp);
 
-  ast_video::AstJpegDecoder d;
-  d.decode(out.buffer, out.width, out.height, out.mode, out.ySelector,
-           out.uvSelector);
+    ast_video::AstJpegDecoder d;
+    d.decode(out.buffer, out.width, out.height, out.mode, out.ySelector,
+             out.uvSelector);
 }
diff --git a/src/base64.cpp b/src/base64.cpp
index 0013c28..851ef72 100644
--- a/src/base64.cpp
+++ b/src/base64.cpp
@@ -1,143 +1,165 @@
 #include <base64.hpp>
 
-namespace base64 {
-bool base64_encode(const std::string &input, std::string &output) {
-  // This is left as a raw array (and not a range checked std::array) under the
-  // suspicion that the optimizer is not smart enough to remove the range checks
-  // that would be done below if at were called.  As is, this array is 64 bytes
-  // long, which should be greater than the max of 0b00111111 when indexed
-  // NOLINT calls below are to silence clang-tidy about this
-  // TODO(ed) this requires further investigation if a more safe method could be
-  // used without performance impact.
-  static const char encoding_data[] =
-      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+namespace base64
+{
+bool base64_encode(const std::string &input, std::string &output)
+{
+    // This is left as a raw array (and not a range checked std::array) under
+    // the suspicion that the optimizer is not smart enough to remove the range
+    // checks that would be done below if at were called.  As is, this array is
+    // 64 bytes long, which should be greater than the max of 0b00111111 when
+    // indexed NOLINT calls below are to silence clang-tidy about this
+    // TODO(ed) this requires further investigation if a more safe method could
+    // be used without performance impact.
+    static const char encoding_data[] =
+        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
-  size_t input_length = input.size();
+    size_t input_length = input.size();
 
-  // allocate space for output string
-  output.clear();
-  output.reserve(((input_length + 2) / 3) * 4);
+    // allocate space for output string
+    output.clear();
+    output.reserve(((input_length + 2) / 3) * 4);
 
-  // for each 3-bytes sequence from the input, extract 4 6-bits sequences and
-  // encode using
-  // encoding_data lookup table.
-  // if input do not contains enough chars to complete 3-byte sequence,use pad
-  // char '='
-  for (size_t i = 0; i < input_length; i++) {
-    int base64code0 = 0;
-    int base64code1 = 0;
-    int base64code2 = 0;
-    int base64code3 = 0;
+    // for each 3-bytes sequence from the input, extract 4 6-bits sequences and
+    // encode using
+    // encoding_data lookup table.
+    // if input do not contains enough chars to complete 3-byte sequence,use pad
+    // char '='
+    for (size_t i = 0; i < input_length; i++)
+    {
+        int base64code0 = 0;
+        int base64code1 = 0;
+        int base64code2 = 0;
+        int base64code3 = 0;
 
-    base64code0 = (input[i] >> 2) & 0x3f;  // 1-byte 6 bits
+        base64code0 = (input[i] >> 2) & 0x3f; // 1-byte 6 bits
 
-    output += encoding_data[base64code0];  // NOLINT
-    base64code1 = (input[i] << 4) & 0x3f;  // 1-byte 2 bits +
+        output += encoding_data[base64code0]; // NOLINT
+        base64code1 = (input[i] << 4) & 0x3f; // 1-byte 2 bits +
 
-    if (++i < input_length) {
-      base64code1 |= (input[i] >> 4) & 0x0f;  // 2-byte 4 bits
-      output += encoding_data[base64code1];   // NOLINT
-      base64code2 = (input[i] << 2) & 0x3f;   // 2-byte 4 bits +
+        if (++i < input_length)
+        {
+            base64code1 |= (input[i] >> 4) & 0x0f; // 2-byte 4 bits
+            output += encoding_data[base64code1];  // NOLINT
+            base64code2 = (input[i] << 2) & 0x3f;  // 2-byte 4 bits +
 
-      if (++i < input_length) {
-        base64code2 |= (input[i] >> 6) & 0x03;  // 3-byte 2 bits
-        base64code3 = input[i] & 0x3f;          // 3-byte 6 bits
-        output += encoding_data[base64code2];   // NOLINT
-        output += encoding_data[base64code3];   // NOLINT
-      } else {
-        output += encoding_data[base64code2];  // NOLINT
-        output += '=';
-      }
-    } else {
-      output += encoding_data[base64code1];  // NOLINT
-      output += '=';
-      output += '=';
+            if (++i < input_length)
+            {
+                base64code2 |= (input[i] >> 6) & 0x03; // 3-byte 2 bits
+                base64code3 = input[i] & 0x3f;         // 3-byte 6 bits
+                output += encoding_data[base64code2];  // NOLINT
+                output += encoding_data[base64code3];  // NOLINT
+            }
+            else
+            {
+                output += encoding_data[base64code2]; // NOLINT
+                output += '=';
+            }
+        }
+        else
+        {
+            output += encoding_data[base64code1]; // NOLINT
+            output += '=';
+            output += '=';
+        }
     }
-  }
 
-  return true;
+    return true;
 }
 
-bool base64_decode(const std::string &input, std::string &output) {
-  static const char nop = -1;
-  // See note on encoding_data[] in above function
-  static const char decoding_data[] = {
-      nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
-      nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
-      nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, 62,  nop,
-      nop, nop, 63,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  nop, nop,
-      nop, nop, nop, nop, nop, 0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
-      10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,
-      25,  nop, nop, nop, nop, nop, nop, 26,  27,  28,  29,  30,  31,  32,  33,
-      34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
-      49,  50,  51,  nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
-      nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
-      nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
-      nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
-      nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
-      nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
-      nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
-      nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
-      nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
-      nop};
+bool base64_decode(const std::string &input, std::string &output)
+{
+    static const char nop = -1;
+    // See note on encoding_data[] in above function
+    static const char decoding_data[] = {
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, 62,  nop, nop, nop, 63,  52,  53,  54,  55,  56,  57,  58,  59,
+        60,  61,  nop, nop, nop, nop, nop, nop, nop, 0,   1,   2,   3,   4,
+        5,   6,   7,   8,   9,   10,  11,  12,  13,  14,  15,  16,  17,  18,
+        19,  20,  21,  22,  23,  24,  25,  nop, nop, nop, nop, nop, nop, 26,
+        27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,
+        41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop, nop,
+        nop, nop, nop, nop};
 
-  size_t input_length = input.size();
+    size_t input_length = input.size();
 
-  // allocate space for output string
-  output.clear();
-  output.reserve(((input_length + 2) / 3) * 4);
+    // allocate space for output string
+    output.clear();
+    output.reserve(((input_length + 2) / 3) * 4);
 
-  // for each 4-bytes sequence from the input, extract 4 6-bits sequences by
-  // droping first two bits
-  // and regenerate into 3 8-bits sequences
+    // for each 4-bytes sequence from the input, extract 4 6-bits sequences by
+    // droping first two bits
+    // and regenerate into 3 8-bits sequences
 
-  for (size_t i = 0; i < input_length; i++) {
-    char base64code0;
-    char base64code1;
-    char base64code2 = 0;  // initialized to 0 to suppress warnings
-    char base64code3;
+    for (size_t i = 0; i < input_length; i++)
+    {
+        char base64code0;
+        char base64code1;
+        char base64code2 = 0; // initialized to 0 to suppress warnings
+        char base64code3;
 
-    base64code0 = decoding_data[static_cast<int>(input[i])];  // NOLINT
-    if (base64code0 == nop) {  // non base64 character
-      return false;
-    }
-    if (!(++i < input_length)) {  // we need at least two input bytes for first
-                                  // byte output
-      return false;
-    }
-    base64code1 = decoding_data[static_cast<int>(input[i])];  // NOLINT
-    if (base64code1 == nop) {  // non base64 character
-      return false;
-    }
-    output +=
-        static_cast<char>((base64code0 << 2) | ((base64code1 >> 4) & 0x3));
+        base64code0 = decoding_data[static_cast<int>(input[i])]; // NOLINT
+        if (base64code0 == nop)
+        { // non base64 character
+            return false;
+        }
+        if (!(++i < input_length))
+        { // we need at least two input bytes for first
+          // byte output
+            return false;
+        }
+        base64code1 = decoding_data[static_cast<int>(input[i])]; // NOLINT
+        if (base64code1 == nop)
+        { // non base64 character
+            return false;
+        }
+        output +=
+            static_cast<char>((base64code0 << 2) | ((base64code1 >> 4) & 0x3));
 
-    if (++i < input_length) {
-      char c = input[i];
-      if (c == '=') {  // padding , end of input
-        return (base64code1 & 0x0f) == 0;
-      }
-      base64code2 = decoding_data[static_cast<int>(input[i])];  // NOLINT
-      if (base64code2 == nop) {  // non base64 character
-        return false;
-      }
-      output += static_cast<char>(((base64code1 << 4) & 0xf0) |
-                                  ((base64code2 >> 2) & 0x0f));
+        if (++i < input_length)
+        {
+            char c = input[i];
+            if (c == '=')
+            { // padding , end of input
+                return (base64code1 & 0x0f) == 0;
+            }
+            base64code2 = decoding_data[static_cast<int>(input[i])]; // NOLINT
+            if (base64code2 == nop)
+            { // non base64 character
+                return false;
+            }
+            output += static_cast<char>(((base64code1 << 4) & 0xf0) |
+                                        ((base64code2 >> 2) & 0x0f));
+        }
+
+        if (++i < input_length)
+        {
+            char c = input[i];
+            if (c == '=')
+            { // padding , end of input
+                return (base64code2 & 0x03) == 0;
+            }
+            base64code3 = decoding_data[static_cast<int>(input[i])]; // NOLINT
+            if (base64code3 == nop)
+            { // non base64 character
+                return false;
+            }
+            output +=
+                static_cast<char>((((base64code2 << 6) & 0xc0) | base64code3));
+        }
     }
 
-    if (++i < input_length) {
-      char c = input[i];
-      if (c == '=') {  // padding , end of input
-        return (base64code2 & 0x03) == 0;
-      }
-      base64code3 = decoding_data[static_cast<int>(input[i])];  // NOLINT
-      if (base64code3 == nop) {  // non base64 character
-        return false;
-      }
-      output += static_cast<char>((((base64code2 << 6) & 0xc0) | base64code3));
-    }
-  }
-
-  return true;
+    return true;
 }
-}  // namespace base64
+} // namespace base64
diff --git a/src/crow_getroutes_test.cpp b/src/crow_getroutes_test.cpp
index 29052a9..e76d221 100644
--- a/src/crow_getroutes_test.cpp
+++ b/src/crow_getroutes_test.cpp
@@ -1,43 +1,47 @@
 #include <crow/app.h>
+
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
 using namespace crow;
 using namespace std;
 
-TEST(GetRoutes, TestEmptyRoutes) {
-  SimpleApp app;
-  decltype(app)::server_t server(&app, "127.0.0.1", 45451);
+TEST(GetRoutes, TestEmptyRoutes)
+{
+    SimpleApp app;
+    decltype(app)::server_t server(&app, "127.0.0.1", 45451);
 
-  EXPECT_THAT(app.getRoutes(), testing::IsEmpty());
+    EXPECT_THAT(app.getRoutes(), testing::IsEmpty());
 }
 
 // Tests that static urls are correctly passed
-TEST(GetRoutes, TestOneRoute) {
-  SimpleApp app;
-  decltype(app)::server_t server(&app, "127.0.0.1", 45451);
-  BMCWEB_ROUTE(app, "/")([]() { return boost::beast::http::status::ok; });
+TEST(GetRoutes, TestOneRoute)
+{
+    SimpleApp app;
+    decltype(app)::server_t server(&app, "127.0.0.1", 45451);
+    BMCWEB_ROUTE(app, "/")([]() { return boost::beast::http::status::ok; });
 
-  EXPECT_THAT(app.getRoutes(),
-              testing::ElementsAre(testing::Pointee(std::string("/"))));
+    EXPECT_THAT(app.getRoutes(),
+                testing::ElementsAre(testing::Pointee(std::string("/"))));
 }
 
 // Tests that static urls are correctly passed
-TEST(GetRoutes, TestlotsOfRoutes) {
-  SimpleApp app;
-  decltype(app)::server_t server(&app, "127.0.0.1", 45451);
-  BMCWEB_ROUTE(app, "/")([]() { return boost::beast::http::status::ok; });
-  BMCWEB_ROUTE(app, "/foo")([]() { return boost::beast::http::status::ok; });
-  BMCWEB_ROUTE(app, "/bar")([]() { return boost::beast::http::status::ok; });
-  BMCWEB_ROUTE(app, "/baz")([]() { return boost::beast::http::status::ok; });
-  BMCWEB_ROUTE(app, "/boo")([]() { return boost::beast::http::status::ok; });
-  BMCWEB_ROUTE(app, "/moo")([]() { return boost::beast::http::status::ok; });
+TEST(GetRoutes, TestlotsOfRoutes)
+{
+    SimpleApp app;
+    decltype(app)::server_t server(&app, "127.0.0.1", 45451);
+    BMCWEB_ROUTE(app, "/")([]() { return boost::beast::http::status::ok; });
+    BMCWEB_ROUTE(app, "/foo")([]() { return boost::beast::http::status::ok; });
+    BMCWEB_ROUTE(app, "/bar")([]() { return boost::beast::http::status::ok; });
+    BMCWEB_ROUTE(app, "/baz")([]() { return boost::beast::http::status::ok; });
+    BMCWEB_ROUTE(app, "/boo")([]() { return boost::beast::http::status::ok; });
+    BMCWEB_ROUTE(app, "/moo")([]() { return boost::beast::http::status::ok; });
 
-  EXPECT_THAT(app.getRoutes(), testing::UnorderedElementsAre(
-                                   testing::Pointee(std::string("/")),
-                                   testing::Pointee(std::string("/foo")),
-                                   testing::Pointee(std::string("/bar")),
-                                   testing::Pointee(std::string("/baz")),
-                                   testing::Pointee(std::string("/boo")),
-                                   testing::Pointee(std::string("/moo"))));
+    EXPECT_THAT(app.getRoutes(), testing::UnorderedElementsAre(
+                                     testing::Pointee(std::string("/")),
+                                     testing::Pointee(std::string("/foo")),
+                                     testing::Pointee(std::string("/bar")),
+                                     testing::Pointee(std::string("/baz")),
+                                     testing::Pointee(std::string("/boo")),
+                                     testing::Pointee(std::string("/moo"))));
 }
\ No newline at end of file
diff --git a/src/crow_test.cpp b/src/crow_test.cpp
index cd66817..96b90b0 100644
--- a/src/crow_test.cpp
+++ b/src/crow_test.cpp
@@ -1,7 +1,9 @@
-#include "crow.h"
 #include <iostream>
 #include <sstream>
 #include <vector>
+
+#include "crow.h"
+
 #include "gtest/gtest.h"
 #undef BMCWEB_LOG_LEVEL
 #define BMCWEB_LOG_LEVEL 0
@@ -10,864 +12,934 @@
 using namespace crow;
 
 bool failed__ = false;
-void error_print() { cerr << endl; }
+void error_print()
+{
+    cerr << endl;
+}
 
 template <typename A, typename... Args>
-void error_print(const A& a, Args... args) {
-  cerr << a;
-  error_print(args...);
+void error_print(const A& a, Args... args)
+{
+    cerr << a;
+    error_print(args...);
 }
 
-template <typename... Args>
-void fail(Args... args) {
-  error_print(args...);
-  failed__ = true;
+template <typename... Args> void fail(Args... args)
+{
+    error_print(args...);
+    failed__ = true;
 }
 
-#define ASSERT_EQUAL(a, b)                                                  \
-  if ((a) != (b))                                                           \
-  fail(__FILE__ ":", __LINE__, ": Assert fail: expected ", (a), " actual ", \
-       (b), ", " #a " == " #b ", at " __FILE__ ":", __LINE__)
-#define ASSERT_NOTEQUAL(a, b)                                       \
-  if ((a) == (b))                                                   \
-  fail(__FILE__ ":", __LINE__, ": Assert fail: not expected ", (a), \
-       ", " #a " != " #b ", at " __FILE__ ":", __LINE__)
+#define ASSERT_EQUAL(a, b)                                                     \
+    if ((a) != (b))                                                            \
+    fail(__FILE__ ":", __LINE__, ": Assert fail: expected ", (a), " actual ",  \
+         (b), ", " #a " == " #b ", at " __FILE__ ":", __LINE__)
+#define ASSERT_NOTEQUAL(a, b)                                                  \
+    if ((a) == (b))                                                            \
+    fail(__FILE__ ":", __LINE__, ": Assert fail: not expected ", (a),          \
+         ", " #a " != " #b ", at " __FILE__ ":", __LINE__)
 
-#define DISABLE_TEST(x) \
-  struct test##x {      \
-    void test();        \
-  } x##_;               \
-  void test##x::test()
+#define DISABLE_TEST(x)                                                        \
+    struct test##x                                                             \
+    {                                                                          \
+        void test();                                                           \
+    } x##_;                                                                    \
+    void test##x::test()
 
 #define LOCALHOST_ADDRESS "127.0.0.1"
 
-TEST(Crow, Rule) {
-  TaggedRule<> r("/http/");
-  r.name("abc");
+TEST(Crow, Rule)
+{
+    TaggedRule<> r("/http/");
+    r.name("abc");
 
-  // empty handler - fail to validate
-  try {
+    // empty handler - fail to validate
+    try
+    {
+        r.validate();
+        fail("empty handler should fail to validate");
+    }
+    catch (runtime_error& e)
+    {
+    }
+
+    int x = 0;
+
+    // registering handler
+    r([&x] {
+        x = 1;
+        return "";
+    });
+
     r.validate();
-    fail("empty handler should fail to validate");
-  } catch (runtime_error& e) {
-  }
 
-  int x = 0;
-
-  // registering handler
-  r([&x] {
-    x = 1;
-    return "";
-  });
-
-  r.validate();
-
-  Response res;
-
-  // executing handler
-  ASSERT_EQUAL(0, x);
-  boost::beast::http::request<boost::beast::http::string_body> req{};
-  r.handle(Request(req), res, RoutingParams());
-  ASSERT_EQUAL(1, x);
-
-  // registering handler with Request argument
-  r([&x](const crow::Request&) {
-    x = 2;
-    return "";
-  });
-
-  r.validate();
-
-  // executing handler
-  ASSERT_EQUAL(1, x);
-  r.handle(Request(req), res, RoutingParams());
-  ASSERT_EQUAL(2, x);
-}
-
-TEST(Crow, ParameterTagging) {
-  static_assert(black_magic::isValid("<int><int><int>"), "valid url");
-  static_assert(!black_magic::isValid("<int><int<<int>"), "invalid url");
-  static_assert(!black_magic::isValid("nt>"), "invalid url");
-  ASSERT_EQUAL(1, black_magic::get_parameter_tag("<int>"));
-  ASSERT_EQUAL(2, black_magic::get_parameter_tag("<uint>"));
-  ASSERT_EQUAL(3, black_magic::get_parameter_tag("<float>"));
-  ASSERT_EQUAL(3, black_magic::get_parameter_tag("<double>"));
-  ASSERT_EQUAL(4, black_magic::get_parameter_tag("<str>"));
-  ASSERT_EQUAL(4, black_magic::get_parameter_tag("<string>"));
-  ASSERT_EQUAL(5, black_magic::get_parameter_tag("<path>"));
-  ASSERT_EQUAL(6 * 6 + 6 + 1,
-               black_magic::get_parameter_tag("<int><int><int>"));
-  ASSERT_EQUAL(6 * 6 + 6 + 2,
-               black_magic::get_parameter_tag("<uint><int><int>"));
-  ASSERT_EQUAL(6 * 6 + 6 * 3 + 2,
-               black_magic::get_parameter_tag("<uint><double><int>"));
-
-  // url definition parsed in compile time, build into *one number*, and given
-  // to template argument
-  static_assert(
-      std::is_same<black_magic::S<uint64_t, double, int64_t>,
-                   black_magic::Arguments<6 * 6 + 6 * 3 + 2>::type>::value,
-      "tag to type container");
-}
-
-TEST(Crow, PathRouting) {
-  SimpleApp app;
-
-  BMCWEB_ROUTE(app, "/file")
-  ([] { return "file"; });
-
-  BMCWEB_ROUTE(app, "/path/")
-  ([] { return "path"; });
-
-  {
-    boost::beast::http::request<boost::beast::http::string_body> r{};
-    Request req{r};
     Response res;
 
-    req.url = "/file";
-
-    app.handle(req, res);
-
-    ASSERT_EQUAL(200, res.resultInt());
-  }
-  {
-    boost::beast::http::request<boost::beast::http::string_body> r{};
-    Request req{r};
-    Response res;
-
-    req.url = "/file/";
-
-    app.handle(req, res);
-    ASSERT_EQUAL(404, res.resultInt());
-  }
-  {
-    boost::beast::http::request<boost::beast::http::string_body> r{};
-    Request req{r};
-    Response res;
-
-    req.url = "/path";
-
-    app.handle(req, res);
-    ASSERT_NOTEQUAL(404, res.resultInt());
-  }
-  {
-    boost::beast::http::request<boost::beast::http::string_body> r{};
-    Request req{r};
-    Response res;
-
-    req.url = "/path/";
-
-    app.handle(req, res);
-    ASSERT_EQUAL(200, res.resultInt());
-  }
-}
-
-TEST(Crow, RoutingTest) {
-  SimpleApp app;
-  int A{};
-  uint32_t b{};
-  double C{};
-  string D{};
-  string E{};
-
-  BMCWEB_ROUTE(app, "/0/<uint>")
-  ([&](uint32_t b) {
-    b = b;
-    return "OK";
-  });
-
-  BMCWEB_ROUTE(app, "/1/<int>/<uint>")
-  ([&](int a, uint32_t b) {
-    A = a;
-    b = b;
-    return "OK";
-  });
-
-  BMCWEB_ROUTE(app, "/4/<int>/<uint>/<double>/<string>")
-  ([&](int a, uint32_t b, double c, string d) {
-    A = a;
-    b = b;
-    C = c;
-    D = d;
-    return "OK";
-  });
-
-  BMCWEB_ROUTE(app, "/5/<int>/<uint>/<double>/<string>/<path>")
-  ([&](int a, uint32_t b, double c, string d, string e) {
-    A = a;
-    b = b;
-    C = c;
-    D = d;
-    E = e;
-    return "OK";
-  });
-
-  app.validate();
-  // app.debugPrint();
-  {
-    boost::beast::http::request<boost::beast::http::string_body> r{};
-    Request req{r};
-    Response res;
-
-    req.url = "/-1";
-
-    app.handle(req, res);
-
-    ASSERT_EQUAL(404, res.resultInt());
-  }
-
-  {
-    boost::beast::http::request<boost::beast::http::string_body> r{};
-    Request req{r};
-    Response res;
-
-    req.url = "/0/1001999";
-
-    app.handle(req, res);
-
-    ASSERT_EQUAL(200, res.resultInt());
-
-    ASSERT_EQUAL(1001999, b);
-  }
-
-  {
-    boost::beast::http::request<boost::beast::http::string_body> r{};
-    Request req{r};
-    Response res;
-
-    req.url = "/1/-100/1999";
-
-    app.handle(req, res);
-
-    ASSERT_EQUAL(200, res.resultInt());
-
-    ASSERT_EQUAL(-100, A);
-    ASSERT_EQUAL(1999, b);
-  }
-  {
-    boost::beast::http::request<boost::beast::http::string_body> r{};
-    Request req{r};
-    Response res;
-
-    req.url = "/4/5000/3/-2.71828/hellhere";
-
-    app.handle(req, res);
-
-    ASSERT_EQUAL(200, res.resultInt());
-
-    ASSERT_EQUAL(5000, A);
-    ASSERT_EQUAL(3, b);
-    ASSERT_EQUAL(-2.71828, C);
-    ASSERT_EQUAL("hellhere", D);
-  }
-  {
-    boost::beast::http::request<boost::beast::http::string_body> r{};
-    Request req{r};
-    Response res;
-
-    req.url = "/5/-5/999/3.141592/hello_there/a/b/c/d";
-
-    app.handle(req, res);
-
-    ASSERT_EQUAL(200, res.resultInt());
-
-    ASSERT_EQUAL(-5, A);
-    ASSERT_EQUAL(999, b);
-    ASSERT_EQUAL(3.141592, C);
-    ASSERT_EQUAL("hello_there", D);
-    ASSERT_EQUAL("a/b/c/d", E);
-  }
-}
-
-TEST(Crow, simple_response_RoutingParams) {
-  ASSERT_EQUAL(100,
-               Response(boost::beast::http::status::continue_).resultInt());
-  ASSERT_EQUAL(200, Response("Hello there").resultInt());
-  ASSERT_EQUAL(500, Response(boost::beast::http::status::internal_server_error,
-                             "Internal Error?")
-                        .resultInt());
-
-  RoutingParams rp;
-  rp.intParams.push_back(1);
-  rp.intParams.push_back(5);
-  rp.uintParams.push_back(2);
-  rp.doubleParams.push_back(3);
-  rp.stringParams.push_back("hello");
-  ASSERT_EQUAL(1, rp.get<int64_t>(0));
-  ASSERT_EQUAL(5, rp.get<int64_t>(1));
-  ASSERT_EQUAL(2, rp.get<uint64_t>(0));
-  ASSERT_EQUAL(3, rp.get<double>(0));
-  ASSERT_EQUAL("hello", rp.get<string>(0));
-}
-
-TEST(Crow, handler_with_response) {
-  SimpleApp app;
-  BMCWEB_ROUTE(app, "/")([](const crow::Request&, crow::Response&) {});
-}
-
-TEST(Crow, http_method) {
-  SimpleApp app;
-
-  BMCWEB_ROUTE(app, "/").methods("POST"_method,
-                                 "GET"_method)([](const Request& req) {
-    if (req.method() == "GET"_method)
-      return "2";
-    else
-      return "1";
-  });
-
-  BMCWEB_ROUTE(app, "/get_only")
-      .methods("GET"_method)([](const Request& /*req*/) { return "get"; });
-  BMCWEB_ROUTE(app, "/post_only")
-      .methods("POST"_method)([](const Request& /*req*/) { return "post"; });
-
-  // cannot have multiple handlers for the same url
-  // BMCWEB_ROUTE(app, "/")
-  //.methods("GET"_method)
-  //([]{ return "2"; });
-
-  {
-    boost::beast::http::request<boost::beast::http::string_body> r{};
-    Request req{r};
-    Response res;
-
-    req.url = "/";
-    app.handle(req, res);
-
-    ASSERT_EQUAL("2", res.body());
-  }
-  {
-    boost::beast::http::request<boost::beast::http::string_body> r{};
-    Request req{r};
-    Response res;
-
-    req.url = "/";
-    r.method("POST"_method);
-    app.handle(req, res);
-
-    ASSERT_EQUAL("1", res.body());
-  }
-
-  {
-    boost::beast::http::request<boost::beast::http::string_body> r{};
-    Request req{r};
-    Response res;
-
-    req.url = "/get_only";
-    app.handle(req, res);
-
-    ASSERT_EQUAL("get", res.body());
-  }
-
-  {
-    boost::beast::http::request<boost::beast::http::string_body> r{};
-    Request req{r};
-    Response res;
-
-    req.url = "/get_only";
-    r.method("POST"_method);
-    app.handle(req, res);
-
-    ASSERT_NOTEQUAL("get", res.body());
-  }
-}
-
-TEST(Crow, server_handling_error_request) {
-  static char buf[2048];
-  SimpleApp app;
-  BMCWEB_ROUTE(app, "/")([] { return "A"; });
-  Server<SimpleApp> server(&app, LOCALHOST_ADDRESS, 45451);
-  auto _ = async(launch::async, [&] { server.run(); });
-  std::string sendmsg = "POX";
-  asio::io_service is;
-  {
-    asio::ip::tcp::socket c(is);
-    c.connect(asio::ip::tcp::endpoint(
-        asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
-
-    c.send(asio::buffer(sendmsg));
-
-    try {
-      c.receive(asio::buffer(buf, 2048));
-      fail();
-    } catch (std::exception& e) {
-      // std::cerr << e.what() << std::endl;
-    }
-  }
-  server.stop();
-}
-
-TEST(Crow, multi_server) {
-  static char buf[2048];
-  SimpleApp app1, app2;
-  BMCWEB_ROUTE(app1, "/").methods("GET"_method,
-                                  "POST"_method)([] { return "A"; });
-  BMCWEB_ROUTE(app2, "/").methods("GET"_method,
-                                  "POST"_method)([] { return "B"; });
-
-  Server<SimpleApp> server1(&app1, LOCALHOST_ADDRESS, 45451);
-  Server<SimpleApp> server2(&app2, LOCALHOST_ADDRESS, 45452);
-
-  auto _ = async(launch::async, [&] { server1.run(); });
-  auto _2 = async(launch::async, [&] { server2.run(); });
-
-  std::string sendmsg =
-      "POST /\r\nContent-Length:3\r\nX-HeaderTest: 123\r\n\r\nA=b\r\n";
-  asio::io_service is;
-  {
-    asio::ip::tcp::socket c(is);
-    c.connect(asio::ip::tcp::endpoint(
-        asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
-
-    c.send(asio::buffer(sendmsg));
-
-    size_t recved = c.receive(asio::buffer(buf, 2048));
-    ASSERT_EQUAL('A', buf[recved - 1]);
-  }
-
-  {
-    asio::ip::tcp::socket c(is);
-    c.connect(asio::ip::tcp::endpoint(
-        asio::ip::address::from_string(LOCALHOST_ADDRESS), 45452));
-
-    for (auto ch : sendmsg) {
-      char buf[1] = {ch};
-      c.send(asio::buffer(buf));
-    }
-
-    size_t recved = c.receive(asio::buffer(buf, 2048));
-    ASSERT_EQUAL('b', buf[recved - 1]);
-  }
-
-  server1.stop();
-  server2.stop();
-}
-
-TEST(Crow, black_magic) {
-  using namespace black_magic;
-  static_assert(
-      std::is_same<void, LastElementType<int, char, void>::type>::value,
-      "LastElementType");
-  static_assert(
-      std::is_same<
-          char, PopBack<int, char, void>::rebind<LastElementType>::type>::value,
-      "pop_back");
-  static_assert(
-      std::is_same<int, PopBack<int, char, void>::rebind<PopBack>::rebind<
-                            LastElementType>::type>::value,
-      "pop_back");
-}
-
-struct NullMiddleware {
-  struct Context {};
-
-  template <typename AllContext>
-  void beforeHandle(Request&, Response&, Context&, AllContext&) {}
-
-  template <typename AllContext>
-  void afterHandle(Request&, Response&, Context&, AllContext&) {}
-};
-
-struct NullSimpleMiddleware {
-  struct Context {};
-
-  void beforeHandle(Request& /*req*/, Response& /*res*/, Context& /*ctx*/) {}
-
-  void afterHandle(Request& /*req*/, Response& /*res*/, Context& /*ctx*/) {}
-};
-
-TEST(Crow, middleware_simple) {
-  App<NullMiddleware, NullSimpleMiddleware> app;
-  decltype(app)::server_t server(&app, LOCALHOST_ADDRESS, 45451);
-  BMCWEB_ROUTE(app, "/")
-  ([&](const crow::Request& req) {
-    app.getContext<NullMiddleware>(req);
-    app.getContext<NullSimpleMiddleware>(req);
-    return "";
-  });
-}
-
-struct IntSettingMiddleware {
-  struct Context {
-    int val;
-  };
-
-  template <typename AllContext>
-  void beforeHandle(Request&, Response&, Context& ctx, AllContext&) {
-    ctx.val = 1;
-  }
-
-  template <typename AllContext>
-  void afterHandle(Request&, Response&, Context& ctx, AllContext&) {
-    ctx.val = 2;
-  }
-};
-
-std::vector<std::string> test_middleware_context_vector;
-
-struct FirstMW {
-  struct Context {
-    std::vector<string> v;
-  };
-
-  void beforeHandle(Request& /*req*/, Response& /*res*/, Context& ctx) {
-    ctx.v.push_back("1 before");
-  }
-
-  void afterHandle(Request& /*req*/, Response& /*res*/, Context& ctx) {
-    ctx.v.push_back("1 after");
-    test_middleware_context_vector = ctx.v;
-  }
-};
-
-struct SecondMW {
-  struct Context {};
-  template <typename AllContext>
-  void beforeHandle(Request& req, Response& res, Context&,
-                    AllContext& all_ctx) {
-    all_ctx.template get<FirstMW>().v.push_back("2 before");
-    if (req.url == "/break") res.end();
-  }
-
-  template <typename AllContext>
-  void afterHandle(Request&, Response&, Context&, AllContext& all_ctx) {
-    all_ctx.template get<FirstMW>().v.push_back("2 after");
-  }
-};
-
-struct ThirdMW {
-  struct Context {};
-  template <typename AllContext>
-  void beforeHandle(Request&, Response&, Context&, AllContext& all_ctx) {
-    all_ctx.template get<FirstMW>().v.push_back("3 before");
-  }
-
-  template <typename AllContext>
-  void afterHandle(Request&, Response&, Context&, AllContext& all_ctx) {
-    all_ctx.template get<FirstMW>().v.push_back("3 after");
-  }
-};
-
-TEST(Crow, middlewareContext) {
-  static char buf[2048];
-  // SecondMW depends on FirstMW (it uses all_ctx.get<FirstMW>)
-  // so it leads to compile error if we remove FirstMW from definition
-  // App<IntSettingMiddleware, SecondMW> app;
-  // or change the order of FirstMW and SecondMW
-  // App<IntSettingMiddleware, SecondMW, FirstMW> app;
-
-  App<IntSettingMiddleware, FirstMW, SecondMW, ThirdMW> app;
-
-  int x{};
-  BMCWEB_ROUTE(app, "/")
-  ([&](const Request& req) {
-    {
-      auto& ctx = app.getContext<IntSettingMiddleware>(req);
-      x = ctx.val;
-    }
-    {
-      auto& ctx = app.getContext<FirstMW>(req);
-      ctx.v.push_back("handle");
-    }
-
-    return "";
-  });
-  BMCWEB_ROUTE(app, "/break")
-  ([&](const Request& req) {
-    {
-      auto& ctx = app.getContext<FirstMW>(req);
-      ctx.v.push_back("handle");
-    }
-
-    return "";
-  });
-
-  decltype(app)::server_t server(&app, LOCALHOST_ADDRESS, 45451);
-  auto _ = async(launch::async, [&] { server.run(); });
-  std::string sendmsg = "GET /\r\n\r\n";
-  asio::io_service is;
-  {
-    asio::ip::tcp::socket c(is);
-    c.connect(asio::ip::tcp::endpoint(
-        asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
-
-    c.send(asio::buffer(sendmsg));
-
-    c.receive(asio::buffer(buf, 2048));
-    c.close();
-  }
-  {
-    auto& out = test_middleware_context_vector;
+    // executing handler
+    ASSERT_EQUAL(0, x);
+    boost::beast::http::request<boost::beast::http::string_body> req{};
+    r.handle(Request(req), res, RoutingParams());
     ASSERT_EQUAL(1, x);
-    ASSERT_EQUAL(7, out.size());
-    ASSERT_EQUAL("1 before", out[0]);
-    ASSERT_EQUAL("2 before", out[1]);
-    ASSERT_EQUAL("3 before", out[2]);
-    ASSERT_EQUAL("handle", out[3]);
-    ASSERT_EQUAL("3 after", out[4]);
-    ASSERT_EQUAL("2 after", out[5]);
-    ASSERT_EQUAL("1 after", out[6]);
-  }
-  std::string sendmsg2 = "GET /break\r\n\r\n";
-  {
-    asio::ip::tcp::socket c(is);
-    c.connect(asio::ip::tcp::endpoint(
-        asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
 
-    c.send(asio::buffer(sendmsg2));
+    // registering handler with Request argument
+    r([&x](const crow::Request&) {
+        x = 2;
+        return "";
+    });
 
-    c.receive(asio::buffer(buf, 2048));
-    c.close();
-  }
-  {
-    auto& out = test_middleware_context_vector;
-    ASSERT_EQUAL(4, out.size());
-    ASSERT_EQUAL("1 before", out[0]);
-    ASSERT_EQUAL("2 before", out[1]);
-    ASSERT_EQUAL("2 after", out[2]);
-    ASSERT_EQUAL("1 after", out[3]);
-  }
-  server.stop();
+    r.validate();
+
+    // executing handler
+    ASSERT_EQUAL(1, x);
+    r.handle(Request(req), res, RoutingParams());
+    ASSERT_EQUAL(2, x);
 }
 
-TEST(Crow, bug_quick_repeated_request) {
-  static char buf[2048];
+TEST(Crow, ParameterTagging)
+{
+    static_assert(black_magic::isValid("<int><int><int>"), "valid url");
+    static_assert(!black_magic::isValid("<int><int<<int>"), "invalid url");
+    static_assert(!black_magic::isValid("nt>"), "invalid url");
+    ASSERT_EQUAL(1, black_magic::get_parameter_tag("<int>"));
+    ASSERT_EQUAL(2, black_magic::get_parameter_tag("<uint>"));
+    ASSERT_EQUAL(3, black_magic::get_parameter_tag("<float>"));
+    ASSERT_EQUAL(3, black_magic::get_parameter_tag("<double>"));
+    ASSERT_EQUAL(4, black_magic::get_parameter_tag("<str>"));
+    ASSERT_EQUAL(4, black_magic::get_parameter_tag("<string>"));
+    ASSERT_EQUAL(5, black_magic::get_parameter_tag("<path>"));
+    ASSERT_EQUAL(6 * 6 + 6 + 1,
+                 black_magic::get_parameter_tag("<int><int><int>"));
+    ASSERT_EQUAL(6 * 6 + 6 + 2,
+                 black_magic::get_parameter_tag("<uint><int><int>"));
+    ASSERT_EQUAL(6 * 6 + 6 * 3 + 2,
+                 black_magic::get_parameter_tag("<uint><double><int>"));
 
-  SimpleApp app;
+    // url definition parsed in compile time, build into *one number*, and given
+    // to template argument
+    static_assert(
+        std::is_same<black_magic::S<uint64_t, double, int64_t>,
+                     black_magic::Arguments<6 * 6 + 6 * 3 + 2>::type>::value,
+        "tag to type container");
+}
 
-  BMCWEB_ROUTE(app, "/")([&] { return "hello"; });
+TEST(Crow, PathRouting)
+{
+    SimpleApp app;
 
-  decltype(app)::server_t server(&app, LOCALHOST_ADDRESS, 45451);
-  auto _ = async(launch::async, [&] { server.run(); });
-  std::string sendmsg = "GET / HTTP/1.1\r\nHost: localhost\r\n\r\n";
-  asio::io_service is;
-  {
-    std::vector<std::future<void>> v;
-    for (int i = 0; i < 5; i++) {
-      v.push_back(async(launch::async, [&] {
+    BMCWEB_ROUTE(app, "/file")
+    ([] { return "file"; });
+
+    BMCWEB_ROUTE(app, "/path/")
+    ([] { return "path"; });
+
+    {
+        boost::beast::http::request<boost::beast::http::string_body> r{};
+        Request req{r};
+        Response res;
+
+        req.url = "/file";
+
+        app.handle(req, res);
+
+        ASSERT_EQUAL(200, res.resultInt());
+    }
+    {
+        boost::beast::http::request<boost::beast::http::string_body> r{};
+        Request req{r};
+        Response res;
+
+        req.url = "/file/";
+
+        app.handle(req, res);
+        ASSERT_EQUAL(404, res.resultInt());
+    }
+    {
+        boost::beast::http::request<boost::beast::http::string_body> r{};
+        Request req{r};
+        Response res;
+
+        req.url = "/path";
+
+        app.handle(req, res);
+        ASSERT_NOTEQUAL(404, res.resultInt());
+    }
+    {
+        boost::beast::http::request<boost::beast::http::string_body> r{};
+        Request req{r};
+        Response res;
+
+        req.url = "/path/";
+
+        app.handle(req, res);
+        ASSERT_EQUAL(200, res.resultInt());
+    }
+}
+
+TEST(Crow, RoutingTest)
+{
+    SimpleApp app;
+    int A{};
+    uint32_t b{};
+    double C{};
+    string D{};
+    string E{};
+
+    BMCWEB_ROUTE(app, "/0/<uint>")
+    ([&](uint32_t b) {
+        b = b;
+        return "OK";
+    });
+
+    BMCWEB_ROUTE(app, "/1/<int>/<uint>")
+    ([&](int a, uint32_t b) {
+        A = a;
+        b = b;
+        return "OK";
+    });
+
+    BMCWEB_ROUTE(app, "/4/<int>/<uint>/<double>/<string>")
+    ([&](int a, uint32_t b, double c, string d) {
+        A = a;
+        b = b;
+        C = c;
+        D = d;
+        return "OK";
+    });
+
+    BMCWEB_ROUTE(app, "/5/<int>/<uint>/<double>/<string>/<path>")
+    ([&](int a, uint32_t b, double c, string d, string e) {
+        A = a;
+        b = b;
+        C = c;
+        D = d;
+        E = e;
+        return "OK";
+    });
+
+    app.validate();
+    // app.debugPrint();
+    {
+        boost::beast::http::request<boost::beast::http::string_body> r{};
+        Request req{r};
+        Response res;
+
+        req.url = "/-1";
+
+        app.handle(req, res);
+
+        ASSERT_EQUAL(404, res.resultInt());
+    }
+
+    {
+        boost::beast::http::request<boost::beast::http::string_body> r{};
+        Request req{r};
+        Response res;
+
+        req.url = "/0/1001999";
+
+        app.handle(req, res);
+
+        ASSERT_EQUAL(200, res.resultInt());
+
+        ASSERT_EQUAL(1001999, b);
+    }
+
+    {
+        boost::beast::http::request<boost::beast::http::string_body> r{};
+        Request req{r};
+        Response res;
+
+        req.url = "/1/-100/1999";
+
+        app.handle(req, res);
+
+        ASSERT_EQUAL(200, res.resultInt());
+
+        ASSERT_EQUAL(-100, A);
+        ASSERT_EQUAL(1999, b);
+    }
+    {
+        boost::beast::http::request<boost::beast::http::string_body> r{};
+        Request req{r};
+        Response res;
+
+        req.url = "/4/5000/3/-2.71828/hellhere";
+
+        app.handle(req, res);
+
+        ASSERT_EQUAL(200, res.resultInt());
+
+        ASSERT_EQUAL(5000, A);
+        ASSERT_EQUAL(3, b);
+        ASSERT_EQUAL(-2.71828, C);
+        ASSERT_EQUAL("hellhere", D);
+    }
+    {
+        boost::beast::http::request<boost::beast::http::string_body> r{};
+        Request req{r};
+        Response res;
+
+        req.url = "/5/-5/999/3.141592/hello_there/a/b/c/d";
+
+        app.handle(req, res);
+
+        ASSERT_EQUAL(200, res.resultInt());
+
+        ASSERT_EQUAL(-5, A);
+        ASSERT_EQUAL(999, b);
+        ASSERT_EQUAL(3.141592, C);
+        ASSERT_EQUAL("hello_there", D);
+        ASSERT_EQUAL("a/b/c/d", E);
+    }
+}
+
+TEST(Crow, simple_response_RoutingParams)
+{
+    ASSERT_EQUAL(100,
+                 Response(boost::beast::http::status::continue_).resultInt());
+    ASSERT_EQUAL(200, Response("Hello there").resultInt());
+    ASSERT_EQUAL(500,
+                 Response(boost::beast::http::status::internal_server_error,
+                          "Internal Error?")
+                     .resultInt());
+
+    RoutingParams rp;
+    rp.intParams.push_back(1);
+    rp.intParams.push_back(5);
+    rp.uintParams.push_back(2);
+    rp.doubleParams.push_back(3);
+    rp.stringParams.push_back("hello");
+    ASSERT_EQUAL(1, rp.get<int64_t>(0));
+    ASSERT_EQUAL(5, rp.get<int64_t>(1));
+    ASSERT_EQUAL(2, rp.get<uint64_t>(0));
+    ASSERT_EQUAL(3, rp.get<double>(0));
+    ASSERT_EQUAL("hello", rp.get<string>(0));
+}
+
+TEST(Crow, handler_with_response)
+{
+    SimpleApp app;
+    BMCWEB_ROUTE(app, "/")([](const crow::Request&, crow::Response&) {});
+}
+
+TEST(Crow, http_method)
+{
+    SimpleApp app;
+
+    BMCWEB_ROUTE(app, "/").methods("POST"_method,
+                                   "GET"_method)([](const Request& req) {
+        if (req.method() == "GET"_method)
+            return "2";
+        else
+            return "1";
+    });
+
+    BMCWEB_ROUTE(app, "/get_only")
+        .methods("GET"_method)([](const Request& /*req*/) { return "get"; });
+    BMCWEB_ROUTE(app, "/post_only")
+        .methods("POST"_method)([](const Request& /*req*/) { return "post"; });
+
+    // cannot have multiple handlers for the same url
+    // BMCWEB_ROUTE(app, "/")
+    //.methods("GET"_method)
+    //([]{ return "2"; });
+
+    {
+        boost::beast::http::request<boost::beast::http::string_body> r{};
+        Request req{r};
+        Response res;
+
+        req.url = "/";
+        app.handle(req, res);
+
+        ASSERT_EQUAL("2", res.body());
+    }
+    {
+        boost::beast::http::request<boost::beast::http::string_body> r{};
+        Request req{r};
+        Response res;
+
+        req.url = "/";
+        r.method("POST"_method);
+        app.handle(req, res);
+
+        ASSERT_EQUAL("1", res.body());
+    }
+
+    {
+        boost::beast::http::request<boost::beast::http::string_body> r{};
+        Request req{r};
+        Response res;
+
+        req.url = "/get_only";
+        app.handle(req, res);
+
+        ASSERT_EQUAL("get", res.body());
+    }
+
+    {
+        boost::beast::http::request<boost::beast::http::string_body> r{};
+        Request req{r};
+        Response res;
+
+        req.url = "/get_only";
+        r.method("POST"_method);
+        app.handle(req, res);
+
+        ASSERT_NOTEQUAL("get", res.body());
+    }
+}
+
+TEST(Crow, server_handling_error_request)
+{
+    static char buf[2048];
+    SimpleApp app;
+    BMCWEB_ROUTE(app, "/")([] { return "A"; });
+    Server<SimpleApp> server(&app, LOCALHOST_ADDRESS, 45451);
+    auto _ = async(launch::async, [&] { server.run(); });
+    std::string sendmsg = "POX";
+    asio::io_service is;
+    {
         asio::ip::tcp::socket c(is);
         c.connect(asio::ip::tcp::endpoint(
             asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
 
-        for (int j = 0; j < 5; j++) {
-          c.send(asio::buffer(sendmsg));
+        c.send(asio::buffer(sendmsg));
 
-          size_t received = c.receive(asio::buffer(buf, 2048));
-          ASSERT_EQUAL("hello",
-                       std::string(buf + received - 5, buf + received));
+        try
+        {
+            c.receive(asio::buffer(buf, 2048));
+            fail();
         }
-        c.close();
-      }));
+        catch (std::exception& e)
+        {
+            // std::cerr << e.what() << std::endl;
+        }
     }
-  }
-  server.stop();
+    server.stop();
 }
 
-TEST(Crow, simple_url_params) {
-  static char buf[2048];
+TEST(Crow, multi_server)
+{
+    static char buf[2048];
+    SimpleApp app1, app2;
+    BMCWEB_ROUTE(app1, "/").methods("GET"_method,
+                                    "POST"_method)([] { return "A"; });
+    BMCWEB_ROUTE(app2, "/").methods("GET"_method,
+                                    "POST"_method)([] { return "B"; });
 
-  SimpleApp app;
+    Server<SimpleApp> server1(&app1, LOCALHOST_ADDRESS, 45451);
+    Server<SimpleApp> server2(&app2, LOCALHOST_ADDRESS, 45452);
 
-  QueryString lastUrlParams;
+    auto _ = async(launch::async, [&] { server1.run(); });
+    auto _2 = async(launch::async, [&] { server2.run(); });
 
-  BMCWEB_ROUTE(app, "/params")
-  ([&lastUrlParams](const crow::Request& req) {
-    lastUrlParams = std::move(req.urlParams);
-    return "OK";
-  });
+    std::string sendmsg =
+        "POST /\r\nContent-Length:3\r\nX-HeaderTest: 123\r\n\r\nA=b\r\n";
+    asio::io_service is;
+    {
+        asio::ip::tcp::socket c(is);
+        c.connect(asio::ip::tcp::endpoint(
+            asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
 
-  /// params?h=1&foo=bar&lol&count[]=1&count[]=4&pew=5.2
+        c.send(asio::buffer(sendmsg));
 
-  decltype(app)::server_t server(&app, LOCALHOST_ADDRESS, 45451);
-  auto _ = async(launch::async, [&] { server.run(); });
-  asio::io_service is;
-  std::string sendmsg;
+        size_t recved = c.receive(asio::buffer(buf, 2048));
+        ASSERT_EQUAL('A', buf[recved - 1]);
+    }
 
-  // check empty params
-  sendmsg = "GET /params\r\n\r\n";
-  {
-    asio::ip::tcp::socket c(is);
-    c.connect(asio::ip::tcp::endpoint(
-        asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
-    c.send(asio::buffer(sendmsg));
-    c.receive(asio::buffer(buf, 2048));
-    c.close();
+    {
+        asio::ip::tcp::socket c(is);
+        c.connect(asio::ip::tcp::endpoint(
+            asio::ip::address::from_string(LOCALHOST_ADDRESS), 45452));
 
-    stringstream ss;
-    ss << lastUrlParams;
+        for (auto ch : sendmsg)
+        {
+            char buf[1] = {ch};
+            c.send(asio::buffer(buf));
+        }
 
-    ASSERT_EQUAL("[  ]", ss.str());
-  }
-  // check single presence
-  sendmsg = "GET /params?foobar\r\n\r\n";
-  {
-    asio::ip::tcp::socket c(is);
-    c.connect(asio::ip::tcp::endpoint(
-        asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
-    c.send(asio::buffer(sendmsg));
-    c.receive(asio::buffer(buf, 2048));
-    c.close();
+        size_t recved = c.receive(asio::buffer(buf, 2048));
+        ASSERT_EQUAL('b', buf[recved - 1]);
+    }
 
-    ASSERT_TRUE(lastUrlParams.get("missing") == nullptr);
-    ASSERT_TRUE(lastUrlParams.get("foobar") != nullptr);
-    ASSERT_TRUE(lastUrlParams.getList("missing").empty());
-  }
-  // check multiple presence
-  sendmsg = "GET /params?foo&bar&baz\r\n\r\n";
-  {
-    asio::ip::tcp::socket c(is);
-    c.connect(asio::ip::tcp::endpoint(
-        asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
-    c.send(asio::buffer(sendmsg));
-    c.receive(asio::buffer(buf, 2048));
-    c.close();
-
-    ASSERT_TRUE(lastUrlParams.get("missing") == nullptr);
-    ASSERT_TRUE(lastUrlParams.get("foo") != nullptr);
-    ASSERT_TRUE(lastUrlParams.get("bar") != nullptr);
-    ASSERT_TRUE(lastUrlParams.get("baz") != nullptr);
-  }
-  // check single value
-  sendmsg = "GET /params?hello=world\r\n\r\n";
-  {
-    asio::ip::tcp::socket c(is);
-    c.connect(asio::ip::tcp::endpoint(
-        asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
-    c.send(asio::buffer(sendmsg));
-    c.receive(asio::buffer(buf, 2048));
-    c.close();
-
-    ASSERT_EQUAL(string(lastUrlParams.get("hello")), "world");
-  }
-  // check multiple value
-  sendmsg = "GET /params?hello=world&left=right&up=down\r\n\r\n";
-  {
-    asio::ip::tcp::socket c(is);
-    c.connect(asio::ip::tcp::endpoint(
-        asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
-    c.send(asio::buffer(sendmsg));
-    c.receive(asio::buffer(buf, 2048));
-    c.close();
-
-    ASSERT_EQUAL(string(lastUrlParams.get("hello")), "world");
-    ASSERT_EQUAL(string(lastUrlParams.get("left")), "right");
-    ASSERT_EQUAL(string(lastUrlParams.get("up")), "down");
-  }
-  // check multiple value, multiple types
-  sendmsg = "GET /params?int=100&double=123.45&boolean=1\r\n\r\n";
-  {
-    asio::ip::tcp::socket c(is);
-    c.connect(asio::ip::tcp::endpoint(
-        asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
-    c.send(asio::buffer(sendmsg));
-    c.receive(asio::buffer(buf, 2048));
-    c.close();
-
-    ASSERT_EQUAL(boost::lexical_cast<int>(lastUrlParams.get("int")), 100);
-    ASSERT_EQUAL(boost::lexical_cast<double>(lastUrlParams.get("double")),
-                 123.45);
-    ASSERT_EQUAL(boost::lexical_cast<bool>(lastUrlParams.get("boolean")), true);
-  }
-  // check single array value
-  sendmsg = "GET /params?tmnt[]=leonardo\r\n\r\n";
-  {
-    asio::ip::tcp::socket c(is);
-
-    c.connect(asio::ip::tcp::endpoint(
-        asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
-    c.send(asio::buffer(sendmsg));
-    c.receive(asio::buffer(buf, 2048));
-    c.close();
-
-    ASSERT_TRUE(lastUrlParams.get("tmnt") == nullptr);
-    ASSERT_EQUAL(lastUrlParams.getList("tmnt").size(), 1);
-    ASSERT_EQUAL(string(lastUrlParams.getList("tmnt")[0]), "leonardo");
-  }
-  // check multiple array value
-  sendmsg =
-      "GET /params?tmnt[]=leonardo&tmnt[]=donatello&tmnt[]=raphael\r\n\r\n";
-  {
-    asio::ip::tcp::socket c(is);
-
-    c.connect(asio::ip::tcp::endpoint(
-        asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
-    c.send(asio::buffer(sendmsg));
-    c.receive(asio::buffer(buf, 2048));
-    c.close();
-
-    ASSERT_EQUAL(lastUrlParams.getList("tmnt").size(), 3);
-    ASSERT_EQUAL(string(lastUrlParams.getList("tmnt")[0]), "leonardo");
-    ASSERT_EQUAL(string(lastUrlParams.getList("tmnt")[1]), "donatello");
-    ASSERT_EQUAL(string(lastUrlParams.getList("tmnt")[2]), "raphael");
-  }
-  server.stop();
+    server1.stop();
+    server2.stop();
 }
 
-TEST(Crow, routeDynamic) {
-  SimpleApp app;
-  int x = 1;
-  app.routeDynamic("/")([&] {
-    x = 2;
-    return "";
-  });
+TEST(Crow, black_magic)
+{
+    using namespace black_magic;
+    static_assert(
+        std::is_same<void, LastElementType<int, char, void>::type>::value,
+        "LastElementType");
+    static_assert(
+        std::is_same<char, PopBack<int, char,
+                                   void>::rebind<LastElementType>::type>::value,
+        "pop_back");
+    static_assert(
+        std::is_same<int, PopBack<int, char, void>::rebind<PopBack>::rebind<
+                              LastElementType>::type>::value,
+        "pop_back");
+}
 
-  app.routeDynamic("/set4")([&](const Request&) {
-    x = 4;
-    return "";
-  });
-  app.routeDynamic("/set5")([&](const Request&, Response& res) {
-    x = 5;
-    res.end();
-  });
+struct NullMiddleware
+{
+    struct Context
+    {
+    };
 
-  app.routeDynamic("/set_int/<int>")([&](int y) {
-    x = y;
-    return "";
-  });
+    template <typename AllContext>
+    void beforeHandle(Request&, Response&, Context&, AllContext&)
+    {
+    }
 
-  try {
-    app.routeDynamic("/invalid_test/<double>/<path>")([]() { return ""; });
-    fail();
-  } catch (std::exception&) {
-  }
+    template <typename AllContext>
+    void afterHandle(Request&, Response&, Context&, AllContext&)
+    {
+    }
+};
 
-  // app is in an invalid state when routeDynamic throws an exception.
-  try {
-    app.validate();
-    fail();
-  } catch (std::exception&) {
-  }
+struct NullSimpleMiddleware
+{
+    struct Context
+    {
+    };
 
-  {
-    boost::beast::http::request<boost::beast::http::string_body> r{};
-    Request req{r};
-    Response res;
-    req.url = "/";
-    app.handle(req, res);
-    ASSERT_EQUAL(x, 2);
-  }
-  {
-    boost::beast::http::request<boost::beast::http::string_body> r{};
-    Request req{r};
-    Response res;
-    req.url = "/set_int/42";
-    app.handle(req, res);
-    ASSERT_EQUAL(x, 42);
-  }
-  {
-    boost::beast::http::request<boost::beast::http::string_body> r{};
-    Request req{r};
-    Response res;
-    req.url = "/set5";
-    app.handle(req, res);
-    ASSERT_EQUAL(x, 5);
-  }
-  {
-    boost::beast::http::request<boost::beast::http::string_body> r{};
-    Request req{r};
-    Response res;
-    req.url = "/set4";
-    app.handle(req, res);
-    ASSERT_EQUAL(x, 4);
-  }
+    void beforeHandle(Request& /*req*/, Response& /*res*/, Context& /*ctx*/)
+    {
+    }
+
+    void afterHandle(Request& /*req*/, Response& /*res*/, Context& /*ctx*/)
+    {
+    }
+};
+
+TEST(Crow, middleware_simple)
+{
+    App<NullMiddleware, NullSimpleMiddleware> app;
+    decltype(app)::server_t server(&app, LOCALHOST_ADDRESS, 45451);
+    BMCWEB_ROUTE(app, "/")
+    ([&](const crow::Request& req) {
+        app.getContext<NullMiddleware>(req);
+        app.getContext<NullSimpleMiddleware>(req);
+        return "";
+    });
+}
+
+struct IntSettingMiddleware
+{
+    struct Context
+    {
+        int val;
+    };
+
+    template <typename AllContext>
+    void beforeHandle(Request&, Response&, Context& ctx, AllContext&)
+    {
+        ctx.val = 1;
+    }
+
+    template <typename AllContext>
+    void afterHandle(Request&, Response&, Context& ctx, AllContext&)
+    {
+        ctx.val = 2;
+    }
+};
+
+std::vector<std::string> test_middleware_context_vector;
+
+struct FirstMW
+{
+    struct Context
+    {
+        std::vector<string> v;
+    };
+
+    void beforeHandle(Request& /*req*/, Response& /*res*/, Context& ctx)
+    {
+        ctx.v.push_back("1 before");
+    }
+
+    void afterHandle(Request& /*req*/, Response& /*res*/, Context& ctx)
+    {
+        ctx.v.push_back("1 after");
+        test_middleware_context_vector = ctx.v;
+    }
+};
+
+struct SecondMW
+{
+    struct Context
+    {
+    };
+    template <typename AllContext>
+    void beforeHandle(Request& req, Response& res, Context&,
+                      AllContext& all_ctx)
+    {
+        all_ctx.template get<FirstMW>().v.push_back("2 before");
+        if (req.url == "/break")
+            res.end();
+    }
+
+    template <typename AllContext>
+    void afterHandle(Request&, Response&, Context&, AllContext& all_ctx)
+    {
+        all_ctx.template get<FirstMW>().v.push_back("2 after");
+    }
+};
+
+struct ThirdMW
+{
+    struct Context
+    {
+    };
+    template <typename AllContext>
+    void beforeHandle(Request&, Response&, Context&, AllContext& all_ctx)
+    {
+        all_ctx.template get<FirstMW>().v.push_back("3 before");
+    }
+
+    template <typename AllContext>
+    void afterHandle(Request&, Response&, Context&, AllContext& all_ctx)
+    {
+        all_ctx.template get<FirstMW>().v.push_back("3 after");
+    }
+};
+
+TEST(Crow, middlewareContext)
+{
+    static char buf[2048];
+    // SecondMW depends on FirstMW (it uses all_ctx.get<FirstMW>)
+    // so it leads to compile error if we remove FirstMW from definition
+    // App<IntSettingMiddleware, SecondMW> app;
+    // or change the order of FirstMW and SecondMW
+    // App<IntSettingMiddleware, SecondMW, FirstMW> app;
+
+    App<IntSettingMiddleware, FirstMW, SecondMW, ThirdMW> app;
+
+    int x{};
+    BMCWEB_ROUTE(app, "/")
+    ([&](const Request& req) {
+        {
+            auto& ctx = app.getContext<IntSettingMiddleware>(req);
+            x = ctx.val;
+        }
+        {
+            auto& ctx = app.getContext<FirstMW>(req);
+            ctx.v.push_back("handle");
+        }
+
+        return "";
+    });
+    BMCWEB_ROUTE(app, "/break")
+    ([&](const Request& req) {
+        {
+            auto& ctx = app.getContext<FirstMW>(req);
+            ctx.v.push_back("handle");
+        }
+
+        return "";
+    });
+
+    decltype(app)::server_t server(&app, LOCALHOST_ADDRESS, 45451);
+    auto _ = async(launch::async, [&] { server.run(); });
+    std::string sendmsg = "GET /\r\n\r\n";
+    asio::io_service is;
+    {
+        asio::ip::tcp::socket c(is);
+        c.connect(asio::ip::tcp::endpoint(
+            asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
+
+        c.send(asio::buffer(sendmsg));
+
+        c.receive(asio::buffer(buf, 2048));
+        c.close();
+    }
+    {
+        auto& out = test_middleware_context_vector;
+        ASSERT_EQUAL(1, x);
+        ASSERT_EQUAL(7, out.size());
+        ASSERT_EQUAL("1 before", out[0]);
+        ASSERT_EQUAL("2 before", out[1]);
+        ASSERT_EQUAL("3 before", out[2]);
+        ASSERT_EQUAL("handle", out[3]);
+        ASSERT_EQUAL("3 after", out[4]);
+        ASSERT_EQUAL("2 after", out[5]);
+        ASSERT_EQUAL("1 after", out[6]);
+    }
+    std::string sendmsg2 = "GET /break\r\n\r\n";
+    {
+        asio::ip::tcp::socket c(is);
+        c.connect(asio::ip::tcp::endpoint(
+            asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
+
+        c.send(asio::buffer(sendmsg2));
+
+        c.receive(asio::buffer(buf, 2048));
+        c.close();
+    }
+    {
+        auto& out = test_middleware_context_vector;
+        ASSERT_EQUAL(4, out.size());
+        ASSERT_EQUAL("1 before", out[0]);
+        ASSERT_EQUAL("2 before", out[1]);
+        ASSERT_EQUAL("2 after", out[2]);
+        ASSERT_EQUAL("1 after", out[3]);
+    }
+    server.stop();
+}
+
+TEST(Crow, bug_quick_repeated_request)
+{
+    static char buf[2048];
+
+    SimpleApp app;
+
+    BMCWEB_ROUTE(app, "/")([&] { return "hello"; });
+
+    decltype(app)::server_t server(&app, LOCALHOST_ADDRESS, 45451);
+    auto _ = async(launch::async, [&] { server.run(); });
+    std::string sendmsg = "GET / HTTP/1.1\r\nHost: localhost\r\n\r\n";
+    asio::io_service is;
+    {
+        std::vector<std::future<void>> v;
+        for (int i = 0; i < 5; i++)
+        {
+            v.push_back(async(launch::async, [&] {
+                asio::ip::tcp::socket c(is);
+                c.connect(asio::ip::tcp::endpoint(
+                    asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
+
+                for (int j = 0; j < 5; j++)
+                {
+                    c.send(asio::buffer(sendmsg));
+
+                    size_t received = c.receive(asio::buffer(buf, 2048));
+                    ASSERT_EQUAL("hello", std::string(buf + received - 5,
+                                                      buf + received));
+                }
+                c.close();
+            }));
+        }
+    }
+    server.stop();
+}
+
+TEST(Crow, simple_url_params)
+{
+    static char buf[2048];
+
+    SimpleApp app;
+
+    QueryString lastUrlParams;
+
+    BMCWEB_ROUTE(app, "/params")
+    ([&lastUrlParams](const crow::Request& req) {
+        lastUrlParams = std::move(req.urlParams);
+        return "OK";
+    });
+
+    /// params?h=1&foo=bar&lol&count[]=1&count[]=4&pew=5.2
+
+    decltype(app)::server_t server(&app, LOCALHOST_ADDRESS, 45451);
+    auto _ = async(launch::async, [&] { server.run(); });
+    asio::io_service is;
+    std::string sendmsg;
+
+    // check empty params
+    sendmsg = "GET /params\r\n\r\n";
+    {
+        asio::ip::tcp::socket c(is);
+        c.connect(asio::ip::tcp::endpoint(
+            asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
+        c.send(asio::buffer(sendmsg));
+        c.receive(asio::buffer(buf, 2048));
+        c.close();
+
+        stringstream ss;
+        ss << lastUrlParams;
+
+        ASSERT_EQUAL("[  ]", ss.str());
+    }
+    // check single presence
+    sendmsg = "GET /params?foobar\r\n\r\n";
+    {
+        asio::ip::tcp::socket c(is);
+        c.connect(asio::ip::tcp::endpoint(
+            asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
+        c.send(asio::buffer(sendmsg));
+        c.receive(asio::buffer(buf, 2048));
+        c.close();
+
+        ASSERT_TRUE(lastUrlParams.get("missing") == nullptr);
+        ASSERT_TRUE(lastUrlParams.get("foobar") != nullptr);
+        ASSERT_TRUE(lastUrlParams.getList("missing").empty());
+    }
+    // check multiple presence
+    sendmsg = "GET /params?foo&bar&baz\r\n\r\n";
+    {
+        asio::ip::tcp::socket c(is);
+        c.connect(asio::ip::tcp::endpoint(
+            asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
+        c.send(asio::buffer(sendmsg));
+        c.receive(asio::buffer(buf, 2048));
+        c.close();
+
+        ASSERT_TRUE(lastUrlParams.get("missing") == nullptr);
+        ASSERT_TRUE(lastUrlParams.get("foo") != nullptr);
+        ASSERT_TRUE(lastUrlParams.get("bar") != nullptr);
+        ASSERT_TRUE(lastUrlParams.get("baz") != nullptr);
+    }
+    // check single value
+    sendmsg = "GET /params?hello=world\r\n\r\n";
+    {
+        asio::ip::tcp::socket c(is);
+        c.connect(asio::ip::tcp::endpoint(
+            asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
+        c.send(asio::buffer(sendmsg));
+        c.receive(asio::buffer(buf, 2048));
+        c.close();
+
+        ASSERT_EQUAL(string(lastUrlParams.get("hello")), "world");
+    }
+    // check multiple value
+    sendmsg = "GET /params?hello=world&left=right&up=down\r\n\r\n";
+    {
+        asio::ip::tcp::socket c(is);
+        c.connect(asio::ip::tcp::endpoint(
+            asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
+        c.send(asio::buffer(sendmsg));
+        c.receive(asio::buffer(buf, 2048));
+        c.close();
+
+        ASSERT_EQUAL(string(lastUrlParams.get("hello")), "world");
+        ASSERT_EQUAL(string(lastUrlParams.get("left")), "right");
+        ASSERT_EQUAL(string(lastUrlParams.get("up")), "down");
+    }
+    // check multiple value, multiple types
+    sendmsg = "GET /params?int=100&double=123.45&boolean=1\r\n\r\n";
+    {
+        asio::ip::tcp::socket c(is);
+        c.connect(asio::ip::tcp::endpoint(
+            asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
+        c.send(asio::buffer(sendmsg));
+        c.receive(asio::buffer(buf, 2048));
+        c.close();
+
+        ASSERT_EQUAL(boost::lexical_cast<int>(lastUrlParams.get("int")), 100);
+        ASSERT_EQUAL(boost::lexical_cast<double>(lastUrlParams.get("double")),
+                     123.45);
+        ASSERT_EQUAL(boost::lexical_cast<bool>(lastUrlParams.get("boolean")),
+                     true);
+    }
+    // check single array value
+    sendmsg = "GET /params?tmnt[]=leonardo\r\n\r\n";
+    {
+        asio::ip::tcp::socket c(is);
+
+        c.connect(asio::ip::tcp::endpoint(
+            asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
+        c.send(asio::buffer(sendmsg));
+        c.receive(asio::buffer(buf, 2048));
+        c.close();
+
+        ASSERT_TRUE(lastUrlParams.get("tmnt") == nullptr);
+        ASSERT_EQUAL(lastUrlParams.getList("tmnt").size(), 1);
+        ASSERT_EQUAL(string(lastUrlParams.getList("tmnt")[0]), "leonardo");
+    }
+    // check multiple array value
+    sendmsg =
+        "GET /params?tmnt[]=leonardo&tmnt[]=donatello&tmnt[]=raphael\r\n\r\n";
+    {
+        asio::ip::tcp::socket c(is);
+
+        c.connect(asio::ip::tcp::endpoint(
+            asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
+        c.send(asio::buffer(sendmsg));
+        c.receive(asio::buffer(buf, 2048));
+        c.close();
+
+        ASSERT_EQUAL(lastUrlParams.getList("tmnt").size(), 3);
+        ASSERT_EQUAL(string(lastUrlParams.getList("tmnt")[0]), "leonardo");
+        ASSERT_EQUAL(string(lastUrlParams.getList("tmnt")[1]), "donatello");
+        ASSERT_EQUAL(string(lastUrlParams.getList("tmnt")[2]), "raphael");
+    }
+    server.stop();
+}
+
+TEST(Crow, routeDynamic)
+{
+    SimpleApp app;
+    int x = 1;
+    app.routeDynamic("/")([&] {
+        x = 2;
+        return "";
+    });
+
+    app.routeDynamic("/set4")([&](const Request&) {
+        x = 4;
+        return "";
+    });
+    app.routeDynamic("/set5")([&](const Request&, Response& res) {
+        x = 5;
+        res.end();
+    });
+
+    app.routeDynamic("/set_int/<int>")([&](int y) {
+        x = y;
+        return "";
+    });
+
+    try
+    {
+        app.routeDynamic("/invalid_test/<double>/<path>")([]() { return ""; });
+        fail();
+    }
+    catch (std::exception&)
+    {
+    }
+
+    // app is in an invalid state when routeDynamic throws an exception.
+    try
+    {
+        app.validate();
+        fail();
+    }
+    catch (std::exception&)
+    {
+    }
+
+    {
+        boost::beast::http::request<boost::beast::http::string_body> r{};
+        Request req{r};
+        Response res;
+        req.url = "/";
+        app.handle(req, res);
+        ASSERT_EQUAL(x, 2);
+    }
+    {
+        boost::beast::http::request<boost::beast::http::string_body> r{};
+        Request req{r};
+        Response res;
+        req.url = "/set_int/42";
+        app.handle(req, res);
+        ASSERT_EQUAL(x, 42);
+    }
+    {
+        boost::beast::http::request<boost::beast::http::string_body> r{};
+        Request req{r};
+        Response res;
+        req.url = "/set5";
+        app.handle(req, res);
+        ASSERT_EQUAL(x, 5);
+    }
+    {
+        boost::beast::http::request<boost::beast::http::string_body> r{};
+        Request req{r};
+        Response res;
+        req.url = "/set4";
+        app.handle(req, res);
+        ASSERT_EQUAL(x, 4);
+    }
 }
diff --git a/src/getvideo_main.cpp b/src/getvideo_main.cpp
index 7055d35..8d5f7af 100644
--- a/src/getvideo_main.cpp
+++ b/src/getvideo_main.cpp
@@ -1,15 +1,15 @@
 #include <fcntl.h>
 #include <unistd.h>
+
 #include <chrono>
+#include <cstdio>
+#include <cstdlib>
 #include <fstream>
 #include <iomanip>
 #include <iostream>
 #include <thread>
 #include <vector>
 
-#include <cstdio>
-#include <cstdlib>
-
 //#define BUILD_CIMG
 #ifdef BUILD_CIMG
 #define cimg_display 0
@@ -19,52 +19,60 @@
 #include <ast_jpeg_decoder.hpp>
 #include <ast_video_puller.hpp>
 
-int main() {
-  ast_video::RawVideoBuffer out;
-  bool have_hardware = false;
-  if (access("/dev/video", F_OK) != -1) {
-    ast_video::SimpleVideoPuller p;
-    p.initialize();
-    out = p.readVideo();
-  } else {
-    FILE *fp = fopen("/home/ed/screendata.bin", "rb");
-    if (fp != nullptr) {
-      size_t newLen = fread(out.buffer.data(), sizeof(char),
-                            out.buffer.size() * sizeof(long), fp);
-      if (ferror(fp) != 0) {
-        fputs("Error reading file", stderr);
-      }
-      fclose(fp);
-      out.buffer.resize(newLen);
-      out.mode = ast_video::YuvMode::YUV444;
-      out.width = 800;
-      out.height = 600;
-      out.ySelector = 0;
-      out.uvSelector = 0;
+int main()
+{
+    ast_video::RawVideoBuffer out;
+    bool have_hardware = false;
+    if (access("/dev/video", F_OK) != -1)
+    {
+        ast_video::SimpleVideoPuller p;
+        p.initialize();
+        out = p.readVideo();
     }
-  }
+    else
+    {
+        FILE *fp = fopen("/home/ed/screendata.bin", "rb");
+        if (fp != nullptr)
+        {
+            size_t newLen = fread(out.buffer.data(), sizeof(char),
+                                  out.buffer.size() * sizeof(long), fp);
+            if (ferror(fp) != 0)
+            {
+                fputs("Error reading file", stderr);
+            }
+            fclose(fp);
+            out.buffer.resize(newLen);
+            out.mode = ast_video::YuvMode::YUV444;
+            out.width = 800;
+            out.height = 600;
+            out.ySelector = 0;
+            out.uvSelector = 0;
+        }
+    }
 
-  FILE *fp = fopen("/tmp/screendata.bin", "wb");
-  fwrite(out.buffer.data(), sizeof(char), out.buffer.size(), fp);
+    FILE *fp = fopen("/tmp/screendata.bin", "wb");
+    fwrite(out.buffer.data(), sizeof(char), out.buffer.size(), fp);
 
-  ast_video::AstJpegDecoder d;
-  d.decode(out.buffer, out.width, out.height, out.mode, out.ySelector,
-           out.uvSelector);
+    ast_video::AstJpegDecoder d;
+    d.decode(out.buffer, out.width, out.height, out.mode, out.ySelector,
+             out.uvSelector);
 #ifdef BUILD_CIMG
-  cimg_library::CImg<unsigned char> image(out.width, out.height, 1,
-                                          3 /*numchannels*/);
-  for (int y = 0; y < out.height; y++) {
-    for (int x = 0; x < out.width; x++) {
-      auto pixel = d.outBuffer[x + (y * out.width)];
-      image(x, y, 0) = pixel.r;
-      image(x, y, 1) = pixel.g;
-      image(x, y, 2) = pixel.b;
+    cimg_library::CImg<unsigned char> image(out.width, out.height, 1,
+                                            3 /*numchannels*/);
+    for (int y = 0; y < out.height; y++)
+    {
+        for (int x = 0; x < out.width; x++)
+        {
+            auto pixel = d.outBuffer[x + (y * out.width)];
+            image(x, y, 0) = pixel.r;
+            image(x, y, 1) = pixel.g;
+            image(x, y, 2) = pixel.b;
+        }
     }
-  }
-  image.save("/tmp/file2.bmp");
+    image.save("/tmp/file2.bmp");
 #endif
 
-  std::cout << "Done!\n";
+    std::cout << "Done!\n";
 
-  return 1;
+    return 1;
 }
diff --git a/src/gtest_main.cpp b/src/gtest_main.cpp
index eec0067..77e70aa 100644
--- a/src/gtest_main.cpp
+++ b/src/gtest_main.cpp
@@ -1,7 +1,8 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
-int main(int argc, char **argv) {
-  ::testing::InitGoogleTest(&argc, argv);
-  return RUN_ALL_TESTS();
+int main(int argc, char **argv)
+{
+    ::testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
 }
\ No newline at end of file
diff --git a/src/kvm_websocket_test.cpp b/src/kvm_websocket_test.cpp
index b5e1bdc..1ddaad9 100644
--- a/src/kvm_websocket_test.cpp
+++ b/src/kvm_websocket_test.cpp
@@ -1,9 +1,12 @@
+#include "gzip_helper.hpp"
+#include "web_kvm.hpp"
+
 #include <iostream>
 #include <sstream>
 #include <vector>
-#include "gzip_helper.hpp"
-#include "web_kvm.hpp"
+
 #include "crow.h"
+
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
@@ -11,93 +14,101 @@
 using namespace testing;
 
 // Tests static files are loaded correctly
-TEST(Kvm, BasicRfb) {
-  return;  // TODO(ed) Make hte code below work again
-  SimpleApp app;
+TEST(Kvm, BasicRfb)
+{
+    return; // TODO(ed) Make hte code below work again
+    SimpleApp app;
 
-  crow::kvm::requestRoutes(app);
-  app.bindaddr("127.0.0.1").port(45451);
-  BMCWEB_ROUTE(app, "/")([]() { return boost::beast::http::status::ok; });
-  auto _ = async(std::launch::async, [&] { app.run(); });
-  auto routes = app.getRoutes();
-  asio::io_service is;
+    crow::kvm::requestRoutes(app);
+    app.bindaddr("127.0.0.1").port(45451);
+    BMCWEB_ROUTE(app, "/")([]() { return boost::beast::http::status::ok; });
+    auto _ = async(std::launch::async, [&] { app.run(); });
+    auto routes = app.getRoutes();
+    asio::io_service is;
 
-  {
-    // Retry a couple of times waiting for the server to come up
-    // TODO(ed)  This is really unfortunate, and should use some form of mock
-    asio::ip::tcp::socket c(is);
-    for (int i = 0; i < 200; i++) {
-      try {
-        c.connect(asio::ip::tcp::endpoint(
-            asio::ip::address::from_string("127.0.0.1"), 45451));
-        c.close();
-        break;
-      } catch (std::exception e) {
-        // do nothing.  We expect this to fail while the server is starting up
-      }
+    {
+        // Retry a couple of times waiting for the server to come up
+        // TODO(ed)  This is really unfortunate, and should use some form of
+        // mock
+        asio::ip::tcp::socket c(is);
+        for (int i = 0; i < 200; i++)
+        {
+            try
+            {
+                c.connect(asio::ip::tcp::endpoint(
+                    asio::ip::address::from_string("127.0.0.1"), 45451));
+                c.close();
+                break;
+            }
+            catch (std::exception e)
+            {
+                // do nothing.  We expect this to fail while the server is
+                // starting up
+            }
+        }
     }
-  }
 
-  // Get the websocket
-  std::string sendmsg =
-      ("GET /kvmws HTTP/1.1\r\n"
-       "Host: localhost:45451\r\n"
-       "Connection: Upgrade\r\n"
-       "Upgrade: websocket\r\n"
-       "Sec-WebSocket-Version: 13\r\n"
-       "Sec-WebSocket-Key: aLeGkmLPZmdv5tTyEpJ3jQ==\r\n"
-       "Sec-WebSocket-Extensions: permessage-deflate; "
-       "client_max_window_bits\r\n"
-       "Sec-WebSocket-Protocol: binary\r\n"
-       "\r\n");
+    // Get the websocket
+    std::string sendmsg = ("GET /kvmws HTTP/1.1\r\n"
+                           "Host: localhost:45451\r\n"
+                           "Connection: Upgrade\r\n"
+                           "Upgrade: websocket\r\n"
+                           "Sec-WebSocket-Version: 13\r\n"
+                           "Sec-WebSocket-Key: aLeGkmLPZmdv5tTyEpJ3jQ==\r\n"
+                           "Sec-WebSocket-Extensions: permessage-deflate; "
+                           "client_max_window_bits\r\n"
+                           "Sec-WebSocket-Protocol: binary\r\n"
+                           "\r\n");
 
-  asio::ip::tcp::socket socket(is);
-  socket.connect(asio::ip::tcp::endpoint(
-      asio::ip::address::from_string("127.0.0.1"), 45451));
-  socket.send(asio::buffer(sendmsg));
+    asio::ip::tcp::socket socket(is);
+    socket.connect(asio::ip::tcp::endpoint(
+        asio::ip::address::from_string("127.0.0.1"), 45451));
+    socket.send(asio::buffer(sendmsg));
 
-  // Read the Response status line. The Response streambuf will automatically
-  // grow to accommodate the entire line. The growth may be limited by passing
-  // a maximum size to the streambuf constructor.
-  boost::asio::streambuf response;
-  boost::asio::read_until(socket, response, "\r\n");
+    // Read the Response status line. The Response streambuf will automatically
+    // grow to accommodate the entire line. The growth may be limited by passing
+    // a maximum size to the streambuf constructor.
+    boost::asio::streambuf response;
+    boost::asio::read_until(socket, response, "\r\n");
 
-  // Check that Response is OK.
-  std::istream response_stream(&response);
-  std::string http_response;
-  std::getline(response_stream, http_response);
+    // Check that Response is OK.
+    std::istream response_stream(&response);
+    std::string http_response;
+    std::getline(response_stream, http_response);
 
-  EXPECT_EQ(http_response, "HTTP/1.1 101 Switching Protocols\r");
+    EXPECT_EQ(http_response, "HTTP/1.1 101 Switching Protocols\r");
 
-  // Read the Response headers, which are terminated by a blank line.
-  boost::asio::read_until(socket, response, "\r\n\r\n");
+    // Read the Response headers, which are terminated by a blank line.
+    boost::asio::read_until(socket, response, "\r\n\r\n");
 
-  // Process the Response headers.
-  std::string header;
-  std::vector<std::string> headers;
-  while (std::getline(response_stream, header) && header != "\r") {
-    headers.push_back(header);
-  }
+    // Process the Response headers.
+    std::string header;
+    std::vector<std::string> headers;
+    while (std::getline(response_stream, header) && header != "\r")
+    {
+        headers.push_back(header);
+    }
 
-  EXPECT_THAT(headers, Contains("Upgrade: websocket\r"));
-  EXPECT_THAT(headers, Contains("Connection: Upgrade\r"));
-  EXPECT_THAT(headers, Contains("Sec-WebSocket-Protocol: binary\r"));
-  // TODO(ed) This is the result that it gives today.  Need to check websocket
-  // docs and make
-  // sure that this calclution is actually being done to spec
-  EXPECT_THAT(headers,
-              Contains("Sec-WebSocket-Accept: /CnDM3l79rIxniLNyxMryXbtLEU=\r"));
-  std::array<char, 13> rfb_open_string;
+    EXPECT_THAT(headers, Contains("Upgrade: websocket\r"));
+    EXPECT_THAT(headers, Contains("Connection: Upgrade\r"));
+    EXPECT_THAT(headers, Contains("Sec-WebSocket-Protocol: binary\r"));
+    // TODO(ed) This is the result that it gives today.  Need to check websocket
+    // docs and make
+    // sure that this calclution is actually being done to spec
+    EXPECT_THAT(
+        headers,
+        Contains("Sec-WebSocket-Accept: /CnDM3l79rIxniLNyxMryXbtLEU=\r"));
+    std::array<char, 13> rfb_open_string;
 
-  //
-  // socket.receive(rfb_open_string.data(), rfb_open_string.size());
-  boost::asio::read(socket, boost::asio::buffer(rfb_open_string));
-  auto open_string =
-      std::string(std::begin(rfb_open_string), std::end(rfb_open_string));
-  // Todo(ed) find out what the two characters at the end of the websocket
-  // stream are
-  open_string = open_string.substr(2);
-  EXPECT_EQ(open_string, "RFB 003.008");
+    //
+    // socket.receive(rfb_open_string.data(), rfb_open_string.size());
+    boost::asio::read(socket, boost::asio::buffer(rfb_open_string));
+    auto open_string =
+        std::string(std::begin(rfb_open_string), std::end(rfb_open_string));
+    // Todo(ed) find out what the two characters at the end of the websocket
+    // stream are
+    open_string = open_string.substr(2);
+    EXPECT_EQ(open_string, "RFB 003.008");
 
-  app.stop();
+    app.stop();
 }
\ No newline at end of file
diff --git a/src/msan_test.cpp b/src/msan_test.cpp
index 9fcb9d5..7e42e48 100644
--- a/src/msan_test.cpp
+++ b/src/msan_test.cpp
@@ -1,7 +1,9 @@
 #include <string>
+
 #include "gtest/gtest.h"
 
-TEST(MemorySanitizer, TestIsWorking) {
-  std::string foo("foo");
-  EXPECT_STREQ("foo", foo.c_str());
+TEST(MemorySanitizer, TestIsWorking)
+{
+    std::string foo("foo");
+    EXPECT_STREQ("foo", foo.c_str());
 }
diff --git a/src/openbmc_jtag_rest_test.cpp b/src/openbmc_jtag_rest_test.cpp
index 7e40d6d..42504d3 100644
--- a/src/openbmc_jtag_rest_test.cpp
+++ b/src/openbmc_jtag_rest_test.cpp
@@ -1,51 +1,53 @@
 #include "openbmc_dbus_rest.hpp"
+
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
-TEST(OpenBmcDbusTest, TestArgSplit) {
-  // test the basic types
-  EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("x"),
-              ::testing::ElementsAre("x"));
-  EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("y"),
-              ::testing::ElementsAre("y"));
-  EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("b"),
-              ::testing::ElementsAre("b"));
-  EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("n"),
-              ::testing::ElementsAre("n"));
-  EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("q"),
-              ::testing::ElementsAre("q"));
-  EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("i"),
-              ::testing::ElementsAre("i"));
-  EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("u"),
-              ::testing::ElementsAre("u"));
-  EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("x"),
-              ::testing::ElementsAre("x"));
-  EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("t"),
-              ::testing::ElementsAre("t"));
-  EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("d"),
-              ::testing::ElementsAre("d"));
-  EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("h"),
-              ::testing::ElementsAre("h"));
-  // test arrays
-  EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("ai"),
-              ::testing::ElementsAre("ai"));
-  EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("ax"),
-              ::testing::ElementsAre("ax"));
-  // test tuples
-  EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("(sss)"),
-              ::testing::ElementsAre("(sss)"));
-  EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("(sss)b"),
-              ::testing::ElementsAre("(sss)", "b"));
-  EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("b(sss)"),
-              ::testing::ElementsAre("b", "(sss)"));
+TEST(OpenBmcDbusTest, TestArgSplit)
+{
+    // test the basic types
+    EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("x"),
+                ::testing::ElementsAre("x"));
+    EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("y"),
+                ::testing::ElementsAre("y"));
+    EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("b"),
+                ::testing::ElementsAre("b"));
+    EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("n"),
+                ::testing::ElementsAre("n"));
+    EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("q"),
+                ::testing::ElementsAre("q"));
+    EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("i"),
+                ::testing::ElementsAre("i"));
+    EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("u"),
+                ::testing::ElementsAre("u"));
+    EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("x"),
+                ::testing::ElementsAre("x"));
+    EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("t"),
+                ::testing::ElementsAre("t"));
+    EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("d"),
+                ::testing::ElementsAre("d"));
+    EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("h"),
+                ::testing::ElementsAre("h"));
+    // test arrays
+    EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("ai"),
+                ::testing::ElementsAre("ai"));
+    EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("ax"),
+                ::testing::ElementsAre("ax"));
+    // test tuples
+    EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("(sss)"),
+                ::testing::ElementsAre("(sss)"));
+    EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("(sss)b"),
+                ::testing::ElementsAre("(sss)", "b"));
+    EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("b(sss)"),
+                ::testing::ElementsAre("b", "(sss)"));
 
-  // Test nested types
-  EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("a{si}b"),
-              ::testing::ElementsAre("a{si}", "b"));
-  EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("a(sss)b"),
-              ::testing::ElementsAre("a(sss)", "b"));
-  EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("aa{si}b"),
-              ::testing::ElementsAre("aa{si}", "b"));
-  EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("i{si}b"),
-              ::testing::ElementsAre("b", "aa{si}"));
+    // Test nested types
+    EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("a{si}b"),
+                ::testing::ElementsAre("a{si}", "b"));
+    EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("a(sss)b"),
+                ::testing::ElementsAre("a(sss)", "b"));
+    EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("aa{si}b"),
+                ::testing::ElementsAre("aa{si}", "b"));
+    EXPECT_THAT(crow::openbmc_mapper::dbus_arg_split("i{si}b"),
+                ::testing::ElementsAre("b", "aa{si}"));
 }
diff --git a/src/security_headers_middleware_test.cpp b/src/security_headers_middleware_test.cpp
index e7008cb..2af15c6 100644
--- a/src/security_headers_middleware_test.cpp
+++ b/src/security_headers_middleware_test.cpp
@@ -1,5 +1,7 @@
-#include <security_headers_middleware.hpp>
 #include <crow/app.h>
+
+#include <security_headers_middleware.hpp>
+
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
@@ -7,68 +9,78 @@
 using namespace std;
 
 // Tests that the security headers are added correctly
-TEST(SecurityHeaders, TestHeadersExist) {
-  App<SecurityHeadersMiddleware> app;
-  app.bindaddr("127.0.0.1").port(45451);
-  BMCWEB_ROUTE(app, "/")([]() { return boost::beast::http::status::ok; });
-  auto _ = async(launch::async, [&] { app.run(); });
+TEST(SecurityHeaders, TestHeadersExist)
+{
+    App<SecurityHeadersMiddleware> app;
+    app.bindaddr("127.0.0.1").port(45451);
+    BMCWEB_ROUTE(app, "/")([]() { return boost::beast::http::status::ok; });
+    auto _ = async(launch::async, [&] { app.run(); });
 
-  asio::io_service is;
-  std::array<char, 2048> buf;
-  std::string sendmsg;
+    asio::io_service is;
+    std::array<char, 2048> buf;
+    std::string sendmsg;
 
-  {
-    // Retry a couple of times waiting for the server to come up
-    // TODO(ed)  This is really unfortunate, and should use some form of mock
+    {
+        // Retry a couple of times waiting for the server to come up
+        // TODO(ed)  This is really unfortunate, and should use some form of
+        // mock
+        asio::ip::tcp::socket c(is);
+        for (int i = 0; i < 200; i++)
+        {
+            try
+            {
+                c.connect(asio::ip::tcp::endpoint(
+                    asio::ip::address::from_string("127.0.0.1"), 45451));
+                c.close();
+                break;
+            }
+            catch (std::exception e)
+            {
+                // do nothing.  We expect this to fail while the server is
+                // starting up
+            }
+        }
+    }
+
+    // Test correct login credentials
+    sendmsg = "GET /\r\n\r\n";
+
     asio::ip::tcp::socket c(is);
-    for (int i = 0; i < 200; i++) {
-      try {
-        c.connect(asio::ip::tcp::endpoint(
-            asio::ip::address::from_string("127.0.0.1"), 45451));
-        c.close();
-        break;
-      } catch (std::exception e) {
-        // do nothing.  We expect this to fail while the server is starting up
-      }
+    c.connect(asio::ip::tcp::endpoint(
+        asio::ip::address::from_string("127.0.0.1"), 45451));
+    c.send(asio::buffer(sendmsg));
+    c.receive(asio::buffer(buf));
+    c.close();
+    auto return_code = std::string(&buf[9], &buf[12]);
+    EXPECT_EQ("200", return_code);
+    std::string response(std::begin(buf), std::end(buf));
+
+    // This is a routine to split strings until a blank is hit
+    // TODO(ed) this should really use the HTTP parser
+    std::vector<std::string> headers;
+    std::string::size_type pos = 0;
+    std::string::size_type prev = 0;
+    while ((pos = response.find("\r\n", prev)) != std::string::npos)
+    {
+        auto this_string = response.substr(prev, pos - prev);
+        if (this_string == "")
+        {
+            break;
+        }
+        headers.push_back(this_string);
+        prev = pos + 2;
     }
-  }
+    headers.push_back(response.substr(prev));
 
-  // Test correct login credentials
-  sendmsg = "GET /\r\n\r\n";
-
-  asio::ip::tcp::socket c(is);
-  c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"),
-                                    45451));
-  c.send(asio::buffer(sendmsg));
-  c.receive(asio::buffer(buf));
-  c.close();
-  auto return_code = std::string(&buf[9], &buf[12]);
-  EXPECT_EQ("200", return_code);
-  std::string response(std::begin(buf), std::end(buf));
-
-  // This is a routine to split strings until a blank is hit
-  // TODO(ed) this should really use the HTTP parser
-  std::vector<std::string> headers;
-  std::string::size_type pos = 0;
-  std::string::size_type prev = 0;
-  while ((pos = response.find("\r\n", prev)) != std::string::npos) {
-    auto this_string = response.substr(prev, pos - prev);
-    if (this_string == "") {
-      break;
-    }
-    headers.push_back(this_string);
-    prev = pos + 2;
-  }
-  headers.push_back(response.substr(prev));
-
-  EXPECT_EQ(headers[0], "HTTP/1.1 200 OK");
-  EXPECT_THAT(headers, ::testing::Contains("Strict-Transport-Security: "
-                                           "max-age=31536000; "
-                                           "includeSubdomains; preload"));
-  EXPECT_THAT(headers, ::testing::Contains("X-UA-Compatible: IE=11"));
-  EXPECT_THAT(headers, ::testing::Contains("X-Frame-Options: DENY"));
-  EXPECT_THAT(headers, ::testing::Contains("X-XSS-Protection: 1; mode=block"));
-  EXPECT_THAT(headers, ::testing::Contains(
-                           "X-Content-Security-Policy: default-src 'self'"));
-  app.stop();
+    EXPECT_EQ(headers[0], "HTTP/1.1 200 OK");
+    EXPECT_THAT(headers, ::testing::Contains("Strict-Transport-Security: "
+                                             "max-age=31536000; "
+                                             "includeSubdomains; preload"));
+    EXPECT_THAT(headers, ::testing::Contains("X-UA-Compatible: IE=11"));
+    EXPECT_THAT(headers, ::testing::Contains("X-Frame-Options: DENY"));
+    EXPECT_THAT(headers,
+                ::testing::Contains("X-XSS-Protection: 1; mode=block"));
+    EXPECT_THAT(headers, ::testing::Contains(
+                             "X-Content-Security-Policy: default-src 'self'"));
+    app.stop();
 }
diff --git a/src/token_authorization_middleware_test.cpp b/src/token_authorization_middleware_test.cpp
index ab735b3..812a6d1 100644
--- a/src/token_authorization_middleware_test.cpp
+++ b/src/token_authorization_middleware_test.cpp
@@ -1,287 +1,322 @@
 #include "token_authorization_middleware.hpp"
+#include "webserver_common.hpp"
+
 #include <condition_variable>
 #include <future>
 #include <mutex>
-#include "webserver_common.hpp"
+
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
 using namespace crow;
 
-class TokenAuth : public ::testing::Test {
- public:
-  TokenAuth()
-      : lk(std::unique_lock<std::mutex>(m)),
-        io(std::make_shared<boost::asio::io_service>()) {}
+class TokenAuth : public ::testing::Test
+{
+  public:
+    TokenAuth() :
+        lk(std::unique_lock<std::mutex>(m)),
+        io(std::make_shared<boost::asio::io_service>())
+    {
+    }
 
-  std::mutex m;
-  std::condition_variable cv;
-  std::unique_lock<std::mutex> lk;
-  std::shared_ptr<boost::asio::io_service> io;
-  int testPort = 45451;
+    std::mutex m;
+    std::condition_variable cv;
+    std::unique_lock<std::mutex> lk;
+    std::shared_ptr<boost::asio::io_service> io;
+    int testPort = 45451;
 };
 
-TEST_F(TokenAuth, SpecialResourcesAreAcceptedWithoutAuth) {
-  CrowApp app(io);
-  crow::token_authorization::requestRoutes(app);
-  BMCWEB_ROUTE(app, "/redfish/v1")
-  ([]() { return boost::beast::http::status::ok; });
-  auto _ = std::async(std::launch::async, [&] {
-    app.port(testPort).run();
-    cv.notify_one();
-    io->run();
-  });
+TEST_F(TokenAuth, SpecialResourcesAreAcceptedWithoutAuth)
+{
+    CrowApp app(io);
+    crow::token_authorization::requestRoutes(app);
+    BMCWEB_ROUTE(app, "/redfish/v1")
+    ([]() { return boost::beast::http::status::ok; });
+    auto _ = std::async(std::launch::async, [&] {
+        app.port(testPort).run();
+        cv.notify_one();
+        io->run();
+    });
 
-  asio::io_service is;
-  std::string sendmsg;
+    asio::io_service is;
+    std::string sendmsg;
 
-  static char buf[2048];
+    static char buf[2048];
 
-  // Homepage should be passed with no credentials
-  sendmsg = "GET /\r\n\r\n";
-  {
-    asio::ip::tcp::socket c(is);
-    c.connect(asio::ip::tcp::endpoint(
-        asio::ip::address::from_string("127.0.0.1"), 45451));
-    c.send(asio::buffer(sendmsg));
-    c.receive(asio::buffer(buf, 2048));
-    c.close();
-    EXPECT_EQ("200", std::string(buf + 9, buf + 12));
-  }
+    // Homepage should be passed with no credentials
+    sendmsg = "GET /\r\n\r\n";
+    {
+        asio::ip::tcp::socket c(is);
+        c.connect(asio::ip::tcp::endpoint(
+            asio::ip::address::from_string("127.0.0.1"), 45451));
+        c.send(asio::buffer(sendmsg));
+        c.receive(asio::buffer(buf, 2048));
+        c.close();
+        EXPECT_EQ("200", std::string(buf + 9, buf + 12));
+    }
 
-  // static should be passed with no credentials
-  sendmsg = "GET /static/index.html\r\n\r\n";
-  {
-    asio::ip::tcp::socket c(is);
-    c.connect(asio::ip::tcp::endpoint(
-        asio::ip::address::from_string("127.0.0.1"), 45451));
-    c.send(asio::buffer(sendmsg));
-    c.receive(asio::buffer(buf, 2048));
-    c.close();
-    EXPECT_EQ("404", std::string(buf + 9, buf + 12));
-  }
+    // static should be passed with no credentials
+    sendmsg = "GET /static/index.html\r\n\r\n";
+    {
+        asio::ip::tcp::socket c(is);
+        c.connect(asio::ip::tcp::endpoint(
+            asio::ip::address::from_string("127.0.0.1"), 45451));
+        c.send(asio::buffer(sendmsg));
+        c.receive(asio::buffer(buf, 2048));
+        c.close();
+        EXPECT_EQ("404", std::string(buf + 9, buf + 12));
+    }
 
-  app.stop();
+    app.stop();
 }
 
 // Tests that Base64 basic strings work
-TEST(TokenAuthentication, TestRejectedResource) {
-  App<crow::persistent_data::Middleware, crow::token_authorization::Middleware>
-      app;
-  app.bindaddr("127.0.0.1").port(45451);
-  BMCWEB_ROUTE(app, "/")([]() { return boost::beast::http::status::ok; });
-  auto _ = async(std::launch::async, [&] { app.run(); });
+TEST(TokenAuthentication, TestRejectedResource)
+{
+    App<crow::persistent_data::Middleware,
+        crow::token_authorization::Middleware>
+        app;
+    app.bindaddr("127.0.0.1").port(45451);
+    BMCWEB_ROUTE(app, "/")([]() { return boost::beast::http::status::ok; });
+    auto _ = async(std::launch::async, [&] { app.run(); });
 
-  asio::io_service is;
-  static char buf[2048];
+    asio::io_service is;
+    static char buf[2048];
 
-  // Other resources should not be passed
-  std::string sendmsg = "GET /foo\r\n\r\n";
-  asio::ip::tcp::socket c(is);
-  for (int i = 0; i < 200; i++) {
-    try {
-      c.connect(asio::ip::tcp::endpoint(
-          asio::ip::address::from_string("127.0.0.1"), 45451));
-    } catch (std::exception e) {
-      // do nothing
+    // Other resources should not be passed
+    std::string sendmsg = "GET /foo\r\n\r\n";
+    asio::ip::tcp::socket c(is);
+    for (int i = 0; i < 200; i++)
+    {
+        try
+        {
+            c.connect(asio::ip::tcp::endpoint(
+                asio::ip::address::from_string("127.0.0.1"), 45451));
+        }
+        catch (std::exception e)
+        {
+            // do nothing
+        }
     }
-  }
-  c.send(asio::buffer(sendmsg));
-  c.receive(asio::buffer(buf, 2048));
-  c.close();
-  EXPECT_EQ("401", std::string(buf + 9, buf + 12));
+    c.send(asio::buffer(sendmsg));
+    c.receive(asio::buffer(buf, 2048));
+    c.close();
+    EXPECT_EQ("401", std::string(buf + 9, buf + 12));
 
-  app.stop();
+    app.stop();
 }
 
 // Tests that Base64 basic strings work
-TEST(TokenAuthentication, TestGetLoginUrl) {
-  App<crow::persistent_data::Middleware, crow::token_authorization::Middleware>
-      app;
-  app.bindaddr("127.0.0.1").port(45451);
-  BMCWEB_ROUTE(app, "/")([]() { return boost::beast::http::status::ok; });
-  auto _ = async(std::launch::async, [&] { app.run(); });
+TEST(TokenAuthentication, TestGetLoginUrl)
+{
+    App<crow::persistent_data::Middleware,
+        crow::token_authorization::Middleware>
+        app;
+    app.bindaddr("127.0.0.1").port(45451);
+    BMCWEB_ROUTE(app, "/")([]() { return boost::beast::http::status::ok; });
+    auto _ = async(std::launch::async, [&] { app.run(); });
 
-  asio::io_service is;
-  static char buf[2048];
+    asio::io_service is;
+    static char buf[2048];
 
-  // Other resources should not be passed
-  std::string sendmsg = "GET /login\r\n\r\n";
-  asio::ip::tcp::socket c(is);
-  for (int i = 0; i < 200; i++) {
-    try {
-      c.connect(asio::ip::tcp::endpoint(
-          asio::ip::address::from_string("127.0.0.1"), 45451));
-    } catch (std::exception e) {
-      // do nothing
+    // Other resources should not be passed
+    std::string sendmsg = "GET /login\r\n\r\n";
+    asio::ip::tcp::socket c(is);
+    for (int i = 0; i < 200; i++)
+    {
+        try
+        {
+            c.connect(asio::ip::tcp::endpoint(
+                asio::ip::address::from_string("127.0.0.1"), 45451));
+        }
+        catch (std::exception e)
+        {
+            // do nothing
+        }
     }
-  }
-  c.send(asio::buffer(sendmsg));
-  c.receive(asio::buffer(buf, 2048));
-  c.close();
-  EXPECT_EQ("401", std::string(buf + 9, buf + 12));
+    c.send(asio::buffer(sendmsg));
+    c.receive(asio::buffer(buf, 2048));
+    c.close();
+    EXPECT_EQ("401", std::string(buf + 9, buf + 12));
 
-  app.stop();
+    app.stop();
 }
 
 // Tests boundary conditions on login
-TEST(TokenAuthentication, TestPostBadLoginUrl) {
-  App<crow::persistent_data::Middleware, crow::token_authorization::Middleware>
-      app;
-  app.bindaddr("127.0.0.1").port(45451);
-  BMCWEB_ROUTE(app, "/")([]() { return boost::beast::http::status::ok; });
-  auto _ = async(std::launch::async, [&] { app.run(); });
+TEST(TokenAuthentication, TestPostBadLoginUrl)
+{
+    App<crow::persistent_data::Middleware,
+        crow::token_authorization::Middleware>
+        app;
+    app.bindaddr("127.0.0.1").port(45451);
+    BMCWEB_ROUTE(app, "/")([]() { return boost::beast::http::status::ok; });
+    auto _ = async(std::launch::async, [&] { app.run(); });
 
-  asio::io_service is;
-  std::array<char, 2048> buf;
-  std::string sendmsg;
+    asio::io_service is;
+    std::array<char, 2048> buf;
+    std::string sendmsg;
 
-  auto send_to_localhost = [&is, &buf](std::string sendmsg) {
-    asio::ip::tcp::socket c(is);
-    c.connect(asio::ip::tcp::endpoint(
-        asio::ip::address::from_string("127.0.0.1"), 45451));
-    c.send(asio::buffer(sendmsg));
-    c.receive(asio::buffer(buf));
-    c.close();
-  };
-
-  {
-    // Retry a couple of times waiting for the server to come up
-    asio::ip::tcp::socket c(is);
-    for (int i = 0; i < 200; i++) {
-      try {
+    auto send_to_localhost = [&is, &buf](std::string sendmsg) {
+        asio::ip::tcp::socket c(is);
         c.connect(asio::ip::tcp::endpoint(
             asio::ip::address::from_string("127.0.0.1"), 45451));
+        c.send(asio::buffer(sendmsg));
+        c.receive(asio::buffer(buf));
         c.close();
-        break;
-      } catch (std::exception e) {
-        // do nothing.  We expect this to fail while the server is starting up
-      }
+    };
+
+    {
+        // Retry a couple of times waiting for the server to come up
+        asio::ip::tcp::socket c(is);
+        for (int i = 0; i < 200; i++)
+        {
+            try
+            {
+                c.connect(asio::ip::tcp::endpoint(
+                    asio::ip::address::from_string("127.0.0.1"), 45451));
+                c.close();
+                break;
+            }
+            catch (std::exception e)
+            {
+                // do nothing.  We expect this to fail while the server is
+                // starting up
+            }
+        }
     }
-  }
 
-  // Test blank login credentials
-  sendmsg = "POST /login\r\nContent-Length:0\r\n\r\n\r\n";
-  {
-    send_to_localhost(sendmsg);
-    auto return_code = std::string(&buf[9], &buf[12]);
-    EXPECT_EQ("400", return_code);
-  }
+    // Test blank login credentials
+    sendmsg = "POST /login\r\nContent-Length:0\r\n\r\n\r\n";
+    {
+        send_to_localhost(sendmsg);
+        auto return_code = std::string(&buf[9], &buf[12]);
+        EXPECT_EQ("400", return_code);
+    }
 
-  // Test wrong login credentials
-  sendmsg =
-      "POST /login\r\nContent-Length:38\r\n\r\n{\"username\": \"foo\", "
-      "\"password\": \"bar\"}\r\n";
-  {
-    send_to_localhost(sendmsg);
-    auto return_code = std::string(&buf[9], &buf[12]);
-    EXPECT_EQ("401", return_code);
-    // TODO(ed) need to test more here.  Response string?
-  }
+    // Test wrong login credentials
+    sendmsg = "POST /login\r\nContent-Length:38\r\n\r\n{\"username\": \"foo\", "
+              "\"password\": \"bar\"}\r\n";
+    {
+        send_to_localhost(sendmsg);
+        auto return_code = std::string(&buf[9], &buf[12]);
+        EXPECT_EQ("401", return_code);
+        // TODO(ed) need to test more here.  Response string?
+    }
 
-  // Test only sending a username
-  sendmsg =
-      "POST /login\r\nContent-Length:19\r\n\r\n{\"username\": \"foo\"}\r\n";
-  {
-    send_to_localhost(sendmsg);
-    auto return_code = std::string(&buf[9], &buf[12]);
-    EXPECT_EQ("400", return_code);
-  }
+    // Test only sending a username
+    sendmsg =
+        "POST /login\r\nContent-Length:19\r\n\r\n{\"username\": \"foo\"}\r\n";
+    {
+        send_to_localhost(sendmsg);
+        auto return_code = std::string(&buf[9], &buf[12]);
+        EXPECT_EQ("400", return_code);
+    }
 
-  // Test only sending a password
-  sendmsg =
-      "POST /login\r\nContent-Length:19\r\n\r\n{\"password\": \"foo\"}\r\n";
-  {
-    send_to_localhost(sendmsg);
-    auto return_code = std::string(&buf[9], &buf[12]);
-    EXPECT_EQ("400", return_code);
-  }
+    // Test only sending a password
+    sendmsg =
+        "POST /login\r\nContent-Length:19\r\n\r\n{\"password\": \"foo\"}\r\n";
+    {
+        send_to_localhost(sendmsg);
+        auto return_code = std::string(&buf[9], &buf[12]);
+        EXPECT_EQ("400", return_code);
+    }
 
-  app.stop();
+    app.stop();
 }
 
 // Test class that allows login for a fixed password.
-class KnownLoginAuthenticator {
- public:
-  inline bool authenticate(const std::string& username,
-                           const std::string& password) {
-    return (username == "dude") && (password == "foo");
-  }
+class KnownLoginAuthenticator
+{
+  public:
+    inline bool authenticate(const std::string& username,
+                             const std::string& password)
+    {
+        return (username == "dude") && (password == "foo");
+    }
 };
 
-TEST(TokenAuthentication, TestSuccessfulLogin) {
-  App<crow::persistent_data::Middleware, crow::token_authorization::Middleware>
-      app;
-  app.bindaddr("127.0.0.1").port(45451);
-  BMCWEB_ROUTE(app, "/")([]() { return boost::beast::http::status::ok; });
-  auto _ = async(std::launch::async, [&] { app.run(); });
+TEST(TokenAuthentication, TestSuccessfulLogin)
+{
+    App<crow::persistent_data::Middleware,
+        crow::token_authorization::Middleware>
+        app;
+    app.bindaddr("127.0.0.1").port(45451);
+    BMCWEB_ROUTE(app, "/")([]() { return boost::beast::http::status::ok; });
+    auto _ = async(std::launch::async, [&] { app.run(); });
 
-  asio::io_service is;
-  std::array<char, 2048> buf;
-  std::string sendmsg;
+    asio::io_service is;
+    std::array<char, 2048> buf;
+    std::string sendmsg;
 
-  auto send_to_localhost = [&is, &buf](std::string sendmsg) {
-    asio::ip::tcp::socket c(is);
-    c.connect(asio::ip::tcp::endpoint(
-        asio::ip::address::from_string("127.0.0.1"), 45451));
-    c.send(asio::buffer(sendmsg));
-    c.receive(asio::buffer(buf));
-    c.close();
-  };
-
-  {
-    // Retry a couple of times waiting for the server to come up
-    asio::ip::tcp::socket c(is);
-    for (int i = 0; i < 200; i++) {
-      try {
+    auto send_to_localhost = [&is, &buf](std::string sendmsg) {
+        asio::ip::tcp::socket c(is);
         c.connect(asio::ip::tcp::endpoint(
             asio::ip::address::from_string("127.0.0.1"), 45451));
+        c.send(asio::buffer(sendmsg));
+        c.receive(asio::buffer(buf));
         c.close();
-        break;
-      } catch (std::exception e) {
-        // do nothing.  We expect this to fail while the server is starting up
-      }
+    };
+
+    {
+        // Retry a couple of times waiting for the server to come up
+        asio::ip::tcp::socket c(is);
+        for (int i = 0; i < 200; i++)
+        {
+            try
+            {
+                c.connect(asio::ip::tcp::endpoint(
+                    asio::ip::address::from_string("127.0.0.1"), 45451));
+                c.close();
+                break;
+            }
+            catch (std::exception e)
+            {
+                // do nothing.  We expect this to fail while the server is
+                // starting up
+            }
+        }
     }
-  }
 
-  // Test correct login credentials
-  sendmsg =
-      "POST /login\r\nContent-Length:40\r\n\r\n{\"username\": \"dude\", "
-      "\"password\": \"foo\"}\r\n";
-  {
-    send_to_localhost(sendmsg);
-    std::string response(std::begin(buf), std::end(buf));
-    // This is a routine to split strings until a newline is hit
-    // TODO(ed) this should really use the HTTP parser
-    std::vector<std::string> headers;
-    std::string::size_type pos = 0;
-    std::string::size_type prev = 0;
-    int content_length = 0;
-    std::string content_encoding("");
-    while ((pos = response.find("\r\n", prev)) != std::string::npos) {
-      auto this_string = response.substr(prev, pos - prev);
-      if (this_string == "") {
-        prev = pos + 2;
-        break;
-      }
+    // Test correct login credentials
+    sendmsg =
+        "POST /login\r\nContent-Length:40\r\n\r\n{\"username\": \"dude\", "
+        "\"password\": \"foo\"}\r\n";
+    {
+        send_to_localhost(sendmsg);
+        std::string response(std::begin(buf), std::end(buf));
+        // This is a routine to split strings until a newline is hit
+        // TODO(ed) this should really use the HTTP parser
+        std::vector<std::string> headers;
+        std::string::size_type pos = 0;
+        std::string::size_type prev = 0;
+        int content_length = 0;
+        std::string content_encoding("");
+        while ((pos = response.find("\r\n", prev)) != std::string::npos)
+        {
+            auto this_string = response.substr(prev, pos - prev);
+            if (this_string == "")
+            {
+                prev = pos + 2;
+                break;
+            }
 
-      headers.push_back(this_string);
-      prev = pos + 2;
+            headers.push_back(this_string);
+            prev = pos + 2;
+        }
+        EXPECT_EQ(headers[0], "HTTP/1.1 200 OK");
+        EXPECT_THAT(headers,
+                    testing::Contains("Content-Type: application/json"));
+        auto http_content = response.substr(prev);
     }
-    EXPECT_EQ(headers[0], "HTTP/1.1 200 OK");
-    EXPECT_THAT(headers, testing::Contains("Content-Type: application/json"));
-    auto http_content = response.substr(prev);
-  }
 
-  // Try to use those login credentials to access a resource
-  sendmsg =
-      "GET /\r\nAuthorization: token\r\n\r\n{\"username\": \"dude\", "
-      "\"password\": \"dude\"}\r\n";
-  {
-    send_to_localhost(sendmsg);
-    auto return_code = std::string(&buf[9], &buf[12]);
-    EXPECT_EQ("200", return_code);
-  }
+    // Try to use those login credentials to access a resource
+    sendmsg = "GET /\r\nAuthorization: token\r\n\r\n{\"username\": \"dude\", "
+              "\"password\": \"dude\"}\r\n";
+    {
+        send_to_localhost(sendmsg);
+        auto return_code = std::string(&buf[9], &buf[12]);
+        EXPECT_EQ("200", return_code);
+    }
 
-  app.stop();
+    app.stop();
 }
\ No newline at end of file
diff --git a/src/webassets_test.cpp b/src/webassets_test.cpp
index 2633c9b..a3106f2 100644
--- a/src/webassets_test.cpp
+++ b/src/webassets_test.cpp
@@ -1,135 +1,145 @@
 #include <crow/app.h>
-#include <gmock/gmock.h>
 
-#include <gzip_helper.hpp>
-#include <webassets.hpp>
-#include <sstream>
 #include <boost/algorithm/string/predicate.hpp>
 #include <boost/lexical_cast.hpp>
+#include <gzip_helper.hpp>
+#include <sstream>
+#include <webassets.hpp>
+
 #include "gtest/gtest.h"
+#include <gmock/gmock.h>
 
 using namespace crow;
 using namespace std;
 using namespace testing;
 
 // Tests static files are loaded correctly
-TEST(Webassets, StaticFilesFixedRoutes) {
-  std::array<char, 2048> buf;
-  SimpleApp app;
-  webassets::requestRoutes(app);
-  Server<SimpleApp> server(&app, "127.0.0.1", 45451);
-  auto _ = async(launch::async, [&] { server.run(); });
+TEST(Webassets, StaticFilesFixedRoutes)
+{
+    std::array<char, 2048> buf;
+    SimpleApp app;
+    webassets::requestRoutes(app);
+    Server<SimpleApp> server(&app, "127.0.0.1", 45451);
+    auto _ = async(launch::async, [&] { server.run(); });
 
-  // get the homepage
-  std::string sendmsg = "GET /\r\n\r\n";
+    // get the homepage
+    std::string sendmsg = "GET /\r\n\r\n";
 
-  asio::io_service is;
+    asio::io_service is;
 
-  asio::ip::tcp::socket c(is);
-  c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"),
-                                    45451));
+    asio::ip::tcp::socket c(is);
+    c.connect(asio::ip::tcp::endpoint(
+        asio::ip::address::from_string("127.0.0.1"), 45451));
 
-  c.send(asio::buffer(sendmsg));
+    c.send(asio::buffer(sendmsg));
 
-  c.receive(asio::buffer(buf, 2048));
-  c.close();
+    c.receive(asio::buffer(buf, 2048));
+    c.close();
 
-  std::string response(std::begin(buf), std::end(buf));
-  // This is a routine to split strings until a newline is hit
-  // TODO(ed) this should really use the HTTP parser
-  std::vector<std::string> headers;
-  std::string::size_type pos = 0;
-  std::string::size_type prev = 0;
-  int content_length = 0;
-  std::string content_encoding("");
-  while ((pos = response.find("\r\n", prev)) != std::string::npos) {
-    auto this_string = response.substr(prev, pos - prev);
-    if (this_string == "") {
-      prev = pos + 2;
-      break;
+    std::string response(std::begin(buf), std::end(buf));
+    // This is a routine to split strings until a newline is hit
+    // TODO(ed) this should really use the HTTP parser
+    std::vector<std::string> headers;
+    std::string::size_type pos = 0;
+    std::string::size_type prev = 0;
+    int content_length = 0;
+    std::string content_encoding("");
+    while ((pos = response.find("\r\n", prev)) != std::string::npos)
+    {
+        auto this_string = response.substr(prev, pos - prev);
+        if (this_string == "")
+        {
+            prev = pos + 2;
+            break;
+        }
+
+        if (boost::starts_with(this_string, "Content-Length: "))
+        {
+            content_length = boost::lexical_cast<int>(this_string.substr(16));
+            // TODO(ed) This is an unfortunate test, but it's all we have at
+            // this point Realistically, the index.html will be more than 500
+            // bytes.  This test will need to be improved at some point
+            EXPECT_GT(content_length, 500);
+        }
+        if (boost::starts_with(this_string, "Content-Encoding: "))
+        {
+            content_encoding = this_string.substr(18);
+        }
+
+        headers.push_back(this_string);
+        prev = pos + 2;
     }
 
-    if (boost::starts_with(this_string, "Content-Length: ")) {
-      content_length = boost::lexical_cast<int>(this_string.substr(16));
-      // TODO(ed) This is an unfortunate test, but it's all we have at this
-      // point
-      // Realistically, the index.html will be more than 500 bytes.  This
-      // test will need to be improved at some point
-      EXPECT_GT(content_length, 500);
-    }
-    if (boost::starts_with(this_string, "Content-Encoding: ")) {
-      content_encoding = this_string.substr(18);
+    auto http_content = response.substr(prev);
+    // TODO(ed) ideally the server should support non-compressed gzip assets.
+    // Once this occurs, this line will be obsolete
+    std::string ungziped_content = http_content;
+    if (content_encoding == "gzip")
+    {
+        EXPECT_TRUE(gzipInflate(http_content, ungziped_content));
     }
 
-    headers.push_back(this_string);
-    prev = pos + 2;
-  }
+    EXPECT_EQ(headers[0], "HTTP/1.1 200 OK");
+    EXPECT_THAT(headers,
+                ::testing::Contains("Content-Type: text/html;charset=UTF-8"));
 
-  auto http_content = response.substr(prev);
-  // TODO(ed) ideally the server should support non-compressed gzip assets.
-  // Once this occurs, this line will be obsolete
-  std::string ungziped_content = http_content;
-  if (content_encoding == "gzip") {
-    EXPECT_TRUE(gzipInflate(http_content, ungziped_content));
-  }
+    EXPECT_EQ(ungziped_content.substr(0, 21), "<!DOCTYPE html>\n<html");
 
-  EXPECT_EQ(headers[0], "HTTP/1.1 200 OK");
-  EXPECT_THAT(headers,
-              ::testing::Contains("Content-Type: text/html;charset=UTF-8"));
-
-  EXPECT_EQ(ungziped_content.substr(0, 21), "<!DOCTYPE html>\n<html");
-
-  server.stop();
+    server.stop();
 }
 
 // Tests static files are loaded correctly
-TEST(Webassets, EtagIsSane) {
-  std::array<char, 2048> buf;
-  SimpleApp app;
-  webassets::requestRoutes(app);
-  Server<SimpleApp> server(&app, "127.0.0.1", 45451);
-  auto _ = async(launch::async, [&] { server.run(); });
+TEST(Webassets, EtagIsSane)
+{
+    std::array<char, 2048> buf;
+    SimpleApp app;
+    webassets::requestRoutes(app);
+    Server<SimpleApp> server(&app, "127.0.0.1", 45451);
+    auto _ = async(launch::async, [&] { server.run(); });
 
-  // get the homepage
-  std::string sendmsg = "GET /\r\n\r\n";
+    // get the homepage
+    std::string sendmsg = "GET /\r\n\r\n";
 
-  asio::io_service is;
+    asio::io_service is;
 
-  asio::ip::tcp::socket c(is);
-  c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"),
-                                    45451));
+    asio::ip::tcp::socket c(is);
+    c.connect(asio::ip::tcp::endpoint(
+        asio::ip::address::from_string("127.0.0.1"), 45451));
 
-  c.send(asio::buffer(sendmsg));
+    c.send(asio::buffer(sendmsg));
 
-  c.receive(asio::buffer(buf, 2048));
-  c.close();
+    c.receive(asio::buffer(buf, 2048));
+    c.close();
 
-  std::string response(std::begin(buf), std::end(buf));
-  // This is a routine to split strings until a newline is hit
-  // TODO(ed) this should really use the HTTP parser
-  std::vector<std::string> headers;
-  std::string::size_type pos = 0;
-  std::string::size_type prev = 0;
-  int content_length = 0;
-  std::string content_encoding("");
-  while ((pos = response.find("\r\n", prev)) != std::string::npos) {
-    auto this_string = response.substr(prev, pos - prev);
-    if (this_string == "") {
-      break;
+    std::string response(std::begin(buf), std::end(buf));
+    // This is a routine to split strings until a newline is hit
+    // TODO(ed) this should really use the HTTP parser
+    std::vector<std::string> headers;
+    std::string::size_type pos = 0;
+    std::string::size_type prev = 0;
+    int content_length = 0;
+    std::string content_encoding("");
+    while ((pos = response.find("\r\n", prev)) != std::string::npos)
+    {
+        auto this_string = response.substr(prev, pos - prev);
+        if (this_string == "")
+        {
+            break;
+        }
+
+        if (boost::starts_with(this_string, "ETag: "))
+        {
+            auto etag = this_string.substr(6);
+            // ETAG should not be blank
+            EXPECT_NE(etag, "");
+            // SHa1 is 20 characters long
+            EXPECT_EQ(etag.size(), 40);
+            EXPECT_THAT(etag, MatchesRegex("^[a-f0-9]+$"));
+        }
+
+        headers.push_back(this_string);
+        prev = pos + 2;
     }
 
-    if (boost::starts_with(this_string, "ETag: ")) {
-      auto etag = this_string.substr(6);
-      // ETAG should not be blank
-      EXPECT_NE(etag, "");
-      // SHa1 is 20 characters long
-      EXPECT_EQ(etag.size(), 40);
-      EXPECT_THAT(etag, MatchesRegex("^[a-f0-9]+$"));
-    }
-
-    headers.push_back(this_string);
-    prev = pos + 2;
-  }
-
-  server.stop();
+    server.stop();
 }
diff --git a/src/webserver_main.cpp b/src/webserver_main.cpp
index 2f89ad4..051b1fe 100644
--- a/src/webserver_main.cpp
+++ b/src/webserver_main.cpp
@@ -1,8 +1,12 @@
+#include <crow/app.h>
 #include <systemd/sd-daemon.h>
+
 #include <bmcweb/settings.hpp>
+#include <boost/asio.hpp>
 #include <dbus_monitor.hpp>
 #include <dbus_singleton.hpp>
 #include <image_upload.hpp>
+#include <memory>
 #include <openbmc_dbus_rest.hpp>
 #include <persistent_data_middleware.hpp>
 #include <redfish.hpp>
@@ -12,84 +16,91 @@
 #include <sdbusplus/server.hpp>
 #include <security_headers_middleware.hpp>
 #include <ssl_key_handler.hpp>
+#include <string>
 #include <token_authorization_middleware.hpp>
 #include <web_kvm.hpp>
 #include <webassets.hpp>
 #include <webserver_common.hpp>
-#include <memory>
-#include <string>
-#include <crow/app.h>
-#include <boost/asio.hpp>
 
 constexpr int defaultPort = 18080;
 
 template <typename... Middlewares>
-void setupSocket(crow::Crow<Middlewares...>& app) {
-  int listenFd = sd_listen_fds(0);
-  if (1 == listenFd) {
-    BMCWEB_LOG_INFO << "attempting systemd socket activation";
-    if (sd_is_socket_inet(SD_LISTEN_FDS_START, AF_UNSPEC, SOCK_STREAM, 1, 0)) {
-      BMCWEB_LOG_INFO << "Starting webserver on socket handle "
-                      << SD_LISTEN_FDS_START;
-      app.socket(SD_LISTEN_FDS_START);
-    } else {
-      BMCWEB_LOG_INFO << "bad incoming socket, starting webserver on port "
-                      << defaultPort;
-      app.port(defaultPort);
+void setupSocket(crow::Crow<Middlewares...>& app)
+{
+    int listenFd = sd_listen_fds(0);
+    if (1 == listenFd)
+    {
+        BMCWEB_LOG_INFO << "attempting systemd socket activation";
+        if (sd_is_socket_inet(SD_LISTEN_FDS_START, AF_UNSPEC, SOCK_STREAM, 1,
+                              0))
+        {
+            BMCWEB_LOG_INFO << "Starting webserver on socket handle "
+                            << SD_LISTEN_FDS_START;
+            app.socket(SD_LISTEN_FDS_START);
+        }
+        else
+        {
+            BMCWEB_LOG_INFO
+                << "bad incoming socket, starting webserver on port "
+                << defaultPort;
+            app.port(defaultPort);
+        }
     }
-  } else {
-    BMCWEB_LOG_INFO << "Starting webserver on port " << defaultPort;
-    app.port(defaultPort);
-  }
+    else
+    {
+        BMCWEB_LOG_INFO << "Starting webserver on port " << defaultPort;
+        app.port(defaultPort);
+    }
 }
 
-int main(int argc, char** argv) {
-  crow::logger::setLogLevel(crow::LogLevel::DEBUG);
+int main(int argc, char** argv)
+{
+    crow::logger::setLogLevel(crow::LogLevel::DEBUG);
 
-  auto io = std::make_shared<boost::asio::io_service>();
-  CrowApp app(io);
+    auto io = std::make_shared<boost::asio::io_service>();
+    CrowApp app(io);
 
 #ifdef BMCWEB_ENABLE_SSL
-  std::string sslPemFile("server.pem");
-  std::cout << "Building SSL Context\n";
+    std::string sslPemFile("server.pem");
+    std::cout << "Building SSL Context\n";
 
-  ensuressl::ensureOpensslKeyPresentAndValid(sslPemFile);
-  std::cout << "SSL Enabled\n";
-  auto sslContext = ensuressl::getSslContext(sslPemFile);
-  app.ssl(std::move(sslContext));
+    ensuressl::ensureOpensslKeyPresentAndValid(sslPemFile);
+    std::cout << "SSL Enabled\n";
+    auto sslContext = ensuressl::getSslContext(sslPemFile);
+    app.ssl(std::move(sslContext));
 #endif
-  // Static assets need to be initialized before Authorization, because auth
-  // needs to build the whitelist from the static routes
+    // Static assets need to be initialized before Authorization, because auth
+    // needs to build the whitelist from the static routes
 
 #ifdef BMCWEB_ENABLE_STATIC_HOSTING
-  crow::webassets::requestRoutes(app);
+    crow::webassets::requestRoutes(app);
 #endif
 
 #ifdef BMCWEB_ENABLE_KVM
-  crow::kvm::requestRoutes(app);
+    crow::kvm::requestRoutes(app);
 #endif
 
 #ifdef BMCWEB_ENABLE_REDFISH
-  crow::redfish::requestRoutes(app);
+    crow::redfish::requestRoutes(app);
 #endif
 
 #ifdef BMCWEB_ENABLE_DBUS_REST
-  crow::dbus_monitor::requestRoutes(app);
-  crow::image_upload::requestRoutes(app);
-  crow::openbmc_mapper::requestRoutes(app);
+    crow::dbus_monitor::requestRoutes(app);
+    crow::image_upload::requestRoutes(app);
+    crow::openbmc_mapper::requestRoutes(app);
 #endif
 
-  crow::token_authorization::requestRoutes(app);
+    crow::token_authorization::requestRoutes(app);
 
-  BMCWEB_LOG_INFO << "bmcweb (" << __DATE__ << ": " << __TIME__ << ')';
-  setupSocket(app);
+    BMCWEB_LOG_INFO << "bmcweb (" << __DATE__ << ": " << __TIME__ << ')';
+    setupSocket(app);
 
-  crow::connections::systemBus =
-      std::make_shared<sdbusplus::asio::connection>(*io);
-  redfish::RedfishService redfish(app);
+    crow::connections::systemBus =
+        std::make_shared<sdbusplus::asio::connection>(*io);
+    redfish::RedfishService redfish(app);
 
-  app.run();
-  io->run();
+    app.run();
+    io->run();
 
-  crow::connections::systemBus.reset();
+    crow::connections::systemBus.reset();
 }
