diff --git a/lldb/tools/debugserver/source/JSON.cpp b/lldb/tools/debugserver/source/JSON.cpp
index 34a01f4..19ebfd0 100644
--- a/lldb/tools/debugserver/source/JSON.cpp
+++ b/lldb/tools/debugserver/source/JSON.cpp
@@ -14,733 +14,575 @@
 #include <limits.h>
 
 // C++ includes
+#include "lldb/Host/StringConvert.h"
 #include <iomanip>
 #include <sstream>
-#include "lldb/Host/StringConvert.h"
 
 using namespace lldb_private;
 
-std::string
-JSONString::json_string_quote_metachars (const std::string &s)
-{
-    if (s.find('"') == std::string::npos)
-        return s;
-    
-    std::string output;
-    const size_t s_size = s.size();
-    const char *s_chars = s.c_str();
-    for (size_t i = 0; i < s_size; i++)
-    {
-        unsigned char ch = *(s_chars + i);
-        if (ch == '"')
-        {
-            output.push_back ('\\');
-        }
-        output.push_back (ch);
+std::string JSONString::json_string_quote_metachars(const std::string &s) {
+  if (s.find('"') == std::string::npos)
+    return s;
+
+  std::string output;
+  const size_t s_size = s.size();
+  const char *s_chars = s.c_str();
+  for (size_t i = 0; i < s_size; i++) {
+    unsigned char ch = *(s_chars + i);
+    if (ch == '"') {
+      output.push_back('\\');
     }
-    return output;
+    output.push_back(ch);
+  }
+  return output;
 }
 
-JSONString::JSONString () :
-    JSONValue(JSONValue::Kind::String),
-    m_data()
-{
+JSONString::JSONString() : JSONValue(JSONValue::Kind::String), m_data() {}
+
+JSONString::JSONString(const char *s)
+    : JSONValue(JSONValue::Kind::String), m_data(s ? s : "") {}
+
+JSONString::JSONString(const std::string &s)
+    : JSONValue(JSONValue::Kind::String), m_data(s) {}
+
+void JSONString::Write(std::ostream &s) {
+  s << "\"" << json_string_quote_metachars(m_data).c_str() << "\"";
 }
 
-JSONString::JSONString (const char* s) :
-    JSONValue(JSONValue::Kind::String),
-    m_data(s ? s : "")
-{
+uint64_t JSONNumber::GetAsUnsigned() const {
+  switch (m_data_type) {
+  case DataType::Unsigned:
+    return m_data.m_unsigned;
+  case DataType::Signed:
+    return (uint64_t)m_data.m_signed;
+  case DataType::Double:
+    return (uint64_t)m_data.m_double;
+  }
+  assert("Unhandled data type");
 }
 
-JSONString::JSONString (const std::string& s) :
-    JSONValue(JSONValue::Kind::String),
-    m_data(s)
-{
+int64_t JSONNumber::GetAsSigned() const {
+  switch (m_data_type) {
+  case DataType::Unsigned:
+    return (int64_t)m_data.m_unsigned;
+  case DataType::Signed:
+    return m_data.m_signed;
+  case DataType::Double:
+    return (int64_t)m_data.m_double;
+  }
+  assert("Unhandled data type");
 }
 
-void
-JSONString::Write (std::ostream& s)
-{
-    s << "\"" << json_string_quote_metachars(m_data).c_str() <<"\"";
+double JSONNumber::GetAsDouble() const {
+  switch (m_data_type) {
+  case DataType::Unsigned:
+    return (double)m_data.m_unsigned;
+  case DataType::Signed:
+    return (double)m_data.m_signed;
+  case DataType::Double:
+    return m_data.m_double;
+  }
+  assert("Unhandled data type");
 }
 
-uint64_t
-JSONNumber::GetAsUnsigned() const
-{
-    switch (m_data_type)
-    {
-        case DataType::Unsigned:
-            return m_data.m_unsigned;
-        case DataType::Signed:
-            return (uint64_t)m_data.m_signed;
-        case DataType::Double:
-            return (uint64_t)m_data.m_double;
-    }
-    assert("Unhandled data type");
+void JSONNumber::Write(std::ostream &s) {
+  switch (m_data_type) {
+  case DataType::Unsigned:
+    s << m_data.m_unsigned;
+    break;
+  case DataType::Signed:
+    s << m_data.m_signed;
+    break;
+  case DataType::Double:
+    // Set max precision to emulate %g.
+    s << std::setprecision(std::numeric_limits<double>::digits10 + 1);
+    s << m_data.m_double;
+    break;
+  }
 }
 
-int64_t
-JSONNumber::GetAsSigned() const
-{
-    switch (m_data_type)
-    {
-        case DataType::Unsigned:
-            return (int64_t)m_data.m_unsigned;
-        case DataType::Signed:
-            return m_data.m_signed;
-        case DataType::Double:
-            return (int64_t)m_data.m_double;
-    }
-    assert("Unhandled data type");
-}
+JSONTrue::JSONTrue() : JSONValue(JSONValue::Kind::True) {}
 
-double
-JSONNumber::GetAsDouble() const
-{
-    switch (m_data_type)
-    {
-        case DataType::Unsigned:
-            return (double)m_data.m_unsigned;
-        case DataType::Signed:
-            return (double)m_data.m_signed;
-        case DataType::Double:
-            return m_data.m_double;
-    }
-    assert("Unhandled data type");
-}
+void JSONTrue::Write(std::ostream &s) { s << "true"; }
 
-void
-JSONNumber::Write (std::ostream& s)
-{
-    switch (m_data_type)
-    {
-        case DataType::Unsigned:
-            s << m_data.m_unsigned;
-            break;
-        case DataType::Signed:
-            s << m_data.m_signed;
-            break;
-        case DataType::Double:
-            // Set max precision to emulate %g.
-            s << std::setprecision(std::numeric_limits<double>::digits10 + 1);
-            s << m_data.m_double;
-            break;
-    }
-}
+JSONFalse::JSONFalse() : JSONValue(JSONValue::Kind::False) {}
 
-JSONTrue::JSONTrue () :
-    JSONValue(JSONValue::Kind::True)
-{
-}
+void JSONFalse::Write(std::ostream &s) { s << "false"; }
 
-void
-JSONTrue::Write(std::ostream& s)
-{
-    s << "true";
-}
+JSONNull::JSONNull() : JSONValue(JSONValue::Kind::Null) {}
 
-JSONFalse::JSONFalse () :
-    JSONValue(JSONValue::Kind::False)
-{
-}
+void JSONNull::Write(std::ostream &s) { s << "null"; }
 
-void
-JSONFalse::Write(std::ostream& s)
-{
-    s << "false";
-}
+JSONObject::JSONObject() : JSONValue(JSONValue::Kind::Object) {}
 
-JSONNull::JSONNull () :
-    JSONValue(JSONValue::Kind::Null)
-{
-}
-
-void
-JSONNull::Write(std::ostream& s)
-{
-    s << "null";
-}
-
-JSONObject::JSONObject () :
-    JSONValue(JSONValue::Kind::Object)
-{
-}
-
-void
-JSONObject::Write (std::ostream& s)
-{
-    bool first = true;
-    s << '{';
-    auto iter = m_elements.begin(), end = m_elements.end();
-    for (;iter != end; iter++)
-    {
-        if (first)
-            first = false;
-        else
-            s << ',';
-        JSONString key(iter->first);
-        JSONValue::SP value(iter->second);
-        key.Write(s);
-        s << ':';
-        value->Write(s);
-    }
-    s << '}';
-}
-
-bool
-JSONObject::SetObject (const std::string& key,
-                       JSONValue::SP value)
-{
-    if (key.empty() || nullptr == value.get())
-        return false;
-    m_elements[key] = value;
-    return true;
-}
-
-JSONValue::SP
-JSONObject::GetObject (const std::string& key) const
-{
-    auto iter = m_elements.find(key), end = m_elements.end();
-    if (iter == end)
-        return JSONValue::SP();
-    return iter->second;
-}
-
-bool
-JSONObject::GetObjectAsBool (const std::string& key, bool& value) const
-{
-    auto value_sp = GetObject(key);
-    if (!value_sp)
-    {
-        // The given key doesn't exist, so we have no value.
-        return false;
-    }
-
-    if (JSONTrue::classof(value_sp.get()))
-    {
-        // We have the value, and it is true.
-        value = true;
-        return true;
-    }
-    else if (JSONFalse::classof(value_sp.get()))
-    {
-        // We have the value, and it is false.
-        value = false;
-        return true;
-    }
+void JSONObject::Write(std::ostream &s) {
+  bool first = true;
+  s << '{';
+  auto iter = m_elements.begin(), end = m_elements.end();
+  for (; iter != end; iter++) {
+    if (first)
+      first = false;
     else
-    {
-        // We don't have a valid bool value for the given key.
-        return false;
-    }
+      s << ',';
+    JSONString key(iter->first);
+    JSONValue::SP value(iter->second);
+    key.Write(s);
+    s << ':';
+    value->Write(s);
+  }
+  s << '}';
 }
 
-bool
-JSONObject::GetObjectAsString (const std::string& key, std::string& value) const
-{
-    auto value_sp = GetObject(key);
-    if (!value_sp)
-    {
-        // The given key doesn't exist, so we have no value.
-        return false;
-    }
-
-    if (!JSONString::classof(value_sp.get()))
-        return false;
-
-    value = static_cast<JSONString*>(value_sp.get())->GetData();
-    return true;
-}
-
-JSONArray::JSONArray () :
-    JSONValue(JSONValue::Kind::Array)
-{
-}
-
-void
-JSONArray::Write (std::ostream& s)
-{
-    bool first = true;
-    s << '[';
-    auto iter = m_elements.begin(), end = m_elements.end();
-    for (;iter != end; iter++)
-    {
-        if (first)
-            first = false;
-        else
-            s << ',';
-        (*iter)->Write(s);
-    }
-    s << ']';
-}
-
-bool
-JSONArray::SetObject (Index i,
-                      JSONValue::SP value)
-{
-    if (value.get() == nullptr)
-        return false;
-    if (i < m_elements.size())
-    {
-        m_elements[i] = value;
-        return true;
-    }
-    if (i == m_elements.size())
-    {
-        m_elements.push_back(value);
-        return true;
-    }
+bool JSONObject::SetObject(const std::string &key, JSONValue::SP value) {
+  if (key.empty() || nullptr == value.get())
     return false;
+  m_elements[key] = value;
+  return true;
 }
 
-bool
-JSONArray::AppendObject (JSONValue::SP value)
-{
-    if (value.get() == nullptr)
-        return false;
+JSONValue::SP JSONObject::GetObject(const std::string &key) const {
+  auto iter = m_elements.find(key), end = m_elements.end();
+  if (iter == end)
+    return JSONValue::SP();
+  return iter->second;
+}
+
+bool JSONObject::GetObjectAsBool(const std::string &key, bool &value) const {
+  auto value_sp = GetObject(key);
+  if (!value_sp) {
+    // The given key doesn't exist, so we have no value.
+    return false;
+  }
+
+  if (JSONTrue::classof(value_sp.get())) {
+    // We have the value, and it is true.
+    value = true;
+    return true;
+  } else if (JSONFalse::classof(value_sp.get())) {
+    // We have the value, and it is false.
+    value = false;
+    return true;
+  } else {
+    // We don't have a valid bool value for the given key.
+    return false;
+  }
+}
+
+bool JSONObject::GetObjectAsString(const std::string &key,
+                                   std::string &value) const {
+  auto value_sp = GetObject(key);
+  if (!value_sp) {
+    // The given key doesn't exist, so we have no value.
+    return false;
+  }
+
+  if (!JSONString::classof(value_sp.get()))
+    return false;
+
+  value = static_cast<JSONString *>(value_sp.get())->GetData();
+  return true;
+}
+
+JSONArray::JSONArray() : JSONValue(JSONValue::Kind::Array) {}
+
+void JSONArray::Write(std::ostream &s) {
+  bool first = true;
+  s << '[';
+  auto iter = m_elements.begin(), end = m_elements.end();
+  for (; iter != end; iter++) {
+    if (first)
+      first = false;
+    else
+      s << ',';
+    (*iter)->Write(s);
+  }
+  s << ']';
+}
+
+bool JSONArray::SetObject(Index i, JSONValue::SP value) {
+  if (value.get() == nullptr)
+    return false;
+  if (i < m_elements.size()) {
+    m_elements[i] = value;
+    return true;
+  }
+  if (i == m_elements.size()) {
     m_elements.push_back(value);
     return true;
+  }
+  return false;
 }
 
-JSONValue::SP
-JSONArray::GetObject (Index i)
-{
-    if (i < m_elements.size())
-        return m_elements[i];
-    return JSONValue::SP();
+bool JSONArray::AppendObject(JSONValue::SP value) {
+  if (value.get() == nullptr)
+    return false;
+  m_elements.push_back(value);
+  return true;
 }
 
-JSONArray::Size
-JSONArray::GetNumElements ()
-{
-    return m_elements.size();
+JSONValue::SP JSONArray::GetObject(Index i) {
+  if (i < m_elements.size())
+    return m_elements[i];
+  return JSONValue::SP();
 }
 
+JSONArray::Size JSONArray::GetNumElements() { return m_elements.size(); }
 
-JSONParser::JSONParser (const char *cstr) :
-    StdStringExtractor(cstr)
-{
-}
+JSONParser::JSONParser(const char *cstr) : StdStringExtractor(cstr) {}
 
-JSONParser::Token
-JSONParser::GetToken (std::string &value)
-{
-    std::ostringstream error;
+JSONParser::Token JSONParser::GetToken(std::string &value) {
+  std::ostringstream error;
 
-    value.clear();
-    SkipSpaces ();
-    const uint64_t start_index = m_index;
-    const char ch = GetChar();
-    switch (ch)
-    {
-        case '{': return Token::ObjectStart;
-        case '}': return Token::ObjectEnd;
-        case '[': return Token::ArrayStart;
-        case ']': return Token::ArrayEnd;
-        case ',': return Token::Comma;
-        case ':': return Token::Colon;
-        case '\0': return Token::EndOfFile;
-        case 't':
-            if (GetChar() == 'r')
-                if (GetChar() == 'u')
-                    if (GetChar() == 'e')
-                        return Token::True;
-            break;
+  value.clear();
+  SkipSpaces();
+  const uint64_t start_index = m_index;
+  const char ch = GetChar();
+  switch (ch) {
+  case '{':
+    return Token::ObjectStart;
+  case '}':
+    return Token::ObjectEnd;
+  case '[':
+    return Token::ArrayStart;
+  case ']':
+    return Token::ArrayEnd;
+  case ',':
+    return Token::Comma;
+  case ':':
+    return Token::Colon;
+  case '\0':
+    return Token::EndOfFile;
+  case 't':
+    if (GetChar() == 'r')
+      if (GetChar() == 'u')
+        if (GetChar() == 'e')
+          return Token::True;
+    break;
 
-        case 'f':
-            if (GetChar() == 'a')
-                if (GetChar() == 'l')
-                    if (GetChar() == 's')
-                        if (GetChar() == 'e')
-                            return Token::False;
-            break;
+  case 'f':
+    if (GetChar() == 'a')
+      if (GetChar() == 'l')
+        if (GetChar() == 's')
+          if (GetChar() == 'e')
+            return Token::False;
+    break;
 
-        case 'n':
-            if (GetChar() == 'u')
-                if (GetChar() == 'l')
-                    if (GetChar() == 'l')
-                        return Token::Null;
-            break;
+  case 'n':
+    if (GetChar() == 'u')
+      if (GetChar() == 'l')
+        if (GetChar() == 'l')
+          return Token::Null;
+    break;
 
-        case '"':
-            {
-                while (1)
-                {
-                    bool was_escaped = false;
-                    int escaped_ch = GetEscapedChar(was_escaped);
-                    if (escaped_ch == -1)
-                    {
-                        error << "error: an error occurred getting a character from offset " <<start_index;
-                        value = error.str();
-                        return Token::Error;
+  case '"': {
+    while (1) {
+      bool was_escaped = false;
+      int escaped_ch = GetEscapedChar(was_escaped);
+      if (escaped_ch == -1) {
+        error << "error: an error occurred getting a character from offset "
+              << start_index;
+        value = error.str();
+        return Token::Error;
 
-                    }
-                    else
-                    {
-                        const bool is_end_quote = escaped_ch == '"';
-                        const bool is_null = escaped_ch == 0;
-                        if (was_escaped || (!is_end_quote && !is_null))
-                        {
-                            if (CHAR_MIN <= escaped_ch && escaped_ch <= CHAR_MAX)
-                            {
-                                value.append(1, (char)escaped_ch);
-                            }
-                            else
-                            {
-                                error << "error: wide character support is needed for unicode character 0x" << std::setprecision(4) << std::hex << escaped_ch;
-                                error << " at offset " << start_index;
-                                value = error.str();
-                                return Token::Error;
-                            }
-                        }
-                        else if (is_end_quote)
-                        {
-                            return Token::String;
-                        }
-                        else if (is_null)
-                        {
-                            value = "error: missing end quote for string";
-                            return Token::Error;
-                        }
-                    }
-                }
-            }
-            break;
-
-        case '-':
-        case '0':
-        case '1':
-        case '2':
-        case '3':
-        case '4':
-        case '5':
-        case '6':
-        case '7':
-        case '8':
-        case '9':
-            {
-                bool done = false;
-                bool got_decimal_point = false;
-                uint64_t exp_index = 0;
-                bool got_int_digits = (ch >= '0') && (ch <= '9');
-                bool got_frac_digits = false;
-                bool got_exp_digits = false;
-                while (!done)
-                {
-                    const char next_ch = PeekChar();
-                    switch (next_ch)
-                    {
-                        case '0':
-                        case '1':
-                        case '2':
-                        case '3':
-                        case '4':
-                        case '5':
-                        case '6':
-                        case '7':
-                        case '8':
-                        case '9':
-                            if (exp_index != 0)
-                            {
-                                got_exp_digits = true;
-                            }
-                            else if (got_decimal_point)
-                            {
-                                got_frac_digits = true;
-                            }
-                            else
-                            {
-                                got_int_digits = true;
-                            }
-                            ++m_index; // Skip this character
-                            break;
-
-                        case '.':
-                            if (got_decimal_point)
-                            {
-                                error << "error: extra decimal point found at offset " << start_index;
-                                value = error.str();
-                                return Token::Error;
-                            }
-                            else
-                            {
-                                got_decimal_point = true;
-                                ++m_index; // Skip this character
-                            }
-                            break;
-
-                        case 'e':
-                        case 'E':
-                            if (exp_index != 0)
-                            {
-                                error << "error: extra exponent character found at offset " << start_index;
-                                value = error.str();
-                                return Token::Error;
-                            }
-                            else
-                            {
-                                exp_index = m_index;
-                                ++m_index; // Skip this character
-                            }
-                            break;
-
-                        case '+':
-                        case '-':
-                            // The '+' and '-' can only come after an exponent character...
-                            if (exp_index == m_index - 1)
-                            {
-                                ++m_index; // Skip the exponent sign character
-                            }
-                            else
-                            {
-                                error << "error: unexpected " << next_ch << " character at offset " << start_index;
-                                value = error.str();
-                                return Token::Error;
-                            }
-                            break;
-
-                        default:
-                            done = true;
-                            break;
-                    }
-                }
-
-                if (m_index > start_index)
-                {
-                    value = m_packet.substr(start_index, m_index - start_index);
-                    if (got_decimal_point)
-                    {
-                        if (exp_index != 0)
-                        {
-                            // We have an exponent, make sure we got exponent digits
-                            if (got_exp_digits)
-                            {
-                                return Token::Float;
-                            }
-                            else
-                            {
-                                error << "error: got exponent character but no exponent digits at offset in float value \"" << value.c_str() << "\"";
-                                value = error.str();
-                                return Token::Error;
-                            }
-                        }
-                        else
-                        {
-                            // No exponent, but we need at least one decimal after the decimal point
-                            if (got_frac_digits)
-                            {
-                                return Token::Float;
-                            }
-                            else
-                            {
-                                error << "error: no digits after decimal point \"" << value.c_str() << "\"";
-                                value = error.str();
-                                return Token::Error;
-                            }
-                        }
-                    }
-                    else
-                    {
-                        // No decimal point
-                        if (got_int_digits)
-                        {
-                            // We need at least some integer digits to make an integer
-                            return Token::Integer;
-                        }
-                        else
-                        {
-                            error << "error: no digits negate sign \"" << value.c_str() << "\"";
-                            value = error.str();
-                            return Token::Error;
-                        }
-                    }
-                }
-                else
-                {
-                    error << "error: invalid number found at offset " << start_index;
-                    value = error.str();
-                    return Token::Error;
-                }
-            }
-            break;
-        default:
-            break;
+      } else {
+        const bool is_end_quote = escaped_ch == '"';
+        const bool is_null = escaped_ch == 0;
+        if (was_escaped || (!is_end_quote && !is_null)) {
+          if (CHAR_MIN <= escaped_ch && escaped_ch <= CHAR_MAX) {
+            value.append(1, (char)escaped_ch);
+          } else {
+            error << "error: wide character support is needed for unicode "
+                     "character 0x"
+                  << std::setprecision(4) << std::hex << escaped_ch;
+            error << " at offset " << start_index;
+            value = error.str();
+            return Token::Error;
+          }
+        } else if (is_end_quote) {
+          return Token::String;
+        } else if (is_null) {
+          value = "error: missing end quote for string";
+          return Token::Error;
+        }
+      }
     }
-    error << "error: failed to parse token at offset " << start_index << " (around character '" << ch << "')";
-    value = error.str();
-    return Token::Error;
-}
+  } break;
 
-int
-JSONParser::GetEscapedChar(bool &was_escaped)
-{
-    was_escaped = false;
-    const char ch = GetChar();
-    if (ch == '\\')
-    {
-        was_escaped = true;
-        const char ch2 = GetChar();
-        switch (ch2)
-        {
-            case '"':
-            case '\\':
-            case '/':
-            default:
-                break;
-
-            case 'b': return '\b';
-            case 'f': return '\f';
-            case 'n': return '\n';
-            case 'r': return '\r';
-            case 't': return '\t';
-            case 'u':
-                {
-                    const int hi_byte = DecodeHexU8();
-                    const int lo_byte = DecodeHexU8();
-                    if (hi_byte >=0 && lo_byte >= 0)
-                        return hi_byte << 8 | lo_byte;
-                    return -1;
-                }
-                break;
+  case '-':
+  case '0':
+  case '1':
+  case '2':
+  case '3':
+  case '4':
+  case '5':
+  case '6':
+  case '7':
+  case '8':
+  case '9': {
+    bool done = false;
+    bool got_decimal_point = false;
+    uint64_t exp_index = 0;
+    bool got_int_digits = (ch >= '0') && (ch <= '9');
+    bool got_frac_digits = false;
+    bool got_exp_digits = false;
+    while (!done) {
+      const char next_ch = PeekChar();
+      switch (next_ch) {
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+        if (exp_index != 0) {
+          got_exp_digits = true;
+        } else if (got_decimal_point) {
+          got_frac_digits = true;
+        } else {
+          got_int_digits = true;
         }
-        return ch2;
+        ++m_index; // Skip this character
+        break;
+
+      case '.':
+        if (got_decimal_point) {
+          error << "error: extra decimal point found at offset " << start_index;
+          value = error.str();
+          return Token::Error;
+        } else {
+          got_decimal_point = true;
+          ++m_index; // Skip this character
+        }
+        break;
+
+      case 'e':
+      case 'E':
+        if (exp_index != 0) {
+          error << "error: extra exponent character found at offset "
+                << start_index;
+          value = error.str();
+          return Token::Error;
+        } else {
+          exp_index = m_index;
+          ++m_index; // Skip this character
+        }
+        break;
+
+      case '+':
+      case '-':
+        // The '+' and '-' can only come after an exponent character...
+        if (exp_index == m_index - 1) {
+          ++m_index; // Skip the exponent sign character
+        } else {
+          error << "error: unexpected " << next_ch << " character at offset "
+                << start_index;
+          value = error.str();
+          return Token::Error;
+        }
+        break;
+
+      default:
+        done = true;
+        break;
+      }
     }
-    return ch;
-}
 
-JSONValue::SP
-JSONParser::ParseJSONObject ()
-{
-    // The "JSONParser::Token::ObjectStart" token should have already been consumed
-    // by the time this function is called
-    std::unique_ptr<JSONObject> dict_up(new JSONObject());
-
-    std::string value;
-    std::string key;
-    while (1)
-    {
-        JSONParser::Token token = GetToken(value);
-
-        if (token == JSONParser::Token::String)
-        {
-            key.swap(value);
-            token = GetToken(value);
-            if (token == JSONParser::Token::Colon)
-            {
-                JSONValue::SP value_sp = ParseJSONValue();
-                if (value_sp)
-                    dict_up->SetObject(key, value_sp);
-                else
-                    break;
-            }
+    if (m_index > start_index) {
+      value = m_packet.substr(start_index, m_index - start_index);
+      if (got_decimal_point) {
+        if (exp_index != 0) {
+          // We have an exponent, make sure we got exponent digits
+          if (got_exp_digits) {
+            return Token::Float;
+          } else {
+            error << "error: got exponent character but no exponent digits at "
+                     "offset in float value \""
+                  << value.c_str() << "\"";
+            value = error.str();
+            return Token::Error;
+          }
+        } else {
+          // No exponent, but we need at least one decimal after the decimal
+          // point
+          if (got_frac_digits) {
+            return Token::Float;
+          } else {
+            error << "error: no digits after decimal point \"" << value.c_str()
+                  << "\"";
+            value = error.str();
+            return Token::Error;
+          }
         }
-        else if (token == JSONParser::Token::ObjectEnd)
-        {
-            return JSONValue::SP(dict_up.release());
+      } else {
+        // No decimal point
+        if (got_int_digits) {
+          // We need at least some integer digits to make an integer
+          return Token::Integer;
+        } else {
+          error << "error: no digits negate sign \"" << value.c_str() << "\"";
+          value = error.str();
+          return Token::Error;
         }
-        else if (token == JSONParser::Token::Comma)
-        {
-            continue;
-        }
-        else
-        {
-            break;
-        }
+      }
+    } else {
+      error << "error: invalid number found at offset " << start_index;
+      value = error.str();
+      return Token::Error;
     }
-    return JSONValue::SP();
+  } break;
+  default:
+    break;
+  }
+  error << "error: failed to parse token at offset " << start_index
+        << " (around character '" << ch << "')";
+  value = error.str();
+  return Token::Error;
 }
 
-JSONValue::SP
-JSONParser::ParseJSONArray ()
-{
-    // The "JSONParser::Token::ObjectStart" token should have already been consumed
-    // by the time this function is called
-    std::unique_ptr<JSONArray> array_up(new JSONArray());
+int JSONParser::GetEscapedChar(bool &was_escaped) {
+  was_escaped = false;
+  const char ch = GetChar();
+  if (ch == '\\') {
+    was_escaped = true;
+    const char ch2 = GetChar();
+    switch (ch2) {
+    case '"':
+    case '\\':
+    case '/':
+    default:
+      break;
 
-    std::string value;
-    std::string key;
-    while (1)
-    {
+    case 'b':
+      return '\b';
+    case 'f':
+      return '\f';
+    case 'n':
+      return '\n';
+    case 'r':
+      return '\r';
+    case 't':
+      return '\t';
+    case 'u': {
+      const int hi_byte = DecodeHexU8();
+      const int lo_byte = DecodeHexU8();
+      if (hi_byte >= 0 && lo_byte >= 0)
+        return hi_byte << 8 | lo_byte;
+      return -1;
+    } break;
+    }
+    return ch2;
+  }
+  return ch;
+}
+
+JSONValue::SP JSONParser::ParseJSONObject() {
+  // The "JSONParser::Token::ObjectStart" token should have already been
+  // consumed
+  // by the time this function is called
+  std::unique_ptr<JSONObject> dict_up(new JSONObject());
+
+  std::string value;
+  std::string key;
+  while (1) {
+    JSONParser::Token token = GetToken(value);
+
+    if (token == JSONParser::Token::String) {
+      key.swap(value);
+      token = GetToken(value);
+      if (token == JSONParser::Token::Colon) {
         JSONValue::SP value_sp = ParseJSONValue();
         if (value_sp)
-            array_up->AppendObject(value_sp);
+          dict_up->SetObject(key, value_sp);
         else
-            break;
-
-        JSONParser::Token token = GetToken(value);
-        if (token == JSONParser::Token::Comma)
-        {
-            continue;
-        }
-        else if (token == JSONParser::Token::ArrayEnd)
-        {
-            return JSONValue::SP(array_up.release());
-        }
-        else
-        {
-            break;
-        }
+          break;
+      }
+    } else if (token == JSONParser::Token::ObjectEnd) {
+      return JSONValue::SP(dict_up.release());
+    } else if (token == JSONParser::Token::Comma) {
+      continue;
+    } else {
+      break;
     }
-    return JSONValue::SP();
+  }
+  return JSONValue::SP();
 }
 
-JSONValue::SP
-JSONParser::ParseJSONValue ()
-{
-    std::string value;
-    const JSONParser::Token token = GetToken(value);
-    switch (token)
-    {
-        case JSONParser::Token::ObjectStart:
-            return ParseJSONObject();
+JSONValue::SP JSONParser::ParseJSONArray() {
+  // The "JSONParser::Token::ObjectStart" token should have already been
+  // consumed
+  // by the time this function is called
+  std::unique_ptr<JSONArray> array_up(new JSONArray());
 
-        case JSONParser::Token::ArrayStart:
-            return ParseJSONArray();
+  std::string value;
+  std::string key;
+  while (1) {
+    JSONValue::SP value_sp = ParseJSONValue();
+    if (value_sp)
+      array_up->AppendObject(value_sp);
+    else
+      break;
 
-        case JSONParser::Token::Integer:
-        {
-            if (value.front() == '-')
-            {
-                bool success = false;
-                int64_t sval = StringConvert::ToSInt64(value.c_str(), 0, 0, &success);
-                if (success)
-                    return JSONValue::SP(new JSONNumber(sval));
-            }
-            else
-            {
-                bool success = false;
-                uint64_t uval = StringConvert::ToUInt64(value.c_str(), 0, 0, &success);
-                if (success)
-                    return JSONValue::SP(new JSONNumber(uval));
-            }
-        }
-            break;
-
-        case JSONParser::Token::Float:
-        {
-            bool success = false;
-            double val = StringConvert::ToDouble(value.c_str(), 0.0, &success);
-            if (success)
-                return JSONValue::SP(new JSONNumber(val));
-        }
-            break;
-
-        case JSONParser::Token::String:
-            return JSONValue::SP(new JSONString(value));
-
-        case JSONParser::Token::True:
-            return JSONValue::SP(new JSONTrue());
-
-        case JSONParser::Token::False:
-            return JSONValue::SP(new JSONFalse());
-
-        case JSONParser::Token::Null:
-            return JSONValue::SP(new JSONNull());
-
-        default:
-            break;
+    JSONParser::Token token = GetToken(value);
+    if (token == JSONParser::Token::Comma) {
+      continue;
+    } else if (token == JSONParser::Token::ArrayEnd) {
+      return JSONValue::SP(array_up.release());
+    } else {
+      break;
     }
-    return JSONValue::SP();
-    
+  }
+  return JSONValue::SP();
+}
+
+JSONValue::SP JSONParser::ParseJSONValue() {
+  std::string value;
+  const JSONParser::Token token = GetToken(value);
+  switch (token) {
+  case JSONParser::Token::ObjectStart:
+    return ParseJSONObject();
+
+  case JSONParser::Token::ArrayStart:
+    return ParseJSONArray();
+
+  case JSONParser::Token::Integer: {
+    if (value.front() == '-') {
+      bool success = false;
+      int64_t sval = StringConvert::ToSInt64(value.c_str(), 0, 0, &success);
+      if (success)
+        return JSONValue::SP(new JSONNumber(sval));
+    } else {
+      bool success = false;
+      uint64_t uval = StringConvert::ToUInt64(value.c_str(), 0, 0, &success);
+      if (success)
+        return JSONValue::SP(new JSONNumber(uval));
+    }
+  } break;
+
+  case JSONParser::Token::Float: {
+    bool success = false;
+    double val = StringConvert::ToDouble(value.c_str(), 0.0, &success);
+    if (success)
+      return JSONValue::SP(new JSONNumber(val));
+  } break;
+
+  case JSONParser::Token::String:
+    return JSONValue::SP(new JSONString(value));
+
+  case JSONParser::Token::True:
+    return JSONValue::SP(new JSONTrue());
+
+  case JSONParser::Token::False:
+    return JSONValue::SP(new JSONFalse());
+
+  case JSONParser::Token::Null:
+    return JSONValue::SP(new JSONNull());
+
+  default:
+    break;
+  }
+  return JSONValue::SP();
 }
