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
