diff --git a/CHAOSFramework.xcodeproj/project.pbxproj b/CHAOSFramework.xcodeproj/project.pbxproj
index 2554304169a44397f21a9b525189c90bc2baf9cd..8f38ce928b66cb814cc181da5bf63b476470204a 100644
--- a/CHAOSFramework.xcodeproj/project.pbxproj
+++ b/CHAOSFramework.xcodeproj/project.pbxproj
@@ -265,10 +265,6 @@
 		324D08B61F31D7F300836E29 /* AbstractUnitProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 324D08B41F31D7F300836E29 /* AbstractUnitProxy.h */; };
 		324D08C51F31EC5000836E29 /* HTTPConnectionAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 324D08C31F31EC5000836E29 /* HTTPConnectionAdapter.cpp */; };
 		324D08C61F31EC5000836E29 /* HTTPConnectionAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 324D08C41F31EC5000836E29 /* HTTPConnectionAdapter.h */; };
-		324D08CA1F31F26600836E29 /* DataPack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 324D08C81F31F26600836E29 /* DataPack.cpp */; };
-		324D08CB1F31F26600836E29 /* DataPack.h in Headers */ = {isa = PBXBuildFile; fileRef = 324D08C91F31F26600836E29 /* DataPack.h */; };
-		324D08D21F31F5A000836E29 /* json.h in Headers */ = {isa = PBXBuildFile; fileRef = 324D08CD1F31F5A000836E29 /* json.h */; };
-		324D08D31F31F5A000836E29 /* jsoncpp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 324D08CE1F31F5A000836E29 /* jsoncpp.cpp */; };
 		324D08D41F31F5A000836E29 /* mongoose.c in Sources */ = {isa = PBXBuildFile; fileRef = 324D08CF1F31F5A000836E29 /* mongoose.c */; };
 		324D08D51F31F5A000836E29 /* mongoose.h in Headers */ = {isa = PBXBuildFile; fileRef = 324D08D01F31F5A000836E29 /* mongoose.h */; };
 		324D08E21F321B4800836E29 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 324D08E11F321B4800836E29 /* main.cpp */; };
@@ -422,6 +418,28 @@
 		3265BF4615D1A9CA00C3CAC6 /* ChaosUIToolkitCWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 3265BF4515D1A9CA00C3CAC6 /* ChaosUIToolkitCWrapper.h */; };
 		3265BF4915D1AA9F00C3CAC6 /* ChaosUIToolkitCWrapper.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3265BF4815D1AA9F00C3CAC6 /* ChaosUIToolkitCWrapper.cc */; };
 		3265F332197E626900F22FBC /* WorkUnitManagement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32D72CA8197D196D00512B89 /* WorkUnitManagement.cpp */; };
+		3265F94B1FB899D400FEA246 /* DataPack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3265F9491FB899D300FEA246 /* DataPack.cpp */; };
+		3265F94C1FB89F6B00FEA246 /* bson-context.c in Sources */ = {isa = PBXBuildFile; fileRef = 3265F9111FB8997300FEA246 /* bson-context.c */; };
+		3265F94D1FB89F6B00FEA246 /* bson-oid.c in Sources */ = {isa = PBXBuildFile; fileRef = 3265F9121FB8997300FEA246 /* bson-oid.c */; };
+		3265F94E1FB89F6B00FEA246 /* bson-error.c in Sources */ = {isa = PBXBuildFile; fileRef = 3265F9141FB8997300FEA246 /* bson-error.c */; };
+		3265F94F1FB89F6B00FEA246 /* bson-atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = 3265F9151FB8997300FEA246 /* bson-atomic.c */; };
+		3265F9501FB89F6B00FEA246 /* bson-string.c in Sources */ = {isa = PBXBuildFile; fileRef = 3265F9171FB8997300FEA246 /* bson-string.c */; };
+		3265F9511FB89F6B00FEA246 /* bson-keys.c in Sources */ = {isa = PBXBuildFile; fileRef = 3265F9181FB8997300FEA246 /* bson-keys.c */; };
+		3265F9521FB89F6B00FEA246 /* bson-iter.c in Sources */ = {isa = PBXBuildFile; fileRef = 3265F91A1FB8997300FEA246 /* bson-iter.c */; };
+		3265F9531FB89F6B00FEA246 /* bson-iso8601.c in Sources */ = {isa = PBXBuildFile; fileRef = 3265F91B1FB8997300FEA246 /* bson-iso8601.c */; };
+		3265F9541FB89F6B00FEA246 /* bson-md5.c in Sources */ = {isa = PBXBuildFile; fileRef = 3265F91F1FB8997300FEA246 /* bson-md5.c */; };
+		3265F9551FB89F6B00FEA246 /* bson-memory.c in Sources */ = {isa = PBXBuildFile; fileRef = 3265F9211FB8997300FEA246 /* bson-memory.c */; };
+		3265F9561FB89F6B00FEA246 /* bson-writer.c in Sources */ = {isa = PBXBuildFile; fileRef = 3265F9221FB8997300FEA246 /* bson-writer.c */; };
+		3265F9571FB89F6B00FEA246 /* bson-value.c in Sources */ = {isa = PBXBuildFile; fileRef = 3265F9251FB8997300FEA246 /* bson-value.c */; };
+		3265F9581FB89F6B00FEA246 /* bson-json.c in Sources */ = {isa = PBXBuildFile; fileRef = 3265F9291FB8997300FEA246 /* bson-json.c */; };
+		3265F9591FB89F6B00FEA246 /* bson.c in Sources */ = {isa = PBXBuildFile; fileRef = 3265F92C1FB8997300FEA246 /* bson.c */; };
+		3265F95A1FB89F6B00FEA246 /* bcon.c in Sources */ = {isa = PBXBuildFile; fileRef = 3265F9331FB8997300FEA246 /* bcon.c */; };
+		3265F95B1FB89F6B00FEA246 /* bson-decimal128.c in Sources */ = {isa = PBXBuildFile; fileRef = 3265F93C1FB8997300FEA246 /* bson-decimal128.c */; };
+		3265F95C1FB89F6B00FEA246 /* bson-timegm.c in Sources */ = {isa = PBXBuildFile; fileRef = 3265F93F1FB8997300FEA246 /* bson-timegm.c */; };
+		3265F95D1FB89F6B00FEA246 /* bson-utf8.c in Sources */ = {isa = PBXBuildFile; fileRef = 3265F9401FB8997300FEA246 /* bson-utf8.c */; };
+		3265F95E1FB89F6B00FEA246 /* bson-reader.c in Sources */ = {isa = PBXBuildFile; fileRef = 3265F9411FB8997300FEA246 /* bson-reader.c */; };
+		3265F95F1FB89F6B00FEA246 /* bson-clock.c in Sources */ = {isa = PBXBuildFile; fileRef = 3265F9421FB8997300FEA246 /* bson-clock.c */; };
+		3265F9601FB8A12B00FEA246 /* jsonsl.c in Sources */ = {isa = PBXBuildFile; fileRef = 3265F9481FB8997300FEA246 /* jsonsl.c */; };
 		32661C6D1AA741D000F1A721 /* ChaosMetadataServiceClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32661C6B1AA741D000F1A721 /* ChaosMetadataServiceClient.cpp */; };
 		32661C6E1AA741D000F1A721 /* ChaosMetadataServiceClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 32661C6C1AA741D000F1A721 /* ChaosMetadataServiceClient.h */; };
 		32661C711AA7606400F1A721 /* NodeMessageChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32661C6F1AA74E4700F1A721 /* NodeMessageChannel.cpp */; };
@@ -1572,10 +1590,6 @@
 		324D08B71F31DA5300836E29 /* connection_type.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = connection_type.h; sourceTree = "<group>"; };
 		324D08C31F31EC5000836E29 /* HTTPConnectionAdapter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTTPConnectionAdapter.cpp; sourceTree = "<group>"; };
 		324D08C41F31EC5000836E29 /* HTTPConnectionAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPConnectionAdapter.h; sourceTree = "<group>"; };
-		324D08C81F31F26600836E29 /* DataPack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DataPack.cpp; sourceTree = "<group>"; };
-		324D08C91F31F26600836E29 /* DataPack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataPack.h; sourceTree = "<group>"; };
-		324D08CD1F31F5A000836E29 /* json.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = json.h; sourceTree = "<group>"; };
-		324D08CE1F31F5A000836E29 /* jsoncpp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = jsoncpp.cpp; sourceTree = "<group>"; };
 		324D08CF1F31F5A000836E29 /* mongoose.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mongoose.c; sourceTree = "<group>"; };
 		324D08D01F31F5A000836E29 /* mongoose.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mongoose.h; sourceTree = "<group>"; };
 		324D08D61F31FFFE00836E29 /* micro_unit_toolkit_types.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = micro_unit_toolkit_types.h; sourceTree = "<group>"; };
@@ -1750,6 +1764,63 @@
 		326573F218CCD365009E9B6B /* TemplatedKeyObjectContainer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TemplatedKeyObjectContainer.h; sourceTree = "<group>"; };
 		3265BF4515D1A9CA00C3CAC6 /* ChaosUIToolkitCWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChaosUIToolkitCWrapper.h; sourceTree = "<group>"; };
 		3265BF4815D1AA9F00C3CAC6 /* ChaosUIToolkitCWrapper.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ChaosUIToolkitCWrapper.cc; sourceTree = "<group>"; };
+		3265F9101FB8997300FEA246 /* b64_ntop.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b64_ntop.h; sourceTree = "<group>"; };
+		3265F9111FB8997300FEA246 /* bson-context.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "bson-context.c"; sourceTree = "<group>"; };
+		3265F9121FB8997300FEA246 /* bson-oid.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "bson-oid.c"; sourceTree = "<group>"; };
+		3265F9131FB8997300FEA246 /* bson.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = bson.h; sourceTree = "<group>"; };
+		3265F9141FB8997300FEA246 /* bson-error.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "bson-error.c"; sourceTree = "<group>"; };
+		3265F9151FB8997300FEA246 /* bson-atomic.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "bson-atomic.c"; sourceTree = "<group>"; };
+		3265F9161FB8997300FEA246 /* bson-json.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-json.h"; sourceTree = "<group>"; };
+		3265F9171FB8997300FEA246 /* bson-string.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "bson-string.c"; sourceTree = "<group>"; };
+		3265F9181FB8997300FEA246 /* bson-keys.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "bson-keys.c"; sourceTree = "<group>"; };
+		3265F9191FB8997300FEA246 /* bson-timegm-private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-timegm-private.h"; sourceTree = "<group>"; };
+		3265F91A1FB8997300FEA246 /* bson-iter.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "bson-iter.c"; sourceTree = "<group>"; };
+		3265F91B1FB8997300FEA246 /* bson-iso8601.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "bson-iso8601.c"; sourceTree = "<group>"; };
+		3265F91C1FB8997300FEA246 /* bcon.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = bcon.h; sourceTree = "<group>"; };
+		3265F91D1FB8997300FEA246 /* bson-endian.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-endian.h"; sourceTree = "<group>"; };
+		3265F91E1FB8997300FEA246 /* bson-decimal128.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-decimal128.h"; sourceTree = "<group>"; };
+		3265F91F1FB8997300FEA246 /* bson-md5.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "bson-md5.c"; sourceTree = "<group>"; };
+		3265F9201FB8997300FEA246 /* bson-config.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-config.h"; sourceTree = "<group>"; };
+		3265F9211FB8997300FEA246 /* bson-memory.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "bson-memory.c"; sourceTree = "<group>"; };
+		3265F9221FB8997300FEA246 /* bson-writer.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "bson-writer.c"; sourceTree = "<group>"; };
+		3265F9231FB8997300FEA246 /* bson-iso8601-private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-iso8601-private.h"; sourceTree = "<group>"; };
+		3265F9241FB8997300FEA246 /* bson-clock.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-clock.h"; sourceTree = "<group>"; };
+		3265F9251FB8997300FEA246 /* bson-value.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "bson-value.c"; sourceTree = "<group>"; };
+		3265F9261FB8997300FEA246 /* bson-reader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-reader.h"; sourceTree = "<group>"; };
+		3265F9271FB8997300FEA246 /* bson-utf8.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-utf8.h"; sourceTree = "<group>"; };
+		3265F9281FB8997300FEA246 /* bson-string.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-string.h"; sourceTree = "<group>"; };
+		3265F9291FB8997300FEA246 /* bson-json.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "bson-json.c"; sourceTree = "<group>"; };
+		3265F92A1FB8997300FEA246 /* bson-atomic.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-atomic.h"; sourceTree = "<group>"; };
+		3265F92B1FB8997300FEA246 /* bson-keys.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-keys.h"; sourceTree = "<group>"; };
+		3265F92C1FB8997300FEA246 /* bson.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = bson.c; sourceTree = "<group>"; };
+		3265F92D1FB8997300FEA246 /* bson-error.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-error.h"; sourceTree = "<group>"; };
+		3265F92E1FB8997300FEA246 /* bson-oid.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-oid.h"; sourceTree = "<group>"; };
+		3265F92F1FB8997300FEA246 /* bson-stdint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-stdint.h"; sourceTree = "<group>"; };
+		3265F9301FB8997300FEA246 /* bson-context.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-context.h"; sourceTree = "<group>"; };
+		3265F9311FB8997300FEA246 /* bson-private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-private.h"; sourceTree = "<group>"; };
+		3265F9321FB8997300FEA246 /* bson-context-private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-context-private.h"; sourceTree = "<group>"; };
+		3265F9331FB8997300FEA246 /* bcon.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = bcon.c; sourceTree = "<group>"; };
+		3265F9341FB8997300FEA246 /* bson-types.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-types.h"; sourceTree = "<group>"; };
+		3265F9351FB8997300FEA246 /* bson-stdint-win32.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-stdint-win32.h"; sourceTree = "<group>"; };
+		3265F9361FB8997300FEA246 /* bson-iter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-iter.h"; sourceTree = "<group>"; };
+		3265F9371FB8997300FEA246 /* bson-thread-private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-thread-private.h"; sourceTree = "<group>"; };
+		3265F9381FB8997300FEA246 /* bson-writer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-writer.h"; sourceTree = "<group>"; };
+		3265F9391FB8997300FEA246 /* bson-memory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-memory.h"; sourceTree = "<group>"; };
+		3265F93A1FB8997300FEA246 /* b64_pton.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b64_pton.h; sourceTree = "<group>"; };
+		3265F93B1FB8997300FEA246 /* bson-compat.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-compat.h"; sourceTree = "<group>"; };
+		3265F93C1FB8997300FEA246 /* bson-decimal128.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "bson-decimal128.c"; sourceTree = "<group>"; };
+		3265F93D1FB8997300FEA246 /* bson-macros.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-macros.h"; sourceTree = "<group>"; };
+		3265F93E1FB8997300FEA246 /* bson-md5.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-md5.h"; sourceTree = "<group>"; };
+		3265F93F1FB8997300FEA246 /* bson-timegm.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "bson-timegm.c"; sourceTree = "<group>"; };
+		3265F9401FB8997300FEA246 /* bson-utf8.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "bson-utf8.c"; sourceTree = "<group>"; };
+		3265F9411FB8997300FEA246 /* bson-reader.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "bson-reader.c"; sourceTree = "<group>"; };
+		3265F9421FB8997300FEA246 /* bson-clock.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "bson-clock.c"; sourceTree = "<group>"; };
+		3265F9431FB8997300FEA246 /* bson-value.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "bson-value.h"; sourceTree = "<group>"; };
+		3265F9441FB8997300FEA246 /* bson.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = bson.h; sourceTree = "<group>"; };
+		3265F9471FB8997300FEA246 /* jsonsl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = jsonsl.h; sourceTree = "<group>"; };
+		3265F9481FB8997300FEA246 /* jsonsl.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = jsonsl.c; sourceTree = "<group>"; };
+		3265F9491FB899D300FEA246 /* DataPack.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DataPack.cpp; sourceTree = "<group>"; };
+		3265F94A1FB899D400FEA246 /* DataPack.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DataPack.h; sourceTree = "<group>"; };
 		32661C661AA73D5B00F1A721 /* libchaos_metadata_service_client.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libchaos_metadata_service_client.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
 		32661C6B1AA741D000F1A721 /* ChaosMetadataServiceClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ChaosMetadataServiceClient.cpp; sourceTree = "<group>"; };
 		32661C6C1AA741D000F1A721 /* ChaosMetadataServiceClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChaosMetadataServiceClient.h; sourceTree = "<group>"; };
@@ -3398,8 +3469,7 @@
 		324D08A31F31CEB400836E29 /* external_lib */ = {
 			isa = PBXGroup;
 			children = (
-				324D08CD1F31F5A000836E29 /* json.h */,
-				324D08CE1F31F5A000836E29 /* jsoncpp.cpp */,
+				3265F90E1FB8997300FEA246 /* bson */,
 				324D08CF1F31F5A000836E29 /* mongoose.c */,
 				324D08D01F31F5A000836E29 /* mongoose.h */,
 				324BE8491F3CA31A00FFDA02 /* base64.cpp */,
@@ -3456,8 +3526,8 @@
 		324D08C71F31F25300836E29 /* data */ = {
 			isa = PBXGroup;
 			children = (
-				324D08C81F31F26600836E29 /* DataPack.cpp */,
-				324D08C91F31F26600836E29 /* DataPack.h */,
+				3265F9491FB899D300FEA246 /* DataPack.cpp */,
+				3265F94A1FB899D400FEA246 /* DataPack.h */,
 			);
 			path = data;
 			sourceTree = "<group>";
@@ -3812,6 +3882,92 @@
 			path = api;
 			sourceTree = "<group>";
 		};
+		3265F90E1FB8997300FEA246 /* bson */ = {
+			isa = PBXGroup;
+			children = (
+				3265F90F1FB8997300FEA246 /* bson */,
+				3265F9441FB8997300FEA246 /* bson.h */,
+				3265F9451FB8997300FEA246 /* util */,
+				3265F9461FB8997300FEA246 /* jsonsl */,
+			);
+			path = bson;
+			sourceTree = "<group>";
+		};
+		3265F90F1FB8997300FEA246 /* bson */ = {
+			isa = PBXGroup;
+			children = (
+				3265F9101FB8997300FEA246 /* b64_ntop.h */,
+				3265F9111FB8997300FEA246 /* bson-context.c */,
+				3265F9121FB8997300FEA246 /* bson-oid.c */,
+				3265F9131FB8997300FEA246 /* bson.h */,
+				3265F9141FB8997300FEA246 /* bson-error.c */,
+				3265F9151FB8997300FEA246 /* bson-atomic.c */,
+				3265F9161FB8997300FEA246 /* bson-json.h */,
+				3265F9171FB8997300FEA246 /* bson-string.c */,
+				3265F9181FB8997300FEA246 /* bson-keys.c */,
+				3265F9191FB8997300FEA246 /* bson-timegm-private.h */,
+				3265F91A1FB8997300FEA246 /* bson-iter.c */,
+				3265F91B1FB8997300FEA246 /* bson-iso8601.c */,
+				3265F91C1FB8997300FEA246 /* bcon.h */,
+				3265F91D1FB8997300FEA246 /* bson-endian.h */,
+				3265F91E1FB8997300FEA246 /* bson-decimal128.h */,
+				3265F91F1FB8997300FEA246 /* bson-md5.c */,
+				3265F9201FB8997300FEA246 /* bson-config.h */,
+				3265F9211FB8997300FEA246 /* bson-memory.c */,
+				3265F9221FB8997300FEA246 /* bson-writer.c */,
+				3265F9231FB8997300FEA246 /* bson-iso8601-private.h */,
+				3265F9241FB8997300FEA246 /* bson-clock.h */,
+				3265F9251FB8997300FEA246 /* bson-value.c */,
+				3265F9261FB8997300FEA246 /* bson-reader.h */,
+				3265F9271FB8997300FEA246 /* bson-utf8.h */,
+				3265F9281FB8997300FEA246 /* bson-string.h */,
+				3265F9291FB8997300FEA246 /* bson-json.c */,
+				3265F92A1FB8997300FEA246 /* bson-atomic.h */,
+				3265F92B1FB8997300FEA246 /* bson-keys.h */,
+				3265F92C1FB8997300FEA246 /* bson.c */,
+				3265F92D1FB8997300FEA246 /* bson-error.h */,
+				3265F92E1FB8997300FEA246 /* bson-oid.h */,
+				3265F92F1FB8997300FEA246 /* bson-stdint.h */,
+				3265F9301FB8997300FEA246 /* bson-context.h */,
+				3265F9311FB8997300FEA246 /* bson-private.h */,
+				3265F9321FB8997300FEA246 /* bson-context-private.h */,
+				3265F9331FB8997300FEA246 /* bcon.c */,
+				3265F9341FB8997300FEA246 /* bson-types.h */,
+				3265F9351FB8997300FEA246 /* bson-stdint-win32.h */,
+				3265F9361FB8997300FEA246 /* bson-iter.h */,
+				3265F9371FB8997300FEA246 /* bson-thread-private.h */,
+				3265F9381FB8997300FEA246 /* bson-writer.h */,
+				3265F9391FB8997300FEA246 /* bson-memory.h */,
+				3265F93A1FB8997300FEA246 /* b64_pton.h */,
+				3265F93B1FB8997300FEA246 /* bson-compat.h */,
+				3265F93C1FB8997300FEA246 /* bson-decimal128.c */,
+				3265F93D1FB8997300FEA246 /* bson-macros.h */,
+				3265F93E1FB8997300FEA246 /* bson-md5.h */,
+				3265F93F1FB8997300FEA246 /* bson-timegm.c */,
+				3265F9401FB8997300FEA246 /* bson-utf8.c */,
+				3265F9411FB8997300FEA246 /* bson-reader.c */,
+				3265F9421FB8997300FEA246 /* bson-clock.c */,
+				3265F9431FB8997300FEA246 /* bson-value.h */,
+			);
+			path = bson;
+			sourceTree = "<group>";
+		};
+		3265F9451FB8997300FEA246 /* util */ = {
+			isa = PBXGroup;
+			children = (
+			);
+			path = util;
+			sourceTree = "<group>";
+		};
+		3265F9461FB8997300FEA246 /* jsonsl */ = {
+			isa = PBXGroup;
+			children = (
+				3265F9471FB8997300FEA246 /* jsonsl.h */,
+				3265F9481FB8997300FEA246 /* jsonsl.c */,
+			);
+			path = jsonsl;
+			sourceTree = "<group>";
+		};
 		32661C6A1AA73DA200F1A721 /* chaos_metadata_service_client */ = {
 			isa = PBXGroup;
 			children = (
@@ -5660,8 +5816,6 @@
 				325F517F1F3C3E11000B842F /* RawDriverHandlerWrapper.h in Headers */,
 				325F51831F3C3E4D000B842F /* UnitProxyHandlerWrapper.h in Headers */,
 				324D08C61F31EC5000836E29 /* HTTPConnectionAdapter.h in Headers */,
-				324D08D21F31F5A000836E29 /* json.h in Headers */,
-				324D08CB1F31F26600836E29 /* DataPack.h in Headers */,
 				324BE84C1F3CA31A00FFDA02 /* base64.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -6663,15 +6817,35 @@
 				324D08A11F30CE2B00836E29 /* ChaosMicroUnitToolkit.cpp in Sources */,
 				324D08AB1F31D5EA00836E29 /* ConnectionManager.cpp in Sources */,
 				324D08D41F31F5A000836E29 /* mongoose.c in Sources */,
+				3265F9591FB89F6B00FEA246 /* bson.c in Sources */,
+				3265F9521FB89F6B00FEA246 /* bson-iter.c in Sources */,
 				324D08B51F31D7F300836E29 /* AbstractUnitProxy.cpp in Sources */,
+				3265F9571FB89F6B00FEA246 /* bson-value.c in Sources */,
 				324D08C51F31EC5000836E29 /* HTTPConnectionAdapter.cpp in Sources */,
 				325F517E1F3C3E11000B842F /* RawDriverHandlerWrapper.cpp in Sources */,
-				324D08CA1F31F26600836E29 /* DataPack.cpp in Sources */,
+				3265F9531FB89F6B00FEA246 /* bson-iso8601.c in Sources */,
+				3265F95C1FB89F6B00FEA246 /* bson-timegm.c in Sources */,
+				3265F94E1FB89F6B00FEA246 /* bson-error.c in Sources */,
+				3265F95D1FB89F6B00FEA246 /* bson-utf8.c in Sources */,
+				3265F9501FB89F6B00FEA246 /* bson-string.c in Sources */,
+				3265F95F1FB89F6B00FEA246 /* bson-clock.c in Sources */,
+				3265F95A1FB89F6B00FEA246 /* bcon.c in Sources */,
+				3265F95E1FB89F6B00FEA246 /* bson-reader.c in Sources */,
+				3265F9511FB89F6B00FEA246 /* bson-keys.c in Sources */,
+				3265F94F1FB89F6B00FEA246 /* bson-atomic.c in Sources */,
 				325F51821F3C3E4D000B842F /* UnitProxyHandlerWrapper.cpp in Sources */,
 				324BE84B1F3CA31A00FFDA02 /* base64.cpp in Sources */,
+				3265F9601FB8A12B00FEA246 /* jsonsl.c in Sources */,
+				3265F94C1FB89F6B00FEA246 /* bson-context.c in Sources */,
+				3265F94B1FB899D400FEA246 /* DataPack.cpp in Sources */,
 				324D08B01F31D70600836E29 /* AbstractConnectionAdapter.cpp in Sources */,
+				3265F9561FB89F6B00FEA246 /* bson-writer.c in Sources */,
+				3265F9541FB89F6B00FEA246 /* bson-md5.c in Sources */,
 				325F517A1F3C3DD2000B842F /* RawDriverUnitProxy.cpp in Sources */,
-				324D08D31F31F5A000836E29 /* jsoncpp.cpp in Sources */,
+				3265F9551FB89F6B00FEA246 /* bson-memory.c in Sources */,
+				3265F94D1FB89F6B00FEA246 /* bson-oid.c in Sources */,
+				3265F9581FB89F6B00FEA246 /* bson-json.c in Sources */,
+				3265F95B1FB89F6B00FEA246 /* bson-decimal128.c in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -7443,6 +7617,7 @@
 				LIBRARY_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
 				MACOSX_DEPLOYMENT_TARGET = 10.12;
 				MTL_ENABLE_DEBUG_INFO = YES;
+				OTHER_LDFLAGS = "-lboost_system";
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SDKROOT = macosx;
 			};
@@ -7495,6 +7670,7 @@
 				LIBRARY_SEARCH_PATHS = "$(SRCROOT)/usr/local/lib";
 				MACOSX_DEPLOYMENT_TARGET = 10.12;
 				MTL_ENABLE_DEBUG_INFO = NO;
+				OTHER_LDFLAGS = "-lboost_system";
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SDKROOT = macosx;
 			};
diff --git a/chaos_micro_unit_toolkit/CMakeLists.txt b/chaos_micro_unit_toolkit/CMakeLists.txt
index c8fa153f40f756fa6442fb8ff9914cc553078213..273e796826e748e9f49d5f3543b24db511c76871 100644
--- a/chaos_micro_unit_toolkit/CMakeLists.txt
+++ b/chaos_micro_unit_toolkit/CMakeLists.txt
@@ -13,8 +13,29 @@ SET(source ${source} connection/unit_proxy/AbstractUnitProxy.cpp
                      connection/unit_proxy/UnitProxyHandlerWrapper.cpp)
 SET(source ${source} connection/unit_proxy/raw_driver/RawDriverUnitProxy.cpp
                      connection/unit_proxy/raw_driver/RawDriverHandlerWrapper.cpp)
-SET(source ${source} external_lib/jsoncpp.cpp
-                     external_lib/mongoose.c
+SET(source ${source}
+                    external_lib/bson/bcon.c
+                    external_lib/bson/bson-atomic.c
+                    external_lib/bson/bson-clock.c
+                    external_lib/bson/bson-context.c
+                    external_lib/bson/bson-decimal128.c
+                    external_lib/bson/bson-error.c
+                    external_lib/bson/bson-iso8601.c
+                    external_lib/bson/bson-iter.c
+                    external_lib/bson/bson-json.c
+                    external_lib/bson/bson-keys.c
+                    external_lib/bson/bson-md5.c
+                    external_lib/bson/bson-memory.c
+                    external_lib/bson/bson-oid.c
+                    external_lib/bson/bson-reader.c
+                    external_lib/bson/bson-string.c
+                    external_lib/bson/bson-timegm.c
+                    external_lib/bson/bson-utf8.c
+                    external_lib/bson/bson-value.c
+                    external_lib/bson/bson-writer.c
+                    external_lib/bson/bson.c
+                    external_lib/jsonsl/jsonsl.c)
+SET(source ${source} external_lib/mongoose.c
                      external_lib/base64.cpp)
 
 IF (BUILD_FORCE_STATIC)
diff --git a/chaos_micro_unit_toolkit/connection/connection_adapter/AbstractConnectionAdapter.cpp b/chaos_micro_unit_toolkit/connection/connection_adapter/AbstractConnectionAdapter.cpp
index a437f5cc30f54c841b97cf90b6711824e92d5593..10688c13b63cde0a8e2e31da7740d3bd602b409b 100644
--- a/chaos_micro_unit_toolkit/connection/connection_adapter/AbstractConnectionAdapter.cpp
+++ b/chaos_micro_unit_toolkit/connection/connection_adapter/AbstractConnectionAdapter.cpp
@@ -33,28 +33,28 @@ adapter_request_id(0){}
 
 AbstractConnectionAdapter::~AbstractConnectionAdapter() {}
 
-void AbstractConnectionAdapter::handleReceivedMessage(data::DataPackSharedPtr& received_message) {
+void AbstractConnectionAdapter::handleReceivedMessage(data::CDWShrdPtr& received_message) {
     //checn whenever the message is a response or spontaneus message
     if(received_message->hasKey("etx_request_id") &&
-       received_message->isInt32("etx_request_id")) {
-        map_req_id_response.insert(MapRequestIDResponsePair((uint32_t)received_message->getInt32("etx_request_id"),
+       received_message->isInt32Value("etx_request_id")) {
+        map_req_id_response.insert(MapRequestIDResponsePair((uint32_t)received_message->getInt32Value("etx_request_id"),
                                                             received_message));
     } else {
         queue_received_messages.push(received_message);
     }
 }
 
-int AbstractConnectionAdapter::sendMessage(data::DataPackUniquePtr& message) {
+int AbstractConnectionAdapter::sendMessage(data::CDWUniquePtr& message) {
     if(connection_status != ConnectionStateAccepted){
         return -1;
     }
     return sendRawMessage(message);
 }
 
-int AbstractConnectionAdapter::sendRequest(data::DataPackUniquePtr& message,
+int AbstractConnectionAdapter::sendRequest(data::CDWUniquePtr& message,
                                            uint32_t& request_id) {
     request_id = adapter_request_id++;
-    message->addInt32("ext_request_id", request_id);
+    message->addInt32Value("ext_request_id", request_id);
     return sendMessage(message);
 }
 
@@ -62,11 +62,11 @@ bool AbstractConnectionAdapter::hasMoreMessage() {
     return queue_received_messages.size();
 }
 
-DataPackSharedPtr AbstractConnectionAdapter::getNextMessage() {
+CDWShrdPtr AbstractConnectionAdapter::getNextMessage() {
     if(queue_received_messages.size() == 0) {
-        return DataPackSharedPtr();
+        return CDWShrdPtr();
     } else {
-        DataPackSharedPtr result = queue_received_messages.front();
+        CDWShrdPtr result = queue_received_messages.front();
         queue_received_messages.pop();
         return result;
     }
@@ -80,8 +80,8 @@ bool AbstractConnectionAdapter::hasResponseAvailable(uint32_t request_id) {
     return map_req_id_response.find(request_id) != map_req_id_response.end();
 }
 
-DataPackSharedPtr AbstractConnectionAdapter::retrieveRequestResponse(uint32_t request_id) {
-    return DataPackSharedPtr();
+CDWShrdPtr AbstractConnectionAdapter::retrieveRequestResponse(uint32_t request_id) {
+    return CDWShrdPtr();
 }
 
 const ConnectionState& AbstractConnectionAdapter::getConnectionState() const {
diff --git a/chaos_micro_unit_toolkit/connection/connection_adapter/AbstractConnectionAdapter.h b/chaos_micro_unit_toolkit/connection/connection_adapter/AbstractConnectionAdapter.h
index 58789c00b65c68efe20732acf6f3a3f51e9485ce..8831cf8c617d1b657d0d86e720ed7ba451ec5d44 100644
--- a/chaos_micro_unit_toolkit/connection/connection_adapter/AbstractConnectionAdapter.h
+++ b/chaos_micro_unit_toolkit/connection/connection_adapter/AbstractConnectionAdapter.h
@@ -54,9 +54,9 @@ namespace chaos {
                 //! Abstract base class for all protocols adapter
                 class AbstractConnectionAdapter {
                 protected:
-                    virtual int sendRawMessage(chaos::micro_unit_toolkit::data::DataPackUniquePtr& message) = 0;
+                    virtual int sendRawMessage(chaos::micro_unit_toolkit::data::CDWUniquePtr& message) = 0;
                     
-                    void handleReceivedMessage(chaos::micro_unit_toolkit::data::DataPackSharedPtr& received_message);
+                    void handleReceivedMessage(chaos::micro_unit_toolkit::data::CDWShrdPtr& received_message);
                 public:
                     const std::string   protocol_endpoint;
                     const std::string   protocol_option;
@@ -88,14 +88,14 @@ namespace chaos {
                     /*!
                      \param message that will be sent to the remote endpoint
                      */
-                    int sendMessage(data::DataPackUniquePtr& message);
+                    int sendMessage(data::CDWUniquePtr& message);
                     
                     //!send a request to the remote endpoint
                     /*!
                      \param message that will be sent to the remote endpoint
                      \param request_id the id associated to the new request
                      */
-                    int sendRequest(data::DataPackUniquePtr& message,
+                    int sendRequest(data::CDWUniquePtr& message,
                                     uint32_t& request_id);
                     
                     //!check if there are message from remote endpoint
@@ -107,7 +107,7 @@ namespace chaos {
                     bool hasMoreMessage();
                     
                     //!return the message of top of the queue
-                    data::DataPackSharedPtr getNextMessage();
+                    data::CDWShrdPtr getNextMessage();
                     
                     //! Chekc if there are answer by remote endpoint
                     /*!
@@ -126,11 +126,11 @@ namespace chaos {
                     /*!
                      \param request_id the id associated to a request
                      */
-                    data::DataPackSharedPtr retrieveRequestResponse(uint32_t request_id);
+                    data::CDWShrdPtr retrieveRequestResponse(uint32_t request_id);
                 protected:
                     //!define the maps for the request response
-                    typedef std::map<uint32_t, data::DataPackSharedPtr> MapRequestIDResponse;
-                    typedef std::pair<uint32_t, data::DataPackSharedPtr> MapRequestIDResponsePair;
+                    typedef std::map<uint32_t, data::CDWShrdPtr> MapRequestIDResponse;
+                    typedef std::pair<uint32_t, data::CDWShrdPtr> MapRequestIDResponsePair;
                     typedef MapRequestIDResponse::iterator MapRequestIDResponseIterator;
 
                     //!the counter of the request id
@@ -140,7 +140,7 @@ namespace chaos {
                     //!define the map that asscoiate the request id to the reponse
                     MapRequestIDResponse                map_req_id_response;
                     //!contains the received message in the order as the have been received
-                    std::queue<data::DataPackSharedPtr> queue_received_messages;
+                    std::queue<data::CDWShrdPtr> queue_received_messages;
                 };
             }
         }
diff --git a/chaos_micro_unit_toolkit/connection/connection_adapter/http/HTTPConnectionAdapter.cpp b/chaos_micro_unit_toolkit/connection/connection_adapter/http/HTTPConnectionAdapter.cpp
index 7bc556c41cccd44f12f07780b17a36b58a40a62e..144364d01328ee27b59d7d9d7accfe5a04ae9d84 100644
--- a/chaos_micro_unit_toolkit/connection/connection_adapter/http/HTTPConnectionAdapter.cpp
+++ b/chaos_micro_unit_toolkit/connection/connection_adapter/http/HTTPConnectionAdapter.cpp
@@ -68,8 +68,8 @@ int HTTPConnectionAdapter::close() {
 
 #pragma mark PrivateMethod
 
-int HTTPConnectionAdapter::sendRawMessage(DataPackUniquePtr& message) {
-    std::string to_send = message->toUnformattedString();
+int HTTPConnectionAdapter::sendRawMessage(CDWUniquePtr& message) {
+    std::string to_send = message->toString();
     mg_send_websocket_frame(root_conn, WEBSOCKET_OP_TEXT, to_send.c_str(), to_send.size());
     return 0;
 }
@@ -95,13 +95,14 @@ void HTTPConnectionAdapter::ev_handler(struct mg_connection *conn,
             
         case MG_EV_WEBSOCKET_FRAME: {
             struct websocket_message *wm = (struct websocket_message *) event_data;
-            data::DataPackSharedPtr received_msg_shrd_ptr(DataPack::newFromBuffer((const char*)wm->data, wm->size).release());
+            std::string got_json((const char*)wm->data, wm->size);
+            data::CDWShrdPtr received_msg_shrd_ptr(DataPack::instanceFromJson(got_json).release());
             if(http_instance->connection_status != ConnectionStateAccepted) {
                 //at this time we need to manage the receivedm of the data unitl we not received
                 //the dapack taht informa us for the connection accepted
                 if(received_msg_shrd_ptr->hasKey(ACCEPTED_CONNECTION_KEY) &&
-                   received_msg_shrd_ptr->isInt32(ACCEPTED_CONNECTION_KEY)) {
-                    int32_t accepted_value = received_msg_shrd_ptr->getInt32(ACCEPTED_CONNECTION_KEY);
+                   received_msg_shrd_ptr->isInt32Value(ACCEPTED_CONNECTION_KEY)) {
+                    int32_t accepted_value = received_msg_shrd_ptr->getInt32Value(ACCEPTED_CONNECTION_KEY);
                     switch (accepted_value) {
                         case 1:
                             //ok
diff --git a/chaos_micro_unit_toolkit/connection/connection_adapter/http/HTTPConnectionAdapter.h b/chaos_micro_unit_toolkit/connection/connection_adapter/http/HTTPConnectionAdapter.h
index 0305949a7c99ca7296d60475f92a0b53decaf45a..c956a54ce638cddea1fb507107b5a9f69434b7d6 100644
--- a/chaos_micro_unit_toolkit/connection/connection_adapter/http/HTTPConnectionAdapter.h
+++ b/chaos_micro_unit_toolkit/connection/connection_adapter/http/HTTPConnectionAdapter.h
@@ -44,7 +44,7 @@ namespace chaos {
                                                int event,
                                                void *event_data);
                         //!inherited method
-                        int sendRawMessage(data::DataPackUniquePtr& message);
+                        int sendRawMessage(chaos::micro_unit_toolkit::data::CDWUniquePtr& message);
                     public:
                         //! point to the protocol constant type define in @chaos::micro_unit_toolkit::connection::ConnectionType
                         static const ConnectionType connection_type;
diff --git a/chaos_micro_unit_toolkit/connection/unit_proxy/AbstractUnitProxy.cpp b/chaos_micro_unit_toolkit/connection/unit_proxy/AbstractUnitProxy.cpp
index e62bb74987b2e814e3907ed4d7f06f55b3701cc6..5a860ac7acde4ecad3537231746e6b62c4a3b1b3 100644
--- a/chaos_micro_unit_toolkit/connection/unit_proxy/AbstractUnitProxy.cpp
+++ b/chaos_micro_unit_toolkit/connection/unit_proxy/AbstractUnitProxy.cpp
@@ -26,14 +26,14 @@ using namespace chaos::micro_unit_toolkit::data;
 using namespace chaos::micro_unit_toolkit::connection::unit_proxy;
 using namespace chaos::micro_unit_toolkit::connection::connection_adapter;
 
-RemoteMessage::RemoteMessage(const DataPackSharedPtr& _message):
+RemoteMessage::RemoteMessage(const CDWShrdPtr& _message):
 message(_message),
-is_request((message->hasKey("req_id") && message->isInt32("req_id"))),
-message_id(is_request?message->getInt32("req_id"):0){
+is_request((message->hasKey("req_id") && message->isInt32Value("req_id"))),
+message_id(is_request?message->getInt32Value("req_id"):0){
     if(is_request &&
        message->hasKey("msg") &&
-       message->isDataPack("msg")) {
-        request_message.reset(message->getDataPack("msg").release());
+       message->isCDWValue("msg")) {
+        request_message.reset(message->getCDWValue("msg").release());
     }
 }
 
@@ -42,15 +42,15 @@ bool RemoteMessage::isError() const {
 }
 
 int32_t RemoteMessage::getErrorCode() const {
-    return message.get()?message->getInt32("error_code"):0;
+    return message.get()?message->getInt32Value("error_code"):0;
 }
 
 std::string RemoteMessage::getErrorMessage() const {
-    return message.get()?message->getString("error_message"):"";
+    return message.get()?message->getStringValue("error_message"):"";
 }
 
 std::string RemoteMessage::getErrorDomain() const {
-    return message.get()?message->getString("error_domain"):"";
+    return message.get()?message->getStringValue("error_domain"):"";
 }
 
 AbstractUnitProxy::AbstractUnitProxy(ChaosUniquePtr<connection_adapter::AbstractConnectionAdapter>& _protocol_adapter):
@@ -61,7 +61,7 @@ AbstractUnitProxy::~AbstractUnitProxy() {
     std::cout <<"exit";
 }
 
-int AbstractUnitProxy::sendMessage(DataPackUniquePtr& message_data) {
+int AbstractUnitProxy::sendMessage(CDWUniquePtr& message_data) {
     return connection_adapter->sendMessage(message_data);
 }
 
diff --git a/chaos_micro_unit_toolkit/connection/unit_proxy/AbstractUnitProxy.h b/chaos_micro_unit_toolkit/connection/unit_proxy/AbstractUnitProxy.h
index a66bdc40dbdd6bbbfe25626c905ceace34f726ec..31c5575ede7fef5d3581be4a0f2ddc0d115be8cf 100644
--- a/chaos_micro_unit_toolkit/connection/unit_proxy/AbstractUnitProxy.h
+++ b/chaos_micro_unit_toolkit/connection/unit_proxy/AbstractUnitProxy.h
@@ -36,11 +36,11 @@ namespace chaos {
                 class RemoteMessage {
                     bool is_error;
                 public:
-                    data::DataPackSharedPtr message;
+                    data::CDWShrdPtr message;
                     const bool is_request;
                     const uint32_t message_id;
-                    data::DataPackSharedPtr request_message;
-                    RemoteMessage(const data::DataPackSharedPtr& _message);
+                    data::CDWShrdPtr request_message;
+                    RemoteMessage(const data::CDWShrdPtr& _message);
                     
                     bool isError() const;
                     int32_t getErrorCode() const;
@@ -63,7 +63,7 @@ namespace chaos {
                     ChaosUniquePtr<connection_adapter::AbstractConnectionAdapter> connection_adapter;
                 protected:
                     AuthorizationState authorization_state;
-                    virtual int sendMessage(data::DataPackUniquePtr& message_data);
+                    virtual int sendMessage(data::CDWUniquePtr& message_data);
                     
                     bool hasMoreMessage();
                     
diff --git a/chaos_micro_unit_toolkit/connection/unit_proxy/UnitProxyHandlerWrapper.h b/chaos_micro_unit_toolkit/connection/unit_proxy/UnitProxyHandlerWrapper.h
index d3f750bcf151ae55f4a4b4fe80535d86a3338ab9..56dbe7d9a42428aef5e8396e35f008afa10a74b0 100644
--- a/chaos_micro_unit_toolkit/connection/unit_proxy/UnitProxyHandlerWrapper.h
+++ b/chaos_micro_unit_toolkit/connection/unit_proxy/UnitProxyHandlerWrapper.h
@@ -33,12 +33,12 @@ namespace chaos {
             namespace unit_proxy {
                 
                 struct UPMessage {
-                    data::DataPackSharedPtr message;
+                    data::CDWShrdPtr message;
                 };
                 
                 struct UPRequest {
-                    data::DataPackSharedPtr message;
-                    data::DataPackUniquePtr response;
+                    data::CDWShrdPtr message;
+                    data::CDWUniquePtr response;
                 };
                 
                 struct UPError {
diff --git a/chaos_micro_unit_toolkit/connection/unit_proxy/raw_driver/RawDriverHandlerWrapper.cpp b/chaos_micro_unit_toolkit/connection/unit_proxy/raw_driver/RawDriverHandlerWrapper.cpp
index 078a67761eb4f838e1d208984141f8261691cbd9..b6838dbd48d4f26e8b395d9f7d81b3d3c446cf84 100644
--- a/chaos_micro_unit_toolkit/connection/unit_proxy/raw_driver/RawDriverHandlerWrapper.cpp
+++ b/chaos_micro_unit_toolkit/connection/unit_proxy/raw_driver/RawDriverHandlerWrapper.cpp
@@ -44,7 +44,7 @@ authorized(false){}
 
 RawDriverHandlerWrapper::~RawDriverHandlerWrapper(){}
 
-int RawDriverHandlerWrapper::sendMessage(data::DataPackUniquePtr& message_data) {
+int RawDriverHandlerWrapper::sendMessage(data::CDWUniquePtr& message_data) {
     RawDriverUnitProxy * const rd = static_cast<RawDriverUnitProxy*>(base_unit.get());
     return rd->sendMessage(message_data);
 }
@@ -89,7 +89,7 @@ int RawDriverHandlerWrapper::manageRemoteMessage() {
         if(remote_message->is_request &&
            remote_message->request_message.get()) {
             if(remote_message->request_message->hasKey("opcode") &&
-               remote_message->request_message->isInt32("opcode")){
+               remote_message->request_message->isInt32Value("opcode")){
                 UPRequest req = {remote_message->request_message, ChaosUniquePtr<DataPack>(new DataPack())};
                 if((err = callHandler(UP_EV_REQ_RECEIVED,
                                       &req)) == 0) {
diff --git a/chaos_micro_unit_toolkit/connection/unit_proxy/raw_driver/RawDriverHandlerWrapper.h b/chaos_micro_unit_toolkit/connection/unit_proxy/raw_driver/RawDriverHandlerWrapper.h
index 7f65576687318397fc77c4af1087c7699349dda5..069fec0fd12f9e48be876da6987cdce6d8abbbb5 100644
--- a/chaos_micro_unit_toolkit/connection/unit_proxy/raw_driver/RawDriverHandlerWrapper.h
+++ b/chaos_micro_unit_toolkit/connection/unit_proxy/raw_driver/RawDriverHandlerWrapper.h
@@ -47,7 +47,7 @@ namespace chaos {
                         ~RawDriverHandlerWrapper();
                         
                         //! send spontaneus message to the remote raw driver layer
-                        int sendMessage(data::DataPackUniquePtr& message_data);
+                        int sendMessage(data::CDWUniquePtr& message_data);
                     };
                     
                 }
diff --git a/chaos_micro_unit_toolkit/connection/unit_proxy/raw_driver/RawDriverUnitProxy.cpp b/chaos_micro_unit_toolkit/connection/unit_proxy/raw_driver/RawDriverUnitProxy.cpp
index 79b12d549f6c9a784fc0e9d336c27ea6685180c8..dd6e571d905eb6d4e479687c771f62c1653df253 100644
--- a/chaos_micro_unit_toolkit/connection/unit_proxy/raw_driver/RawDriverUnitProxy.cpp
+++ b/chaos_micro_unit_toolkit/connection/unit_proxy/raw_driver/RawDriverUnitProxy.cpp
@@ -40,8 +40,8 @@ RawDriverUnitProxy::~RawDriverUnitProxy() {}
 
 void RawDriverUnitProxy::authorization(const std::string& authorization_key) {
     authorization_state = AuthorizationStateRequested;
-    data::DataPackUniquePtr message(new data::DataPack());
-    message->addString(AUTHORIZATION_KEY, authorization_key);
+    data::CDWUniquePtr message(new data::DataPack());
+    message->addStringValue(AUTHORIZATION_KEY, authorization_key);
     AbstractUnitProxy::sendMessage(message);
 }
 
@@ -51,8 +51,8 @@ bool RawDriverUnitProxy::manageAutorizationPhase() {
         //!check authentication state
         RemoteMessageUniquePtr result = getNextMessage();
         if(result->message->hasKey(AUTHORIZATION_STATE) ||
-           result->message->isBool(AUTHORIZATION_STATE)) {
-            authorization_state = (AuthorizationState)result->message->getBool(AUTHORIZATION_STATE);
+           result->message->isBoolValue(AUTHORIZATION_STATE)) {
+            authorization_state = (AuthorizationState)result->message->getBoolValue(AUTHORIZATION_STATE);
         }
     }
     return result;
@@ -65,7 +65,7 @@ int RawDriverUnitProxy::sendMessage(DataPackUniquePtr& message_data) {
 }
 
 int RawDriverUnitProxy::sendAnswer(RemoteMessageUniquePtr& message,
-                                  DataPackUniquePtr& message_data) {
+                                   CDWUniquePtr& message_data) {
     if(message->is_request == false) return - 1;
     DataPackUniquePtr answer(new DataPack());
     answer->addInt32(REQUEST_IDENTIFICATION, message->message_id);
diff --git a/chaos_micro_unit_toolkit/connection/unit_proxy/raw_driver/RawDriverUnitProxy.h b/chaos_micro_unit_toolkit/connection/unit_proxy/raw_driver/RawDriverUnitProxy.h
index 93221d986a2f00a6cee7a4a9269a5dd82c5232c7..2cc44dbf6ce02416b104f2c21ee8240616ec3895 100644
--- a/chaos_micro_unit_toolkit/connection/unit_proxy/raw_driver/RawDriverUnitProxy.h
+++ b/chaos_micro_unit_toolkit/connection/unit_proxy/raw_driver/RawDriverUnitProxy.h
@@ -39,8 +39,8 @@ namespace chaos {
                         void authorization(const std::string& authorization_key);
                         bool manageAutorizationPhase();
                         int sendAnswer(RemoteMessageUniquePtr& message,
-                                       data::DataPackUniquePtr& message_data);
-                        int sendMessage(data::DataPackUniquePtr& message_data);
+                                       data::CDWUniquePtr& message_data);
+                        int sendMessage(data::CDWUniquePtr& message_data);
                         using AbstractUnitProxy::sendMessage;
                         using AbstractUnitProxy::hasMoreMessage;
                         using AbstractUnitProxy::getNextMessage;
diff --git a/chaos_micro_unit_toolkit/data/DataPack.cpp b/chaos_micro_unit_toolkit/data/DataPack.cpp
index 409466245c8ca718aaeb87d7c59ca8e64311a0e5..373bc7ce32c90c84bfcd3df79635c6276214eef0 100644
--- a/chaos_micro_unit_toolkit/data/DataPack.cpp
+++ b/chaos_micro_unit_toolkit/data/DataPack.cpp
@@ -1,165 +1,733 @@
 /*
- * Copyright 2012, 2017 INFN
+ *	DataPack.cpp
+ *	!CHAOS
+ *	Created by Bisegni Claudio.
  *
- * Licensed under the EUPL, Version 1.2 or – as soon they
- * will be approved by the European Commission - subsequent
- * versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the
- * Licence.
- * You may obtain a copy of the Licence at:
+ *    	Copyright 2012 INFN, National Institute of Nuclear Physics
  *
- * https://joinup.ec.europa.eu/software/page/eupl
+ *    	Licensed under the Apache License, Version 2.0 (the "License");
+ *    	you may not use this file except in compliance with the License.
+ *    	You may obtain a copy of the License at
  *
- * Unless required by applicable law or agreed to in
- * writing, software distributed under the Licence is
- * distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied.
- * See the Licence for the specific language governing
- * permissions and limitations under the Licence.
+ *    	http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    	Unless required by applicable law or agreed to in writing, software
+ *    	distributed under the License is distributed on an "AS IS" BASIS,
+ *    	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    	See the License for the specific language governing permissions and
+ *    	limitations under the License.
  */
-
 #include <chaos_micro_unit_toolkit/data/DataPack.h>
-#include <chaos_micro_unit_toolkit/external_lib/base64.h>
-
-using namespace Json;
-using namespace chaos::micro_unit_toolkit;
+#include <cassert>
 using namespace chaos::micro_unit_toolkit::data;
 
-DataPackUniquePtr DataPack::newFromBuffer(const char *data,
-                                          const size_t data_len,
-                                          bool *parsed) {
-    DataPackUniquePtr new_dp(new DataPack());
-    Reader reader;
-    bool parse_result = reader.parse(data,
-                                     data+data_len,
-                                     new_dp->root_json_object);
-    if(parsed){*parsed = parse_result;}
-    return new_dp;
+#pragma mark Utility
+
+#define ALLOCATE_BSONT(x) ChaosBsonShrdPtr(x, &bsonDeallocator)
+
+#define ACCESS_BSON(x) static_cast<bson_t*>(x.get())
+
+#define ENSURE_ARRAY(x) \
+if(x.get() == NULL) {array_index = 0; x = ALLOCATE_BSONT(bson_new());}
+
+#define FIND_AND_CHECK(k,c)\
+bson_iter_t element_found;\
+bson_iter_init(&element_found, ACCESS_BSON(bson));\
+if(bson_iter_find_case(&element_found, key.c_str()) && c(&element_found))
+
+static void bsonDeallocator(bson_t* bson) {if(bson){bson_destroy(bson);}}
+
+#pragma mark DataPack
+DataPack::DataPack():
+bson(ALLOCATE_BSONT(bson_new())),
+array_index(0){
+    assert(bson);
+}
+
+DataPack::DataPack(const bson_t *copy_bson):
+bson(ALLOCATE_BSONT(bson_copy(copy_bson))),
+array_index(0){}
+
+DataPack::DataPack(const char* mem_ser,
+                           uint32_t mem_size):
+bson(ALLOCATE_BSONT(bson_new_from_data((const uint8_t*)mem_ser,
+                                       mem_size))),
+array_index(0){
+    assert(bson);
+}
+
+DataPack::DataPack(const char* mem_ser):
+array_index(0) {
+    uint32_t size = BSON_UINT32_FROM_LE(*reinterpret_cast<const uint32_t *>(mem_ser));
+    bson = ALLOCATE_BSONT(bson_new_from_data((const uint8_t*)mem_ser,
+                                             size));
+    assert(bson);
+}
+
+DataPack::DataPack(const std::string& json_document):
+array_index(0) {
+    bson_error_t err;
+    bson = ALLOCATE_BSONT(bson_new_from_json((const uint8_t*)json_document.c_str(),
+                                             json_document.size(),
+                                             &err));
+    assert(bson);
+}
+
+DataPack::~DataPack(){}
+
+CDWUniquePtr DataPack::instanceFromJson(const std::string& json_serialization) {
+    return CDWUniquePtr(new DataPack(json_serialization));
+}
+
+DataPack *DataPack::clone() {
+    return new DataPack(bson.get());
+}
+
+
+//add a csdata value
+void DataPack::addCDWValue(const std::string& key,
+                               const DataPack& value) {
+    bson_append_document(ACCESS_BSON(bson),
+                         key.c_str(),
+                         (int)key.size(),
+                         ACCESS_BSON(value.bson));
+}
+
+//add a string value
+void DataPack::addStringValue(const std::string& key, const std::string& value) {
+    bson_append_utf8(ACCESS_BSON(bson),
+                     key.c_str(),
+                     (int)key.size(),
+                     value.c_str(),
+                     (int)value.size());
+}
+
+//append a strin gto an open array
+void DataPack::appendStringToArray(const std::string& value) {
+    ENSURE_ARRAY(bson_tmp_array);
+    char str[12];
+    sprintf(str, "%d", array_index++);
+    bson_append_utf8(ACCESS_BSON(bson_tmp_array),
+                     str,
+                     -1,
+                     value.c_str(),
+                     (int)value.size());
+}
+
+//append a strin gto an open array
+void DataPack::appendInt32ToArray(int32_t value) {
+    ENSURE_ARRAY(bson_tmp_array);
+    char str[12];
+    sprintf(str, "%d", array_index++);
+    bson_append_int32(ACCESS_BSON(bson_tmp_array),
+                      str,
+                      -1,
+                      value);
+}
+
+//append a strin gto an open array
+void DataPack::appendInt64ToArray(int64_t value) {
+    ENSURE_ARRAY(bson_tmp_array);
+    char str[12];
+    sprintf(str, "%d", array_index++);
+    bson_append_int64(ACCESS_BSON(bson_tmp_array),
+                      str,
+                      -1,
+                      value);
+}
+
+//append a strin gto an open array
+void DataPack::appendDoubleToArray(double value) {
+    ENSURE_ARRAY(bson_tmp_array);
+    char str[12];
+    sprintf(str, "%d", array_index++);
+    bson_append_double(ACCESS_BSON(bson_tmp_array),
+                       str,
+                       -1,
+                       value);
+}
+
+//appen a DataPack to an open array
+void DataPack::appendDataPackToArray(DataPack& value) {
+    ENSURE_ARRAY(bson_tmp_array);
+    char str[12];
+    sprintf(str, "%d", array_index++);
+    bson_append_document(ACCESS_BSON(bson_tmp_array),
+                         str,
+                         -1,
+                         value.bson.get());
+}
+
+//finalize the array into a key for the current dataobject
+void DataPack::finalizeArrayForKey(const std::string& key) {
+    ENSURE_ARRAY(bson_tmp_array);
+    bson_append_array(ACCESS_BSON(bson),
+                      key.c_str(),
+                      (int)key.size(),
+                      bson_tmp_array.get());
+    bson_tmp_array.reset();
+}
+
+//return a vectorvalue for a key
+CMultiTypeDataArrayWrapper* DataPack::getVectorValue(const std::string& key)  const{
+    return new CMultiTypeDataArrayWrapper(bson,
+                                          key);
+}
+
+void DataPack::addNullValue(const std::string& key) {
+    bson_append_null(ACCESS_BSON(bson),
+                     key.c_str(),
+                     (int)key.size());
+}
+//add a long value
+void DataPack::addInt32Value(const std::string& key, int32_t value) {
+    bson_append_int32(ACCESS_BSON(bson),
+                      key.c_str(),
+                      (int)key.size(),
+                      value);
+}
+//add a long value
+void DataPack::addInt32Value(const std::string& key, uint32_t value) {
+    bson_append_int32(ACCESS_BSON(bson),
+                      key.c_str(),
+                      (int)key.size(),
+                      static_cast<int32_t>(value));
+}
+//add a double value
+void DataPack::addDoubleValue(const std::string& key, double value) {
+    bson_append_double(ACCESS_BSON(bson),
+                       key.c_str(),
+                       (int)key.size(),
+                       value);
+}
+
+//add a integer value
+void DataPack::addInt64Value(const std::string& key, int64_t value) {
+    bson_append_int64(ACCESS_BSON(bson),
+                      key.c_str(),
+                      (int)key.size(),
+                      value);
+}
+
+//add a integer value
+void DataPack::addInt64Value(const std::string& key, uint64_t value) {
+    bson_append_int64(ACCESS_BSON(bson),
+                      key.c_str(),
+                      (int)key.size(),
+                      static_cast<int64_t>(value));
+}
+
+CDWUniquePtr DataPack::getCDWValue(const std::string& key) const{
+    FIND_AND_CHECK(key, BSON_ITER_HOLDS_DOCUMENT){
+        uint32_t document_len = 0;
+        const uint8_t *document = NULL;
+        bson_iter_document(&element_found,
+                           &document_len,
+                           &document);
+        return CDWUniquePtr(new DataPack((const char *)document,document_len));
+    } else {
+        return CDWUniquePtr(new DataPack());
+    }
 }
 
-DataPack::DataPack() {}
+//get string value
+std::string  DataPack::getStringValue(const std::string& key) const{
+    FIND_AND_CHECK(key, BSON_ITER_HOLDS_UTF8){
+        return std::string(bson_iter_utf8(&element_found, NULL));
+    }
+    return std::string();
+}
 
-DataPack::DataPack(const Value& src_root_json_object):
-root_json_object(src_root_json_object){}
+//get string value
+const char *  DataPack::getCStringValue(const std::string& key) const{
+    return getRawValuePtr(key);
+}
 
-DataPack::~DataPack() {}
+//add a integer value
+int32_t DataPack::getInt32Value(const std::string& key,
+                                    int32_t default_value) const{
+    FIND_AND_CHECK(key, BSON_ITER_HOLDS_INT32){
+        return bson_iter_int32(&element_found);
+    } else {
+        return default_value;
+    }
+}
+//add a integer value
+uint32_t DataPack::getUInt32Value(const std::string& key,
+                                      uint32_t default_value) const{
+    FIND_AND_CHECK(key, BSON_ITER_HOLDS_INT32){
+        return static_cast<uint32_t>(bson_iter_int32(&element_found));
+    } else {
+        return default_value;
+    }
+}
+//add a integer value
+int64_t DataPack::getInt64Value(const std::string& key,
+                                    int64_t default_value) const{
+    FIND_AND_CHECK(key, BSON_ITER_HOLDS_INT64){
+        return bson_iter_int64(&element_found);
+    } else {
+        return default_value;
+    }
+}
+//add a integer value
+uint64_t DataPack::getUInt64Value(const std::string& key,
+                                      uint64_t default_value) const{
+    FIND_AND_CHECK(key, BSON_ITER_HOLDS_INT64){
+        return static_cast<uint64_t>(bson_iter_int64(&element_found));
+    } else {
+        return default_value;
+    }
+}
+//add a integer value
+double DataPack::getDoubleValue(const std::string& key,
+                                    double default_value) const{
+    FIND_AND_CHECK(key, BSON_ITER_HOLDS_DOUBLE){
+        return bson_iter_double(&element_found);
+    } else {
+        return default_value;
+    }
+}
 
-bool DataPack::hasKey(const std::string& key) {
-    return root_json_object.isMember(key);
+//get a bool value
+bool  DataPack::getBoolValue(const std::string& key,
+                                 bool default_value) const{
+    FIND_AND_CHECK(key, BSON_ITER_HOLDS_BOOL){
+        return bson_iter_bool(&element_found);
+    } else {
+        return default_value;
+    }
 }
 
-void DataPack::addBool(const std::string& key, bool value) {
-    root_json_object[key] = Value(value);
+//set a binary data value
+void DataPack::addBinaryValue(const std::string& key,
+                                  const char *buff,
+                                  int bufLen) {
+    bson_append_binary(ACCESS_BSON(bson),
+                       key.c_str(),
+                       (int)key.size(),
+                       BSON_SUBTYPE_BINARY,
+                       (const uint8_t *)buff,
+                       bufLen);
 }
-const bool DataPack::isBool(const std::string& key) const {
-    return root_json_object[key].isBool();
+
+//return the binary data value
+const char* DataPack::getBinaryValue(const std::string& key, uint32_t& bufLen) const{
+    const uint8_t* ret = NULL;
+    unsigned int sub;
+    FIND_AND_CHECK(key, BSON_ITER_HOLDS_BINARY){
+        bson_iter_binary(&element_found,
+                         &sub,
+                         &bufLen,
+                         &ret);
+    }
+    return (const char*)ret;
 }
 
-const bool DataPack::getBool(const std::string& key) const {
-    return root_json_object[key].asBool();
+//check if the key is present in data wrapper
+bool DataPack::hasKey(const std::string& key) const{
+    return bson_has_field(ACCESS_BSON(bson), key.c_str());
 }
-void DataPack::addInt32(const std::string& key,
-                        int32_t value) {
-    root_json_object[key] = Value(value);
+
+bool DataPack::isVector(const std::string& key) const{
+    FIND_AND_CHECK(key, BSON_ITER_HOLDS_ARRAY){
+        return true;
+    } else {
+        return false;
+    }
 }
-const bool DataPack::isInt32(const std::string& key) const {
-    return root_json_object[key].isInt();
+
+//return all key contained into the object
+void DataPack::getAllKey(std::vector<std::string>& contained_key) const {
+    bson_iter_t it;
+    bson_iter_init(&it, ACCESS_BSON(bson));
+    while(bson_iter_next(&it)) {
+        contained_key.push_back(bson_iter_key(&it));
+    }
 }
-const int32_t DataPack::getInt32(const std::string& key) const {
-    return root_json_object[key].asInt();
+
+//return all key contained into the object
+void DataPack::getAllKey(std::set<std::string>& contained_key) const {
+    bson_iter_t it;
+    bson_iter_init(&it, ACCESS_BSON(bson));
+    while(bson_iter_next(&it)) {
+        contained_key.insert(bson_iter_key(&it));
+    }
 }
-void DataPack::addInt64(const std::string& key,
-                        int64_t value) {
-    root_json_object[key] = Value(value);
+
+//return all key contained into the object
+uint32_t DataPack::getValueSize(const std::string& key) const{
+    bson_iter_t it;
+    bson_iter_init(&it, ACCESS_BSON(bson));
+    if(bson_iter_find_case(&it, key.c_str()) == false) return 0;
+    const bson_value_t *v = bson_iter_value(&it);
+    switch(v->value_type) {
+        case BSON_TYPE_INT64:
+            return sizeof(int64_t);
+        case BSON_TYPE_INT32:
+            return sizeof(int32_t);
+        case BSON_TYPE_BOOL:
+            return sizeof(bool);
+        case BSON_TYPE_DOUBLE:
+            return sizeof(double);
+        case BSON_TYPE_UTF8:
+            return v->value.v_utf8.len;
+        case BSON_TYPE_BINARY:
+            return v->value.v_binary.data_len;
+        case BSON_TYPE_ARRAY:{
+            uint32_t array_len = 0;
+            const uint8_t *array = NULL;
+            bson_iter_array(&it, &array_len, &array);
+            return array_len;
+        }
+        case BSON_TYPE_DOCUMENT:{
+            return v->value.v_doc.data_len;
+        }
+        default:
+            return 0;
+            break;
+    }
+    return 0;
 }
-const bool DataPack::isInt64(const std::string& key) const {
-    return root_json_object[key].isInt64();
+
+//! return the raw value ptr address
+const char * DataPack::getRawValuePtr(const std::string& key) const{
+    bson_iter_t it;
+    bson_iter_init(&it, ACCESS_BSON(bson));
+    if(bson_iter_find_case(&it, key.c_str()) == false) return 0;
+    const bson_value_t *v = bson_iter_value(&it);
+    switch(v->value_type) {
+        case BSON_TYPE_INT64:
+            return reinterpret_cast<const char*>(&v->value.v_int64);
+        case BSON_TYPE_INT32:
+            return reinterpret_cast<const char*>(&v->value.v_int32);
+        case BSON_TYPE_BOOL:
+            return reinterpret_cast<const char*>(&v->value.v_bool);
+        case BSON_TYPE_DOUBLE:
+            return reinterpret_cast<const char*>(&v->value.v_double);
+        case BSON_TYPE_UTF8:
+            return static_cast<const char*>(v->value.v_utf8.str);
+        case BSON_TYPE_BINARY:
+            return reinterpret_cast<const char*>(v->value.v_binary.data);
+        case BSON_TYPE_ARRAY:{
+            uint32_t array_len = 0;
+            const uint8_t *array = NULL;
+            bson_iter_array(&it, &array_len, &array);
+            return reinterpret_cast<const char*>(array);
+        }
+        case BSON_TYPE_DOCUMENT:{
+            return reinterpret_cast<const char*>(v->value.v_doc.data);
+        }
+        default:
+            return NULL;
+            break;
+    }
+    
 }
-const int64_t DataPack::getInt64(const std::string& key) const {
-    return root_json_object[key].asInt64();
+
+void DataPack::addBoolValue(const std::string& key, bool value) {
+    bson_append_bool(ACCESS_BSON(bson),
+                     key.c_str(),
+                     (int)key.size(),
+                     value);
 }
-void DataPack::addDouble(const std::string& key,
-                         double value) {
-    root_json_object[key] = Value(value);
+
+const char* DataPack::getBSONRawData() const{
+    return reinterpret_cast<const char*>(bson_get_data(ACCESS_BSON(bson)));
 }
-const bool DataPack::isDouble(const std::string& key) const {
-    return root_json_object[key].isDouble();
+
+const int DataPack::getBSONRawSize() const{
+    return bson->len;
 }
-const double DataPack::getDouble(const std::string& key) const {
-    return root_json_object[key].asDouble();
+
+//return the json data
+std::string DataPack::toString()  const{
+    size_t str_size = 0;
+    char * str_c = bson_as_extended_json(ACCESS_BSON(bson),
+                                         &str_size);
+    std::string result(str_c);
+    bson_free(str_c);
+    return result;
+}
+//reinitialize the object with bson data
+void DataPack::setSerializedData(const char* bson_data) {
+    bson_iter_t it;
+    size_t len = (size_t)BSON_UINT32_FROM_LE(*reinterpret_cast<const uint32_t *>(bson_data));
+    if(!bson_iter_init_from_data(&it,
+                                 reinterpret_cast<const uint8_t *>(bson_data),
+                                 len)) return;
+    while(bson_iter_next(&it)){
+        bson_append_value(ACCESS_BSON(bson),
+                          bson_iter_key(&it),
+                          -1,
+                          bson_iter_value(&it));
+    }
+    
 }
-void DataPack::addString(const std::string& key,
-                         const std::string& value) {
-    root_json_object[key] = Value(value);
+
+//reinitialize the object with bson data
+void DataPack::setSerializedJsonData(const char* json_data) {
+    bson_error_t err;
+    size_t len = (size_t)strlen(json_data);
+    bson =ALLOCATE_BSONT(bson_new_from_json((const uint8_t*)json_data,
+                                            len,
+                                            &err));
+    assert(bson);
 }
-const bool DataPack::isString(const std::string& key) const {
-    return root_json_object[key].isString();
+
+//append all elemento of an
+void DataPack::appendAllElement(DataPack& src_cdw) {
+    bson_iter_t it;
+    bson_iter_init(&it, ACCESS_BSON(src_cdw.bson));
+    while (bson_iter_next(&it)) {
+        bson_append_value(ACCESS_BSON(bson),
+                          bson_iter_key(&it),
+                          -1,
+                          bson_iter_value(&it));
+    }
 }
-std::string DataPack::getString(const std::string& key) const {
-    return root_json_object[key].asString();
+
+bool DataPack::copyKeyTo(const std::string& key_to_copy,
+                             DataPack& destination) {
+    return copyKeyToNewKey(key_to_copy,
+                           key_to_copy,
+                           destination);
 }
-void DataPack::addDataPack(const std::string& key,
-                           DataPack& value) {
-    root_json_object[key] = value.root_json_object;
+
+//!copy a key(with value) from this instance to another DataPack witha new key
+bool DataPack::copyKeyToNewKey(const std::string& key_to_copy,
+                                   const std::string& new_key,
+                                   DataPack& destination) {
+    bson_iter_t it;
+    bson_iter_init(&it, ACCESS_BSON(bson));
+    if(bson_iter_find_case(&it, key_to_copy.c_str()) == false) return false;
+    bson_append_value(ACCESS_BSON(destination.bson),
+                      new_key.c_str(),
+                      (int)new_key.size(),
+                      bson_iter_value(&it));
+    return true;
 }
-const bool DataPack::isDataPack(const std::string& key) const {
-    return root_json_object[key].isObject();
+
+void DataPack::copyAllTo(DataPack& destination) {
+    bson_iter_t it;
+    bson_iter_init(&it, ACCESS_BSON(bson));
+    while (bson_iter_next(&it)) {
+        bson_append_value(ACCESS_BSON(destination.bson),
+                          bson_iter_key(&it),
+                          -1,
+                          bson_iter_value(&it));
+    }
 }
-DataPackUniquePtr DataPack::getDataPack(const std::string& key) const {
-    return DataPackUniquePtr(new DataPack(root_json_object[key]));
+
+//reset the datawrapper
+void DataPack::reset() {
+    bson_reinit(ACCESS_BSON(bson));
+    bson_tmp_array.reset();
 }
 
-void DataPack::addBinary(const std::string& key,
-                         const char *s,
-                         const unsigned int len) {
-    root_json_object[key] = Value(base64_encode(reinterpret_cast<const unsigned char*>(s), len));
+std::string DataPack::toHash() const{
+    char ret[33];
+    bson_md5_t m;
+    uint8_t digest[16];
+    bson_md5_init(&m);
+    bson_md5_append(&m,
+                    bson_get_data(ACCESS_BSON(bson)),
+                    bson->len);
+    bson_md5_finish(&m,
+                    digest);
+    memset(ret, 0, 33);
+    for(int i = 0; i < 16; ++i) {
+        sprintf(&ret[i*2], "%02x", (unsigned int)digest[i]);
+    }
+    return std::string(ret, 33);
 }
-std::string DataPack::getBinary(const std::string& key) {
-    return base64_decode(root_json_object[key].asString());
+
+//------------------------checking utility
+
+bool DataPack::isNullValue(const std::string& key) const{
+    FIND_AND_CHECK(key, BSON_ITER_HOLDS_NULL){
+        return true;
+    }
+    return false;
 }
 
-void DataPack::createArrayForKey(const std::string& key) {
-    root_json_object[key] = Value(arrayValue);
+bool DataPack::isBoolValue(const std::string& key) const{
+    FIND_AND_CHECK(key, BSON_ITER_HOLDS_BOOL){
+        return true;
+    }
+    return false;
 }
-const bool DataPack::isArray(const std::string& key) const {
-    return root_json_object[key].isArray();
+
+bool DataPack::isInt32Value(const std::string& key) const{
+    FIND_AND_CHECK(key, BSON_ITER_HOLDS_INT32){
+        return true;
+    }
+    return false;
 }
-void DataPack::appendBool(const std::string& arr_key,
-                          bool value) {
-    root_json_object[arr_key].append(Value(value));
+
+bool DataPack::isInt64Value(const std::string& key) const{
+    FIND_AND_CHECK(key, BSON_ITER_HOLDS_INT64){
+        return true;
+    }
+    return false;
 }
 
-void DataPack::appendInt32(const std::string& arr_key,
-                           int32_t value) {
-    root_json_object[arr_key].append(Value(value));
+bool DataPack::isDoubleValue(const std::string& key) const{
+    FIND_AND_CHECK(key, BSON_ITER_HOLDS_DOUBLE){
+        return true;
+    }
+    return false;
 }
 
-void DataPack::appendInt64(const std::string& arr_key,
-                           int64_t value) {
-    root_json_object[arr_key].append(Value(value));
+bool DataPack::isStringValue(const std::string& key) const{
+    FIND_AND_CHECK(key, BSON_ITER_HOLDS_UTF8){
+        return true;
+    }
+    return false;
 }
 
-void DataPack::appendDouble(const std::string& arr_key,
-                            double value) {
-    root_json_object[arr_key].append(Value(value));
+bool DataPack::isBinaryValue(const std::string& key) const{
+    FIND_AND_CHECK(key, BSON_ITER_HOLDS_BINARY){
+        return true;
+    }
+    return false;
 }
 
-void DataPack::appendString(const std::string& arr_key,
-                            const std::string& value) {
-    root_json_object[arr_key].append(Value(value));
+bool DataPack::isCDWValue(const std::string& key) const{
+    FIND_AND_CHECK(key, BSON_ITER_HOLDS_DOCUMENT){
+        return true;
+    }
+    return false;
 }
 
-void DataPack::appendDataPack(const std::string& arr_key, DataPack& value) {
-    root_json_object[arr_key].append(value.root_json_object);
+bool DataPack::isVectorValue(const std::string& key) const{
+    FIND_AND_CHECK(key, BSON_ITER_HOLDS_ARRAY){
+        return true;
+    }
+    return false;
 }
 
-std::string DataPack::toString() {
-    StyledWriter w;
-    return w.write(root_json_object);
+DataPackType DataPack::getValueType(const std::string& key) const{
+    DataPackType result = DataPackTypeNoType;
+    bson_iter_t it;
+    bson_iter_init(&it, ACCESS_BSON(bson));
+    if(bson_iter_find_case(&it, key.c_str()) == false) return result;
+    switch(bson_iter_type(&it)) {
+        case BSON_TYPE_ARRAY:
+            result = DataPackTypeVector;
+            break;
+        case BSON_TYPE_DOCUMENT:
+            result = DataPackTypeObject;
+            break;
+        case BSON_TYPE_BINARY:
+            result = DataPackTypeBinary;
+            break;
+        case BSON_TYPE_UTF8:
+            result = DataPackTypeString;
+            break;
+        case BSON_TYPE_DOUBLE:
+            result = DataPackTypeDouble;
+            break;
+        case BSON_TYPE_INT32:
+            result = DataPackTypeInt32;
+            break;
+        case BSON_TYPE_INT64:
+            result = DataPackTypeInt64;
+            break;
+        case BSON_TYPE_BOOL:
+            result = DataPackTypeBool;
+            break;
+        case BSON_TYPE_NULL:
+            result = DataPackTypeNULL;
+            break;
+        default:
+            break;
+            
+    }
+    return result;
 }
 
-std::string DataPack::toUnformattedString() {
-    FastWriter w;
-    return w.write(root_json_object);
+bool DataPack::isEmpty() const {
+    return (bson_count_keys(ACCESS_BSON(bson)) == 0);
+}
+
+#pragma mark CMultiTypeDataArrayWrapper
+CMultiTypeDataArrayWrapper::CMultiTypeDataArrayWrapper(const ChaosBsonShrdPtr& _document_shrd_ptr,
+                                                       const std::string& key):
+document_shrd_ptr(_document_shrd_ptr) {
+    bson_iter_t element_found;
+    bson_iter_init(&element_found, ACCESS_BSON(_document_shrd_ptr));
+    if(bson_iter_find_case(&element_found, key.c_str())&&
+       BSON_ITER_HOLDS_ARRAY(&element_found)) {
+        uint32_t array_len;
+        const uint8_t *array;
+        bson_iter_array(&element_found,
+                        &array_len,
+                        &array);
+        
+        if (bson_init_static(&array_doc, array, array_len)) {
+            bson_iter_t iter;
+            if(bson_iter_init(&iter, &array_doc)) {
+                while(bson_iter_next(&iter)) {
+                    bson_value_t copy;
+                    bson_value_copy(bson_iter_value(&iter), &copy);
+                    values.push_back(copy);
+                }
+            }
+        }
+    }
+}
+
+CMultiTypeDataArrayWrapper::~CMultiTypeDataArrayWrapper() {
+    for(VectorBsonValuesIterator it = values.begin(),
+        end = values.end();
+        it != end;
+        it++) {
+        bson_value_destroy(&(*it));
+    }
+}
+
+std::string CMultiTypeDataArrayWrapper::getStringElementAtIndex(const int pos) const{
+    assert(values[pos].value_type == BSON_TYPE_UTF8);
+    return std::string(values[pos].value.v_utf8.str, values[pos].value.v_utf8.len);
+}
+
+double CMultiTypeDataArrayWrapper::getDoubleElementAtIndex(const int pos) const{
+    assert(values[pos].value_type == BSON_TYPE_DOUBLE);
+    return values[pos].value.v_double;
+}
+int32_t CMultiTypeDataArrayWrapper::getInt32ElementAtIndex(const int pos) const{
+    return values[pos].value.v_int32;
+}
+int64_t CMultiTypeDataArrayWrapper::getint64ElementAtIndex(const int pos) const{
+    assert(values[pos].value_type == BSON_TYPE_INT64);
+    return values[pos].value.v_int64;
+}
+
+bool CMultiTypeDataArrayWrapper::isStringElementAtIndex(const int pos) const{
+    return values[pos].value_type == BSON_TYPE_UTF8;
+}
+
+bool CMultiTypeDataArrayWrapper::isDoubleElementAtIndex(const int pos) const{
+    return values[pos].value_type == BSON_TYPE_DOUBLE;
+}
+
+bool CMultiTypeDataArrayWrapper::isInt32ElementAtIndex(const int pos) const{
+    return values[pos].value_type == BSON_TYPE_INT32;
+}
+
+bool CMultiTypeDataArrayWrapper::isInt64ElementAtIndex(const int pos) const{
+    return values[pos].value_type == BSON_TYPE_INT64;
+}
+
+bool CMultiTypeDataArrayWrapper::isDataPackElementAtIndex(const int pos) const{
+    return values[pos].value_type == BSON_TYPE_DOCUMENT;
+}
+
+DataPack* CMultiTypeDataArrayWrapper::getDataPackElementAtIndex(const int pos) const{
+    assert(values[pos].value_type == BSON_TYPE_DOCUMENT);
+    return new DataPack((const char *)values[pos].value.v_doc.data, values[pos].value.v_doc.data_len);
+}
+size_t CMultiTypeDataArrayWrapper::size() const{
+    return values.size();
 }
diff --git a/chaos_micro_unit_toolkit/data/DataPack.h b/chaos_micro_unit_toolkit/data/DataPack.h
index 8dbaa1a01d262043b2933a303b567610f9a86b3c..4d38fcc0111800d9b8ad83584b535b4cc7de428f 100644
--- a/chaos_micro_unit_toolkit/data/DataPack.h
+++ b/chaos_micro_unit_toolkit/data/DataPack.h
@@ -1,108 +1,285 @@
 /*
- * Copyright 2012, 2017 INFN
+ *	DataPack.h
+ *	!CHAOS
+ *	Created by Bisegni Claudio.
  *
- * Licensed under the EUPL, Version 1.2 or – as soon they
- * will be approved by the European Commission - subsequent
- * versions of the EUPL (the "Licence");
- * You may not use this work except in compliance with the
- * Licence.
- * You may obtain a copy of the Licence at:
+ *    	Copyright 2012 INFN, National Institute of Nuclear Physics
  *
- * https://joinup.ec.europa.eu/software/page/eupl
+ *    	Licensed under the Apache License, Version 2.0 (the "License");
+ *    	you may not use this file except in compliance with the License.
+ *    	You may obtain a copy of the License at
  *
- * Unless required by applicable law or agreed to in
- * writing, software distributed under the Licence is
- * distributed on an "AS IS" basis,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied.
- * See the Licence for the specific language governing
- * permissions and limitations under the Licence.
+ *    	http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    	Unless required by applicable law or agreed to in writing, software
+ *    	distributed under the License is distributed on an "AS IS" BASIS,
+ *    	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    	See the License for the specific language governing permissions and
+ *    	limitations under the License.
  */
+#ifndef DataPack_H
+#define DataPack_H
 
-#ifndef __CHAOSFramework__FF18E47_E86B_4A8B_B5CA_7EA5C789F2FB_DataPack_h
-#define __CHAOSFramework__FF18E47_E86B_4A8B_B5CA_7EA5C789F2FB_DataPack_h
+#pragma GCC diagnostic ignored "-Wignored-attributes"
 
+#include <chaos_micro_unit_toolkit/external_lib/bson/bson.h>
 #include <chaos_micro_unit_toolkit/micro_unit_toolkit_types.h>
-#include <chaos_micro_unit_toolkit/external_lib/json.h>
 
+#include <set>
+#include <string>
 #include <vector>
-
 namespace chaos {
     namespace micro_unit_toolkit {
         namespace data {
+            
+            typedef enum DataPackType {
+                DataPackTypeNoType,
+                DataPackTypeNULL,
+                DataPackTypeBool,
+                DataPackTypeInt32,
+                DataPackTypeInt64,
+                DataPackTypeDouble,
+                DataPackTypeString,
+                DataPackTypeBinary,
+                DataPackTypeObject,
+                DataPackTypeVector
+            } DataPackType;
+            
             class DataPack;
-            typedef ChaosUniquePtr<DataPack> DataPackUniquePtr;
-            typedef ChaosSharedPtr<DataPack> DataPackSharedPtr;
-            //! main singleton lab entrypoint
+            /*!
+             Class to read the and arry of multivalue
+             */
+            class CMultiTypeDataArrayWrapper;
+            
+            typedef micro_unit_toolkit::ChaosSharedPtr<bson_t> ChaosBsonShrdPtr;
+            typedef micro_unit_toolkit::ChaosUniquePtr<DataPack> CDWUniquePtr;
+            typedef micro_unit_toolkit::ChaosSharedPtr<DataPack> CDWShrdPtr;
+            /*!
+             Class that wrap the serializaiton system for data storage
+             */
             class DataPack {
-                //data pointer is not owned by this object
-                Json::Value root_json_object;
-                DataPack(const Json::Value& src_root_json_object);
+                ChaosBsonShrdPtr bson;
+                
+                int array_index;
+                ChaosBsonShrdPtr bson_tmp_array;
+                DataPack(const bson_t *copy_bson);
+                explicit DataPack(const std::string& json_document);
             public:
+                
                 DataPack();
-                virtual ~DataPack();
-                static DataPackUniquePtr newFromBuffer(const char *data,
-                                                       const size_t data_len,
-                                                       bool *parsed = NULL);
-                
-                bool hasKey(const std::string& key);
-                
-                void addBool(const std::string& key, bool value);
-                const bool isBool(const std::string& key) const;
-                const bool getBool(const std::string& key) const;
-                
-                void addInt32(const std::string& key, int32_t value);
-                const bool isInt32(const std::string& key) const;
-                const int32_t getInt32(const std::string& key) const;
-                
-                void addInt64(const std::string& key, int64_t value);
-                const bool isInt64(const std::string& key) const;
-                const int64_t getInt64(const std::string& key) const;
-                
-                void addDouble(const std::string& key, double value);
-                const bool isDouble(const std::string& key) const;
-                const double getDouble(const std::string& key) const;
-                
-                void addString(const std::string& key, const std::string& value);
-                const bool isString(const std::string& key) const;
-                std::string getString(const std::string& key) const;
-                
-                void addDataPack(const std::string& key, DataPack& value);
-                const bool isDataPack(const std::string& key) const;
-                DataPackUniquePtr getDataPack(const std::string& key) const;
-                
-                void addBinary(const std::string& key,
-                               const char *s,
-                               const unsigned int len);
-                std::string getBinary(const std::string& key);
-                void createArrayForKey(const std::string& key);
-                const bool isArray(const std::string& key) const;
-                void appendBool(const std::string& arr_key, bool value);
-                void appendInt32(const std::string& arr_key, int32_t value);
-                void appendInt64(const std::string& arr_key, int64_t value);
-                void appendDouble(const std::string& arr_key, double value);
-                void appendString(const std::string& arr_key, const std::string& value);
-                void appendDataPack(const std::string& arr_key, DataPack& value);
+                explicit DataPack(const char* mem_ser,
+                                      uint32_t mem_size);
+                
+                explicit DataPack(const char* mem_ser);
+                ~DataPack();
+                
+                static CDWUniquePtr instanceFromJson(const std::string& json_serialization);
+                
+                DataPack *clone();
+                
+                //add a csdata value
+                void addCDWValue(const std::string& key,
+                                 const DataPack& value);
+                CDWUniquePtr getCDWValue(const std::string& key) const;
+                bool isCDWValue(const std::string& key) const;
+                
+                //add a string value
+                //void addStringValue(const char *, const char *);
+                
+                //add a string value
+                void addStringValue(const std::string&, const std::string&);
+                void appendStringToArray(const std::string &value);
+                std::string  getStringValue(const std::string&) const;
+                
+                
+                void appendInt32ToArray(int32_t value);
+                void appendInt64ToArray(int64_t value);
+                void appendDoubleToArray(double value);
+                void appendDataPackToArray(DataPack& value);
+                //finalize the array into a key for the current dataobject
+                void finalizeArrayForKey(const std::string&);
+                
+                //get a string value
+                const char *  getCStringValue(const std::string& key) const;
+                //return a vectorvalue for a key
+                CMultiTypeDataArrayWrapper* getVectorValue(const std::string&) const;
+                
+                void addNullValue(const std::string&);
+                
+                //add a integer value
+                void addInt32Value(const std::string&, int32_t);
+                
+                //add a integer value
+                void addInt32Value(const std::string&, uint32_t);
+                //add a integer value
+                void addInt64Value(const std::string&, int64_t);
+                //add a integer value
+                void addInt64Value(const std::string&, uint64_t);
+                
+                //add a double value
+                void addDoubleValue(const std::string&key, double dValue);
+                
+                //add a bool value
+                void addBoolValue(const std::string&, bool);
+                
+                //set a binary data value
+                void addBinaryValue(const std::string&, const char *, int);
+                const char* getBinaryValue(const std::string& key, uint32_t& bufLen) const;
+                //get a integer value
+                int32_t getInt32Value(const std::string& key,
+                                      int32_t default_value = 0) const;
+                
+                //get a integer value
+                int64_t getInt64Value(const std::string& key,
+                                      int64_t default_value = 0) const;
+                
+                //get a integer value
+                uint32_t getUInt32Value(const std::string& key,
+                                        uint32_t default_value = 0) const;
+                
+                //get a integer value
+                uint64_t getUInt64Value(const std::string& key,
+                                        uint64_t default_value = 0) const;
+                
+                //add a integer value
+                double getDoubleValue(const std::string& key,
+                                      double default_value = 0) const;
+                
+                //get a bool value
+                bool getBoolValue(const std::string&,
+                                  bool default_value = 0) const;
+                
                 
                 template<typename T>
-                void addArray(const std::string& key, const std::vector<T> &value) {
-                    using namespace Json;
-                    root_json_object[key] = Value(arrayValue);
-                    Value& array_value = root_json_object[key];
-                    for(typename std::vector<T>::const_iterator it = value.begin(),
-                        end = value.end();
-                        it != end;
-                        it++) {
-                        array_value.append(*it);
+                T getValue(const std::string& key) const{
+                    T v;
+                    bson_iter_t element_found;
+                    bson_iter_init(&element_found, bson.get());
+                    if(bson_iter_find_case(&element_found, key.c_str())){
+                        v = static_cast<T>(element_found.raw);
                     }
-                    
+                    return v;
                 }
                 
-                std::string toString();
-                std::string toUnformattedString();
+                const char* getBSONRawData() const;
+                
+                const int getBSONRawSize() const;
+                
+                //return the json representation for this data wrapper
+                std::string toString() const;
+                
+                //reinitialize the object with bson data
+                void setSerializedData(const char* bsonData);
+                
+                //reinitialize the object with bson data
+                void setSerializedJsonData(const char* jsonData);
+                
+                //check if the key is present in data wrapper
+                bool hasKey(const std::string& key) const;
+                
+                bool isVector(const std::string& key) const;
+                
+                //return all key contained into the object
+                void getAllKey(std::vector<std::string>& contained_key) const;
+                
+                //return all key contained into the object
+                void getAllKey(std::set<std::string>& contained_key) const;
+                
+                //return all key contained into the object
+                uint32_t getValueSize(const std::string& key) const;
+                
+                //! get raw value ptr address
+                const char * getRawValuePtr(const std::string& key) const;
+                
+                //reset the datawrapper
+                void reset();
+                
+                //append all element of an data wrapper
+                void appendAllElement(DataPack&);
+                
+                //!copy a key(with value) from this instance to another DataPack one
+                bool copyKeyTo(const std::string& key_to_copy,
+                               DataPack& destination);
+                
+                //!copy a key(with value) from this instance to another DataPack witha new key
+                bool copyKeyToNewKey(const std::string& key_to_copy,
+                                     const std::string& new_key,
+                                     DataPack& destination);
+                
+                //!copy all key(with value) from this instance to another DataPack one
+                void copyAllTo(DataPack& destination);
+                
+                //! Return the Hashing represetnation of the DataPack
+                std::string toHash() const;
+                
+                //---checking funciton
+                
+                bool isNullValue(const std::string& key) const;
+                
+                bool isBoolValue(const std::string& key) const;
+                
+                bool isInt32Value(const std::string& key) const;
+                
+                bool isInt64Value(const std::string& key) const;
+                
+                bool isDoubleValue(const std::string& key) const;
+                
+                bool isStringValue(const std::string& key) const;
+                
+                bool isBinaryValue(const std::string& key) const;
+
+                
+                bool isVectorValue(const std::string& key) const;
+                
+                bool isJsonValue(const std::string& key) const;
+                
+                DataPackType getValueType(const std::string& key) const;
+                
+                bool isEmpty() const;
             };
+            
+            typedef std::vector<bson_value_t> VectorBsonValues;
+            typedef std::vector<bson_value_t>::iterator VectorBsonValuesIterator;
+            /*!
+             Class to read the and arry of multivalue
+             */
+            class CMultiTypeDataArrayWrapper {
+                friend class DataPack;
+                const ChaosBsonShrdPtr document_shrd_ptr;
+                bson_t array_doc;
+                VectorBsonValues values;
+                CMultiTypeDataArrayWrapper(const ChaosBsonShrdPtr& _document_shrd_ptr,
+                                           const std::string& key);
+            public:
+                ~CMultiTypeDataArrayWrapper();
+                std::string getStringElementAtIndex(const int) const;
+                
+                
+                double getDoubleElementAtIndex(const int) const;
+                int32_t getInt32ElementAtIndex(const int) const;
+                int64_t getint64ElementAtIndex(const int) const;
+                DataPack* getDataPackElementAtIndex(const int) const;
+                
+                bool isStringElementAtIndex(const int) const;
+                bool isDoubleElementAtIndex(const int) const;
+                bool isInt32ElementAtIndex(const int) const;
+                bool isInt64ElementAtIndex(const int) const;
+                bool isDataPackElementAtIndex(const int) const;
+                
+                size_t size() const;
+            };
+            
+#define CDW_GET_SRT_WITH_DEFAULT(c, k, d) ((c)->hasKey(k)?(c)->getStringValue(k):d)
+#define CDW_GET_BOOL_WITH_DEFAULT(c, k, d) ((c)->hasKey(k)?(c)->getBoolValue(k):d)
+#define CDW_GET_INT32_WITH_DEFAULT(c, k, d) ((c)->hasKey(k)?(c)->getInt32Value(k):d)
+#define CDW_GET_INT64_WITH_DEFAULT(c, k, d) ((c)->hasKey(k)?(c)->getInt64Value(k):d)
+#define CDW_GET_DOUBLE_WITH_DEFAULT(c, k, d) ((c)->hasKey(k)?(c)->getDoubleValue(k):d)
+#define CDW_CHECK_AND_SET(chk, cdw, t, k, v) if(chk){cdw->t(k,v);}
+#define CDW_GET_VALUE_WITH_DEFAULT(c, k, t, d) ((c)->hasKey(k)?(c)->t(k):d)
+            
+
+
         }
     }
 }
-
-#endif /* __CHAOSFramework__FF18E47_E86B_4A8B_B5CA_7EA5C789F2FB_DataPack_h */
+#endif
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson.h b/chaos_micro_unit_toolkit/external_lib/bson/bson.h
new file mode 100644
index 0000000000000000000000000000000000000000..41e8d9490aae439095509feda337fc147c377fa0
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson.h
@@ -0,0 +1,14 @@
+//
+//  bson.h
+//  CHAOSFramework
+//
+//  Created by bisegni on 20/05/2017.
+//  Copyright © 2017 INFN. All rights reserved.
+//
+
+#ifndef bson_h
+#define bson_h
+#include <chaos_micro_unit_toolkit/external_lib/bson/bson/bson-config.h>
+#include <chaos_micro_unit_toolkit/external_lib/bson/bson/bson.h>
+
+#endif /* bson_h */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/b64_ntop.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/b64_ntop.h
new file mode 100644
index 0000000000000000000000000000000000000000..ada76a5c80394de7d347a07c4d68edc74415caad
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/b64_ntop.h
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 1996, 1998 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1995 by International Business Machines, Inc.
+ *
+ * International Business Machines, Inc. (hereinafter called IBM) grants
+ * permission under its copyrights to use, copy, modify, and distribute this
+ * Software with or without fee, provided that the above copyright notice and
+ * all paragraphs of this notice appear in all copies, and that the name of IBM
+ * not be used in connection with the marketing of any product incorporating
+ * the Software or modifications thereof, without specific, written prior
+ * permission.
+ *
+ * To the extent it has a right to do so, IBM grants an immunity from suit
+ * under its patents, if any, for the use, sale or manufacture of products to
+ * the extent that such products are used for performing Domain Name System
+ * dynamic updates in TCP/IP networks by means of the Software.  No immunity is
+ * granted for any product per se or for any other function of any product.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
+ * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
+ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include "bson-compat.h"
+#include "bson-macros.h"
+#include "bson-types.h"
+
+#define Assert(Cond) \
+   if (!(Cond))      \
+   abort ()
+
+static const char Base64[] =
+   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+static const char Pad64 = '=';
+
+/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
+ * The following encoding technique is taken from RFC 1521 by Borenstein
+ * and Freed.  It is reproduced here in a slightly edited form for
+ * convenience.
+ *
+ * A 65-character subset of US-ASCII is used, enabling 6 bits to be
+ * represented per printable character. (The extra 65th character, "=",
+ * is used to signify a special processing function.)
+ *
+ * The encoding process represents 24-bit groups of input bits as output
+ * strings of 4 encoded characters. Proceeding from left to right, a
+ * 24-bit input group is formed by concatenating 3 8-bit input groups.
+ * These 24 bits are then treated as 4 concatenated 6-bit groups, each
+ * of which is translated into a single digit in the base64 alphabet.
+ *
+ * Each 6-bit group is used as an index into an array of 64 printable
+ * characters. The character referenced by the index is placed in the
+ * output string.
+ *
+ *                       Table 1: The Base64 Alphabet
+ *
+ *    Value Encoding  Value Encoding  Value Encoding  Value Encoding
+ *        0 A            17 R            34 i            51 z
+ *        1 B            18 S            35 j            52 0
+ *        2 C            19 T            36 k            53 1
+ *        3 D            20 U            37 l            54 2
+ *        4 E            21 V            38 m            55 3
+ *        5 F            22 W            39 n            56 4
+ *        6 G            23 X            40 o            57 5
+ *        7 H            24 Y            41 p            58 6
+ *        8 I            25 Z            42 q            59 7
+ *        9 J            26 a            43 r            60 8
+ *       10 K            27 b            44 s            61 9
+ *       11 L            28 c            45 t            62 +
+ *       12 M            29 d            46 u            63 /
+ *       13 N            30 e            47 v
+ *       14 O            31 f            48 w         (pad) =
+ *       15 P            32 g            49 x
+ *       16 Q            33 h            50 y
+ *
+ * Special processing is performed if fewer than 24 bits are available
+ * at the end of the data being encoded.  A full encoding quantum is
+ * always completed at the end of a quantity.  When fewer than 24 input
+ * bits are available in an input group, zero bits are added (on the
+ * right) to form an integral number of 6-bit groups.  Padding at the
+ * end of the data is performed using the '=' character.
+ *
+ * Since all base64 input is an integral number of octets, only the
+ * following cases can arise:
+ *
+ *     (1) the final quantum of encoding input is an integral
+ *         multiple of 24 bits; here, the final unit of encoded
+ *    output will be an integral multiple of 4 characters
+ *    with no "=" padding,
+ *     (2) the final quantum of encoding input is exactly 8 bits;
+ *         here, the final unit of encoded output will be two
+ *    characters followed by two "=" padding characters, or
+ *     (3) the final quantum of encoding input is exactly 16 bits;
+ *         here, the final unit of encoded output will be three
+ *    characters followed by one "=" padding character.
+ */
+
+static ssize_t
+b64_ntop (uint8_t const *src, size_t srclength, char *target, size_t targsize)
+{
+   size_t datalength = 0;
+   uint8_t input[3];
+   uint8_t output[4];
+   size_t i;
+
+   while (2 < srclength) {
+      input[0] = *src++;
+      input[1] = *src++;
+      input[2] = *src++;
+      srclength -= 3;
+
+      output[0] = input[0] >> 2;
+      output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
+      output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
+      output[3] = input[2] & 0x3f;
+      Assert (output[0] < 64);
+      Assert (output[1] < 64);
+      Assert (output[2] < 64);
+      Assert (output[3] < 64);
+
+      if (datalength + 4 > targsize) {
+         return -1;
+      }
+      target[datalength++] = Base64[output[0]];
+      target[datalength++] = Base64[output[1]];
+      target[datalength++] = Base64[output[2]];
+      target[datalength++] = Base64[output[3]];
+   }
+
+   /* Now we worry about padding. */
+   if (0 != srclength) {
+      /* Get what's left. */
+      input[0] = input[1] = input[2] = '\0';
+
+      for (i = 0; i < srclength; i++) {
+         input[i] = *src++;
+      }
+      output[0] = input[0] >> 2;
+      output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
+      output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
+      Assert (output[0] < 64);
+      Assert (output[1] < 64);
+      Assert (output[2] < 64);
+
+      if (datalength + 4 > targsize) {
+         return -1;
+      }
+      target[datalength++] = Base64[output[0]];
+      target[datalength++] = Base64[output[1]];
+
+      if (srclength == 1) {
+         target[datalength++] = Pad64;
+      } else {
+         target[datalength++] = Base64[output[2]];
+      }
+      target[datalength++] = Pad64;
+   }
+
+   if (datalength >= targsize) {
+      return -1;
+   }
+   target[datalength] = '\0'; /* Returned value doesn't count \0. */
+   return datalength;
+}
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/b64_pton.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/b64_pton.h
new file mode 100644
index 0000000000000000000000000000000000000000..281df9220cc3c5c1dcdd2326e73acaa15ae018c8
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/b64_pton.h
@@ -0,0 +1,382 @@
+/*
+ * Copyright (c) 1996, 1998 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1995 by International Business Machines, Inc.
+ *
+ * International Business Machines, Inc. (hereinafter called IBM) grants
+ * permission under its copyrights to use, copy, modify, and distribute this
+ * Software with or without fee, provided that the above copyright notice and
+ * all paragraphs of this notice appear in all copies, and that the name of IBM
+ * not be used in connection with the marketing of any product incorporating
+ * the Software or modifications thereof, without specific, written prior
+ * permission.
+ *
+ * To the extent it has a right to do so, IBM grants an immunity from suit
+ * under its patents, if any, for the use, sale or manufacture of products to
+ * the extent that such products are used for performing Domain Name System
+ * dynamic updates in TCP/IP networks by means of the Software.  No immunity is
+ * granted for any product per se or for any other function of any product.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
+ * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
+ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include "bson-compat.h"
+
+#define Assert(Cond) \
+   if (!(Cond))      \
+   abort ()
+
+static const char Base64[] =
+   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+static const char Pad64 = '=';
+
+/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
+   The following encoding technique is taken from RFC 1521 by Borenstein
+   and Freed.  It is reproduced here in a slightly edited form for
+   convenience.
+
+   A 65-character subset of US-ASCII is used, enabling 6 bits to be
+   represented per printable character. (The extra 65th character, "=",
+   is used to signify a special processing function.)
+
+   The encoding process represents 24-bit groups of input bits as output
+   strings of 4 encoded characters. Proceeding from left to right, a
+   24-bit input group is formed by concatenating 3 8-bit input groups.
+   These 24 bits are then treated as 4 concatenated 6-bit groups, each
+   of which is translated into a single digit in the base64 alphabet.
+
+   Each 6-bit group is used as an index into an array of 64 printable
+   characters. The character referenced by the index is placed in the
+   output string.
+
+                         Table 1: The Base64 Alphabet
+
+      Value Encoding  Value Encoding  Value Encoding  Value Encoding
+          0 A            17 R            34 i            51 z
+          1 B            18 S            35 j            52 0
+          2 C            19 T            36 k            53 1
+          3 D            20 U            37 l            54 2
+          4 E            21 V            38 m            55 3
+          5 F            22 W            39 n            56 4
+          6 G            23 X            40 o            57 5
+          7 H            24 Y            41 p            58 6
+          8 I            25 Z            42 q            59 7
+          9 J            26 a            43 r            60 8
+         10 K            27 b            44 s            61 9
+         11 L            28 c            45 t            62 +
+         12 M            29 d            46 u            63 /
+         13 N            30 e            47 v
+         14 O            31 f            48 w         (pad) =
+         15 P            32 g            49 x
+         16 Q            33 h            50 y
+
+   Special processing is performed if fewer than 24 bits are available
+   at the end of the data being encoded.  A full encoding quantum is
+   always completed at the end of a quantity.  When fewer than 24 input
+   bits are available in an input group, zero bits are added (on the
+   right) to form an integral number of 6-bit groups.  Padding at the
+   end of the data is performed using the '=' character.
+
+   Since all base64 input is an integral number of octets, only the
+   following cases can arise:
+
+       (1) the final quantum of encoding input is an integral
+           multiple of 24 bits; here, the final unit of encoded
+      output will be an integral multiple of 4 characters
+      with no "=" padding,
+       (2) the final quantum of encoding input is exactly 8 bits;
+           here, the final unit of encoded output will be two
+      characters followed by two "=" padding characters, or
+       (3) the final quantum of encoding input is exactly 16 bits;
+           here, the final unit of encoded output will be three
+      characters followed by one "=" padding character.
+   */
+
+/* skips all whitespace anywhere.
+   converts characters, four at a time, starting at (or after)
+   src from base - 64 numbers into three 8 bit bytes in the target area.
+   it returns the number of data bytes stored at the target, or -1 on error.
+ */
+
+static int b64rmap_initialized = 0;
+static uint8_t b64rmap[256];
+
+static const uint8_t b64rmap_special = 0xf0;
+static const uint8_t b64rmap_end = 0xfd;
+static const uint8_t b64rmap_space = 0xfe;
+static const uint8_t b64rmap_invalid = 0xff;
+
+/**
+ * Initializing the reverse map is not thread safe.
+ * Which is fine for NSD. For now...
+ **/
+static void
+b64_initialize_rmap ()
+{
+   int i;
+   unsigned char ch;
+
+   /* Null: end of string, stop parsing */
+   b64rmap[0] = b64rmap_end;
+
+   for (i = 1; i < 256; ++i) {
+      ch = (unsigned char) i;
+      /* Whitespaces */
+      if (isspace (ch))
+         b64rmap[i] = b64rmap_space;
+      /* Padding: stop parsing */
+      else if (ch == Pad64)
+         b64rmap[i] = b64rmap_end;
+      /* Non-base64 char */
+      else
+         b64rmap[i] = b64rmap_invalid;
+   }
+
+   /* Fill reverse mapping for base64 chars */
+   for (i = 0; Base64[i] != '\0'; ++i)
+      b64rmap[(uint8_t) Base64[i]] = i;
+
+   b64rmap_initialized = 1;
+}
+
+static int
+b64_pton_do (char const *src, uint8_t *target, size_t targsize)
+{
+   int tarindex, state, ch;
+   uint8_t ofs;
+
+   state = 0;
+   tarindex = 0;
+
+   while (1) {
+      ch = *src++;
+      ofs = b64rmap[ch];
+
+      if (ofs >= b64rmap_special) {
+         /* Ignore whitespaces */
+         if (ofs == b64rmap_space)
+            continue;
+         /* End of base64 characters */
+         if (ofs == b64rmap_end)
+            break;
+         /* A non-base64 character. */
+         return (-1);
+      }
+
+      switch (state) {
+      case 0:
+         if ((size_t) tarindex >= targsize)
+            return (-1);
+         target[tarindex] = ofs << 2;
+         state = 1;
+         break;
+      case 1:
+         if ((size_t) tarindex + 1 >= targsize)
+            return (-1);
+         target[tarindex] |= ofs >> 4;
+         target[tarindex + 1] = (ofs & 0x0f) << 4;
+         tarindex++;
+         state = 2;
+         break;
+      case 2:
+         if ((size_t) tarindex + 1 >= targsize)
+            return (-1);
+         target[tarindex] |= ofs >> 2;
+         target[tarindex + 1] = (ofs & 0x03) << 6;
+         tarindex++;
+         state = 3;
+         break;
+      case 3:
+         if ((size_t) tarindex >= targsize)
+            return (-1);
+         target[tarindex] |= ofs;
+         tarindex++;
+         state = 0;
+         break;
+      default:
+         abort ();
+      }
+   }
+
+   /*
+    * We are done decoding Base-64 chars.  Let's see if we ended
+    * on a byte boundary, and/or with erroneous trailing characters.
+    */
+
+   if (ch == Pad64) { /* We got a pad char. */
+      ch = *src++;    /* Skip it, get next. */
+      switch (state) {
+      case 0: /* Invalid = in first position */
+      case 1: /* Invalid = in second position */
+         return (-1);
+
+      case 2: /* Valid, means one byte of info */
+         /* Skip any number of spaces. */
+         for ((void) NULL; ch != '\0'; ch = *src++)
+            if (b64rmap[ch] != b64rmap_space)
+               break;
+         /* Make sure there is another trailing = sign. */
+         if (ch != Pad64)
+            return (-1);
+         ch = *src++; /* Skip the = */
+                      /* Fall through to "single trailing =" case. */
+                      /* FALLTHROUGH */
+
+      case 3: /* Valid, means two bytes of info */
+         /*
+          * We know this char is an =.  Is there anything but
+          * whitespace after it?
+          */
+         for ((void) NULL; ch != '\0'; ch = *src++)
+            if (b64rmap[ch] != b64rmap_space)
+               return (-1);
+
+         /*
+          * Now make sure for cases 2 and 3 that the "extra"
+          * bits that slopped past the last full byte were
+          * zeros.  If we don't check them, they become a
+          * subliminal channel.
+          */
+         if (target[tarindex] != 0)
+            return (-1);
+      default:
+         break;
+      }
+   } else {
+      /*
+       * We ended by seeing the end of the string.  Make sure we
+       * have no partial bytes lying around.
+       */
+      if (state != 0)
+         return (-1);
+   }
+
+   return (tarindex);
+}
+
+
+static int
+b64_pton_len (char const *src)
+{
+   int tarindex, state, ch;
+   uint8_t ofs;
+
+   state = 0;
+   tarindex = 0;
+
+   while (1) {
+      ch = *src++;
+      ofs = b64rmap[ch];
+
+      if (ofs >= b64rmap_special) {
+         /* Ignore whitespaces */
+         if (ofs == b64rmap_space)
+            continue;
+         /* End of base64 characters */
+         if (ofs == b64rmap_end)
+            break;
+         /* A non-base64 character. */
+         return (-1);
+      }
+
+      switch (state) {
+      case 0:
+         state = 1;
+         break;
+      case 1:
+         tarindex++;
+         state = 2;
+         break;
+      case 2:
+         tarindex++;
+         state = 3;
+         break;
+      case 3:
+         tarindex++;
+         state = 0;
+         break;
+      default:
+         abort ();
+      }
+   }
+
+   /*
+    * We are done decoding Base-64 chars.  Let's see if we ended
+    * on a byte boundary, and/or with erroneous trailing characters.
+    */
+
+   if (ch == Pad64) { /* We got a pad char. */
+      ch = *src++;    /* Skip it, get next. */
+      switch (state) {
+      case 0: /* Invalid = in first position */
+      case 1: /* Invalid = in second position */
+         return (-1);
+
+      case 2: /* Valid, means one byte of info */
+         /* Skip any number of spaces. */
+         for ((void) NULL; ch != '\0'; ch = *src++)
+            if (b64rmap[ch] != b64rmap_space)
+               break;
+         /* Make sure there is another trailing = sign. */
+         if (ch != Pad64)
+            return (-1);
+         ch = *src++; /* Skip the = */
+                      /* Fall through to "single trailing =" case. */
+                      /* FALLTHROUGH */
+
+      case 3: /* Valid, means two bytes of info */
+         /*
+          * We know this char is an =.  Is there anything but
+          * whitespace after it?
+          */
+         for ((void) NULL; ch != '\0'; ch = *src++)
+            if (b64rmap[ch] != b64rmap_space)
+               return (-1);
+
+      default:
+         break;
+      }
+   } else {
+      /*
+       * We ended by seeing the end of the string.  Make sure we
+       * have no partial bytes lying around.
+       */
+      if (state != 0)
+         return (-1);
+   }
+
+   return (tarindex);
+}
+
+
+static int
+b64_pton (char const *src, uint8_t *target, size_t targsize)
+{
+   if (!b64rmap_initialized)
+      b64_initialize_rmap ();
+
+   if (target)
+      return b64_pton_do (src, target, targsize);
+   else
+      return b64_pton_len (src);
+}
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bcon.c b/chaos_micro_unit_toolkit/external_lib/bson/bson/bcon.c
new file mode 100644
index 0000000000000000000000000000000000000000..cab14ed9a568fc56ca08d66a8d55c54551a33df3
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bcon.c
@@ -0,0 +1,1016 @@
+/*
+ * @file bcon.c
+ * @brief BCON (BSON C Object Notation) Implementation
+ */
+
+/*    Copyright 2009-2013 MongoDB, Inc.
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+
+#include <stdio.h>
+
+#include "bcon.h"
+#include "bson-config.h"
+
+/* These stack manipulation macros are used to manage append recursion in
+ * bcon_append_ctx_va().  They take care of some awkward dereference rules (the
+ * real bson object isn't in the stack, but accessed by pointer) and add in run
+ * time asserts to make sure we don't blow the stack in either direction */
+
+#define STACK_ELE(_delta, _name) (ctx->stack[(_delta) + ctx->n]._name)
+
+#define STACK_BSON(_delta) \
+   (((_delta) + ctx->n) == 0 ? bson : &STACK_ELE (_delta, bson))
+
+#define STACK_ITER(_delta) \
+   (((_delta) + ctx->n) == 0 ? &root_iter : &STACK_ELE (_delta, iter))
+
+#define STACK_BSON_PARENT STACK_BSON (-1)
+#define STACK_BSON_CHILD STACK_BSON (0)
+
+#define STACK_ITER_PARENT STACK_ITER (-1)
+#define STACK_ITER_CHILD STACK_ITER (0)
+
+#define STACK_I STACK_ELE (0, i)
+#define STACK_IS_ARRAY STACK_ELE (0, is_array)
+
+#define STACK_PUSH_ARRAY(statement)                \
+   do {                                            \
+      BSON_ASSERT (ctx->n < (BCON_STACK_MAX - 1)); \
+      ctx->n++;                                    \
+      STACK_I = 0;                                 \
+      STACK_IS_ARRAY = 1;                          \
+      statement;                                   \
+   } while (0)
+
+#define STACK_PUSH_DOC(statement)                  \
+   do {                                            \
+      BSON_ASSERT (ctx->n < (BCON_STACK_MAX - 1)); \
+      ctx->n++;                                    \
+      STACK_IS_ARRAY = 0;                          \
+      statement;                                   \
+   } while (0)
+
+#define STACK_POP_ARRAY(statement)  \
+   do {                             \
+      BSON_ASSERT (STACK_IS_ARRAY); \
+      BSON_ASSERT (ctx->n != 0);    \
+      statement;                    \
+      ctx->n--;                     \
+   } while (0)
+
+#define STACK_POP_DOC(statement)     \
+   do {                              \
+      BSON_ASSERT (!STACK_IS_ARRAY); \
+      BSON_ASSERT (ctx->n != 0);     \
+      statement;                     \
+      ctx->n--;                      \
+   } while (0)
+
+/* This is a landing pad union for all of the types we can process with bcon.
+ * We need actual storage for this to capture the return value of va_arg, which
+ * takes multiple calls to get everything we need for some complex types */
+typedef union bcon_append {
+   char *UTF8;
+   double DOUBLE;
+   bson_t *DOCUMENT;
+   bson_t *ARRAY;
+   bson_t *BCON;
+
+   struct {
+      bson_subtype_t subtype;
+      uint8_t *binary;
+      uint32_t length;
+   } BIN;
+
+   bson_oid_t *OID;
+   bool BOOL;
+   int64_t DATE_TIME;
+
+   struct {
+      char *regex;
+      char *flags;
+   } REGEX;
+
+   struct {
+      char *collection;
+      bson_oid_t *oid;
+   } DBPOINTER;
+
+   const char *CODE;
+
+   char *SYMBOL;
+
+   struct {
+      const char *js;
+      bson_t *scope;
+   } CODEWSCOPE;
+
+   int32_t INT32;
+
+   struct {
+      uint32_t timestamp;
+      uint32_t increment;
+   } TIMESTAMP;
+
+   int64_t INT64;
+   bson_decimal128_t *DECIMAL128;
+   const bson_iter_t *ITER;
+} bcon_append_t;
+
+/* same as bcon_append_t.  Some extra symbols and varying types that handle the
+ * differences between bson_append and bson_iter */
+typedef union bcon_extract {
+   bson_type_t TYPE;
+   bson_iter_t *ITER;
+   const char *key;
+   const char **UTF8;
+   double *DOUBLE;
+   bson_t *DOCUMENT;
+   bson_t *ARRAY;
+
+   struct {
+      bson_subtype_t *subtype;
+      const uint8_t **binary;
+      uint32_t *length;
+   } BIN;
+
+   const bson_oid_t **OID;
+   bool *BOOL;
+   int64_t *DATE_TIME;
+
+   struct {
+      const char **regex;
+      const char **flags;
+   } REGEX;
+
+   struct {
+      const char **collection;
+      const bson_oid_t **oid;
+   } DBPOINTER;
+
+   const char **CODE;
+
+   const char **SYMBOL;
+
+   struct {
+      const char **js;
+      bson_t *scope;
+   } CODEWSCOPE;
+
+   int32_t *INT32;
+
+   struct {
+      uint32_t *timestamp;
+      uint32_t *increment;
+   } TIMESTAMP;
+
+   int64_t *INT64;
+   bson_decimal128_t *DECIMAL128;
+} bcon_extract_t;
+
+static const char *gBconMagic = "BCON_MAGIC";
+static const char *gBconeMagic = "BCONE_MAGIC";
+
+const char *
+bson_bcon_magic (void)
+{
+   return gBconMagic;
+}
+
+
+const char *
+bson_bcone_magic (void)
+{
+   return gBconeMagic;
+}
+
+static void
+_noop (void)
+{
+}
+
+/* appends val to the passed bson object.  Meant to be a super simple dispatch
+ * table */
+static void
+_bcon_append_single (bson_t *bson,
+                     bcon_type_t type,
+                     const char *key,
+                     bcon_append_t *val)
+{
+   switch ((int) type) {
+   case BCON_TYPE_UTF8:
+      bson_append_utf8 (bson, key, -1, val->UTF8, -1);
+      break;
+   case BCON_TYPE_DOUBLE:
+      bson_append_double (bson, key, -1, val->DOUBLE);
+      break;
+   case BCON_TYPE_BIN: {
+      bson_append_binary (
+         bson, key, -1, val->BIN.subtype, val->BIN.binary, val->BIN.length);
+      break;
+   }
+   case BCON_TYPE_UNDEFINED:
+      bson_append_undefined (bson, key, -1);
+      break;
+   case BCON_TYPE_OID:
+      bson_append_oid (bson, key, -1, val->OID);
+      break;
+   case BCON_TYPE_BOOL:
+      bson_append_bool (bson, key, -1, (bool) val->BOOL);
+      break;
+   case BCON_TYPE_DATE_TIME:
+      bson_append_date_time (bson, key, -1, val->DATE_TIME);
+      break;
+   case BCON_TYPE_NULL:
+      bson_append_null (bson, key, -1);
+      break;
+   case BCON_TYPE_REGEX: {
+      bson_append_regex (bson, key, -1, val->REGEX.regex, val->REGEX.flags);
+      break;
+   }
+   case BCON_TYPE_DBPOINTER: {
+      bson_append_dbpointer (
+         bson, key, -1, val->DBPOINTER.collection, val->DBPOINTER.oid);
+      break;
+   }
+   case BCON_TYPE_CODE:
+      bson_append_code (bson, key, -1, val->CODE);
+      break;
+   case BCON_TYPE_SYMBOL:
+      bson_append_symbol (bson, key, -1, val->SYMBOL, -1);
+      break;
+   case BCON_TYPE_CODEWSCOPE:
+      bson_append_code_with_scope (
+         bson, key, -1, val->CODEWSCOPE.js, val->CODEWSCOPE.scope);
+      break;
+   case BCON_TYPE_INT32:
+      bson_append_int32 (bson, key, -1, val->INT32);
+      break;
+   case BCON_TYPE_TIMESTAMP: {
+      bson_append_timestamp (
+         bson, key, -1, val->TIMESTAMP.timestamp, val->TIMESTAMP.increment);
+      break;
+   }
+   case BCON_TYPE_INT64:
+      bson_append_int64 (bson, key, -1, val->INT64);
+      break;
+   case BCON_TYPE_DECIMAL128:
+      bson_append_decimal128 (bson, key, -1, val->DECIMAL128);
+      break;
+   case BCON_TYPE_MAXKEY:
+      bson_append_maxkey (bson, key, -1);
+      break;
+   case BCON_TYPE_MINKEY:
+      bson_append_minkey (bson, key, -1);
+      break;
+   case BCON_TYPE_ARRAY: {
+      bson_append_array (bson, key, -1, val->ARRAY);
+      break;
+   }
+   case BCON_TYPE_DOCUMENT: {
+      bson_append_document (bson, key, -1, val->DOCUMENT);
+      break;
+   }
+   case BCON_TYPE_ITER:
+      bson_append_iter (bson, key, -1, val->ITER);
+      break;
+   default:
+      BSON_ASSERT (0);
+      break;
+   }
+}
+
+#define CHECK_TYPE(_type)                     \
+   do {                                       \
+      if (bson_iter_type (iter) != (_type)) { \
+         return false;                        \
+      }                                       \
+   } while (0)
+
+/* extracts the value under the iterator and writes it to val.  returns false
+ * if the iterator type doesn't match the token type.
+ *
+ * There are two magic tokens:
+ *
+ * BCONE_SKIP -
+ *    Let's us verify that a key has a type, without caring about its value.
+ *    This allows for wider declarative BSON verification
+ *
+ * BCONE_ITER -
+ *    Returns the underlying iterator.  This could allow for more complicated,
+ *    procedural verification (if a parameter could have multiple types).
+ * */
+static bool
+_bcon_extract_single (const bson_iter_t *iter,
+                      bcon_type_t type,
+                      bcon_extract_t *val)
+{
+   switch ((int) type) {
+   case BCON_TYPE_UTF8:
+      CHECK_TYPE (BSON_TYPE_UTF8);
+      *val->UTF8 = bson_iter_utf8 (iter, NULL);
+      break;
+   case BCON_TYPE_DOUBLE:
+      CHECK_TYPE (BSON_TYPE_DOUBLE);
+      *val->DOUBLE = bson_iter_double (iter);
+      break;
+   case BCON_TYPE_BIN:
+      CHECK_TYPE (BSON_TYPE_BINARY);
+      bson_iter_binary (
+         iter, val->BIN.subtype, val->BIN.length, val->BIN.binary);
+      break;
+   case BCON_TYPE_UNDEFINED:
+      CHECK_TYPE (BSON_TYPE_UNDEFINED);
+      break;
+   case BCON_TYPE_OID:
+      CHECK_TYPE (BSON_TYPE_OID);
+      *val->OID = bson_iter_oid (iter);
+      break;
+   case BCON_TYPE_BOOL:
+      CHECK_TYPE (BSON_TYPE_BOOL);
+      *val->BOOL = bson_iter_bool (iter);
+      break;
+   case BCON_TYPE_DATE_TIME:
+      CHECK_TYPE (BSON_TYPE_DATE_TIME);
+      *val->DATE_TIME = bson_iter_date_time (iter);
+      break;
+   case BCON_TYPE_NULL:
+      CHECK_TYPE (BSON_TYPE_NULL);
+      break;
+   case BCON_TYPE_REGEX:
+      CHECK_TYPE (BSON_TYPE_REGEX);
+      *val->REGEX.regex = bson_iter_regex (iter, val->REGEX.flags);
+
+      break;
+   case BCON_TYPE_DBPOINTER:
+      CHECK_TYPE (BSON_TYPE_DBPOINTER);
+      bson_iter_dbpointer (
+         iter, NULL, val->DBPOINTER.collection, val->DBPOINTER.oid);
+      break;
+   case BCON_TYPE_CODE:
+      CHECK_TYPE (BSON_TYPE_CODE);
+      *val->CODE = bson_iter_code (iter, NULL);
+      break;
+   case BCON_TYPE_SYMBOL:
+      CHECK_TYPE (BSON_TYPE_SYMBOL);
+      *val->SYMBOL = bson_iter_symbol (iter, NULL);
+      break;
+   case BCON_TYPE_CODEWSCOPE: {
+      const uint8_t *buf;
+      uint32_t len;
+
+      CHECK_TYPE (BSON_TYPE_CODEWSCOPE);
+
+      *val->CODEWSCOPE.js = bson_iter_codewscope (iter, NULL, &len, &buf);
+
+      bson_init_static (val->CODEWSCOPE.scope, buf, len);
+      break;
+   }
+   case BCON_TYPE_INT32:
+      CHECK_TYPE (BSON_TYPE_INT32);
+      *val->INT32 = bson_iter_int32 (iter);
+      break;
+   case BCON_TYPE_TIMESTAMP:
+      CHECK_TYPE (BSON_TYPE_TIMESTAMP);
+      bson_iter_timestamp (
+         iter, val->TIMESTAMP.timestamp, val->TIMESTAMP.increment);
+      break;
+   case BCON_TYPE_INT64:
+      CHECK_TYPE (BSON_TYPE_INT64);
+      *val->INT64 = bson_iter_int64 (iter);
+      break;
+   case BCON_TYPE_DECIMAL128:
+      CHECK_TYPE (BSON_TYPE_DECIMAL128);
+      bson_iter_decimal128 (iter, val->DECIMAL128);
+      break;
+   case BCON_TYPE_MAXKEY:
+      CHECK_TYPE (BSON_TYPE_MAXKEY);
+      break;
+   case BCON_TYPE_MINKEY:
+      CHECK_TYPE (BSON_TYPE_MINKEY);
+      break;
+   case BCON_TYPE_ARRAY: {
+      const uint8_t *buf;
+      uint32_t len;
+
+      CHECK_TYPE (BSON_TYPE_ARRAY);
+
+      bson_iter_array (iter, &len, &buf);
+
+      bson_init_static (val->ARRAY, buf, len);
+      break;
+   }
+   case BCON_TYPE_DOCUMENT: {
+      const uint8_t *buf;
+      uint32_t len;
+
+      CHECK_TYPE (BSON_TYPE_DOCUMENT);
+
+      bson_iter_document (iter, &len, &buf);
+
+      bson_init_static (val->DOCUMENT, buf, len);
+      break;
+   }
+   case BCON_TYPE_SKIP:
+      CHECK_TYPE (val->TYPE);
+      break;
+   case BCON_TYPE_ITER:
+      memcpy (val->ITER, iter, sizeof *iter);
+      break;
+   default:
+      BSON_ASSERT (0);
+      break;
+   }
+
+   return true;
+}
+
+/* Consumes ap, storing output values into u and returning the type of the
+ * captured token.
+ *
+ * The basic workflow goes like this:
+ *
+ * 1. Look at the current arg.  It will be a char *
+ *    a. If it's a NULL, we're done processing.
+ *    b. If it's BCON_MAGIC (a symbol with storage in this module)
+ *       I. The next token is the type
+ *       II. The type specifies how many args to eat and their types
+ *    c. Otherwise it's either recursion related or a raw string
+ *       I. If the first byte is '{', '}', '[', or ']' pass back an
+ *          appropriate recursion token
+ *       II. If not, just call it a UTF8 token and pass that back
+ */
+static bcon_type_t
+_bcon_append_tokenize (va_list *ap, bcon_append_t *u)
+{
+   char *mark;
+   bcon_type_t type;
+
+   mark = va_arg (*ap, char *);
+
+   BSON_ASSERT (mark != BCONE_MAGIC);
+
+   if (mark == NULL) {
+      type = BCON_TYPE_END;
+   } else if (mark == BCON_MAGIC) {
+      type = va_arg (*ap, bcon_type_t);
+
+      switch ((int) type) {
+      case BCON_TYPE_UTF8:
+         u->UTF8 = va_arg (*ap, char *);
+         break;
+      case BCON_TYPE_DOUBLE:
+         u->DOUBLE = va_arg (*ap, double);
+         break;
+      case BCON_TYPE_DOCUMENT:
+         u->DOCUMENT = va_arg (*ap, bson_t *);
+         break;
+      case BCON_TYPE_ARRAY:
+         u->ARRAY = va_arg (*ap, bson_t *);
+         break;
+      case BCON_TYPE_BIN:
+         u->BIN.subtype = va_arg (*ap, bson_subtype_t);
+         u->BIN.binary = va_arg (*ap, uint8_t *);
+         u->BIN.length = va_arg (*ap, uint32_t);
+         break;
+      case BCON_TYPE_UNDEFINED:
+         break;
+      case BCON_TYPE_OID:
+         u->OID = va_arg (*ap, bson_oid_t *);
+         break;
+      case BCON_TYPE_BOOL:
+         u->BOOL = va_arg (*ap, int);
+         break;
+      case BCON_TYPE_DATE_TIME:
+         u->DATE_TIME = va_arg (*ap, int64_t);
+         break;
+      case BCON_TYPE_NULL:
+         break;
+      case BCON_TYPE_REGEX:
+         u->REGEX.regex = va_arg (*ap, char *);
+         u->REGEX.flags = va_arg (*ap, char *);
+         break;
+      case BCON_TYPE_DBPOINTER:
+         u->DBPOINTER.collection = va_arg (*ap, char *);
+         u->DBPOINTER.oid = va_arg (*ap, bson_oid_t *);
+         break;
+      case BCON_TYPE_CODE:
+         u->CODE = va_arg (*ap, char *);
+         break;
+      case BCON_TYPE_SYMBOL:
+         u->SYMBOL = va_arg (*ap, char *);
+         break;
+      case BCON_TYPE_CODEWSCOPE:
+         u->CODEWSCOPE.js = va_arg (*ap, char *);
+         u->CODEWSCOPE.scope = va_arg (*ap, bson_t *);
+         break;
+      case BCON_TYPE_INT32:
+         u->INT32 = va_arg (*ap, int32_t);
+         break;
+      case BCON_TYPE_TIMESTAMP:
+         u->TIMESTAMP.timestamp = va_arg (*ap, uint32_t);
+         u->TIMESTAMP.increment = va_arg (*ap, uint32_t);
+         break;
+      case BCON_TYPE_INT64:
+         u->INT64 = va_arg (*ap, int64_t);
+         break;
+      case BCON_TYPE_DECIMAL128:
+         u->DECIMAL128 = va_arg (*ap, bson_decimal128_t *);
+         break;
+      case BCON_TYPE_MAXKEY:
+         break;
+      case BCON_TYPE_MINKEY:
+         break;
+      case BCON_TYPE_BCON:
+         u->BCON = va_arg (*ap, bson_t *);
+         break;
+      case BCON_TYPE_ITER:
+         u->ITER = va_arg (*ap, const bson_iter_t *);
+         break;
+      default:
+         BSON_ASSERT (0);
+         break;
+      }
+   } else {
+      switch (mark[0]) {
+      case '{':
+         type = BCON_TYPE_DOC_START;
+         break;
+      case '}':
+         type = BCON_TYPE_DOC_END;
+         break;
+      case '[':
+         type = BCON_TYPE_ARRAY_START;
+         break;
+      case ']':
+         type = BCON_TYPE_ARRAY_END;
+         break;
+
+      default:
+         type = BCON_TYPE_UTF8;
+         u->UTF8 = mark;
+         break;
+      }
+   }
+
+   return type;
+}
+
+
+/* Consumes ap, storing output values into u and returning the type of the
+ * captured token.
+ *
+ * The basic workflow goes like this:
+ *
+ * 1. Look at the current arg.  It will be a char *
+ *    a. If it's a NULL, we're done processing.
+ *    b. If it's BCONE_MAGIC (a symbol with storage in this module)
+ *       I. The next token is the type
+ *       II. The type specifies how many args to eat and their types
+ *    c. Otherwise it's either recursion related or a raw string
+ *       I. If the first byte is '{', '}', '[', or ']' pass back an
+ *          appropriate recursion token
+ *       II. If not, just call it a UTF8 token and pass that back
+ */
+static bcon_type_t
+_bcon_extract_tokenize (va_list *ap, bcon_extract_t *u)
+{
+   char *mark;
+   bcon_type_t type;
+
+   mark = va_arg (*ap, char *);
+
+   BSON_ASSERT (mark != BCON_MAGIC);
+
+   if (mark == NULL) {
+      type = BCON_TYPE_END;
+   } else if (mark == BCONE_MAGIC) {
+      type = va_arg (*ap, bcon_type_t);
+
+      switch ((int) type) {
+      case BCON_TYPE_UTF8:
+         u->UTF8 = va_arg (*ap, const char **);
+         break;
+      case BCON_TYPE_DOUBLE:
+         u->DOUBLE = va_arg (*ap, double *);
+         break;
+      case BCON_TYPE_DOCUMENT:
+         u->DOCUMENT = va_arg (*ap, bson_t *);
+         break;
+      case BCON_TYPE_ARRAY:
+         u->ARRAY = va_arg (*ap, bson_t *);
+         break;
+      case BCON_TYPE_BIN:
+         u->BIN.subtype = va_arg (*ap, bson_subtype_t *);
+         u->BIN.binary = va_arg (*ap, const uint8_t **);
+         u->BIN.length = va_arg (*ap, uint32_t *);
+         break;
+      case BCON_TYPE_UNDEFINED:
+         break;
+      case BCON_TYPE_OID:
+         u->OID = va_arg (*ap, const bson_oid_t **);
+         break;
+      case BCON_TYPE_BOOL:
+         u->BOOL = va_arg (*ap, bool *);
+         break;
+      case BCON_TYPE_DATE_TIME:
+         u->DATE_TIME = va_arg (*ap, int64_t *);
+         break;
+      case BCON_TYPE_NULL:
+         break;
+      case BCON_TYPE_REGEX:
+         u->REGEX.regex = va_arg (*ap, const char **);
+         u->REGEX.flags = va_arg (*ap, const char **);
+         break;
+      case BCON_TYPE_DBPOINTER:
+         u->DBPOINTER.collection = va_arg (*ap, const char **);
+         u->DBPOINTER.oid = va_arg (*ap, const bson_oid_t **);
+         break;
+      case BCON_TYPE_CODE:
+         u->CODE = va_arg (*ap, const char **);
+         break;
+      case BCON_TYPE_SYMBOL:
+         u->SYMBOL = va_arg (*ap, const char **);
+         break;
+      case BCON_TYPE_CODEWSCOPE:
+         u->CODEWSCOPE.js = va_arg (*ap, const char **);
+         u->CODEWSCOPE.scope = va_arg (*ap, bson_t *);
+         break;
+      case BCON_TYPE_INT32:
+         u->INT32 = va_arg (*ap, int32_t *);
+         break;
+      case BCON_TYPE_TIMESTAMP:
+         u->TIMESTAMP.timestamp = va_arg (*ap, uint32_t *);
+         u->TIMESTAMP.increment = va_arg (*ap, uint32_t *);
+         break;
+      case BCON_TYPE_INT64:
+         u->INT64 = va_arg (*ap, int64_t *);
+         break;
+      case BCON_TYPE_DECIMAL128:
+         u->DECIMAL128 = va_arg (*ap, bson_decimal128_t *);
+         break;
+      case BCON_TYPE_MAXKEY:
+         break;
+      case BCON_TYPE_MINKEY:
+         break;
+      case BCON_TYPE_SKIP:
+         u->TYPE = va_arg (*ap, bson_type_t);
+         break;
+      case BCON_TYPE_ITER:
+         u->ITER = va_arg (*ap, bson_iter_t *);
+         break;
+      default:
+         BSON_ASSERT (0);
+         break;
+      }
+   } else {
+      switch (mark[0]) {
+      case '{':
+         type = BCON_TYPE_DOC_START;
+         break;
+      case '}':
+         type = BCON_TYPE_DOC_END;
+         break;
+      case '[':
+         type = BCON_TYPE_ARRAY_START;
+         break;
+      case ']':
+         type = BCON_TYPE_ARRAY_END;
+         break;
+
+      default:
+         type = BCON_TYPE_RAW;
+         u->key = mark;
+         break;
+      }
+   }
+
+   return type;
+}
+
+
+/* This trivial utility function is useful for concatenating a bson object onto
+ * the end of another, ignoring the keys from the source bson object and
+ * continuing to use and increment the keys from the source.  It's only useful
+ * when called from bcon_append_ctx_va */
+static void
+_bson_concat_array (bson_t *dest, const bson_t *src, bcon_append_ctx_t *ctx)
+{
+   bson_iter_t iter;
+   const char *key;
+   char i_str[16];
+   bool r;
+
+   r = bson_iter_init (&iter, src);
+
+   if (!r) {
+      fprintf (stderr, "Invalid BSON document, possible memory coruption.\n");
+      return;
+   }
+
+   STACK_I--;
+
+   while (bson_iter_next (&iter)) {
+      bson_uint32_to_string (STACK_I, &key, i_str, sizeof i_str);
+      STACK_I++;
+
+      bson_append_iter (dest, key, -1, &iter);
+   }
+}
+
+
+/* Append_ctx_va consumes the va_list until NULL is found, appending into bson
+ * as tokens are found.  It can receive or return an in-progress bson object
+ * via the ctx param.  It can also operate on the middle of a va_list, and so
+ * can be wrapped inside of another varargs function.
+ *
+ * Note that passing in a va_list that isn't perferectly formatted for BCON
+ * ingestion will almost certainly result in undefined behavior
+ *
+ * The workflow relies on the passed ctx object, which holds a stack of bson
+ * objects, along with metadata (if the emedded layer is an array, and which
+ * element it is on if so).  We iterate, generating tokens from the va_list,
+ * until we reach an END token.  If any errors occur, we just blow up (the
+ * var_args stuff is already incredibly fragile to mistakes, and we have no way
+ * of introspecting, so just don't screw it up).
+ *
+ * There are also a few STACK_* macros in here which manimpulate ctx that are
+ * defined up top.
+ * */
+void
+bcon_append_ctx_va (bson_t *bson, bcon_append_ctx_t *ctx, va_list *ap)
+{
+   bcon_type_t type;
+   const char *key;
+   char i_str[16];
+
+   bcon_append_t u = {0};
+
+   while (1) {
+      if (STACK_IS_ARRAY) {
+         bson_uint32_to_string (STACK_I, &key, i_str, sizeof i_str);
+         STACK_I++;
+      } else {
+         type = _bcon_append_tokenize (ap, &u);
+
+         if (type == BCON_TYPE_END) {
+            return;
+         }
+
+         if (type == BCON_TYPE_DOC_END) {
+            STACK_POP_DOC (
+               bson_append_document_end (STACK_BSON_PARENT, STACK_BSON_CHILD));
+            continue;
+         }
+
+         if (type == BCON_TYPE_BCON) {
+            bson_concat (STACK_BSON_CHILD, u.BCON);
+            continue;
+         }
+
+         BSON_ASSERT (type == BCON_TYPE_UTF8);
+
+         key = u.UTF8;
+      }
+
+      type = _bcon_append_tokenize (ap, &u);
+      BSON_ASSERT (type != BCON_TYPE_END);
+
+      switch ((int) type) {
+      case BCON_TYPE_BCON:
+         BSON_ASSERT (STACK_IS_ARRAY);
+         _bson_concat_array (STACK_BSON_CHILD, u.BCON, ctx);
+
+         break;
+      case BCON_TYPE_DOC_START:
+         STACK_PUSH_DOC (bson_append_document_begin (
+            STACK_BSON_PARENT, key, -1, STACK_BSON_CHILD));
+         break;
+      case BCON_TYPE_DOC_END:
+         STACK_POP_DOC (
+            bson_append_document_end (STACK_BSON_PARENT, STACK_BSON_CHILD));
+         break;
+      case BCON_TYPE_ARRAY_START:
+         STACK_PUSH_ARRAY (bson_append_array_begin (
+            STACK_BSON_PARENT, key, -1, STACK_BSON_CHILD));
+         break;
+      case BCON_TYPE_ARRAY_END:
+         STACK_POP_ARRAY (
+            bson_append_array_end (STACK_BSON_PARENT, STACK_BSON_CHILD));
+         break;
+      default:
+         _bcon_append_single (STACK_BSON_CHILD, type, key, &u);
+
+         break;
+      }
+   }
+}
+
+
+/* extract_ctx_va consumes the va_list until NULL is found, extracting values
+ * as tokens are found.  It can receive or return an in-progress bson object
+ * via the ctx param.  It can also operate on the middle of a va_list, and so
+ * can be wrapped inside of another varargs function.
+ *
+ * Note that passing in a va_list that isn't perferectly formatted for BCON
+ * ingestion will almost certainly result in undefined behavior
+ *
+ * The workflow relies on the passed ctx object, which holds a stack of iterator
+ * objects, along with metadata (if the emedded layer is an array, and which
+ * element it is on if so).  We iterate, generating tokens from the va_list,
+ * until we reach an END token.  If any errors occur, we just blow up (the
+ * var_args stuff is already incredibly fragile to mistakes, and we have no way
+ * of introspecting, so just don't screw it up).
+ *
+ * There are also a few STACK_* macros in here which manimpulate ctx that are
+ * defined up top.
+ *
+ * The function returns true if all tokens could be successfully matched, false
+ * otherwise.
+ * */
+bool
+bcon_extract_ctx_va (bson_t *bson, bcon_extract_ctx_t *ctx, va_list *ap)
+{
+   bcon_type_t type;
+   const char *key;
+   bson_iter_t root_iter;
+   bson_iter_t current_iter;
+   char i_str[16];
+
+   bcon_extract_t u = {0};
+
+   bson_iter_init (&root_iter, bson);
+
+   while (1) {
+      if (STACK_IS_ARRAY) {
+         bson_uint32_to_string (STACK_I, &key, i_str, sizeof i_str);
+         STACK_I++;
+      } else {
+         type = _bcon_extract_tokenize (ap, &u);
+
+         if (type == BCON_TYPE_END) {
+            return true;
+         }
+
+         if (type == BCON_TYPE_DOC_END) {
+            STACK_POP_DOC (_noop ());
+            continue;
+         }
+
+         BSON_ASSERT (type == BCON_TYPE_RAW);
+
+         key = u.key;
+      }
+
+      type = _bcon_extract_tokenize (ap, &u);
+      BSON_ASSERT (type != BCON_TYPE_END);
+
+      if (type == BCON_TYPE_DOC_END) {
+         STACK_POP_DOC (_noop ());
+      } else if (type == BCON_TYPE_ARRAY_END) {
+         STACK_POP_ARRAY (_noop ());
+      } else {
+         memcpy (&current_iter, STACK_ITER_CHILD, sizeof current_iter);
+
+         if (!bson_iter_find (&current_iter, key)) {
+            return false;
+         }
+
+         switch ((int) type) {
+         case BCON_TYPE_DOC_START:
+
+            if (bson_iter_type (&current_iter) != BSON_TYPE_DOCUMENT) {
+               return false;
+            }
+
+            STACK_PUSH_DOC (
+               bson_iter_recurse (&current_iter, STACK_ITER_CHILD));
+            break;
+         case BCON_TYPE_ARRAY_START:
+
+            if (bson_iter_type (&current_iter) != BSON_TYPE_ARRAY) {
+               return false;
+            }
+
+            STACK_PUSH_ARRAY (
+               bson_iter_recurse (&current_iter, STACK_ITER_CHILD));
+            break;
+         default:
+
+            if (!_bcon_extract_single (&current_iter, type, &u)) {
+               return false;
+            }
+
+            break;
+         }
+      }
+   }
+}
+
+void
+bcon_extract_ctx_init (bcon_extract_ctx_t *ctx)
+{
+   ctx->n = 0;
+   ctx->stack[0].is_array = false;
+}
+
+bool
+bcon_extract (bson_t *bson, ...)
+{
+   va_list ap;
+   bcon_extract_ctx_t ctx;
+   bool r;
+
+   bcon_extract_ctx_init (&ctx);
+
+   va_start (ap, bson);
+
+   r = bcon_extract_ctx_va (bson, &ctx, &ap);
+
+   va_end (ap);
+
+   return r;
+}
+
+
+void
+bcon_append (bson_t *bson, ...)
+{
+   va_list ap;
+   bcon_append_ctx_t ctx;
+
+   bcon_append_ctx_init (&ctx);
+
+   va_start (ap, bson);
+
+   bcon_append_ctx_va (bson, &ctx, &ap);
+
+   va_end (ap);
+}
+
+
+void
+bcon_append_ctx (bson_t *bson, bcon_append_ctx_t *ctx, ...)
+{
+   va_list ap;
+
+   va_start (ap, ctx);
+
+   bcon_append_ctx_va (bson, ctx, &ap);
+
+   va_end (ap);
+}
+
+
+void
+bcon_extract_ctx (bson_t *bson, bcon_extract_ctx_t *ctx, ...)
+{
+   va_list ap;
+
+   va_start (ap, ctx);
+
+   bcon_extract_ctx_va (bson, ctx, &ap);
+
+   va_end (ap);
+}
+
+void
+bcon_append_ctx_init (bcon_append_ctx_t *ctx)
+{
+   ctx->n = 0;
+   ctx->stack[0].is_array = 0;
+}
+
+
+bson_t *
+bcon_new (void *unused, ...)
+{
+   va_list ap;
+   bcon_append_ctx_t ctx;
+   bson_t *bson;
+
+   bcon_append_ctx_init (&ctx);
+
+   bson = bson_new ();
+
+   va_start (ap, unused);
+
+   bcon_append_ctx_va (bson, &ctx, &ap);
+
+   va_end (ap);
+
+   return bson;
+}
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bcon.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bcon.h
new file mode 100644
index 0000000000000000000000000000000000000000..e8c08de6c15e9fb43aa14e34d6990c74878066ac
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bcon.h
@@ -0,0 +1,293 @@
+/*
+ * @file bcon.h
+ * @brief BCON (BSON C Object Notation) Declarations
+ */
+
+/*    Copyright 2009-2013 MongoDB, Inc.
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#ifndef BCON_H_
+#define BCON_H_
+
+#include "bson.h"
+
+
+BSON_BEGIN_DECLS
+
+
+#define BCON_STACK_MAX 100
+
+#define BCON_ENSURE_DECLARE(fun, type)                 \
+   static BSON_INLINE type bcon_ensure_##fun (type _t) \
+   {                                                   \
+      return _t;                                       \
+   }
+
+#define BCON_ENSURE(fun, val) bcon_ensure_##fun (val)
+
+#define BCON_ENSURE_STORAGE(fun, val) bcon_ensure_##fun (&(val))
+
+BCON_ENSURE_DECLARE (const_char_ptr, const char *)
+BCON_ENSURE_DECLARE (const_char_ptr_ptr, const char **)
+BCON_ENSURE_DECLARE (double, double)
+BCON_ENSURE_DECLARE (double_ptr, double *)
+BCON_ENSURE_DECLARE (const_bson_ptr, const bson_t *)
+BCON_ENSURE_DECLARE (bson_ptr, bson_t *)
+BCON_ENSURE_DECLARE (subtype, bson_subtype_t)
+BCON_ENSURE_DECLARE (subtype_ptr, bson_subtype_t *)
+BCON_ENSURE_DECLARE (const_uint8_ptr, const uint8_t *)
+BCON_ENSURE_DECLARE (const_uint8_ptr_ptr, const uint8_t **)
+BCON_ENSURE_DECLARE (uint32, uint32_t)
+BCON_ENSURE_DECLARE (uint32_ptr, uint32_t *)
+BCON_ENSURE_DECLARE (const_oid_ptr, const bson_oid_t *)
+BCON_ENSURE_DECLARE (const_oid_ptr_ptr, const bson_oid_t **)
+BCON_ENSURE_DECLARE (int32, int32_t)
+BCON_ENSURE_DECLARE (int32_ptr, int32_t *)
+BCON_ENSURE_DECLARE (int64, int64_t)
+BCON_ENSURE_DECLARE (int64_ptr, int64_t *)
+BCON_ENSURE_DECLARE (const_decimal128_ptr, const bson_decimal128_t *)
+BCON_ENSURE_DECLARE (bool, bool)
+BCON_ENSURE_DECLARE (bool_ptr, bool *)
+BCON_ENSURE_DECLARE (bson_type, bson_type_t)
+BCON_ENSURE_DECLARE (bson_iter_ptr, bson_iter_t *)
+BCON_ENSURE_DECLARE (const_bson_iter_ptr, const bson_iter_t *)
+
+#define BCON_UTF8(_val) \
+   BCON_MAGIC, BCON_TYPE_UTF8, BCON_ENSURE (const_char_ptr, (_val))
+#define BCON_DOUBLE(_val) \
+   BCON_MAGIC, BCON_TYPE_DOUBLE, BCON_ENSURE (double, (_val))
+#define BCON_DOCUMENT(_val) \
+   BCON_MAGIC, BCON_TYPE_DOCUMENT, BCON_ENSURE (const_bson_ptr, (_val))
+#define BCON_ARRAY(_val) \
+   BCON_MAGIC, BCON_TYPE_ARRAY, BCON_ENSURE (const_bson_ptr, (_val))
+#define BCON_BIN(_subtype, _binary, _length)                     \
+   BCON_MAGIC, BCON_TYPE_BIN, BCON_ENSURE (subtype, (_subtype)), \
+      BCON_ENSURE (const_uint8_ptr, (_binary)),                  \
+      BCON_ENSURE (uint32, (_length))
+#define BCON_UNDEFINED BCON_MAGIC, BCON_TYPE_UNDEFINED
+#define BCON_OID(_val) \
+   BCON_MAGIC, BCON_TYPE_OID, BCON_ENSURE (const_oid_ptr, (_val))
+#define BCON_BOOL(_val) BCON_MAGIC, BCON_TYPE_BOOL, BCON_ENSURE (bool, (_val))
+#define BCON_DATE_TIME(_val) \
+   BCON_MAGIC, BCON_TYPE_DATE_TIME, BCON_ENSURE (int64, (_val))
+#define BCON_NULL BCON_MAGIC, BCON_TYPE_NULL
+#define BCON_REGEX(_regex, _flags)                                      \
+   BCON_MAGIC, BCON_TYPE_REGEX, BCON_ENSURE (const_char_ptr, (_regex)), \
+      BCON_ENSURE (const_char_ptr, (_flags))
+#define BCON_DBPOINTER(_collection, _oid)          \
+   BCON_MAGIC, BCON_TYPE_DBPOINTER,                \
+      BCON_ENSURE (const_char_ptr, (_collection)), \
+      BCON_ENSURE (const_oid_ptr, (_oid))
+#define BCON_CODE(_val) \
+   BCON_MAGIC, BCON_TYPE_CODE, BCON_ENSURE (const_char_ptr, (_val))
+#define BCON_SYMBOL(_val) \
+   BCON_MAGIC, BCON_TYPE_SYMBOL, BCON_ENSURE (const_char_ptr, (_val))
+#define BCON_CODEWSCOPE(_js, _scope)                                      \
+   BCON_MAGIC, BCON_TYPE_CODEWSCOPE, BCON_ENSURE (const_char_ptr, (_js)), \
+      BCON_ENSURE (const_bson_ptr, (_scope))
+#define BCON_INT32(_val) \
+   BCON_MAGIC, BCON_TYPE_INT32, BCON_ENSURE (int32, (_val))
+#define BCON_TIMESTAMP(_timestamp, _increment)                         \
+   BCON_MAGIC, BCON_TYPE_TIMESTAMP, BCON_ENSURE (int32, (_timestamp)), \
+      BCON_ENSURE (int32, (_increment))
+#define BCON_INT64(_val) \
+   BCON_MAGIC, BCON_TYPE_INT64, BCON_ENSURE (int64, (_val))
+#define BCON_DECIMAL128(_val) \
+   BCON_MAGIC, BCON_TYPE_DECIMAL128, BCON_ENSURE (const_decimal128_ptr, (_val))
+#define BCON_MAXKEY BCON_MAGIC, BCON_TYPE_MAXKEY
+#define BCON_MINKEY BCON_MAGIC, BCON_TYPE_MINKEY
+#define BCON(_val) \
+   BCON_MAGIC, BCON_TYPE_BCON, BCON_ENSURE (const_bson_ptr, (_val))
+#define BCON_ITER(_val) \
+   BCON_MAGIC, BCON_TYPE_ITER, BCON_ENSURE (const_bson_iter_ptr, (_val))
+
+#define BCONE_UTF8(_val) \
+   BCONE_MAGIC, BCON_TYPE_UTF8, BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_val))
+#define BCONE_DOUBLE(_val) \
+   BCONE_MAGIC, BCON_TYPE_DOUBLE, BCON_ENSURE_STORAGE (double_ptr, (_val))
+#define BCONE_DOCUMENT(_val) \
+   BCONE_MAGIC, BCON_TYPE_DOCUMENT, BCON_ENSURE_STORAGE (bson_ptr, (_val))
+#define BCONE_ARRAY(_val) \
+   BCONE_MAGIC, BCON_TYPE_ARRAY, BCON_ENSURE_STORAGE (bson_ptr, (_val))
+#define BCONE_BIN(subtype, binary, length)                                   \
+   BCONE_MAGIC, BCON_TYPE_BIN, BCON_ENSURE_STORAGE (subtype_ptr, (subtype)), \
+      BCON_ENSURE_STORAGE (const_uint8_ptr_ptr, (binary)),                   \
+      BCON_ENSURE_STORAGE (uint32_ptr, (length))
+#define BCONE_UNDEFINED BCONE_MAGIC, BCON_TYPE_UNDEFINED
+#define BCONE_OID(_val) \
+   BCONE_MAGIC, BCON_TYPE_OID, BCON_ENSURE_STORAGE (const_oid_ptr_ptr, (_val))
+#define BCONE_BOOL(_val) \
+   BCONE_MAGIC, BCON_TYPE_BOOL, BCON_ENSURE_STORAGE (bool_ptr, (_val))
+#define BCONE_DATE_TIME(_val) \
+   BCONE_MAGIC, BCON_TYPE_DATE_TIME, BCON_ENSURE_STORAGE (int64_ptr, (_val))
+#define BCONE_NULL BCONE_MAGIC, BCON_TYPE_NULL
+#define BCONE_REGEX(_regex, _flags)                       \
+   BCONE_MAGIC, BCON_TYPE_REGEX,                          \
+      BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_regex)), \
+      BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_flags))
+#define BCONE_DBPOINTER(_collection, _oid)                     \
+   BCONE_MAGIC, BCON_TYPE_DBPOINTER,                           \
+      BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_collection)), \
+      BCON_ENSURE_STORAGE (const_oid_ptr_ptr, (_oid))
+#define BCONE_CODE(_val) \
+   BCONE_MAGIC, BCON_TYPE_CODE, BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_val))
+#define BCONE_SYMBOL(_val)        \
+   BCONE_MAGIC, BCON_TYPE_SYMBOL, \
+      BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_val))
+#define BCONE_CODEWSCOPE(_js, _scope)                  \
+   BCONE_MAGIC, BCON_TYPE_CODEWSCOPE,                  \
+      BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_js)), \
+      BCON_ENSURE_STORAGE (bson_ptr, (_scope))
+#define BCONE_INT32(_val) \
+   BCONE_MAGIC, BCON_TYPE_INT32, BCON_ENSURE_STORAGE (int32_ptr, (_val))
+#define BCONE_TIMESTAMP(_timestamp, _increment)      \
+   BCONE_MAGIC, BCON_TYPE_TIMESTAMP,                 \
+      BCON_ENSURE_STORAGE (int32_ptr, (_timestamp)), \
+      BCON_ENSURE_STORAGE (int32_ptr, (_increment))
+#define BCONE_INT64(_val) \
+   BCONE_MAGIC, BCON_TYPE_INT64, BCON_ENSURE_STORAGE (int64_ptr, (_val))
+#define BCONE_DECIMAL128(_val)        \
+   BCONE_MAGIC, BCON_TYPE_DECIMAL128, \
+      BCON_ENSURE_STORAGE (const_decimal128_ptr, (_val))
+#define BCONE_MAXKEY BCONE_MAGIC, BCON_TYPE_MAXKEY
+#define BCONE_MINKEY BCONE_MAGIC, BCON_TYPE_MINKEY
+#define BCONE_SKIP(_val) \
+   BCONE_MAGIC, BCON_TYPE_SKIP, BCON_ENSURE (bson_type, (_val))
+#define BCONE_ITER(_val) \
+   BCONE_MAGIC, BCON_TYPE_ITER, BCON_ENSURE_STORAGE (bson_iter_ptr, (_val))
+
+#define BCON_MAGIC bson_bcon_magic ()
+#define BCONE_MAGIC bson_bcone_magic ()
+
+typedef enum {
+   BCON_TYPE_UTF8,
+   BCON_TYPE_DOUBLE,
+   BCON_TYPE_DOCUMENT,
+   BCON_TYPE_ARRAY,
+   BCON_TYPE_BIN,
+   BCON_TYPE_UNDEFINED,
+   BCON_TYPE_OID,
+   BCON_TYPE_BOOL,
+   BCON_TYPE_DATE_TIME,
+   BCON_TYPE_NULL,
+   BCON_TYPE_REGEX,
+   BCON_TYPE_DBPOINTER,
+   BCON_TYPE_CODE,
+   BCON_TYPE_SYMBOL,
+   BCON_TYPE_CODEWSCOPE,
+   BCON_TYPE_INT32,
+   BCON_TYPE_TIMESTAMP,
+   BCON_TYPE_INT64,
+   BCON_TYPE_DECIMAL128,
+   BCON_TYPE_MAXKEY,
+   BCON_TYPE_MINKEY,
+   BCON_TYPE_BCON,
+   BCON_TYPE_ARRAY_START,
+   BCON_TYPE_ARRAY_END,
+   BCON_TYPE_DOC_START,
+   BCON_TYPE_DOC_END,
+   BCON_TYPE_END,
+   BCON_TYPE_RAW,
+   BCON_TYPE_SKIP,
+   BCON_TYPE_ITER,
+   BCON_TYPE_ERROR,
+} bcon_type_t;
+
+typedef struct bcon_append_ctx_frame {
+   int i;
+   bool is_array;
+   bson_t bson;
+} bcon_append_ctx_frame_t;
+
+typedef struct bcon_extract_ctx_frame {
+   int i;
+   bool is_array;
+   bson_iter_t iter;
+} bcon_extract_ctx_frame_t;
+
+typedef struct _bcon_append_ctx_t {
+   bcon_append_ctx_frame_t stack[BCON_STACK_MAX];
+   int n;
+} bcon_append_ctx_t;
+
+typedef struct _bcon_extract_ctx_t {
+   bcon_extract_ctx_frame_t stack[BCON_STACK_MAX];
+   int n;
+} bcon_extract_ctx_t;
+
+BSON_EXPORT (void)
+bcon_append (bson_t *bson, ...) BSON_GNUC_NULL_TERMINATED;
+BSON_EXPORT (void)
+bcon_append_ctx (bson_t *bson,
+                 bcon_append_ctx_t *ctx,
+                 ...) BSON_GNUC_NULL_TERMINATED;
+BSON_EXPORT (void)
+bcon_append_ctx_va (bson_t *bson, bcon_append_ctx_t *ctx, va_list *va);
+BSON_EXPORT (void)
+bcon_append_ctx_init (bcon_append_ctx_t *ctx);
+
+BSON_EXPORT (void)
+bcon_extract_ctx_init (bcon_extract_ctx_t *ctx);
+
+BSON_EXPORT (void)
+bcon_extract_ctx (bson_t *bson,
+                  bcon_extract_ctx_t *ctx,
+                  ...) BSON_GNUC_NULL_TERMINATED;
+
+BSON_EXPORT (bool)
+bcon_extract_ctx_va (bson_t *bson, bcon_extract_ctx_t *ctx, va_list *ap);
+
+BSON_EXPORT (bool)
+bcon_extract (bson_t *bson, ...) BSON_GNUC_NULL_TERMINATED;
+
+BSON_EXPORT (bool)
+bcon_extract_va (bson_t *bson,
+                 bcon_extract_ctx_t *ctx,
+                 ...) BSON_GNUC_NULL_TERMINATED;
+
+BSON_EXPORT (bson_t *)
+bcon_new (void *unused, ...) BSON_GNUC_NULL_TERMINATED;
+
+/**
+ * The bcon_..() functions are all declared with __attribute__((sentinel)).
+ *
+ * From GCC manual for "sentinel": "A valid NULL in this context is defined as
+ * zero with any pointer type. If your system defines the NULL macro with an
+ * integer type then you need to add an explicit cast."
+ * Case in point: GCC on Solaris (at least)
+ */
+#define BCON_APPEND(_bson, ...) \
+   bcon_append ((_bson), __VA_ARGS__, (void *) NULL)
+#define BCON_APPEND_CTX(_bson, _ctx, ...) \
+   bcon_append_ctx ((_bson), (_ctx), __VA_ARGS__, (void *) NULL)
+
+#define BCON_EXTRACT(_bson, ...) \
+   bcon_extract ((_bson), __VA_ARGS__, (void *) NULL)
+
+#define BCON_EXTRACT_CTX(_bson, _ctx, ...) \
+   bcon_extract ((_bson), (_ctx), __VA_ARGS__, (void *) NULL)
+
+#define BCON_NEW(...) bcon_new (NULL, __VA_ARGS__, (void *) NULL)
+
+BSON_EXPORT (const char *)
+bson_bcon_magic (void) BSON_GNUC_CONST;
+BSON_EXPORT (const char *)
+bson_bcone_magic (void) BSON_GNUC_CONST;
+
+
+BSON_END_DECLS
+
+
+#endif
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-atomic.c b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-atomic.c
new file mode 100644
index 0000000000000000000000000000000000000000..2c8bfdaaa43e75d6c2e930202bf6e3d470ebaacf
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-atomic.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2014 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include "bson-atomic.h"
+
+
+/*
+ * We should only ever hit these on non-Windows systems, for which we require
+ * pthread support. Therefore, we will avoid making a threading portability
+ * for threads here and just use pthreads directly.
+ */
+
+
+#ifdef __BSON_NEED_BARRIER
+#include <pthread.h>
+static pthread_mutex_t gBarrier = PTHREAD_MUTEX_INITIALIZER;
+void
+bson_memory_barrier (void)
+{
+   pthread_mutex_lock (&gBarrier);
+   pthread_mutex_unlock (&gBarrier);
+}
+#endif
+
+
+#ifdef __BSON_NEED_ATOMIC_32
+#include <pthread.h>
+static pthread_mutex_t gSync32 = PTHREAD_MUTEX_INITIALIZER;
+int32_t
+bson_atomic_int_add (volatile int32_t *p, int32_t n)
+{
+   int ret;
+
+   pthread_mutex_lock (&gSync32);
+   *p += n;
+   ret = *p;
+   pthread_mutex_unlock (&gSync32);
+
+   return ret;
+}
+#endif
+
+
+#ifdef __BSON_NEED_ATOMIC_64
+#include <pthread.h>
+static pthread_mutex_t gSync64 = PTHREAD_MUTEX_INITIALIZER;
+int64_t
+bson_atomic_int64_add (volatile int64_t *p, int64_t n)
+{
+   int64_t ret;
+
+   pthread_mutex_lock (&gSync64);
+   *p += n;
+   ret = *p;
+   pthread_mutex_unlock (&gSync64);
+
+   return ret;
+}
+#endif
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-atomic.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-atomic.h
new file mode 100644
index 0000000000000000000000000000000000000000..2ee6f2bd287ce3158b0ee9483a929fda0538c459
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-atomic.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2013-2014 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef BSON_ATOMIC_H
+#define BSON_ATOMIC_H
+
+
+#include "bson-config.h"
+#include "bson-compat.h"
+#include "bson-macros.h"
+
+
+BSON_BEGIN_DECLS
+
+
+#if defined(__sun) && defined(__SVR4)
+/* Solaris */
+#include <atomic.h>
+#define bson_atomic_int_add(p, v) \
+   atomic_add_32_nv ((volatile uint32_t *) p, (v))
+#define bson_atomic_int64_add(p, v) \
+   atomic_add_64_nv ((volatile uint64_t *) p, (v))
+#elif defined(_WIN32)
+/* MSVC/MinGW */
+#define bson_atomic_int_add(p, v) \
+   (InterlockedExchangeAdd ((volatile LONG *) (p), (LONG) (v)) + (LONG) (v))
+#define bson_atomic_int64_add(p, v)                                        \
+   (InterlockedExchangeAdd64 ((volatile LONGLONG *) (p), (LONGLONG) (v)) + \
+    (LONGLONG) (v))
+#else
+#ifdef BSON_HAVE_ATOMIC_32_ADD_AND_FETCH
+#define bson_atomic_int_add(p, v) __sync_add_and_fetch ((p), (v))
+#else
+#define __BSON_NEED_ATOMIC_32
+#endif
+#ifdef BSON_HAVE_ATOMIC_64_ADD_AND_FETCH
+#if BSON_GNUC_IS_VERSION(4, 1)
+/*
+ * GCC 4.1 on i386 can generate buggy 64-bit atomic increment.
+ * So we will work around with a fallback.
+ *
+ * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=40693
+ */
+#define __BSON_NEED_ATOMIC_64
+#else
+#define bson_atomic_int64_add(p, v) \
+   __sync_add_and_fetch ((volatile int64_t *) (p), (int64_t) (v))
+#endif
+#else
+#define __BSON_NEED_ATOMIC_64
+#endif
+#endif
+
+#ifdef __BSON_NEED_ATOMIC_32
+BSON_EXPORT (int32_t)
+bson_atomic_int_add (volatile int32_t *p, int32_t n);
+#endif
+#ifdef __BSON_NEED_ATOMIC_64
+BSON_EXPORT (int64_t)
+bson_atomic_int64_add (volatile int64_t *p, int64_t n);
+#endif
+
+
+#if defined(_WIN32)
+#define bson_memory_barrier() MemoryBarrier ()
+#elif defined(__GNUC__)
+#if BSON_GNUC_CHECK_VERSION(4, 1)
+#define bson_memory_barrier() __sync_synchronize ()
+#else
+#warning "GCC Pre-4.1 discovered, using inline assembly for memory barrier."
+#define bson_memory_barrier() __asm__ volatile("" ::: "memory")
+#endif
+#elif defined(__SUNPRO_C)
+#include <mbarrier.h>
+#define bson_memory_barrier() __machine_rw_barrier ()
+#elif defined(__xlC__)
+#define bson_memory_barrier() __sync ()
+#else
+#define __BSON_NEED_BARRIER 1
+#warning "Unknown compiler, using lock for compiler barrier."
+BSON_EXPORT (void)
+bson_memory_barrier (void);
+#endif
+
+
+BSON_END_DECLS
+
+
+#endif /* BSON_ATOMIC_H */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-clock.c b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-clock.c
new file mode 100644
index 0000000000000000000000000000000000000000..5260eb1820b2a7ca15ff54fb14abc3206f948438
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-clock.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifdef __APPLE__
+#include <mach/clock.h>
+#include <mach/mach.h>
+#include <mach/mach_time.h>
+#include <sys/time.h>
+#endif
+
+
+#include "bson-config.h"
+#include "bson-compat.h"
+
+
+#if defined(BSON_HAVE_CLOCK_GETTIME)
+#include <time.h>
+#include <sys/time.h>
+#endif
+
+#include "bson-clock.h"
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_gettimeofday --
+ *
+ *       A wrapper around gettimeofday() with fallback support for Windows.
+ *
+ * Returns:
+ *       0 if successful.
+ *
+ * Side effects:
+ *       @tv is set.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+int
+bson_gettimeofday (struct timeval *tv) /* OUT */
+{
+#if defined(_WIN32)
+#if defined(_MSC_VER)
+#define DELTA_EPOCH_IN_MICROSEC 11644473600000000Ui64
+#else
+#define DELTA_EPOCH_IN_MICROSEC 11644473600000000ULL
+#endif
+   FILETIME ft;
+   uint64_t tmp = 0;
+
+   /*
+    * The const value is shamelessy stolen from
+    * http://www.boost.org/doc/libs/1_55_0/boost/chrono/detail/inlined/win/chrono.hpp
+    *
+    * File times are the number of 100 nanosecond intervals elapsed since
+    * 12:00 am Jan 1, 1601 UTC.  I haven't check the math particularly hard
+    *
+    * ...  good luck
+    */
+
+   if (tv) {
+      GetSystemTimeAsFileTime (&ft);
+
+      /* pull out of the filetime into a 64 bit uint */
+      tmp |= ft.dwHighDateTime;
+      tmp <<= 32;
+      tmp |= ft.dwLowDateTime;
+
+      /* convert from 100's of nanosecs to microsecs */
+      tmp /= 10;
+
+      /* adjust to unix epoch */
+      tmp -= DELTA_EPOCH_IN_MICROSEC;
+
+      tv->tv_sec = (long) (tmp / 1000000UL);
+      tv->tv_usec = (long) (tmp % 1000000UL);
+   }
+
+   return 0;
+#else
+   return gettimeofday (tv, NULL);
+#endif
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_get_monotonic_time --
+ *
+ *       Returns the monotonic system time, if available. A best effort is
+ *       made to use the monotonic clock. However, some systems may not
+ *       support such a feature.
+ *
+ * Returns:
+ *       The monotonic clock in microseconds.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+int64_t
+bson_get_monotonic_time (void)
+{
+#if defined(BSON_HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
+   struct timespec ts;
+   clock_gettime (CLOCK_MONOTONIC, &ts);
+   return ((ts.tv_sec * 1000000UL) + (ts.tv_nsec / 1000UL));
+#elif defined(__APPLE__)
+   static mach_timebase_info_data_t info = {0};
+   static double ratio = 0.0;
+
+   if (!info.denom) {
+      /* the value from mach_absolute_time () * info.numer / info.denom
+       * is in nano seconds. So we have to divid by 1000.0 to get micro
+       * seconds*/
+      mach_timebase_info (&info);
+      ratio = (double) info.numer / (double) info.denom / 1000.0;
+   }
+
+   return mach_absolute_time () * ratio;
+#elif defined(_WIN32)
+   /* Despite it's name, this is in milliseconds! */
+   int64_t ticks = GetTickCount64 ();
+   return (ticks * 1000L);
+#elif defined(__hpux__)
+   int64_t nanosec = gethrtime ();
+   return (nanosec / 1000UL);
+#else
+#warning "Monotonic clock is not yet supported on your platform."
+   struct timeval tv;
+
+   bson_gettimeofday (&tv);
+   return (tv.tv_sec * 1000000UL) + tv.tv_usec;
+#endif
+}
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-clock.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-clock.h
new file mode 100644
index 0000000000000000000000000000000000000000..652c14da604e0d6e5302ded6e677623538d28e87
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-clock.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2014 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef BSON_CLOCK_H
+#define BSON_CLOCK_H
+
+
+#if !defined(BSON_INSIDE) && !defined(BSON_COMPILATION)
+#error "Only <bson.h> can be included directly."
+#endif
+
+
+#include "bson-compat.h"
+#include "bson-macros.h"
+#include "bson-types.h"
+
+
+BSON_BEGIN_DECLS
+
+
+BSON_EXPORT (int64_t)
+bson_get_monotonic_time (void);
+BSON_EXPORT (int)
+bson_gettimeofday (struct timeval *tv);
+
+
+BSON_END_DECLS
+
+
+#endif /* BSON_CLOCK_H */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-compat.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-compat.h
new file mode 100644
index 0000000000000000000000000000000000000000..d82dd90afbc83dfd1c889d9a4b432d5f970342a1
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-compat.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef BSON_COMPAT_H
+#define BSON_COMPAT_H
+
+
+#if defined(__MINGW32__)
+#if defined(__USE_MINGW_ANSI_STDIO)
+#if __USE_MINGW_ANSI_STDIO < 1
+#error "__USE_MINGW_ANSI_STDIO > 0 is required for correct PRI* macros"
+#endif
+#else
+#define __USE_MINGW_ANSI_STDIO 1
+#endif
+#endif
+
+#include "bson-config.h"
+#include "bson-macros.h"
+
+
+#ifdef BSON_OS_WIN32
+#if defined(_WIN32_WINNT) && (_WIN32_WINNT < 0x0600)
+#undef _WIN32_WINNT
+#endif
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0600
+#endif
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+#include <winsock2.h>
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+#else
+#include <windows.h>
+#endif
+#include <direct.h>
+#include <io.h>
+#endif
+
+
+#ifdef BSON_OS_UNIX
+#include <unistd.h>
+#include <sys/time.h>
+#endif
+
+
+#include "bson-macros.h"
+
+
+#include <errno.h>
+#include <ctype.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+
+BSON_BEGIN_DECLS
+
+
+#ifdef _MSC_VER
+#include "bson-stdint-win32.h"
+#ifndef __cplusplus
+/* benign redefinition of type */
+#pragma warning(disable : 4142)
+#ifndef _SSIZE_T_DEFINED
+#define _SSIZE_T_DEFINED
+typedef SSIZE_T ssize_t;
+#endif
+#ifndef _SIZE_T_DEFINED
+#define _SIZE_T_DEFINED
+typedef SIZE_T size_t;
+#endif
+#pragma warning(default : 4142)
+#else
+/*
+ * MSVC++ does not include ssize_t, just size_t.
+ * So we need to synthesize that as well.
+ */
+#pragma warning(disable : 4142)
+#ifndef _SSIZE_T_DEFINED
+#define _SSIZE_T_DEFINED
+typedef SSIZE_T ssize_t;
+#endif
+#pragma warning(default : 4142)
+#endif
+#define PRIi32 "d"
+#define PRId32 "d"
+#define PRIu32 "u"
+#define PRIi64 "I64i"
+#define PRId64 "I64i"
+#define PRIu64 "I64u"
+#else
+#include "bson-stdint.h"
+#include <inttypes.h>
+#endif
+
+#if defined(__MINGW32__) && !defined(INIT_ONCE_STATIC_INIT)
+#define INIT_ONCE_STATIC_INIT RTL_RUN_ONCE_INIT
+typedef RTL_RUN_ONCE INIT_ONCE;
+#endif
+
+#ifdef BSON_HAVE_STDBOOL_H
+#include <stdbool.h>
+#elif !defined(__bool_true_false_are_defined)
+#ifndef __cplusplus
+typedef signed char bool;
+#define false 0
+#define true 1
+#endif
+#define __bool_true_false_are_defined 1
+#endif
+
+
+#if defined(__GNUC__)
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
+#define bson_sync_synchronize() __sync_synchronize ()
+#elif defined(__i386__) || defined(__i486__) || defined(__i586__) || \
+   defined(__i686__) || defined(__x86_64__)
+#define bson_sync_synchronize() asm volatile("mfence" ::: "memory")
+#else
+#define bson_sync_synchronize() asm volatile("sync" ::: "memory")
+#endif
+#elif defined(_MSC_VER)
+#define bson_sync_synchronize() MemoryBarrier ()
+#endif
+
+
+#if !defined(va_copy) && defined(__va_copy)
+#define va_copy(dst, src) __va_copy (dst, src)
+#endif
+
+
+#if !defined(va_copy)
+#define va_copy(dst, src) ((dst) = (src))
+#endif
+
+
+BSON_END_DECLS
+
+
+#endif /* BSON_COMPAT_H */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-config.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-config.h
new file mode 100644
index 0000000000000000000000000000000000000000..bbd734675427b93566060208d428402e235b579b
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-config.h
@@ -0,0 +1,128 @@
+#ifndef BSON_CONFIG_H
+#define BSON_CONFIG_H
+
+#include <boost/detail/endian.hpp>
+
+/*
+ * Define to 1234 for Little Endian, 4321 for Big Endian.
+ */
+#if defined(BOOST_LITTLE_ENDIAN)
+#define BSON_BYTE_ORDER 1234
+#elif defined(BOOST_BIG_ENDIAN)
+#define BSON_BYTE_ORDER 4321
+#else
+#error "unable to determine system endianness"
+#endif
+
+#define BSON_INSIDE
+#define BSON_COMPILATION
+
+/*
+ * Define to 1 if you have stdbool.h
+ */
+#define BSON_HAVE_STDBOOL_H 1
+#if BSON_HAVE_STDBOOL_H != 1
+# undef BSON_HAVE_STDBOOL_H
+#endif
+
+
+/*
+ * Define to 1 for POSIX-like systems, 2 for Windows.
+ */
+#define BSON_OS 1
+
+
+/*
+ * Define to 1 if we have access to GCC 32-bit atomic builtins.
+ * While this requires GCC 4.1+ in most cases, it is also architecture
+ * dependent. For example, some PPC or ARM systems may not have it even
+ * if it is a recent GCC version.
+ */
+#define BSON_HAVE_ATOMIC_32_ADD_AND_FETCH 1
+#if BSON_HAVE_ATOMIC_32_ADD_AND_FETCH != 1
+# undef BSON_HAVE_ATOMIC_32_ADD_AND_FETCH
+#endif
+
+/*
+ * Similarly, define to 1 if we have access to GCC 64-bit atomic builtins.
+ */
+#define BSON_HAVE_ATOMIC_64_ADD_AND_FETCH 1
+#if BSON_HAVE_ATOMIC_64_ADD_AND_FETCH != 1
+# undef BSON_HAVE_ATOMIC_64_ADD_AND_FETCH
+#endif
+
+
+/*
+ * Define to 1 if your system requires {} around PTHREAD_ONCE_INIT.
+ * This is typically just Solaris 8-10.
+ */
+#define BSON_PTHREAD_ONCE_INIT_NEEDS_BRACES 0
+#if BSON_PTHREAD_ONCE_INIT_NEEDS_BRACES != 1
+# undef BSON_PTHREAD_ONCE_INIT_NEEDS_BRACES
+#endif
+
+
+/*
+ * Define to 1 if you have clock_gettime() available.
+ */
+#define BSON_HAVE_CLOCK_GETTIME 1
+#if BSON_HAVE_CLOCK_GETTIME != 1
+# undef BSON_HAVE_CLOCK_GETTIME
+#endif
+
+
+/*
+ * Define to 1 if you have strnlen available on your platform.
+ */
+#define BSON_HAVE_STRNLEN 1
+#if BSON_HAVE_STRNLEN != 1
+# undef BSON_HAVE_STRNLEN
+#endif
+
+
+/*
+ * Define to 1 if you have snprintf available on your platform.
+ */
+#define BSON_HAVE_SNPRINTF 1
+#if BSON_HAVE_SNPRINTF != 1
+# undef BSON_HAVE_SNPRINTF
+#endif
+
+
+/*
+ * Define to 1 if you have reallocf available on your platform.
+ */
+#define BSON_HAVE_REALLOCF 0
+#if BSON_HAVE_REALLOCF != 1
+# undef BSON_HAVE_REALLOCF
+#endif
+
+
+/*
+ * Define to 1 if you have struct timespec available on your platform.
+ */
+#define BSON_HAVE_TIMESPEC 1
+#if BSON_HAVE_TIMESPEC != 1
+# undef BSON_HAVE_TIMESPEC
+#endif
+
+
+/*
+ * Define to 1 if you want extra aligned types in libbson
+ */
+#define BSON_EXTRA_ALIGN 1
+#if BSON_EXTRA_ALIGN != 1
+# undef BSON_EXTRA_ALIGN
+#endif
+
+
+/*
+ * Define to 1 if you have SYS_gettid syscall
+ */
+#define BSON_HAVE_SYSCALL_TID 0
+#if BSON_HAVE_SYSCALL_TID != 1
+# undef BSON_HAVE_SYSCALL_TID
+#endif
+
+
+#endif /* BSON_CONFIG_H */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-context-private.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-context-private.h
new file mode 100644
index 0000000000000000000000000000000000000000..26918984d01b4cb369ad7d3b436b759c993416f1
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-context-private.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2014 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef BSON_CONTEXT_PRIVATE_H
+#define BSON_CONTEXT_PRIVATE_H
+
+
+#include "bson-context.h"
+#include "bson-thread-private.h"
+
+
+BSON_BEGIN_DECLS
+
+
+struct _bson_context_t {
+   bson_context_flags_t flags : 7;
+   bool pidbe_once : 1;
+   uint8_t pidbe[2];
+   uint8_t md5[3];
+   int32_t seq32;
+   int64_t seq64;
+
+   void (*oid_get_host) (bson_context_t *context, bson_oid_t *oid);
+   void (*oid_get_pid) (bson_context_t *context, bson_oid_t *oid);
+   void (*oid_get_seq32) (bson_context_t *context, bson_oid_t *oid);
+   void (*oid_get_seq64) (bson_context_t *context, bson_oid_t *oid);
+};
+
+
+BSON_END_DECLS
+
+
+#endif /* BSON_CONTEXT_PRIVATE_H */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-context.c b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-context.c
new file mode 100644
index 0000000000000000000000000000000000000000..763fbc6dfc014ec97eb631c9e802e4c0b74e41a9
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-context.c
@@ -0,0 +1,502 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "bson-compat.h"
+
+#include <limits.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "bson-atomic.h"
+#include "bson-clock.h"
+#include "bson-context.h"
+#include "bson-context-private.h"
+#include "bson-md5.h"
+#include "bson-memory.h"
+#include "bson-thread-private.h"
+
+#ifdef BSON_HAVE_SYSCALL_TID
+#include <sys/syscall.h>
+#endif
+
+
+#ifndef HOST_NAME_MAX
+#define HOST_NAME_MAX 256
+#endif
+
+
+/*
+ * Globals.
+ */
+static bson_context_t gContextDefault;
+
+
+#ifdef BSON_HAVE_SYSCALL_TID
+static uint16_t
+gettid (void)
+{
+   return syscall (SYS_gettid);
+}
+#endif
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_context_get_oid_host --
+ *
+ *       Retrieves the first three bytes of MD5(hostname) and assigns them
+ *       to the host portion of oid.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       @oid is modified.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static void
+_bson_context_get_oid_host (bson_context_t *context, /* IN */
+                            bson_oid_t *oid)         /* OUT */
+{
+   uint8_t *bytes = (uint8_t *) oid;
+   uint8_t digest[16];
+   bson_md5_t md5;
+   char hostname[HOST_NAME_MAX];
+
+   BSON_ASSERT (context);
+   BSON_ASSERT (oid);
+
+   gethostname (hostname, sizeof hostname);
+   hostname[HOST_NAME_MAX - 1] = '\0';
+
+   bson_md5_init (&md5);
+   bson_md5_append (
+      &md5, (const uint8_t *) hostname, (uint32_t) strlen (hostname));
+   bson_md5_finish (&md5, &digest[0]);
+
+   bytes[4] = digest[0];
+   bytes[5] = digest[1];
+   bytes[6] = digest[2];
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_context_get_oid_host_cached --
+ *
+ *       Fetch the cached copy of the MD5(hostname).
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       @oid is modified.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static void
+_bson_context_get_oid_host_cached (bson_context_t *context, /* IN */
+                                   bson_oid_t *oid)         /* OUT */
+{
+   BSON_ASSERT (context);
+   BSON_ASSERT (oid);
+
+   oid->bytes[4] = context->md5[0];
+   oid->bytes[5] = context->md5[1];
+   oid->bytes[6] = context->md5[2];
+}
+
+
+static BSON_INLINE uint16_t
+_bson_getpid (void)
+{
+   uint16_t pid;
+#ifdef BSON_OS_WIN32
+   DWORD real_pid;
+
+   real_pid = GetCurrentProcessId ();
+   pid = (real_pid & 0xFFFF) ^ ((real_pid >> 16) & 0xFFFF);
+#else
+   pid = getpid ();
+#endif
+
+   return pid;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_context_get_oid_pid --
+ *
+ *       Initialize the pid field of @oid.
+ *
+ *       The pid field is 2 bytes, big-endian for memcmp().
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       @oid is modified.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static void
+_bson_context_get_oid_pid (bson_context_t *context, /* IN */
+                           bson_oid_t *oid)         /* OUT */
+{
+   uint16_t pid = _bson_getpid ();
+   uint8_t *bytes = (uint8_t *) &pid;
+
+   BSON_ASSERT (context);
+   BSON_ASSERT (oid);
+
+   pid = BSON_UINT16_TO_BE (pid);
+
+   oid->bytes[7] = bytes[0];
+   oid->bytes[8] = bytes[1];
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_context_get_oid_pid_cached --
+ *
+ *       Fetch the cached copy of the current pid.
+ *       This helps avoid multiple calls to getpid() which is slower
+ *       on some systems.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       @oid is modified.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static void
+_bson_context_get_oid_pid_cached (bson_context_t *context, /* IN */
+                                  bson_oid_t *oid)         /* OUT */
+{
+   oid->bytes[7] = context->pidbe[0];
+   oid->bytes[8] = context->pidbe[1];
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_context_get_oid_seq32 --
+ *
+ *       32-bit sequence generator, non-thread-safe version.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       @oid is modified.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static void
+_bson_context_get_oid_seq32 (bson_context_t *context, /* IN */
+                             bson_oid_t *oid)         /* OUT */
+{
+   uint32_t seq = context->seq32++;
+
+   seq = BSON_UINT32_TO_BE (seq);
+   memcpy (&oid->bytes[9], ((uint8_t *) &seq) + 1, 3);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_context_get_oid_seq32_threadsafe --
+ *
+ *       Thread-safe version of 32-bit sequence generator.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       @oid is modified.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static void
+_bson_context_get_oid_seq32_threadsafe (bson_context_t *context, /* IN */
+                                        bson_oid_t *oid)         /* OUT */
+{
+   int32_t seq = bson_atomic_int_add (&context->seq32, 1);
+
+   seq = BSON_UINT32_TO_BE (seq);
+   memcpy (&oid->bytes[9], ((uint8_t *) &seq) + 1, 3);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_context_get_oid_seq64 --
+ *
+ *       64-bit oid sequence generator, non-thread-safe version.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       @oid is modified.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static void
+_bson_context_get_oid_seq64 (bson_context_t *context, /* IN */
+                             bson_oid_t *oid)         /* OUT */
+{
+   uint64_t seq;
+
+   BSON_ASSERT (context);
+   BSON_ASSERT (oid);
+
+   seq = BSON_UINT64_TO_BE (context->seq64++);
+   memcpy (&oid->bytes[4], &seq, sizeof (seq));
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_context_get_oid_seq64_threadsafe --
+ *
+ *       Thread-safe 64-bit sequence generator.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       @oid is modified.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static void
+_bson_context_get_oid_seq64_threadsafe (bson_context_t *context, /* IN */
+                                        bson_oid_t *oid)         /* OUT */
+{
+   int64_t seq = bson_atomic_int64_add (&context->seq64, 1);
+
+   seq = BSON_UINT64_TO_BE (seq);
+   memcpy (&oid->bytes[4], &seq, sizeof (seq));
+}
+
+
+static void
+_bson_context_init (bson_context_t *context,    /* IN */
+                    bson_context_flags_t flags) /* IN */
+{
+   struct timeval tv;
+   uint16_t pid;
+   unsigned int seed[3];
+   unsigned int real_seed;
+   bson_oid_t oid;
+
+   context->flags = flags;
+   context->oid_get_host = _bson_context_get_oid_host_cached;
+   context->oid_get_pid = _bson_context_get_oid_pid_cached;
+   context->oid_get_seq32 = _bson_context_get_oid_seq32;
+   context->oid_get_seq64 = _bson_context_get_oid_seq64;
+
+   /*
+    * Generate a seed for our the random starting position of our increment
+    * bytes. We mask off the last nibble so that the last digit of the OID will
+    * start at zero. Just to be nice.
+    *
+    * The seed itself is made up of the current time in seconds, milliseconds,
+    * and pid xored together. I welcome better solutions if at all necessary.
+    */
+   bson_gettimeofday (&tv);
+   seed[0] = (unsigned int) tv.tv_sec;
+   seed[1] = (unsigned int) tv.tv_usec;
+   seed[2] = _bson_getpid ();
+   real_seed = seed[0] ^ seed[1] ^ seed[2];
+
+#ifdef BSON_OS_WIN32
+   /* ms's runtime is multithreaded by default, so no rand_r */
+   srand (real_seed);
+   context->seq32 = rand () & 0x007FFFF0;
+#else
+   context->seq32 = rand_r (&real_seed) & 0x007FFFF0;
+#endif
+
+   if ((flags & BSON_CONTEXT_DISABLE_HOST_CACHE)) {
+      context->oid_get_host = _bson_context_get_oid_host;
+   } else {
+      _bson_context_get_oid_host (context, &oid);
+      context->md5[0] = oid.bytes[4];
+      context->md5[1] = oid.bytes[5];
+      context->md5[2] = oid.bytes[6];
+   }
+
+   if ((flags & BSON_CONTEXT_THREAD_SAFE)) {
+      context->oid_get_seq32 = _bson_context_get_oid_seq32_threadsafe;
+      context->oid_get_seq64 = _bson_context_get_oid_seq64_threadsafe;
+   }
+
+   if ((flags & BSON_CONTEXT_DISABLE_PID_CACHE)) {
+      context->oid_get_pid = _bson_context_get_oid_pid;
+   } else {
+#ifdef BSON_HAVE_SYSCALL_TID
+      if ((flags & BSON_CONTEXT_USE_TASK_ID)) {
+         int32_t tid;
+
+         /* This call is always successful */
+         tid = gettid ();
+         pid = BSON_UINT16_TO_BE (tid);
+      } else
+#endif
+      pid = BSON_UINT16_TO_BE (_bson_getpid ());
+
+      memcpy (&context->pidbe[0], &pid, 2);
+   }
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_context_new --
+ *
+ *       Initializes a new context with the flags specified.
+ *
+ *       In most cases, you want to call this with @flags set to
+ *       BSON_CONTEXT_NONE.
+ *
+ *       If you are running on Linux, %BSON_CONTEXT_USE_TASK_ID can result
+ *       in a healthy speedup for multi-threaded scenarios.
+ *
+ *       If you absolutely must have a single context for your application
+ *       and use more than one thread, then %BSON_CONTEXT_THREAD_SAFE should
+ *       be bitwise-or'd with your flags. This requires synchronization
+ *       between threads.
+ *
+ *       If you expect your hostname to change often, you may consider
+ *       specifying %BSON_CONTEXT_DISABLE_HOST_CACHE so that gethostname()
+ *       is called for every OID generated. This is much slower.
+ *
+ *       If you expect your pid to change without notice, such as from an
+ *       unexpected call to fork(), then specify
+ *       %BSON_CONTEXT_DISABLE_PID_CACHE.
+ *
+ * Returns:
+ *       A newly allocated bson_context_t that should be freed with
+ *       bson_context_destroy().
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bson_context_t *
+bson_context_new (bson_context_flags_t flags)
+{
+   bson_context_t *context;
+
+   context = bson_malloc0 (sizeof *context);
+   _bson_context_init (context, flags);
+
+   return context;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_context_destroy --
+ *
+ *       Cleans up a bson_context_t and releases any associated resources.
+ *       This should be called when you are done using @context.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_context_destroy (bson_context_t *context) /* IN */
+{
+   if (context != &gContextDefault) {
+      memset (context, 0, sizeof *context);
+      bson_free (context);
+   }
+}
+
+
+static BSON_ONCE_FUN (_bson_context_init_default)
+{
+   _bson_context_init (
+      &gContextDefault,
+      (BSON_CONTEXT_THREAD_SAFE | BSON_CONTEXT_DISABLE_PID_CACHE));
+   BSON_ONCE_RETURN;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_context_get_default --
+ *
+ *       Fetches the default, thread-safe implementation of #bson_context_t.
+ *       If you need faster generation, it is recommended you create your
+ *       own #bson_context_t with bson_context_new().
+ *
+ * Returns:
+ *       A shared instance to the default #bson_context_t. This should not
+ *       be modified or freed.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bson_context_t *
+bson_context_get_default (void)
+{
+   static bson_once_t once = BSON_ONCE_INIT;
+
+   bson_once (&once, _bson_context_init_default);
+
+   return &gContextDefault;
+}
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-context.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-context.h
new file mode 100644
index 0000000000000000000000000000000000000000..5f1cb40cb4c7409df04d143de480761a6ec5ebd2
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-context.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef BSON_CONTEXT_H
+#define BSON_CONTEXT_H
+
+
+#if !defined(BSON_INSIDE) && !defined(BSON_COMPILATION)
+#error "Only <bson.h> can be included directly."
+#endif
+
+
+#include "bson-macros.h"
+#include "bson-types.h"
+
+
+BSON_BEGIN_DECLS
+
+
+BSON_EXPORT (bson_context_t *)
+bson_context_new (bson_context_flags_t flags);
+BSON_EXPORT (void)
+bson_context_destroy (bson_context_t *context);
+BSON_EXPORT (bson_context_t *)
+bson_context_get_default (void) BSON_GNUC_CONST;
+
+
+BSON_END_DECLS
+
+
+#endif /* BSON_CONTEXT_H */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-decimal128.c b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-decimal128.c
new file mode 100644
index 0000000000000000000000000000000000000000..5f73df694d096857af00a2d359155de157bc555f
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-decimal128.c
@@ -0,0 +1,734 @@
+
+/*
+ * Copyright 2015 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "bson-decimal128.h"
+#include "bson-types.h"
+#include "bson-macros.h"
+#include "bson-string.h"
+
+
+#define BSON_DECIMAL128_EXPONENT_MAX 6111
+#define BSON_DECIMAL128_EXPONENT_MIN -6176
+#define BSON_DECIMAL128_EXPONENT_BIAS 6176
+#define BSON_DECIMAL128_MAX_DIGITS 34
+
+#define BSON_DECIMAL128_SET_NAN(dec)      \
+   do {                                   \
+      (dec).high = 0x7c00000000000000ull; \
+      (dec).low = 0;                      \
+   } while (0);
+#define BSON_DECIMAL128_SET_INF(dec, isneg)                                 \
+   do {                                                                     \
+      (dec).high = 0x7800000000000000ull + 0x8000000000000000ull * (isneg); \
+      (dec).low = 0;                                                        \
+   } while (0);
+
+/**
+ * _bson_uint128_t:
+ *
+ * This struct represents a 128 bit integer.
+ */
+typedef struct {
+   uint32_t parts[4]; /* 32-bit words stored high to low. */
+} _bson_uint128_t;
+
+
+/**
+ *------------------------------------------------------------------------------
+ *
+ * _bson_uint128_divide1B --
+ *
+ *    This function divides a #_bson_uint128_t by 1000000000 (1 billion) and
+ *    computes the quotient and remainder.
+ *
+ *    The remainder will contain 9 decimal digits for conversion to string.
+ *
+ * @value     The #_bson_uint128_t operand.
+ * @quotient  A pointer to store the #_bson_uint128_t quotient.
+ * @rem       A pointer to store the #uint64_t remainder.
+ *
+ * Returns:
+ *    The quotient at @quotient and the remainder at @rem.
+ *
+ * Side effects:
+ *    None.
+ *
+ *------------------------------------------------------------------------------
+ */
+static void
+_bson_uint128_divide1B (_bson_uint128_t value,     /* IN */
+                        _bson_uint128_t *quotient, /* OUT */
+                        uint32_t *rem)             /* OUT */
+{
+   const uint32_t DIVISOR = 1000 * 1000 * 1000;
+   uint64_t _rem = 0;
+   int i = 0;
+
+   if (!value.parts[0] && !value.parts[1] && !value.parts[2] &&
+       !value.parts[3]) {
+      *quotient = value;
+      *rem = 0;
+      return;
+   }
+
+
+   for (i = 0; i <= 3; i++) {
+      _rem <<= 32; /* Adjust remainder to match value of next dividend */
+      _rem += value.parts[i]; /* Add the divided to _rem */
+      value.parts[i] = (uint32_t) (_rem / DIVISOR);
+      _rem %= DIVISOR; /* Store the remainder */
+   }
+
+   *quotient = value;
+   *rem = (uint32_t) _rem;
+}
+
+
+/**
+ *------------------------------------------------------------------------------
+ *
+ * bson_decimal128_to_string --
+ *
+ *    This function converts a BID formatted decimal128 value to string,
+ *    accepting a &bson_decimal128_t as @dec.  The string is stored at @str.
+ *
+ * @dec : The BID formatted decimal to convert.
+ * @str : The output decimal128 string. At least %BSON_DECIMAL128_STRING
+ *characters.
+ *
+ * Returns:
+ *    None.
+ *
+ * Side effects:
+ *    None.
+ *
+ *------------------------------------------------------------------------------
+ */
+void
+bson_decimal128_to_string (const bson_decimal128_t *dec, /* IN  */
+                           char *str)                    /* OUT */
+{
+   uint32_t COMBINATION_MASK = 0x1f;   /* Extract least significant 5 bits */
+   uint32_t EXPONENT_MASK = 0x3fff;    /* Extract least significant 14 bits */
+   uint32_t COMBINATION_INFINITY = 30; /* Value of combination field for Inf */
+   uint32_t COMBINATION_NAN = 31;      /* Value of combination field for NaN */
+   uint32_t EXPONENT_BIAS = 6176;      /* decimal128 exponent bias */
+
+   char *str_out = str;      /* output pointer in string */
+   char significand_str[35]; /* decoded significand digits */
+
+
+   /* Note: bits in this routine are referred to starting at 0, */
+   /* from the sign bit, towards the coefficient. */
+   uint32_t high;                   /* bits 0 - 31 */
+   uint32_t midh;                   /* bits 32 - 63 */
+   uint32_t midl;                   /* bits 64 - 95 */
+   uint32_t low;                    /* bits 96 - 127 */
+   uint32_t combination;            /* bits 1 - 5 */
+   uint32_t biased_exponent;        /* decoded biased exponent (14 bits) */
+   uint32_t significand_digits = 0; /* the number of significand digits */
+   uint32_t significand[36] = {0};  /* the base-10 digits in the significand */
+   uint32_t *significand_read = significand; /* read pointer into significand */
+   int32_t exponent;                         /* unbiased exponent */
+   int32_t scientific_exponent; /* the exponent if scientific notation is
+                                 * used */
+   bool is_zero = false;        /* true if the number is zero */
+
+   uint8_t significand_msb; /* the most signifcant significand bits (50-46) */
+   _bson_uint128_t
+      significand128; /* temporary storage for significand decoding */
+   size_t i;          /* indexing variables */
+   int j, k;
+
+   memset (significand_str, 0, sizeof (significand_str));
+
+   if ((int64_t) dec->high < 0) { /* negative */
+      *(str_out++) = '-';
+   }
+
+   low = (uint32_t) dec->low, midl = (uint32_t) (dec->low >> 32),
+   midh = (uint32_t) dec->high, high = (uint32_t) (dec->high >> 32);
+
+   /* Decode combination field and exponent */
+   combination = (high >> 26) & COMBINATION_MASK;
+
+   if (BSON_UNLIKELY ((combination >> 3) == 3)) {
+      /* Check for 'special' values */
+      if (combination == COMBINATION_INFINITY) { /* Infinity */
+         strcpy (str_out, BSON_DECIMAL128_INF);
+         return;
+      } else if (combination == COMBINATION_NAN) { /* NaN */
+         /* str, not str_out, to erase the sign */
+         strcpy (str, BSON_DECIMAL128_NAN);
+         /* we don't care about the NaN payload. */
+         return;
+      } else {
+         biased_exponent = (high >> 15) & EXPONENT_MASK;
+         significand_msb = 0x8 + ((high >> 14) & 0x1);
+      }
+   } else {
+      significand_msb = (high >> 14) & 0x7;
+      biased_exponent = (high >> 17) & EXPONENT_MASK;
+   }
+
+   exponent = biased_exponent - EXPONENT_BIAS;
+   /* Create string of significand digits */
+
+   /* Convert the 114-bit binary number represented by */
+   /* (high, midh, midl, low) to at most 34 decimal */
+   /* digits through modulo and division. */
+   significand128.parts[0] = (high & 0x3fff) + ((significand_msb & 0xf) << 14);
+   significand128.parts[1] = midh;
+   significand128.parts[2] = midl;
+   significand128.parts[3] = low;
+
+   if (significand128.parts[0] == 0 && significand128.parts[1] == 0 &&
+       significand128.parts[2] == 0 && significand128.parts[3] == 0) {
+      is_zero = true;
+   } else if (significand128.parts[0] >= (1 << 17)) {
+      /* The significand is non-canonical or zero.
+       * In order to preserve compatability with the densely packed decimal
+       * format, the maximum value for the significand of decimal128 is
+       * 1e34 - 1.  If the value is greater than 1e34 - 1, the IEEE 754
+       * standard dictates that the significand is interpreted as zero.
+       */
+      is_zero = true;
+   } else {
+      for (k = 3; k >= 0; k--) {
+         uint32_t least_digits = 0;
+         _bson_uint128_divide1B (
+            significand128, &significand128, &least_digits);
+
+         /* We now have the 9 least significant digits (in base 2). */
+         /* Convert and output to string. */
+         if (!least_digits) {
+            continue;
+         }
+
+         for (j = 8; j >= 0; j--) {
+            significand[k * 9 + j] = least_digits % 10;
+            least_digits /= 10;
+         }
+      }
+   }
+
+   /* Output format options: */
+   /* Scientific - [-]d.dddE(+/-)dd or [-]dE(+/-)dd */
+   /* Regular    - ddd.ddd */
+
+   if (is_zero) {
+      significand_digits = 1;
+      *significand_read = 0;
+   } else {
+      significand_digits = 36;
+      while (!(*significand_read)) {
+         significand_digits--;
+         significand_read++;
+      }
+   }
+
+   scientific_exponent = significand_digits - 1 + exponent;
+
+   /* The scientific exponent checks are dictated by the string conversion
+    * specification and are somewhat arbitrary cutoffs.
+    *
+    * We must check exponent > 0, because if this is the case, the number
+    * has trailing zeros.  However, we *cannot* output these trailing zeros,
+    * because doing so would change the precision of the value, and would
+    * change stored data if the string converted number is round tripped.
+    */
+   if (scientific_exponent < -6 || exponent > 0) {
+      /* Scientific format */
+      *(str_out++) = *(significand_read++) + '0';
+      significand_digits--;
+
+      if (significand_digits) {
+         *(str_out++) = '.';
+      }
+
+      for (i = 0; i < significand_digits; i++) {
+         *(str_out++) = *(significand_read++) + '0';
+      }
+      /* Exponent */
+      *(str_out++) = 'E';
+      bson_snprintf (str_out, 6, "%+d", scientific_exponent);
+   } else {
+      /* Regular format with no decimal place */
+      if (exponent >= 0) {
+         for (i = 0; i < significand_digits; i++) {
+            *(str_out++) = *(significand_read++) + '0';
+         }
+         *str_out = '\0';
+      } else {
+         int32_t radix_position = significand_digits + exponent;
+
+         if (radix_position > 0) { /* non-zero digits before radix */
+            for (i = 0; i < radix_position; i++) {
+               *(str_out++) = *(significand_read++) + '0';
+            }
+         } else { /* leading zero before radix point */
+            *(str_out++) = '0';
+         }
+
+         *(str_out++) = '.';
+         while (radix_position++ < 0) { /* add leading zeros after radix */
+            *(str_out++) = '0';
+         }
+
+         for (i = 0; i < significand_digits - BSON_MAX (radix_position - 1, 0);
+              i++) {
+            *(str_out++) = *(significand_read++) + '0';
+         }
+         *str_out = '\0';
+      }
+   }
+}
+
+typedef struct {
+   uint64_t high, low;
+} _bson_uint128_6464_t;
+
+
+/**
+ *-------------------------------------------------------------------------
+ *
+ * mul64x64 --
+ *
+ *    This function multiplies two &uint64_t into a &_bson_uint128_6464_t.
+ *
+ * Returns:
+ *    The product of @left and @right.
+ *
+ * Side Effects:
+ *    None.
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+_mul_64x64 (uint64_t left,                 /* IN */
+            uint64_t right,                /* IN */
+            _bson_uint128_6464_t *product) /* OUT */
+{
+   uint64_t left_high, left_low, right_high, right_low, product_high,
+      product_mid, product_mid2, product_low;
+   _bson_uint128_6464_t rt = {0};
+
+   if (!left && !right) {
+      *product = rt;
+      return;
+   }
+
+   left_high = left >> 32;
+   left_low = (uint32_t) left;
+   right_high = right >> 32;
+   right_low = (uint32_t) right;
+
+   product_high = left_high * right_high;
+   product_mid = left_high * right_low;
+   product_mid2 = left_low * right_high;
+   product_low = left_low * right_low;
+
+   product_high += product_mid >> 32;
+   product_mid = (uint32_t) product_mid + product_mid2 + (product_low >> 32);
+
+   product_high = product_high + (product_mid >> 32);
+   product_low = (product_mid << 32) + (uint32_t) product_low;
+
+   rt.high = product_high;
+   rt.low = product_low;
+   *product = rt;
+}
+
+/**
+ *------------------------------------------------------------------------------
+ *
+ * _dec128_tolower --
+ *
+ *    This function converts the ASCII character @c to lowercase.  It is locale
+ *    insensitive (unlike the stdlib tolower).
+ *
+ * Returns:
+ *    The lowercased character.
+ */
+char
+_dec128_tolower (char c)
+{
+   if (isupper (c)) {
+      c += 32;
+   }
+
+   return c;
+}
+
+/**
+ *------------------------------------------------------------------------------
+ *
+ * _dec128_istreq --
+ *
+ *    This function compares the null-terminated *ASCII* strings @a and @b
+ *    for case-insensitive equality.
+ *
+ * Returns:
+ *    true if the strings are equal, false otherwise.
+ */
+bool
+_dec128_istreq (const char *a, /* IN */
+                const char *b /* IN */)
+{
+   while (*a != '\0' || *b != '\0') {
+      /* strings are different lengths. */
+      if (*a == '\0' || *b == '\0') {
+         return false;
+      }
+
+      if (_dec128_tolower (*a) != _dec128_tolower (*b)) {
+         return false;
+      }
+
+      a++;
+      b++;
+   }
+
+   return true;
+}
+
+/**
+ *------------------------------------------------------------------------------
+ *
+ * bson_decimal128_from_string --
+ *
+ *    This function converts @string in the format [+-]ddd[.]ddd[E][+-]dddd to
+ *    decimal128.  Out of range values are converted to +/-Infinity.  Invalid
+ *    strings are converted to NaN.
+ *
+ *    If more digits are provided than the available precision allows,
+ *    round to the nearest expressable decimal128 with ties going to even will
+ *    occur.
+ *
+ *    Note: @string must be ASCII only!
+ *
+ * Returns:
+ *    true on success, or false on failure. @dec will be NaN if @str was invalid
+ *    The &bson_decimal128_t converted from @string at @dec.
+ *
+ * Side effects:
+ *    None.
+ *
+ *------------------------------------------------------------------------------
+ */
+bool
+bson_decimal128_from_string (const char *string,     /* IN */
+                             bson_decimal128_t *dec) /* OUT */
+{
+   _bson_uint128_6464_t significand = {0};
+
+   const char *str_read = string; /* Read pointer for consuming str. */
+
+   /* Parsing state tracking */
+   bool is_negative = false;
+   bool saw_radix = false;
+   bool includes_sign = false; /* True if the input string contains a sign. */
+   bool found_nonzero = false;
+
+   size_t significant_digits = 0; /* Total number of significant digits
+                                   * (no leading or trailing zero) */
+   size_t ndigits_read = 0;       /* Total number of significand digits read */
+   size_t ndigits = 0;        /* Total number of digits (no leading zeros) */
+   size_t radix_position = 0; /* The number of the digits after radix */
+   size_t first_nonzero = 0;  /* The index of the first non-zero in *str* */
+
+   uint16_t digits[BSON_DECIMAL128_MAX_DIGITS] = {0};
+   uint16_t ndigits_stored = 0;      /* The number of digits in digits */
+   uint16_t *digits_insert = digits; /* Insertion pointer for digits */
+   size_t first_digit = 0;           /* The index of the first non-zero digit */
+   size_t last_digit = 0;            /* The index of the last digit */
+
+   int32_t exponent = 0;
+   uint64_t significand_high = 0; /* The high 17 digits of the significand */
+   uint64_t significand_low = 0;  /* The low 17 digits of the significand */
+   uint16_t biased_exponent = 0;  /* The biased exponent */
+
+   BSON_ASSERT (dec);
+   dec->high = 0;
+   dec->low = 0;
+
+   if (*str_read == '+' || *str_read == '-') {
+      is_negative = *(str_read++) == '-';
+      includes_sign = true;
+   }
+
+   /* Check for Infinity or NaN */
+   if (!isdigit (*str_read) && *str_read != '.') {
+      if (_dec128_istreq (str_read, "inf") ||
+          _dec128_istreq (str_read, "infinity")) {
+         BSON_DECIMAL128_SET_INF (*dec, is_negative);
+         return true;
+      } else if (_dec128_istreq (str_read, "nan")) {
+         BSON_DECIMAL128_SET_NAN (*dec);
+         return true;
+      }
+
+      BSON_DECIMAL128_SET_NAN (*dec);
+      return false;
+   }
+
+   /* Read digits */
+   while (isdigit (*str_read) || *str_read == '.') {
+      if (*str_read == '.') {
+         if (saw_radix) {
+            BSON_DECIMAL128_SET_NAN (*dec);
+            return false;
+         }
+
+         saw_radix = true;
+         str_read++;
+         continue;
+      }
+
+      if (ndigits_stored < 34) {
+         if (*str_read != '0' || found_nonzero) {
+            if (!found_nonzero) {
+               first_nonzero = ndigits_read;
+            }
+
+            found_nonzero = true;
+            *(digits_insert++) = *(str_read) - '0'; /* Only store 34 digits */
+            ndigits_stored++;
+         }
+      }
+
+      if (found_nonzero) {
+         ndigits++;
+      }
+
+      if (saw_radix) {
+         radix_position++;
+      }
+
+      ndigits_read++;
+      str_read++;
+   }
+
+   if (saw_radix && !ndigits_read) {
+      BSON_DECIMAL128_SET_NAN (*dec);
+      return false;
+   }
+
+   /* Read exponent if exists */
+   if (*str_read == 'e' || *str_read == 'E') {
+      int nread = 0;
+#ifdef _MSC_VER
+#define SSCANF sscanf_s
+#else
+#define SSCANF sscanf
+#endif
+      int read_exponent = SSCANF (++str_read, "%d%n", &exponent, &nread);
+      str_read += nread;
+
+      if (!read_exponent || nread == 0) {
+         BSON_DECIMAL128_SET_NAN (*dec);
+         return false;
+      }
+
+#undef SSCANF
+   }
+
+   if (*str_read) {
+      BSON_DECIMAL128_SET_NAN (*dec);
+      return false;
+   }
+
+   /* Done reading input. */
+   /* Find first non-zero digit in digits */
+   first_digit = 0;
+
+   if (!ndigits_stored) { /* value is zero */
+      first_digit = 0;
+      last_digit = 0;
+      digits[0] = 0;
+      ndigits = 1;
+      ndigits_stored = 1;
+      significant_digits = 0;
+   } else {
+      last_digit = ndigits_stored - 1;
+      significant_digits = ndigits;
+      /* Mark trailing zeros as non-significant */
+      while (string[first_nonzero + significant_digits - 1 + includes_sign +
+                    saw_radix] == '0') {
+         significant_digits--;
+      }
+   }
+
+
+   /* Normalization of exponent */
+   /* Correct exponent based on radix position, and shift significand as needed
+    */
+   /* to represent user input */
+
+   /* Overflow prevention */
+   if (exponent <= radix_position && radix_position - exponent > (1 << 14)) {
+      exponent = BSON_DECIMAL128_EXPONENT_MIN;
+   } else {
+      exponent -= radix_position;
+   }
+
+   /* Attempt to normalize the exponent */
+   while (exponent > BSON_DECIMAL128_EXPONENT_MAX) {
+      /* Shift exponent to significand and decrease */
+      last_digit++;
+
+      if (last_digit - first_digit > BSON_DECIMAL128_MAX_DIGITS) {
+         /* The exponent is too great to shift into the significand. */
+         if (significant_digits == 0) {
+            /* Value is zero, we are allowed to clamp the exponent. */
+            exponent = BSON_DECIMAL128_EXPONENT_MAX;
+            break;
+         }
+
+         /* Overflow is not permitted, error. */
+         BSON_DECIMAL128_SET_NAN (*dec);
+         return false;
+      }
+
+      exponent--;
+   }
+
+   while (exponent < BSON_DECIMAL128_EXPONENT_MIN || ndigits_stored < ndigits) {
+      /* Shift last digit */
+      if (last_digit == 0) {
+         /* underflow is not allowed, but zero clamping is */
+         if (significant_digits == 0) {
+            exponent = BSON_DECIMAL128_EXPONENT_MIN;
+            break;
+         }
+
+         BSON_DECIMAL128_SET_NAN (*dec);
+         return false;
+      }
+
+      if (ndigits_stored < ndigits) {
+         if (string[ndigits - 1 + includes_sign + saw_radix] - '0' != 0 &&
+             significant_digits != 0) {
+            BSON_DECIMAL128_SET_NAN (*dec);
+            return false;
+         }
+
+         ndigits--; /* adjust to match digits not stored */
+      } else {
+         if (digits[last_digit] != 0) {
+            /* Inexact rounding is not allowed. */
+            BSON_DECIMAL128_SET_NAN (*dec);
+            return false;
+         }
+
+
+         last_digit--; /* adjust to round */
+      }
+
+      if (exponent < BSON_DECIMAL128_EXPONENT_MAX) {
+         exponent++;
+      } else {
+         BSON_DECIMAL128_SET_NAN (*dec);
+         return false;
+      }
+   }
+
+   /* Round */
+   /* We've normalized the exponent, but might still need to round. */
+   if (last_digit - first_digit + 1 < significant_digits) {
+      uint8_t round_digit;
+
+      /* There are non-zero digits after last_digit that need rounding. */
+      /* We round to nearest, ties to even */
+      round_digit =
+         string[first_nonzero + last_digit + includes_sign + saw_radix + 1] -
+         '0';
+
+      if (round_digit != 0) {
+         /* Inexact (non-zero) rounding is not allowed */
+         BSON_DECIMAL128_SET_NAN (*dec);
+         return false;
+      }
+   }
+
+   /* Encode significand */
+   significand_high = 0,   /* The high 17 digits of the significand */
+      significand_low = 0; /* The low 17 digits of the significand */
+
+   if (significant_digits == 0) { /* read a zero */
+      significand_high = 0;
+      significand_low = 0;
+   } else if (last_digit - first_digit < 17) {
+      size_t d_idx = first_digit;
+      significand_low = digits[d_idx++];
+
+      for (; d_idx <= last_digit; d_idx++) {
+         significand_low *= 10;
+         significand_low += digits[d_idx];
+         significand_high = 0;
+      }
+   } else {
+      size_t d_idx = first_digit;
+      significand_high = digits[d_idx++];
+
+      for (; d_idx <= last_digit - 17; d_idx++) {
+         significand_high *= 10;
+         significand_high += digits[d_idx];
+      }
+
+      significand_low = digits[d_idx++];
+
+      for (; d_idx <= last_digit; d_idx++) {
+         significand_low *= 10;
+         significand_low += digits[d_idx];
+      }
+   }
+
+   _mul_64x64 (significand_high, 100000000000000000ull, &significand);
+   significand.low += significand_low;
+
+   if (significand.low < significand_low) {
+      significand.high += 1;
+   }
+
+
+   biased_exponent = (exponent + (int16_t) BSON_DECIMAL128_EXPONENT_BIAS);
+
+   /* Encode combination, exponent, and significand. */
+   if ((significand.high >> 49) & 1) {
+      /* Encode '11' into bits 1 to 3 */
+      dec->high |= (0x3ull << 61);
+      dec->high |= (biased_exponent & 0x3fffull) << 47;
+      dec->high |= significand.high & 0x7fffffffffffull;
+   } else {
+      dec->high |= (biased_exponent & 0x3fffull) << 49;
+      dec->high |= significand.high & 0x1ffffffffffffull;
+   }
+
+   dec->low = significand.low;
+
+   /* Encode sign */
+   if (is_negative) {
+      dec->high |= 0x8000000000000000ull;
+   }
+
+   return true;
+}
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-decimal128.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-decimal128.h
new file mode 100644
index 0000000000000000000000000000000000000000..e2c0a3327d41946e446cd0740a88d3d327a465ca
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-decimal128.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2015 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef BSON_DECIMAL128_H
+#define BSON_DECIMAL128_H
+
+#include <string.h>
+
+#include "bson-macros.h"
+#include "bson-config.h"
+#include "bson-types.h"
+
+
+/**
+ * BSON_DECIMAL128_STRING:
+ *
+ * The length of a decimal128 string (with null terminator).
+ *
+ * 1  for the sign
+ * 35 for digits and radix
+ * 2  for exponent indicator and sign
+ * 4  for exponent digits
+ */
+#define BSON_DECIMAL128_STRING 43
+#define BSON_DECIMAL128_INF "Infinity"
+#define BSON_DECIMAL128_NAN "NaN"
+
+
+BSON_BEGIN_DECLS
+
+BSON_EXPORT (void)
+bson_decimal128_to_string (const bson_decimal128_t *dec, char *str);
+
+
+/* Note: @string must be ASCII characters only! */
+BSON_EXPORT (bool)
+bson_decimal128_from_string (const char *string, bson_decimal128_t *dec);
+
+
+BSON_END_DECLS
+
+
+#endif /* BSON_DECIMAL128_H */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-endian.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-endian.h
new file mode 100644
index 0000000000000000000000000000000000000000..6bfe40530a34b15c578353ef6ca85f6574bdabc3
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-endian.h
@@ -0,0 +1,230 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef BSON_ENDIAN_H
+#define BSON_ENDIAN_H
+
+
+#if !defined(BSON_INSIDE) && !defined(BSON_COMPILATION)
+#error "Only <bson.h> can be included directly."
+#endif
+
+
+#if defined(__sun)
+#include <sys/byteorder.h>
+#endif
+
+#include "bson-config.h"
+#include "bson-macros.h"
+#include "bson-compat.h"
+
+
+BSON_BEGIN_DECLS
+
+
+#define BSON_BIG_ENDIAN 4321
+#define BSON_LITTLE_ENDIAN 1234
+
+
+#if defined(__sun)
+#define BSON_UINT16_SWAP_LE_BE(v) BSWAP_16 ((uint16_t) v)
+#define BSON_UINT32_SWAP_LE_BE(v) BSWAP_32 ((uint32_t) v)
+#define BSON_UINT64_SWAP_LE_BE(v) BSWAP_64 ((uint64_t) v)
+#elif defined(__clang__) && defined(__clang_major__) &&  \
+   defined(__clang_minor__) && (__clang_major__ >= 3) && \
+   (__clang_minor__ >= 1)
+#if __has_builtin(__builtin_bswap16)
+#define BSON_UINT16_SWAP_LE_BE(v) __builtin_bswap16 (v)
+#endif
+#if __has_builtin(__builtin_bswap32)
+#define BSON_UINT32_SWAP_LE_BE(v) __builtin_bswap32 (v)
+#endif
+#if __has_builtin(__builtin_bswap64)
+#define BSON_UINT64_SWAP_LE_BE(v) __builtin_bswap64 (v)
+#endif
+#elif defined(__GNUC__) && (__GNUC__ >= 4)
+#if __GNUC__ > 4 || (defined(__GNUC_MINOR__) && __GNUC_MINOR__ >= 3)
+#define BSON_UINT32_SWAP_LE_BE(v) __builtin_bswap32 ((uint32_t) v)
+#define BSON_UINT64_SWAP_LE_BE(v) __builtin_bswap64 ((uint64_t) v)
+#endif
+#if __GNUC__ > 4 || (defined(__GNUC_MINOR__) && __GNUC_MINOR__ >= 8)
+#define BSON_UINT16_SWAP_LE_BE(v) __builtin_bswap16 ((uint32_t) v)
+#endif
+#endif
+
+
+#ifndef BSON_UINT16_SWAP_LE_BE
+#define BSON_UINT16_SWAP_LE_BE(v) __bson_uint16_swap_slow ((uint16_t) v)
+#endif
+
+
+#ifndef BSON_UINT32_SWAP_LE_BE
+#define BSON_UINT32_SWAP_LE_BE(v) __bson_uint32_swap_slow ((uint32_t) v)
+#endif
+
+
+#ifndef BSON_UINT64_SWAP_LE_BE
+#define BSON_UINT64_SWAP_LE_BE(v) __bson_uint64_swap_slow ((uint64_t) v)
+#endif
+
+
+#if BSON_BYTE_ORDER == BSON_LITTLE_ENDIAN
+#define BSON_UINT16_FROM_LE(v) ((uint16_t) v)
+#define BSON_UINT16_TO_LE(v) ((uint16_t) v)
+#define BSON_UINT16_FROM_BE(v) BSON_UINT16_SWAP_LE_BE (v)
+#define BSON_UINT16_TO_BE(v) BSON_UINT16_SWAP_LE_BE (v)
+#define BSON_UINT32_FROM_LE(v) ((uint32_t) v)
+#define BSON_UINT32_TO_LE(v) ((uint32_t) v)
+#define BSON_UINT32_FROM_BE(v) BSON_UINT32_SWAP_LE_BE (v)
+#define BSON_UINT32_TO_BE(v) BSON_UINT32_SWAP_LE_BE (v)
+#define BSON_UINT64_FROM_LE(v) ((uint64_t) v)
+#define BSON_UINT64_TO_LE(v) ((uint64_t) v)
+#define BSON_UINT64_FROM_BE(v) BSON_UINT64_SWAP_LE_BE (v)
+#define BSON_UINT64_TO_BE(v) BSON_UINT64_SWAP_LE_BE (v)
+#define BSON_DOUBLE_FROM_LE(v) ((double) v)
+#define BSON_DOUBLE_TO_LE(v) ((double) v)
+#elif BSON_BYTE_ORDER == BSON_BIG_ENDIAN
+#define BSON_UINT16_FROM_LE(v) BSON_UINT16_SWAP_LE_BE (v)
+#define BSON_UINT16_TO_LE(v) BSON_UINT16_SWAP_LE_BE (v)
+#define BSON_UINT16_FROM_BE(v) ((uint16_t) v)
+#define BSON_UINT16_TO_BE(v) ((uint16_t) v)
+#define BSON_UINT32_FROM_LE(v) BSON_UINT32_SWAP_LE_BE (v)
+#define BSON_UINT32_TO_LE(v) BSON_UINT32_SWAP_LE_BE (v)
+#define BSON_UINT32_FROM_BE(v) ((uint32_t) v)
+#define BSON_UINT32_TO_BE(v) ((uint32_t) v)
+#define BSON_UINT64_FROM_LE(v) BSON_UINT64_SWAP_LE_BE (v)
+#define BSON_UINT64_TO_LE(v) BSON_UINT64_SWAP_LE_BE (v)
+#define BSON_UINT64_FROM_BE(v) ((uint64_t) v)
+#define BSON_UINT64_TO_BE(v) ((uint64_t) v)
+#define BSON_DOUBLE_FROM_LE(v) (__bson_double_swap_slow (v))
+#define BSON_DOUBLE_TO_LE(v) (__bson_double_swap_slow (v))
+#else
+#error "The endianness of target architecture is unknown."
+#endif
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * __bson_uint16_swap_slow --
+ *
+ *       Fallback endianness conversion for 16-bit integers.
+ *
+ * Returns:
+ *       The endian swapped version.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static BSON_INLINE uint16_t
+__bson_uint16_swap_slow (uint16_t v) /* IN */
+{
+   return ((v & 0x00FF) << 8) | ((v & 0xFF00) >> 8);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * __bson_uint32_swap_slow --
+ *
+ *       Fallback endianness conversion for 32-bit integers.
+ *
+ * Returns:
+ *       The endian swapped version.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static BSON_INLINE uint32_t
+__bson_uint32_swap_slow (uint32_t v) /* IN */
+{
+   return ((v & 0x000000FFU) << 24) | ((v & 0x0000FF00U) << 8) |
+          ((v & 0x00FF0000U) >> 8) | ((v & 0xFF000000U) >> 24);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * __bson_uint64_swap_slow --
+ *
+ *       Fallback endianness conversion for 64-bit integers.
+ *
+ * Returns:
+ *       The endian swapped version.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static BSON_INLINE uint64_t
+__bson_uint64_swap_slow (uint64_t v) /* IN */
+{
+   return ((v & 0x00000000000000FFULL) << 56) |
+          ((v & 0x000000000000FF00ULL) << 40) |
+          ((v & 0x0000000000FF0000ULL) << 24) |
+          ((v & 0x00000000FF000000ULL) << 8) |
+          ((v & 0x000000FF00000000ULL) >> 8) |
+          ((v & 0x0000FF0000000000ULL) >> 24) |
+          ((v & 0x00FF000000000000ULL) >> 40) |
+          ((v & 0xFF00000000000000ULL) >> 56);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * __bson_double_swap_slow --
+ *
+ *       Fallback endianness conversion for double floating point.
+ *
+ * Returns:
+ *       The endian swapped version.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+BSON_STATIC_ASSERT (sizeof (double) == sizeof (uint64_t));
+
+static BSON_INLINE double
+__bson_double_swap_slow (double v) /* IN */
+{
+   uint64_t uv;
+
+   memcpy (&uv, &v, sizeof (v));
+   uv = BSON_UINT64_SWAP_LE_BE (uv);
+   memcpy (&v, &uv, sizeof (v));
+
+   return v;
+}
+
+BSON_END_DECLS
+
+
+#endif /* BSON_ENDIAN_H */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-error.c b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-error.c
new file mode 100644
index 0000000000000000000000000000000000000000..d16b5faefcf6fe03f9a55f98903bf17f19d8bb4d
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-error.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "bson-compat.h"
+#include "bson-config.h"
+#include "bson-error.h"
+#include "bson-memory.h"
+#include "bson-string.h"
+#include "bson-types.h"
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_set_error --
+ *
+ *       Initializes @error using the parameters specified.
+ *
+ *       @domain is an application specific error domain which should
+ *       describe which module initiated the error. Think of this as the
+ *       exception type.
+ *
+ *       @code is the @domain specific error code.
+ *
+ *       @format is used to generate the format string. It uses vsnprintf()
+ *       internally so the format should match what you would use there.
+ *
+ * Parameters:
+ *       @error: A #bson_error_t.
+ *       @domain: The error domain.
+ *       @code: The error code.
+ *       @format: A printf style format string.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       @error is initialized.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_set_error (bson_error_t *error, /* OUT */
+                uint32_t domain,     /* IN */
+                uint32_t code,       /* IN */
+                const char *format,  /* IN */
+                ...)                 /* IN */
+{
+   va_list args;
+
+   if (error) {
+      error->domain = domain;
+      error->code = code;
+
+      va_start (args, format);
+      bson_vsnprintf (error->message, sizeof error->message, format, args);
+      va_end (args);
+
+      error->message[sizeof error->message - 1] = '\0';
+   }
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_strerror_r --
+ *
+ *       This is a reentrant safe macro for strerror.
+ *
+ *       The resulting string may be stored in @buf.
+ *
+ * Returns:
+ *       A pointer to a static string or @buf.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+char *
+bson_strerror_r (int err_code,  /* IN */
+                 char *buf,     /* IN */
+                 size_t buflen) /* IN */
+{
+   static const char *unknown_msg = "Unknown error";
+   char *ret = NULL;
+
+#if defined(_WIN32)
+   if (strerror_s (buf, buflen, err_code) != 0) {
+      ret = buf;
+   }
+#elif defined(__GNUC__) && defined(_GNU_SOURCE)
+   ret = strerror_r (err_code, buf, buflen);
+#else /* XSI strerror_r */
+   if (strerror_r (err_code, buf, buflen) == 0) {
+      ret = buf;
+   }
+#endif
+
+   if (!ret) {
+      bson_strncpy (buf, unknown_msg, buflen);
+      ret = buf;
+   }
+
+   return ret;
+}
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-error.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-error.h
new file mode 100644
index 0000000000000000000000000000000000000000..044cd37a3507cf83036a8ec6f531e36fa1bbdf79
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-error.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef BSON_ERROR_H
+#define BSON_ERROR_H
+
+
+#include "bson-compat.h"
+#include "bson-macros.h"
+#include "bson-types.h"
+
+
+BSON_BEGIN_DECLS
+
+
+#define BSON_ERROR_JSON 1
+#define BSON_ERROR_READER 2
+#define BSON_ERROR_INVALID 3
+
+
+BSON_EXPORT (void)
+bson_set_error (bson_error_t *error,
+                uint32_t domain,
+                uint32_t code,
+                const char *format,
+                ...) BSON_GNUC_PRINTF (4, 5);
+BSON_EXPORT (char *)
+bson_strerror_r (int err_code, char *buf, size_t buflen);
+
+
+BSON_END_DECLS
+
+
+#endif /* BSON_ERROR_H */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-iso8601-private.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-iso8601-private.h
new file mode 100644
index 0000000000000000000000000000000000000000..1c587d73470a15d3fc25d26e632c5276d4a213bf
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-iso8601-private.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2014 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef BSON_ISO8601_PRIVATE_H
+#define BSON_ISO8601_PRIVATE_H
+
+
+#include "bson-compat.h"
+#include "bson-macros.h"
+
+
+BSON_BEGIN_DECLS
+
+bool
+_bson_iso8601_date_parse (const char *str,
+                          int32_t len,
+                          int64_t *out,
+                          bson_error_t *error);
+
+BSON_END_DECLS
+
+
+#endif /* BSON_ISO8601_PRIVATE_H */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-iso8601.c b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-iso8601.c
new file mode 100644
index 0000000000000000000000000000000000000000..153173586401f116905232a03cf6e51b3eccd3e4
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-iso8601.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include "bson-compat.h"
+#include "bson-macros.h"
+#include "bson-error.h"
+#include "bson-iso8601-private.h"
+#include "bson-json.h"
+#include "bson-timegm-private.h"
+
+
+static bool
+get_tok (const char *terminals,
+         const char **ptr,
+         int32_t *remaining,
+         const char **out,
+         int32_t *out_len)
+{
+   const char *terminal;
+   bool found_terminal = false;
+
+   if (!*remaining) {
+      *out = "";
+      *out_len = 0;
+   }
+
+   *out = *ptr;
+   *out_len = -1;
+
+   for (; *remaining && !found_terminal;
+        (*ptr)++, (*remaining)--, (*out_len)++) {
+      for (terminal = terminals; *terminal; terminal++) {
+         if (**ptr == *terminal) {
+            found_terminal = true;
+            break;
+         }
+      }
+   }
+
+   if (!found_terminal) {
+      (*out_len)++;
+   }
+
+   return found_terminal;
+}
+
+static bool
+digits_only (const char *str, int32_t len)
+{
+   int i;
+
+   for (i = 0; i < len; i++) {
+      if (!isdigit (str[i])) {
+         return false;
+      }
+   }
+
+   return true;
+}
+
+static bool
+parse_num (const char *str,
+           int32_t len,
+           int32_t digits,
+           int32_t min,
+           int32_t max,
+           int32_t *out)
+{
+   int i;
+   int magnitude = 1;
+   int32_t value = 0;
+
+   if ((digits >= 0 && len != digits) || !digits_only (str, len)) {
+      return false;
+   }
+
+   for (i = 1; i <= len; i++, magnitude *= 10) {
+      value += (str[len - i] - '0') * magnitude;
+   }
+
+   if (value < min || value > max) {
+      return false;
+   }
+
+   *out = value;
+
+   return true;
+}
+
+bool
+_bson_iso8601_date_parse (const char *str,
+                          int32_t len,
+                          int64_t *out,
+                          bson_error_t *error)
+{
+   const char *ptr;
+   int32_t remaining = len;
+
+   const char *year_ptr;
+   const char *month_ptr;
+   const char *day_ptr;
+   const char *hour_ptr;
+   const char *min_ptr;
+   const char *sec_ptr;
+   const char *millis_ptr;
+   const char *tz_ptr;
+
+   int32_t year_len = 0;
+   int32_t month_len = 0;
+   int32_t day_len = 0;
+   int32_t hour_len = 0;
+   int32_t min_len = 0;
+   int32_t sec_len = 0;
+   int32_t millis_len = 0;
+   int32_t tz_len = 0;
+
+   int32_t year;
+   int32_t month;
+   int32_t day;
+   int32_t hour;
+   int32_t min;
+   int32_t sec = 0;
+   int64_t millis = 0;
+   int32_t tz_adjustment = 0;
+
+   struct bson_tm posix_date = {0};
+
+#define DATE_PARSE_ERR(msg)                                \
+   bson_set_error (error,                                  \
+                   BSON_ERROR_JSON,                        \
+                   BSON_JSON_ERROR_READ_INVALID_PARAM,     \
+                   "Could not parse \"%s\" as date: " msg, \
+                   str);                                   \
+   return false
+
+#define DEFAULT_DATE_PARSE_ERR                                                 \
+   DATE_PARSE_ERR ("use ISO8601 format yyyy-mm-ddThh:mm plus timezone, either" \
+                   " \"Z\" or like \"+0500\"")
+
+   ptr = str;
+
+   /* we have to match at least yyyy-mm-ddThh:mm */
+   if (!(get_tok ("-", &ptr, &remaining, &year_ptr, &year_len) &&
+         get_tok ("-", &ptr, &remaining, &month_ptr, &month_len) &&
+         get_tok ("T", &ptr, &remaining, &day_ptr, &day_len) &&
+         get_tok (":", &ptr, &remaining, &hour_ptr, &hour_len) &&
+         get_tok (":+-Z", &ptr, &remaining, &min_ptr, &min_len))) {
+      DEFAULT_DATE_PARSE_ERR;
+   }
+
+   /* if the minute has a ':' at the end look for seconds */
+   if (min_ptr[min_len] == ':') {
+      if (remaining < 2) {
+         DATE_PARSE_ERR ("reached end of date while looking for seconds");
+      }
+
+      get_tok (".+-Z", &ptr, &remaining, &sec_ptr, &sec_len);
+
+      if (!sec_len) {
+         DATE_PARSE_ERR ("minute ends in \":\" seconds is required");
+      }
+   }
+
+   /* if we had a second and it is followed by a '.' look for milliseconds */
+   if (sec_len && sec_ptr[sec_len] == '.') {
+      if (remaining < 2) {
+         DATE_PARSE_ERR ("reached end of date while looking for milliseconds");
+      }
+
+      get_tok ("+-Z", &ptr, &remaining, &millis_ptr, &millis_len);
+
+      if (!millis_len) {
+         DATE_PARSE_ERR ("seconds ends in \".\", milliseconds is required");
+      }
+   }
+
+   /* backtrack by 1 to put ptr on the timezone */
+   ptr--;
+   remaining++;
+
+   get_tok ("", &ptr, &remaining, &tz_ptr, &tz_len);
+
+   if (!parse_num (year_ptr, year_len, 4, -9999, 9999, &year)) {
+      DATE_PARSE_ERR ("year must be an integer");
+   }
+
+   /* values are as in struct tm */
+   year -= 1900;
+
+   if (!parse_num (month_ptr, month_len, 2, 1, 12, &month)) {
+      DATE_PARSE_ERR ("month must be an integer");
+   }
+
+   /* values are as in struct tm */
+   month -= 1;
+
+   if (!parse_num (day_ptr, day_len, 2, 1, 31, &day)) {
+      DATE_PARSE_ERR ("day must be an integer");
+   }
+
+   if (!parse_num (hour_ptr, hour_len, 2, 0, 23, &hour)) {
+      DATE_PARSE_ERR ("hour must be an integer");
+   }
+
+   if (!parse_num (min_ptr, min_len, 2, 0, 59, &min)) {
+      DATE_PARSE_ERR ("minute must be an integer");
+   }
+
+   if (sec_len && !parse_num (sec_ptr, sec_len, 2, 0, 60, &sec)) {
+      DATE_PARSE_ERR ("seconds must be an integer");
+   }
+
+   if (tz_len > 0) {
+      if (tz_ptr[0] == 'Z' && tz_len == 1) {
+         /* valid */
+      } else if (tz_ptr[0] == '+' || tz_ptr[0] == '-') {
+         int32_t tz_hour;
+         int32_t tz_min;
+
+         if (tz_len != 5 || !digits_only (tz_ptr + 1, 4)) {
+            DATE_PARSE_ERR ("could not parse timezone");
+         }
+
+         if (!parse_num (tz_ptr + 1, 2, -1, -23, 23, &tz_hour)) {
+            DATE_PARSE_ERR ("timezone hour must be at most 23");
+         }
+
+         if (!parse_num (tz_ptr + 3, 2, -1, 0, 59, &tz_min)) {
+            DATE_PARSE_ERR ("timezone minute must be at most 59");
+         }
+
+         /* we inflect the meaning of a 'positive' timezone.  Those are hours
+          * we have to substract, and vice versa */
+         tz_adjustment =
+            (tz_ptr[0] == '-' ? 1 : -1) * ((tz_min * 60) + (tz_hour * 60 * 60));
+
+         if (!(tz_adjustment > -86400 && tz_adjustment < 86400)) {
+            DATE_PARSE_ERR ("timezone offset must be less than 24 hours");
+         }
+      } else {
+         DATE_PARSE_ERR ("timezone is required");
+      }
+   }
+
+   if (millis_len > 0) {
+      int i;
+      int magnitude;
+      millis = 0;
+
+      if (millis_len > 3 || !digits_only (millis_ptr, millis_len)) {
+         DATE_PARSE_ERR ("milliseconds must be an integer");
+      }
+
+      for (i = 1, magnitude = 1; i <= millis_len; i++, magnitude *= 10) {
+         millis += (millis_ptr[millis_len - i] - '0') * magnitude;
+      }
+
+      if (millis_len == 1) {
+         millis *= 100;
+      } else if (millis_len == 2) {
+         millis *= 10;
+      }
+
+      if (millis < 0 || millis > 1000) {
+         DATE_PARSE_ERR ("milliseconds must be at least 0 and less than 1000");
+      }
+   }
+
+   posix_date.tm_sec = sec;
+   posix_date.tm_min = min;
+   posix_date.tm_hour = hour;
+   posix_date.tm_mday = day;
+   posix_date.tm_mon = month;
+   posix_date.tm_year = year;
+   posix_date.tm_wday = 0;
+   posix_date.tm_yday = 0;
+
+   millis = 1000 * _bson_timegm (&posix_date) + millis;
+   millis += tz_adjustment * 1000;
+   *out = millis;
+
+   return true;
+}
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-iter.c b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-iter.c
new file mode 100644
index 0000000000000000000000000000000000000000..7d162e7101b2252694a924cf93faa160810aa0af
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-iter.c
@@ -0,0 +1,2425 @@
+/*
+ * Copyright 2013-2014 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include "bson-iter.h"
+#include "bson-config.h"
+#include "bson-decimal128.h"
+
+
+#define ITER_TYPE(i) ((bson_type_t) * ((i)->raw + (i)->type))
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_init --
+ *
+ *       Initializes @iter to be used to iterate @bson.
+ *
+ * Returns:
+ *       true if bson_iter_t was initialized. otherwise false.
+ *
+ * Side effects:
+ *       @iter is initialized.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+bson_iter_init (bson_iter_t *iter,  /* OUT */
+                const bson_t *bson) /* IN */
+{
+   BSON_ASSERT (iter);
+   BSON_ASSERT (bson);
+
+   if (BSON_UNLIKELY (bson->len < 5)) {
+      memset (iter, 0, sizeof *iter);
+      return false;
+   }
+
+   iter->raw = bson_get_data (bson);
+   iter->len = bson->len;
+   iter->off = 0;
+   iter->type = 0;
+   iter->key = 0;
+   iter->d1 = 0;
+   iter->d2 = 0;
+   iter->d3 = 0;
+   iter->d4 = 0;
+   iter->next_off = 4;
+   iter->err_off = 0;
+
+   return true;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_init_from_data --
+ *
+ *       Initializes @iter to be used to iterate @data of length @length
+ *
+ * Returns:
+ *       true if bson_iter_t was initialized. otherwise false.
+ *
+ * Side effects:
+ *       @iter is initialized.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+bson_iter_init_from_data (bson_iter_t *iter,   /* OUT */
+                          const uint8_t *data, /* IN */
+                          size_t length)       /* IN */
+{
+   uint32_t len_le;
+
+   BSON_ASSERT (iter);
+   BSON_ASSERT (data);
+
+   if (BSON_UNLIKELY ((length < 5) || (length > INT_MAX))) {
+      memset (iter, 0, sizeof *iter);
+      return false;
+   }
+
+   memcpy (&len_le, data, sizeof (len_le));
+
+   if (BSON_UNLIKELY ((size_t) BSON_UINT32_FROM_LE (len_le) != length)) {
+      memset (iter, 0, sizeof *iter);
+      return false;
+   }
+
+   if (BSON_UNLIKELY (data[length - 1])) {
+      memset (iter, 0, sizeof *iter);
+      return false;
+   }
+
+   iter->raw = (uint8_t *) data;
+   iter->len = length;
+   iter->off = 0;
+   iter->type = 0;
+   iter->key = 0;
+   iter->d1 = 0;
+   iter->d2 = 0;
+   iter->d3 = 0;
+   iter->d4 = 0;
+   iter->next_off = 4;
+   iter->err_off = 0;
+
+   return true;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_recurse --
+ *
+ *       Creates a new sub-iter looking at the document or array that @iter
+ *       is currently pointing at.
+ *
+ * Returns:
+ *       true if successful and @child was initialized.
+ *
+ * Side effects:
+ *       @child is initialized.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+bson_iter_recurse (const bson_iter_t *iter, /* IN */
+                   bson_iter_t *child)      /* OUT */
+{
+   const uint8_t *data = NULL;
+   uint32_t len = 0;
+
+   BSON_ASSERT (iter);
+   BSON_ASSERT (child);
+
+   if (ITER_TYPE (iter) == BSON_TYPE_DOCUMENT) {
+      bson_iter_document (iter, &len, &data);
+   } else if (ITER_TYPE (iter) == BSON_TYPE_ARRAY) {
+      bson_iter_array (iter, &len, &data);
+   } else {
+      return false;
+   }
+
+   child->raw = data;
+   child->len = len;
+   child->off = 0;
+   child->type = 0;
+   child->key = 0;
+   child->d1 = 0;
+   child->d2 = 0;
+   child->d3 = 0;
+   child->d4 = 0;
+   child->next_off = 4;
+   child->err_off = 0;
+
+   return true;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_init_find --
+ *
+ *       Initializes a #bson_iter_t and moves the iter to the first field
+ *       matching @key.
+ *
+ * Returns:
+ *       true if the field named @key was found; otherwise false.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+bson_iter_init_find (bson_iter_t *iter,  /* INOUT */
+                     const bson_t *bson, /* IN */
+                     const char *key)    /* IN */
+{
+   BSON_ASSERT (iter);
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+
+   return bson_iter_init (iter, bson) && bson_iter_find (iter, key);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_init_find_case --
+ *
+ *       A case-insensitive version of bson_iter_init_find().
+ *
+ * Returns:
+ *       true if the field was found and @iter is observing that field.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+bson_iter_init_find_case (bson_iter_t *iter,  /* INOUT */
+                          const bson_t *bson, /* IN */
+                          const char *key)    /* IN */
+{
+   BSON_ASSERT (iter);
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+
+   return bson_iter_init (iter, bson) && bson_iter_find_case (iter, key);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_iter_find_with_len --
+ *
+ *       Internal helper for finding an exact key.
+ *
+ * Returns:
+ *       true if the field @key was found.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static bool
+_bson_iter_find_with_len (bson_iter_t *iter, /* INOUT */
+                          const char *key,   /* IN */
+                          int keylen)        /* IN */
+{
+   const char *ikey;
+
+   if (keylen == 0) {
+      return false;
+   }
+
+   if (keylen < 0) {
+      keylen = (int) strlen (key);
+   }
+
+   while (bson_iter_next (iter)) {
+      ikey = bson_iter_key (iter);
+
+      if ((0 == strncmp (key, ikey, keylen)) && (ikey[keylen] == '\0')) {
+         return true;
+      }
+   }
+
+   return false;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_find --
+ *
+ *       Searches through @iter starting from the current position for a key
+ *       matching @key. This is a case-sensitive search meaning "KEY" and
+ *       "key" would NOT match.
+ *
+ * Returns:
+ *       true if @key is found.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+bson_iter_find (bson_iter_t *iter, /* INOUT */
+                const char *key)   /* IN */
+{
+   BSON_ASSERT (iter);
+   BSON_ASSERT (key);
+
+   return _bson_iter_find_with_len (iter, key, -1);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_find_case --
+ *
+ *       Searches through @iter starting from the current position for a key
+ *       matching @key. This is a case-insensitive search meaning "KEY" and
+ *       "key" would match.
+ *
+ * Returns:
+ *       true if @key is found.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+bson_iter_find_case (bson_iter_t *iter, /* INOUT */
+                     const char *key)   /* IN */
+{
+   BSON_ASSERT (iter);
+   BSON_ASSERT (key);
+
+   while (bson_iter_next (iter)) {
+      if (!bson_strcasecmp (key, bson_iter_key (iter))) {
+         return true;
+      }
+   }
+
+   return false;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_find_descendant --
+ *
+ *       Locates a descendant using the "parent.child.key" notation. This
+ *       operates similar to bson_iter_find() except that it can recurse
+ *       into children documents using the dot notation.
+ *
+ * Returns:
+ *       true if the descendant was found and @descendant was initialized.
+ *
+ * Side effects:
+ *       @descendant may be initialized.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+bson_iter_find_descendant (bson_iter_t *iter,       /* INOUT */
+                           const char *dotkey,      /* IN */
+                           bson_iter_t *descendant) /* OUT */
+{
+   bson_iter_t tmp;
+   const char *dot;
+   size_t sublen;
+
+   BSON_ASSERT (iter);
+   BSON_ASSERT (dotkey);
+   BSON_ASSERT (descendant);
+
+   if ((dot = strchr (dotkey, '.'))) {
+      sublen = dot - dotkey;
+   } else {
+      sublen = strlen (dotkey);
+   }
+
+   if (_bson_iter_find_with_len (iter, dotkey, (int) sublen)) {
+      if (!dot) {
+         *descendant = *iter;
+         return true;
+      }
+
+      if (BSON_ITER_HOLDS_DOCUMENT (iter) || BSON_ITER_HOLDS_ARRAY (iter)) {
+         if (bson_iter_recurse (iter, &tmp)) {
+            return bson_iter_find_descendant (&tmp, dot + 1, descendant);
+         }
+      }
+   }
+
+   return false;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_key --
+ *
+ *       Retrieves the key of the current field. The resulting key is valid
+ *       while @iter is valid.
+ *
+ * Returns:
+ *       A string that should not be modified or freed.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+const char *
+bson_iter_key (const bson_iter_t *iter) /* IN */
+{
+   BSON_ASSERT (iter);
+
+   return bson_iter_key_unsafe (iter);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_type --
+ *
+ *       Retrieves the type of the current field.  It may be useful to check
+ *       the type using the BSON_ITER_HOLDS_*() macros.
+ *
+ * Returns:
+ *       A bson_type_t.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bson_type_t
+bson_iter_type (const bson_iter_t *iter) /* IN */
+{
+   BSON_ASSERT (iter);
+   BSON_ASSERT (iter->raw);
+   BSON_ASSERT (iter->len);
+
+   return bson_iter_type_unsafe (iter);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_iter_next_internal --
+ *
+ *       Internal function to advance @iter to the next field and retrieve
+ *       the key and BSON type before error-checking.
+ *
+ * Return:
+ *       true if an element was decoded, else false.
+ *
+ * Side effects:
+ *       @key and @bson_type are set.
+ *
+ *       If the return value is false:
+ *        - @iter is invalidated: @iter->raw is NULLed
+ *        - @unsupported is set to true if the bson type is unsupported
+ *        - otherwise if the BSON is corrupt, @iter->err_off is nonzero
+ *        - otherwise @bson_type is set to BSON_TYPE_EOD
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static bool
+_bson_iter_next_internal (bson_iter_t *iter,   /* INOUT */
+                          const char **key,    /* OUT */
+                          uint32_t *bson_type, /* OUT */
+                          bool *unsupported)   /* OUT */
+{
+   const uint8_t *data;
+   uint32_t o;
+   unsigned int len;
+
+   BSON_ASSERT (iter);
+
+   *unsupported = false;
+
+   if (!iter->raw) {
+      *key = NULL;
+      *bson_type = BSON_TYPE_EOD;
+      return false;
+   }
+
+   data = iter->raw;
+   len = iter->len;
+
+   iter->off = iter->next_off;
+   iter->type = iter->off;
+   iter->key = iter->off + 1;
+   iter->d1 = 0;
+   iter->d2 = 0;
+   iter->d3 = 0;
+   iter->d4 = 0;
+
+   /* iterate from start to end of NULL-terminated key string */
+   for (o = iter->off + 1; o < len; o++) {
+      if (!data[o]) {
+         iter->d1 = ++o;
+         goto fill_data_fields;
+      }
+   }
+
+   goto mark_invalid;
+
+fill_data_fields:
+
+   *key = bson_iter_key_unsafe (iter);
+   *bson_type = ITER_TYPE (iter);
+
+   switch (*bson_type) {
+   case BSON_TYPE_DATE_TIME:
+   case BSON_TYPE_DOUBLE:
+   case BSON_TYPE_INT64:
+   case BSON_TYPE_TIMESTAMP:
+      iter->next_off = o + 8;
+      break;
+   case BSON_TYPE_CODE:
+   case BSON_TYPE_SYMBOL:
+   case BSON_TYPE_UTF8: {
+      uint32_t l;
+
+      if ((o + 4) >= len) {
+         iter->err_off = o;
+         goto mark_invalid;
+      }
+
+      iter->d2 = o + 4;
+      memcpy (&l, iter->raw + iter->d1, sizeof (l));
+      l = BSON_UINT32_FROM_LE (l);
+
+      if (l > (len - (o + 4))) {
+         iter->err_off = o;
+         goto mark_invalid;
+      }
+
+      iter->next_off = o + 4 + l;
+
+      /*
+       * Make sure the string length includes the NUL byte.
+       */
+      if (BSON_UNLIKELY ((l == 0) || (iter->next_off >= len))) {
+         iter->err_off = o;
+         goto mark_invalid;
+      }
+
+      /*
+       * Make sure the last byte is a NUL byte.
+       */
+      if (BSON_UNLIKELY ((iter->raw + iter->d2)[l - 1] != '\0')) {
+         iter->err_off = o + 4 + l - 1;
+         goto mark_invalid;
+      }
+   } break;
+   case BSON_TYPE_BINARY: {
+      bson_subtype_t subtype;
+      uint32_t l;
+
+      if (o >= (len - 4)) {
+         iter->err_off = o;
+         goto mark_invalid;
+      }
+
+      iter->d2 = o + 4;
+      iter->d3 = o + 5;
+
+      memcpy (&l, iter->raw + iter->d1, sizeof (l));
+      l = BSON_UINT32_FROM_LE (l);
+
+      if (l >= (len - o)) {
+         iter->err_off = o;
+         goto mark_invalid;
+      }
+
+      subtype = *(iter->raw + iter->d2);
+
+      if (subtype == BSON_SUBTYPE_BINARY_DEPRECATED) {
+         int32_t binary_len;
+
+         if (l < 4) {
+            iter->err_off = o;
+            goto mark_invalid;
+         }
+
+         /* subtype 2 has a redundant length header in the data */
+         memcpy (&binary_len, (iter->raw + iter->d3), sizeof (binary_len));
+         binary_len = BSON_UINT32_FROM_LE (binary_len);
+         if (binary_len + 4 != l) {
+            iter->err_off = iter->d3;
+            goto mark_invalid;
+         }
+      }
+
+      iter->next_off = o + 5 + l;
+   } break;
+   case BSON_TYPE_ARRAY:
+   case BSON_TYPE_DOCUMENT: {
+      uint32_t l;
+
+      if (o >= (len - 4)) {
+         iter->err_off = o;
+         goto mark_invalid;
+      }
+
+      memcpy (&l, iter->raw + iter->d1, sizeof (l));
+      l = BSON_UINT32_FROM_LE (l);
+
+      if ((l > len) || (l > (len - o))) {
+         iter->err_off = o;
+         goto mark_invalid;
+      }
+
+      iter->next_off = o + l;
+   } break;
+   case BSON_TYPE_OID:
+      iter->next_off = o + 12;
+      break;
+   case BSON_TYPE_BOOL: {
+      char val;
+
+      if (iter->d1 >= len) {
+         iter->err_off = o;
+         goto mark_invalid;
+      }
+
+      memcpy (&val, iter->raw + iter->d1, 1);
+      if (val != 0x00 && val != 0x01) {
+         iter->err_off = o;
+         goto mark_invalid;
+      }
+
+      iter->next_off = o + 1;
+   } break;
+   case BSON_TYPE_REGEX: {
+      bool eor = false;
+      bool eoo = false;
+
+      for (; o < len; o++) {
+         if (!data[o]) {
+            iter->d2 = ++o;
+            eor = true;
+            break;
+         }
+      }
+
+      if (!eor) {
+         iter->err_off = iter->next_off;
+         goto mark_invalid;
+      }
+
+      for (; o < len; o++) {
+         if (!data[o]) {
+            eoo = true;
+            break;
+         }
+      }
+
+      if (!eoo) {
+         iter->err_off = iter->next_off;
+         goto mark_invalid;
+      }
+
+      iter->next_off = o + 1;
+   } break;
+   case BSON_TYPE_DBPOINTER: {
+      uint32_t l;
+
+      if (o >= (len - 4)) {
+         iter->err_off = o;
+         goto mark_invalid;
+      }
+
+      iter->d2 = o + 4;
+      memcpy (&l, iter->raw + iter->d1, sizeof (l));
+      l = BSON_UINT32_FROM_LE (l);
+
+      if ((l > len) || (l > (len - o))) {
+         iter->err_off = o;
+         goto mark_invalid;
+      }
+
+      if (*(iter->raw + o + l + 3)) {
+         /* not null terminated */
+         iter->err_off = o + l + 3;
+         goto mark_invalid;
+      }
+
+      iter->d3 = o + 4 + l;
+      iter->next_off = o + 4 + l + 12;
+   } break;
+   case BSON_TYPE_CODEWSCOPE: {
+      uint32_t l;
+      uint32_t doclen;
+
+      if ((len < 19) || (o >= (len - 14))) {
+         iter->err_off = o;
+         goto mark_invalid;
+      }
+
+      iter->d2 = o + 4;
+      iter->d3 = o + 8;
+
+      memcpy (&l, iter->raw + iter->d1, sizeof (l));
+      l = BSON_UINT32_FROM_LE (l);
+
+      if ((l < 14) || (l >= (len - o))) {
+         iter->err_off = o;
+         goto mark_invalid;
+      }
+
+      iter->next_off = o + l;
+
+      if (iter->next_off >= len) {
+         iter->err_off = o;
+         goto mark_invalid;
+      }
+
+      memcpy (&l, iter->raw + iter->d2, sizeof (l));
+      l = BSON_UINT32_FROM_LE (l);
+
+      if (l >= (len - o - 4 - 4)) {
+         iter->err_off = o;
+         goto mark_invalid;
+      }
+
+      if ((o + 4 + 4 + l + 4) >= iter->next_off) {
+         iter->err_off = o + 4;
+         goto mark_invalid;
+      }
+
+      iter->d4 = o + 4 + 4 + l;
+      memcpy (&doclen, iter->raw + iter->d4, sizeof (doclen));
+      doclen = BSON_UINT32_FROM_LE (doclen);
+
+      if ((o + 4 + 4 + l + doclen) != iter->next_off) {
+         iter->err_off = o + 4 + 4 + l;
+         goto mark_invalid;
+      }
+   } break;
+   case BSON_TYPE_INT32:
+      iter->next_off = o + 4;
+      break;
+   case BSON_TYPE_DECIMAL128:
+      iter->next_off = o + 16;
+      break;
+   case BSON_TYPE_MAXKEY:
+   case BSON_TYPE_MINKEY:
+   case BSON_TYPE_NULL:
+   case BSON_TYPE_UNDEFINED:
+      iter->d1 = -1;
+      iter->next_off = o;
+      break;
+   default:
+      *unsupported = true;
+   /* FALL THROUGH */
+   case BSON_TYPE_EOD:
+      iter->err_off = o;
+      goto mark_invalid;
+   }
+
+   /*
+    * Check to see if any of the field locations would overflow the
+    * current BSON buffer. If so, set the error location to the offset
+    * of where the field starts.
+    */
+   if (iter->next_off >= len) {
+      iter->err_off = o;
+      goto mark_invalid;
+   }
+
+   iter->err_off = 0;
+
+   return true;
+
+mark_invalid:
+   iter->raw = NULL;
+   iter->len = 0;
+   iter->next_off = 0;
+
+   return false;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_next --
+ *
+ *       Advances @iter to the next field of the underlying BSON document.
+ *       If all fields have been exhausted, then %false is returned.
+ *
+ *       It is a programming error to use @iter after this function has
+ *       returned false.
+ *
+ * Returns:
+ *       true if the iter was advanced to the next record.
+ *       otherwise false and @iter should be considered invalid.
+ *
+ * Side effects:
+ *       @iter may be invalidated.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+bson_iter_next (bson_iter_t *iter) /* INOUT */
+{
+   uint32_t bson_type;
+   const char *key;
+   bool unsupported;
+
+   return _bson_iter_next_internal (iter, &key, &bson_type, &unsupported);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_binary --
+ *
+ *       Retrieves the BSON_TYPE_BINARY field. The subtype is stored in
+ *       @subtype.  The length of @binary in bytes is stored in @binary_len.
+ *
+ *       @binary should not be modified or freed and is only valid while
+ *       @iter's bson_t is valid and unmodified.
+ *
+ * Parameters:
+ *       @iter: A bson_iter_t
+ *       @subtype: A location for the binary subtype.
+ *       @binary_len: A location for the length of @binary.
+ *       @binary: A location for a pointer to the binary data.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_iter_binary (const bson_iter_t *iter, /* IN */
+                  unsigned int *subtype, /* OUT */
+                  uint32_t *binary_len,    /* OUT */
+                  const uint8_t **binary)  /* OUT */
+{
+   unsigned int backup;
+
+   BSON_ASSERT (iter);
+   BSON_ASSERT (!binary || binary_len);
+
+   if (ITER_TYPE (iter) == BSON_TYPE_BINARY) {
+      if (!subtype) {
+         subtype = &backup;
+      }
+
+      *subtype = (unsigned int) * (iter->raw + iter->d2);
+
+      if (binary) {
+         memcpy (binary_len, (iter->raw + iter->d1), sizeof (*binary_len));
+         *binary_len = BSON_UINT32_FROM_LE (*binary_len);
+         *binary = iter->raw + iter->d3;
+
+         if (*subtype == BSON_SUBTYPE_BINARY_DEPRECATED) {
+            *binary_len -= sizeof (int32_t);
+            *binary += sizeof (int32_t);
+         }
+      }
+
+      return;
+   }
+
+   if (binary) {
+      *binary = NULL;
+   }
+
+   if (binary_len) {
+      *binary_len = 0;
+   }
+
+   if (subtype) {
+      *subtype = BSON_SUBTYPE_BINARY;
+   }
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_bool --
+ *
+ *       Retrieves the current field of type BSON_TYPE_BOOL.
+ *
+ * Returns:
+ *       true or false, dependent on bson document.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+bson_iter_bool (const bson_iter_t *iter) /* IN */
+{
+   BSON_ASSERT (iter);
+
+   if (ITER_TYPE (iter) == BSON_TYPE_BOOL) {
+      return bson_iter_bool_unsafe (iter);
+   }
+
+   return false;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_as_bool --
+ *
+ *       If @iter is on a boolean field, returns the boolean. If it is on a
+ *       non-boolean field such as int32, int64, or double, it will convert
+ *       the value to a boolean.
+ *
+ *       Zero is false, and non-zero is true.
+ *
+ * Returns:
+ *       true or false, dependent on field type.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+bson_iter_as_bool (const bson_iter_t *iter) /* IN */
+{
+   BSON_ASSERT (iter);
+
+   switch ((int) ITER_TYPE (iter)) {
+   case BSON_TYPE_BOOL:
+      return bson_iter_bool (iter);
+   case BSON_TYPE_DOUBLE:
+      return !(bson_iter_double (iter) == 0.0);
+   case BSON_TYPE_INT64:
+      return !(bson_iter_int64 (iter) == 0);
+   case BSON_TYPE_INT32:
+      return !(bson_iter_int32 (iter) == 0);
+   case BSON_TYPE_UTF8:
+      return true;
+   case BSON_TYPE_NULL:
+   case BSON_TYPE_UNDEFINED:
+      return false;
+   default:
+      return true;
+   }
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_double --
+ *
+ *       Retrieves the current field of type BSON_TYPE_DOUBLE.
+ *
+ * Returns:
+ *       A double.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+double
+bson_iter_double (const bson_iter_t *iter) /* IN */
+{
+   BSON_ASSERT (iter);
+
+   if (ITER_TYPE (iter) == BSON_TYPE_DOUBLE) {
+      return bson_iter_double_unsafe (iter);
+   }
+
+   return 0;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_as_double --
+ *
+ *       If @iter is on a field of type BSON_TYPE_DOUBLE,
+ *       returns the double. If it is on an integer field
+ *       such as int32, int64, or bool, it will convert
+ *       the value to a double.
+ *
+ *
+ * Returns:
+ *       A double.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+double
+bson_iter_as_double (const bson_iter_t *iter) /* IN */
+{
+  BSON_ASSERT (iter);
+
+  switch ((int) ITER_TYPE (iter)) {
+  case BSON_TYPE_BOOL:
+    return (double) bson_iter_bool (iter);
+  case BSON_TYPE_DOUBLE:
+    return bson_iter_double (iter);
+  case BSON_TYPE_INT32:
+    return (double) bson_iter_int32 (iter);
+  case BSON_TYPE_INT64:
+    return (double) bson_iter_int64 (iter);
+  default:
+    return 0;
+  }
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_int32 --
+ *
+ *       Retrieves the value of the field of type BSON_TYPE_INT32.
+ *
+ * Returns:
+ *       A 32-bit signed integer.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+int32_t
+bson_iter_int32 (const bson_iter_t *iter) /* IN */
+{
+   BSON_ASSERT (iter);
+
+   if (ITER_TYPE (iter) == BSON_TYPE_INT32) {
+      return bson_iter_int32_unsafe (iter);
+   }
+
+   return 0;
+}
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_int64 --
+ *
+ *       Retrieves a 64-bit signed integer for the current BSON_TYPE_INT64
+ *       field.
+ *
+ * Returns:
+ *       A 64-bit signed integer.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+int64_t
+bson_iter_int64 (const bson_iter_t *iter) /* IN */
+{
+   BSON_ASSERT (iter);
+
+   if (ITER_TYPE (iter) == BSON_TYPE_INT64) {
+      return bson_iter_int64_unsafe (iter);
+   }
+
+   return 0;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_as_int64 --
+ *
+ *       If @iter is not an int64 field, it will try to convert the value to
+ *       an int64. Such field types include:
+ *
+ *        - bool
+ *        - double
+ *        - int32
+ *
+ * Returns:
+ *       An int64_t.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+int64_t
+bson_iter_as_int64 (const bson_iter_t *iter) /* IN */
+{
+   BSON_ASSERT (iter);
+
+   switch ((int) ITER_TYPE (iter)) {
+   case BSON_TYPE_BOOL:
+      return (int64_t) bson_iter_bool (iter);
+   case BSON_TYPE_DOUBLE:
+      return (int64_t) bson_iter_double (iter);
+   case BSON_TYPE_INT64:
+      return bson_iter_int64 (iter);
+   case BSON_TYPE_INT32:
+      return (int64_t) bson_iter_int32 (iter);
+   default:
+      return 0;
+   }
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_decimal128 --
+ *
+ *       This function retrieves the current field of type
+ *%BSON_TYPE_DECIMAL128.
+ *       The result is valid while @iter is valid, and is stored in @dec.
+ *
+ * Returns:
+ *
+ *       True on success, false on failure.
+ *
+ * Side Effects:
+ *    None.
+ *
+ *--------------------------------------------------------------------------
+ */
+bool
+bson_iter_decimal128 (const bson_iter_t *iter, /* IN */
+                      bson_decimal128_t *dec)  /* OUT */
+{
+   BSON_ASSERT (iter);
+
+   if (ITER_TYPE (iter) == BSON_TYPE_DECIMAL128) {
+      bson_iter_decimal128_unsafe (iter, dec);
+      return true;
+   }
+
+   return false;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_oid --
+ *
+ *       Retrieves the current field of type %BSON_TYPE_OID. The result is
+ *       valid while @iter is valid.
+ *
+ * Returns:
+ *       A bson_oid_t that should not be modified or freed.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+const bson_oid_t *
+bson_iter_oid (const bson_iter_t *iter) /* IN */
+{
+   BSON_ASSERT (iter);
+
+   if (ITER_TYPE (iter) == BSON_TYPE_OID) {
+      return bson_iter_oid_unsafe (iter);
+   }
+
+   return NULL;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_regex --
+ *
+ *       Fetches the current field from the iter which should be of type
+ *       BSON_TYPE_REGEX.
+ *
+ * Returns:
+ *       Regex from @iter. This should not be modified or freed.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+const char *
+bson_iter_regex (const bson_iter_t *iter, /* IN */
+                 const char **options)    /* IN */
+{
+   const char *ret = NULL;
+   const char *ret_options = NULL;
+
+   BSON_ASSERT (iter);
+
+   if (ITER_TYPE (iter) == BSON_TYPE_REGEX) {
+      ret = (const char *) (iter->raw + iter->d1);
+      ret_options = (const char *) (iter->raw + iter->d2);
+   }
+
+   if (options) {
+      *options = ret_options;
+   }
+
+   return ret;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_utf8 --
+ *
+ *       Retrieves the current field of type %BSON_TYPE_UTF8 as a UTF-8
+ *       encoded string.
+ *
+ * Parameters:
+ *       @iter: A bson_iter_t.
+ *       @length: A location for the length of the string.
+ *
+ * Returns:
+ *       A string that should not be modified or freed.
+ *
+ * Side effects:
+ *       @length will be set to the result strings length if non-NULL.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+const char *
+bson_iter_utf8 (const bson_iter_t *iter, /* IN */
+                uint32_t *length)        /* OUT */
+{
+   BSON_ASSERT (iter);
+
+   if (ITER_TYPE (iter) == BSON_TYPE_UTF8) {
+      if (length) {
+         *length = bson_iter_utf8_len_unsafe (iter);
+      }
+
+      return (const char *) (iter->raw + iter->d2);
+   }
+
+   if (length) {
+      *length = 0;
+   }
+
+   return NULL;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_dup_utf8 --
+ *
+ *       Copies the current UTF-8 element into a newly allocated string. The
+ *       string should be freed using bson_free() when the caller is
+ *       finished with it.
+ *
+ * Returns:
+ *       A newly allocated char* that should be freed with bson_free().
+ *
+ * Side effects:
+ *       @length will be set to the result strings length if non-NULL.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+char *
+bson_iter_dup_utf8 (const bson_iter_t *iter, /* IN */
+                    uint32_t *length)        /* OUT */
+{
+   uint32_t local_length = 0;
+   const char *str;
+   char *ret = NULL;
+
+   BSON_ASSERT (iter);
+
+   if ((str = bson_iter_utf8 (iter, &local_length))) {
+      ret = bson_malloc0 (local_length + 1);
+      memcpy (ret, str, local_length);
+      ret[local_length] = '\0';
+   }
+
+   if (length) {
+      *length = local_length;
+   }
+
+   return ret;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_code --
+ *
+ *       Retrieves the current field of type %BSON_TYPE_CODE. The length of
+ *       the resulting string is stored in @length.
+ *
+ * Parameters:
+ *       @iter: A bson_iter_t.
+ *       @length: A location for the code length.
+ *
+ * Returns:
+ *       A NUL-terminated string containing the code which should not be
+ *       modified or freed.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+const char *
+bson_iter_code (const bson_iter_t *iter, /* IN */
+                uint32_t *length)        /* OUT */
+{
+   BSON_ASSERT (iter);
+
+   if (ITER_TYPE (iter) == BSON_TYPE_CODE) {
+      if (length) {
+         *length = bson_iter_utf8_len_unsafe (iter);
+      }
+
+      return (const char *) (iter->raw + iter->d2);
+   }
+
+   if (length) {
+      *length = 0;
+   }
+
+   return NULL;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_codewscope --
+ *
+ *       Similar to bson_iter_code() but with a scope associated encoded as
+ *       a BSON document. @scope should not be modified or freed. It is
+ *       valid while @iter is valid.
+ *
+ * Parameters:
+ *       @iter: A #bson_iter_t.
+ *       @length: A location for the length of resulting string.
+ *       @scope_len: A location for the length of @scope.
+ *       @scope: A location for the scope encoded as BSON.
+ *
+ * Returns:
+ *       A NUL-terminated string that should not be modified or freed.
+ *
+ * Side effects:
+ *       @length is set to the resulting string length in bytes.
+ *       @scope_len is set to the length of @scope in bytes.
+ *       @scope is set to the scope documents buffer which can be
+ *       turned into a bson document with bson_init_static().
+ *
+ *--------------------------------------------------------------------------
+ */
+
+const char *
+bson_iter_codewscope (const bson_iter_t *iter, /* IN */
+                      uint32_t *length,        /* OUT */
+                      uint32_t *scope_len,     /* OUT */
+                      const uint8_t **scope)   /* OUT */
+{
+   uint32_t len;
+
+   BSON_ASSERT (iter);
+
+   if (ITER_TYPE (iter) == BSON_TYPE_CODEWSCOPE) {
+      if (length) {
+         memcpy (&len, iter->raw + iter->d2, sizeof (len));
+         *length = BSON_UINT32_FROM_LE (len) - 1;
+      }
+
+      memcpy (&len, iter->raw + iter->d4, sizeof (len));
+      *scope_len = BSON_UINT32_FROM_LE (len);
+      *scope = iter->raw + iter->d4;
+      return (const char *) (iter->raw + iter->d3);
+   }
+
+   if (length) {
+      *length = 0;
+   }
+
+   if (scope_len) {
+      *scope_len = 0;
+   }
+
+   if (scope) {
+      *scope = NULL;
+   }
+
+   return NULL;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_dbpointer --
+ *
+ *       Retrieves a BSON_TYPE_DBPOINTER field. @collection_len will be set
+ *       to the length of the collection name. The collection name will be
+ *       placed into @collection. The oid will be placed into @oid.
+ *
+ *       @collection and @oid should not be modified.
+ *
+ * Parameters:
+ *       @iter: A #bson_iter_t.
+ *       @collection_len: A location for the length of @collection.
+ *       @collection: A location for the collection name.
+ *       @oid: A location for the oid.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       @collection_len is set to the length of @collection in bytes
+ *       excluding the null byte.
+ *       @collection is set to the collection name, including a terminating
+ *       null byte.
+ *       @oid is initialized with the oid.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_iter_dbpointer (const bson_iter_t *iter,  /* IN */
+                     uint32_t *collection_len, /* OUT */
+                     const char **collection,  /* OUT */
+                     const bson_oid_t **oid)   /* OUT */
+{
+   BSON_ASSERT (iter);
+
+   if (collection) {
+      *collection = NULL;
+   }
+
+   if (oid) {
+      *oid = NULL;
+   }
+
+   if (ITER_TYPE (iter) == BSON_TYPE_DBPOINTER) {
+      if (collection_len) {
+         memcpy (
+            collection_len, (iter->raw + iter->d1), sizeof (*collection_len));
+         *collection_len = BSON_UINT32_FROM_LE (*collection_len);
+
+         if ((*collection_len) > 0) {
+            (*collection_len)--;
+         }
+      }
+
+      if (collection) {
+         *collection = (const char *) (iter->raw + iter->d2);
+      }
+
+      if (oid) {
+         *oid = (const bson_oid_t *) (iter->raw + iter->d3);
+      }
+   }
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_symbol --
+ *
+ *       Retrieves the symbol of the current field of type BSON_TYPE_SYMBOL.
+ *
+ * Parameters:
+ *       @iter: A bson_iter_t.
+ *       @length: A location for the length of the symbol.
+ *
+ * Returns:
+ *       A string containing the symbol as UTF-8. The value should not be
+ *       modified or freed.
+ *
+ * Side effects:
+ *       @length is set to the resulting strings length in bytes,
+ *       excluding the null byte.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+const char *
+bson_iter_symbol (const bson_iter_t *iter, /* IN */
+                  uint32_t *length)        /* OUT */
+{
+   const char *ret = NULL;
+   uint32_t ret_length = 0;
+
+   BSON_ASSERT (iter);
+
+   if (ITER_TYPE (iter) == BSON_TYPE_SYMBOL) {
+      ret = (const char *) (iter->raw + iter->d2);
+      ret_length = bson_iter_utf8_len_unsafe (iter);
+   }
+
+   if (length) {
+      *length = ret_length;
+   }
+
+   return ret;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_date_time --
+ *
+ *       Fetches the number of milliseconds elapsed since the UNIX epoch.
+ *       This value can be negative as times before 1970 are valid.
+ *
+ * Returns:
+ *       A signed 64-bit integer containing the number of milliseconds.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+int64_t
+bson_iter_date_time (const bson_iter_t *iter) /* IN */
+{
+   BSON_ASSERT (iter);
+
+   if (ITER_TYPE (iter) == BSON_TYPE_DATE_TIME) {
+      return bson_iter_int64_unsafe (iter);
+   }
+
+   return 0;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_time_t --
+ *
+ *       Retrieves the current field of type BSON_TYPE_DATE_TIME as a
+ *       time_t.
+ *
+ * Returns:
+ *       A #time_t of the number of seconds since UNIX epoch in UTC.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+time_t
+bson_iter_time_t (const bson_iter_t *iter) /* IN */
+{
+   BSON_ASSERT (iter);
+
+   if (ITER_TYPE (iter) == BSON_TYPE_DATE_TIME) {
+      return bson_iter_time_t_unsafe (iter);
+   }
+
+   return 0;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_timestamp --
+ *
+ *       Fetches the current field if it is a BSON_TYPE_TIMESTAMP.
+ *
+ * Parameters:
+ *       @iter: A #bson_iter_t.
+ *       @timestamp: a location for the timestamp.
+ *       @increment: A location for the increment.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       @timestamp is initialized.
+ *       @increment is initialized.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_iter_timestamp (const bson_iter_t *iter, /* IN */
+                     uint32_t *timestamp,     /* OUT */
+                     uint32_t *increment)     /* OUT */
+{
+   uint64_t encoded;
+   uint32_t ret_timestamp = 0;
+   uint32_t ret_increment = 0;
+
+   BSON_ASSERT (iter);
+
+   if (ITER_TYPE (iter) == BSON_TYPE_TIMESTAMP) {
+      memcpy (&encoded, iter->raw + iter->d1, sizeof (encoded));
+      encoded = BSON_UINT64_FROM_LE (encoded);
+      ret_timestamp = (encoded >> 32) & 0xFFFFFFFF;
+      ret_increment = encoded & 0xFFFFFFFF;
+   }
+
+   if (timestamp) {
+      *timestamp = ret_timestamp;
+   }
+
+   if (increment) {
+      *increment = ret_increment;
+   }
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_timeval --
+ *
+ *       Retrieves the current field of type BSON_TYPE_DATE_TIME and stores
+ *       it into the struct timeval provided. tv->tv_sec is set to the
+ *       number of seconds since the UNIX epoch in UTC.
+ *
+ *       Since BSON_TYPE_DATE_TIME does not support fractions of a second,
+ *       tv->tv_usec will always be set to zero.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       @tv is initialized.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_iter_timeval (const bson_iter_t *iter, /* IN */
+                   struct timeval *tv)      /* OUT */
+{
+   BSON_ASSERT (iter);
+
+   if (ITER_TYPE (iter) == BSON_TYPE_DATE_TIME) {
+      bson_iter_timeval_unsafe (iter, tv);
+      return;
+   }
+
+   memset (tv, 0, sizeof *tv);
+}
+
+
+/**
+ * bson_iter_document:
+ * @iter: a bson_iter_t.
+ * @document_len: A location for the document length.
+ * @document: A location for a pointer to the document buffer.
+ *
+ */
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_document --
+ *
+ *       Retrieves the data to the document BSON structure and stores the
+ *       length of the document buffer in @document_len and the document
+ *       buffer in @document.
+ *
+ *       If you would like to iterate over the child contents, you might
+ *       consider creating a bson_t on the stack such as the following. It
+ *       allows you to call functions taking a const bson_t* only.
+ *
+ *          bson_t b;
+ *          uint32_t len;
+ *          const uint8_t *data;
+ *
+ *          bson_iter_document(iter, &len, &data);
+ *
+ *          if (bson_init_static (&b, data, len)) {
+ *             ...
+ *          }
+ *
+ *       There is no need to cleanup the bson_t structure as no data can be
+ *       modified in the process of its use (as it is static/const).
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       @document_len is initialized.
+ *       @document is initialized.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_iter_document (const bson_iter_t *iter,  /* IN */
+                    uint32_t *document_len,   /* OUT */
+                    const uint8_t **document) /* OUT */
+{
+   BSON_ASSERT (iter);
+   BSON_ASSERT (document_len);
+   BSON_ASSERT (document);
+
+   *document = NULL;
+   *document_len = 0;
+
+   if (ITER_TYPE (iter) == BSON_TYPE_DOCUMENT) {
+      memcpy (document_len, (iter->raw + iter->d1), sizeof (*document_len));
+      *document_len = BSON_UINT32_FROM_LE (*document_len);
+      *document = (iter->raw + iter->d1);
+   }
+}
+
+
+/**
+ * bson_iter_array:
+ * @iter: a #bson_iter_t.
+ * @array_len: A location for the array length.
+ * @array: A location for a pointer to the array buffer.
+ */
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_array --
+ *
+ *       Retrieves the data to the array BSON structure and stores the
+ *       length of the array buffer in @array_len and the array buffer in
+ *       @array.
+ *
+ *       If you would like to iterate over the child contents, you might
+ *       consider creating a bson_t on the stack such as the following. It
+ *       allows you to call functions taking a const bson_t* only.
+ *
+ *          bson_t b;
+ *          uint32_t len;
+ *          const uint8_t *data;
+ *
+ *          bson_iter_array (iter, &len, &data);
+ *
+ *          if (bson_init_static (&b, data, len)) {
+ *             ...
+ *          }
+ *
+ *       There is no need to cleanup the #bson_t structure as no data can be
+ *       modified in the process of its use.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       @array_len is initialized.
+ *       @array is initialized.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_iter_array (const bson_iter_t *iter, /* IN */
+                 uint32_t *array_len,     /* OUT */
+                 const uint8_t **array)   /* OUT */
+{
+   BSON_ASSERT (iter);
+   BSON_ASSERT (array_len);
+   BSON_ASSERT (array);
+
+   *array = NULL;
+   *array_len = 0;
+
+   if (ITER_TYPE (iter) == BSON_TYPE_ARRAY) {
+      memcpy (array_len, (iter->raw + iter->d1), sizeof (*array_len));
+      *array_len = BSON_UINT32_FROM_LE (*array_len);
+      *array = (iter->raw + iter->d1);
+   }
+}
+
+
+#define VISIT_FIELD(name) visitor->visit_##name && visitor->visit_##name
+#define VISIT_AFTER VISIT_FIELD (after)
+#define VISIT_BEFORE VISIT_FIELD (before)
+#define VISIT_CORRUPT          \
+   if (visitor->visit_corrupt) \
+   visitor->visit_corrupt
+#define VISIT_DOUBLE VISIT_FIELD (double)
+#define VISIT_UTF8 VISIT_FIELD (utf8)
+#define VISIT_DOCUMENT VISIT_FIELD (document)
+#define VISIT_ARRAY VISIT_FIELD (array)
+#define VISIT_BINARY VISIT_FIELD (binary)
+#define VISIT_UNDEFINED VISIT_FIELD (undefined)
+#define VISIT_OID VISIT_FIELD (oid)
+#define VISIT_BOOL VISIT_FIELD (bool)
+#define VISIT_DATE_TIME VISIT_FIELD (date_time)
+#define VISIT_NULL VISIT_FIELD (null)
+#define VISIT_REGEX VISIT_FIELD (regex)
+#define VISIT_DBPOINTER VISIT_FIELD (dbpointer)
+#define VISIT_CODE VISIT_FIELD (code)
+#define VISIT_SYMBOL VISIT_FIELD (symbol)
+#define VISIT_CODEWSCOPE VISIT_FIELD (codewscope)
+#define VISIT_INT32 VISIT_FIELD (int32)
+#define VISIT_TIMESTAMP VISIT_FIELD (timestamp)
+#define VISIT_INT64 VISIT_FIELD (int64)
+#define VISIT_DECIMAL128 VISIT_FIELD (decimal128)
+#define VISIT_MAXKEY VISIT_FIELD (maxkey)
+#define VISIT_MINKEY VISIT_FIELD (minkey)
+
+
+/**
+ * bson_iter_visit_all:
+ * @iter: A #bson_iter_t.
+ * @visitor: A #bson_visitor_t containing the visitors.
+ * @data: User data for @visitor data parameters.
+ *
+ *
+ * Returns: true if the visitor was pre-maturely ended; otherwise false.
+ */
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_visit_all --
+ *
+ *       Visits all fields forward from the current position of @iter. For
+ *       each field found a function in @visitor will be called. Typically
+ *       you will use this immediately after initializing a bson_iter_t.
+ *
+ *          bson_iter_init (&iter, b);
+ *          bson_iter_visit_all (&iter, my_visitor, NULL);
+ *
+ *       @iter will no longer be valid after this function has executed and
+ *       will need to be reinitialized if intending to reuse.
+ *
+ * Returns:
+ *       true if successfully visited all fields or callback requested
+ *       early termination, otherwise false.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+bson_iter_visit_all (bson_iter_t *iter,             /* INOUT */
+                     const bson_visitor_t *visitor, /* IN */
+                     void *data)                    /* IN */
+{
+   uint32_t bson_type;
+   const char *key;
+   bool unsupported;
+
+   BSON_ASSERT (iter);
+   BSON_ASSERT (visitor);
+
+   while (_bson_iter_next_internal (iter, &key, &bson_type, &unsupported)) {
+      if (*key && !bson_utf8_validate (key, strlen (key), false)) {
+         iter->err_off = iter->off;
+         break;
+      }
+
+      if (VISIT_BEFORE (iter, key, data)) {
+         return true;
+      }
+
+      switch (bson_type) {
+      case BSON_TYPE_DOUBLE:
+
+         if (VISIT_DOUBLE (iter, key, bson_iter_double (iter), data)) {
+            return true;
+         }
+
+         break;
+      case BSON_TYPE_UTF8: {
+         uint32_t utf8_len;
+         const char *utf8;
+
+         utf8 = bson_iter_utf8 (iter, &utf8_len);
+
+         if (!bson_utf8_validate (utf8, utf8_len, true)) {
+            iter->err_off = iter->off;
+            return true;
+         }
+
+         if (VISIT_UTF8 (iter, key, utf8_len, utf8, data)) {
+            return true;
+         }
+      } break;
+      case BSON_TYPE_DOCUMENT: {
+         const uint8_t *docbuf = NULL;
+         uint32_t doclen = 0;
+         bson_t b;
+
+         bson_iter_document (iter, &doclen, &docbuf);
+
+         if (bson_init_static (&b, docbuf, doclen) &&
+             VISIT_DOCUMENT (iter, key, &b, data)) {
+            return true;
+         }
+      } break;
+      case BSON_TYPE_ARRAY: {
+         const uint8_t *docbuf = NULL;
+         uint32_t doclen = 0;
+         bson_t b;
+
+         bson_iter_array (iter, &doclen, &docbuf);
+
+         if (bson_init_static (&b, docbuf, doclen) &&
+             VISIT_ARRAY (iter, key, &b, data)) {
+            return true;
+         }
+      } break;
+      case BSON_TYPE_BINARY: {
+         const uint8_t *binary = NULL;
+         bson_subtype_t subtype = BSON_SUBTYPE_BINARY;
+         uint32_t binary_len = 0;
+
+         bson_iter_binary (iter, &subtype, &binary_len, &binary);
+
+         if (VISIT_BINARY (iter, key, subtype, binary_len, binary, data)) {
+            return true;
+         }
+      } break;
+      case BSON_TYPE_UNDEFINED:
+
+         if (VISIT_UNDEFINED (iter, key, data)) {
+            return true;
+         }
+
+         break;
+      case BSON_TYPE_OID:
+
+         if (VISIT_OID (iter, key, bson_iter_oid (iter), data)) {
+            return true;
+         }
+
+         break;
+      case BSON_TYPE_BOOL:
+
+         if (VISIT_BOOL (iter, key, bson_iter_bool (iter), data)) {
+            return true;
+         }
+
+         break;
+      case BSON_TYPE_DATE_TIME:
+
+         if (VISIT_DATE_TIME (iter, key, bson_iter_date_time (iter), data)) {
+            return true;
+         }
+
+         break;
+      case BSON_TYPE_NULL:
+
+         if (VISIT_NULL (iter, key, data)) {
+            return true;
+         }
+
+         break;
+      case BSON_TYPE_REGEX: {
+         const char *regex = NULL;
+         const char *options = NULL;
+         regex = bson_iter_regex (iter, &options);
+
+         if (!bson_utf8_validate (regex, strlen (regex), true)) {
+            iter->err_off = iter->off;
+            return true;
+         }
+
+         if (VISIT_REGEX (iter, key, regex, options, data)) {
+            return true;
+         }
+      } break;
+      case BSON_TYPE_DBPOINTER: {
+         uint32_t collection_len = 0;
+         const char *collection = NULL;
+         const bson_oid_t *oid = NULL;
+
+         bson_iter_dbpointer (iter, &collection_len, &collection, &oid);
+
+         if (!bson_utf8_validate (collection, collection_len, true)) {
+            iter->err_off = iter->off;
+            return true;
+         }
+
+         if (VISIT_DBPOINTER (
+                iter, key, collection_len, collection, oid, data)) {
+            return true;
+         }
+      } break;
+      case BSON_TYPE_CODE: {
+         uint32_t code_len;
+         const char *code;
+
+         code = bson_iter_code (iter, &code_len);
+
+         if (!bson_utf8_validate (code, code_len, true)) {
+            iter->err_off = iter->off;
+            return true;
+         }
+
+         if (VISIT_CODE (iter, key, code_len, code, data)) {
+            return true;
+         }
+      } break;
+      case BSON_TYPE_SYMBOL: {
+         uint32_t symbol_len;
+         const char *symbol;
+
+         symbol = bson_iter_symbol (iter, &symbol_len);
+
+         if (!bson_utf8_validate (symbol, symbol_len, true)) {
+            iter->err_off = iter->off;
+            return true;
+         }
+
+         if (VISIT_SYMBOL (iter, key, symbol_len, symbol, data)) {
+            return true;
+         }
+      } break;
+      case BSON_TYPE_CODEWSCOPE: {
+         uint32_t length = 0;
+         const char *code;
+         const uint8_t *docbuf = NULL;
+         uint32_t doclen = 0;
+         bson_t b;
+
+         code = bson_iter_codewscope (iter, &length, &doclen, &docbuf);
+
+         if (!bson_utf8_validate (code, length, true)) {
+            iter->err_off = iter->off;
+            return true;
+         }
+
+         if (bson_init_static (&b, docbuf, doclen) &&
+             VISIT_CODEWSCOPE (iter, key, length, code, &b, data)) {
+            return true;
+         }
+      } break;
+      case BSON_TYPE_INT32:
+
+         if (VISIT_INT32 (iter, key, bson_iter_int32 (iter), data)) {
+            return true;
+         }
+
+         break;
+      case BSON_TYPE_TIMESTAMP: {
+         uint32_t timestamp;
+         uint32_t increment;
+         bson_iter_timestamp (iter, &timestamp, &increment);
+
+         if (VISIT_TIMESTAMP (iter, key, timestamp, increment, data)) {
+            return true;
+         }
+      } break;
+      case BSON_TYPE_INT64:
+
+         if (VISIT_INT64 (iter, key, bson_iter_int64 (iter), data)) {
+            return true;
+         }
+
+         break;
+      case BSON_TYPE_DECIMAL128: {
+         bson_decimal128_t dec;
+         bson_iter_decimal128 (iter, &dec);
+
+         if (VISIT_DECIMAL128 (iter, key, &dec, data)) {
+            return true;
+         }
+      } break;
+      case BSON_TYPE_MAXKEY:
+
+         if (VISIT_MAXKEY (iter, bson_iter_key_unsafe (iter), data)) {
+            return true;
+         }
+
+         break;
+      case BSON_TYPE_MINKEY:
+
+         if (VISIT_MINKEY (iter, bson_iter_key_unsafe (iter), data)) {
+            return true;
+         }
+
+         break;
+      case BSON_TYPE_EOD:
+      default:
+         break;
+      }
+
+      if (VISIT_AFTER (iter, bson_iter_key_unsafe (iter), data)) {
+         return true;
+      }
+   }
+
+   if (iter->err_off) {
+      if (unsupported && visitor->visit_unsupported_type &&
+          bson_utf8_validate (key, strlen (key), false)) {
+         visitor->visit_unsupported_type (iter, key, bson_type, data);
+         return false;
+      }
+
+      VISIT_CORRUPT (iter, data);
+   }
+
+#undef VISIT_FIELD
+
+   return false;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_overwrite_bool --
+ *
+ *       Overwrites the current BSON_TYPE_BOOLEAN field with a new value.
+ *       This is performed in-place and therefore no keys are moved.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_iter_overwrite_bool (bson_iter_t *iter, /* IN */
+                          bool value)        /* IN */
+{
+   BSON_ASSERT (iter);
+   value = !!value;
+
+   if (ITER_TYPE (iter) == BSON_TYPE_BOOL) {
+      memcpy ((void *) (iter->raw + iter->d1), &value, 1);
+   }
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_overwrite_int32 --
+ *
+ *       Overwrites the current BSON_TYPE_INT32 field with a new value.
+ *       This is performed in-place and therefore no keys are moved.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_iter_overwrite_int32 (bson_iter_t *iter, /* IN */
+                           int32_t value)     /* IN */
+{
+   BSON_ASSERT (iter);
+
+   if (ITER_TYPE (iter) == BSON_TYPE_INT32) {
+#if BSON_BYTE_ORDER != BSON_LITTLE_ENDIAN
+      value = BSON_UINT32_TO_LE (value);
+#endif
+      memcpy ((void *) (iter->raw + iter->d1), &value, sizeof (value));
+   }
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_overwrite_int64 --
+ *
+ *       Overwrites the current BSON_TYPE_INT64 field with a new value.
+ *       This is performed in-place and therefore no keys are moved.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_iter_overwrite_int64 (bson_iter_t *iter, /* IN */
+                           int64_t value)     /* IN */
+{
+   BSON_ASSERT (iter);
+
+   if (ITER_TYPE (iter) == BSON_TYPE_INT64) {
+#if BSON_BYTE_ORDER != BSON_LITTLE_ENDIAN
+      value = BSON_UINT64_TO_LE (value);
+#endif
+      memcpy ((void *) (iter->raw + iter->d1), &value, sizeof (value));
+   }
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_overwrite_double --
+ *
+ *       Overwrites the current BSON_TYPE_DOUBLE field with a new value.
+ *       This is performed in-place and therefore no keys are moved.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_iter_overwrite_double (bson_iter_t *iter, /* IN */
+                            double value)      /* IN */
+{
+   BSON_ASSERT (iter);
+
+   if (ITER_TYPE (iter) == BSON_TYPE_DOUBLE) {
+      value = BSON_DOUBLE_TO_LE (value);
+      memcpy ((void *) (iter->raw + iter->d1), &value, sizeof (value));
+   }
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_overwrite_decimal128 --
+ *
+ *       Overwrites the current BSON_TYPE_DECIMAL128 field with a new value.
+ *       This is performed in-place and therefore no keys are moved.
+ *
+ * Returns:
+ *    None.
+ *
+ * Side effects:
+ *    None.
+ *
+ *--------------------------------------------------------------------------
+ */
+void
+bson_iter_overwrite_decimal128 (bson_iter_t *iter,        /* IN */
+                                bson_decimal128_t *value) /* IN */
+{
+   BSON_ASSERT (iter);
+
+   if (ITER_TYPE (iter) == BSON_TYPE_DECIMAL128) {
+#if BSON_BYTE_ORDER != BSON_LITTLE_ENDIAN
+      uint64_t data[2];
+      data[0] = BSON_UINT64_TO_LE (value->low);
+      data[1] = BSON_UINT64_TO_LE (value->high);
+      memcpy ((void *) (iter->raw + iter->d1), data, sizeof (data));
+#else
+      memcpy ((void *) (iter->raw + iter->d1), value, sizeof (*value));
+#endif
+   }
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_iter_value --
+ *
+ *       Retrieves a bson_value_t containing the boxed value of the current
+ *       element. The result of this function valid until the state of
+ *       iter has been changed (through the use of bson_iter_next()).
+ *
+ * Returns:
+ *       A bson_value_t that should not be modified or freed. If you need
+ *       to hold on to the value, use bson_value_copy().
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+const bson_value_t *
+bson_iter_value (bson_iter_t *iter) /* IN */
+{
+   bson_value_t *value;
+
+   BSON_ASSERT (iter);
+
+   value = &iter->value;
+   value->value_type = ITER_TYPE (iter);
+
+   switch (value->value_type) {
+   case BSON_TYPE_DOUBLE:
+      value->value.v_double = bson_iter_double (iter);
+      break;
+   case BSON_TYPE_UTF8:
+      value->value.v_utf8.str =
+         (char *) bson_iter_utf8 (iter, &value->value.v_utf8.len);
+      break;
+   case BSON_TYPE_DOCUMENT:
+      bson_iter_document (iter,
+                          &value->value.v_doc.data_len,
+                          (const uint8_t **) &value->value.v_doc.data);
+      break;
+   case BSON_TYPE_ARRAY:
+      bson_iter_array (iter,
+                       &value->value.v_doc.data_len,
+                       (const uint8_t **) &value->value.v_doc.data);
+      break;
+   case BSON_TYPE_BINARY:
+      bson_iter_binary (iter,
+                        &value->value.v_binary.subtype,
+                        &value->value.v_binary.data_len,
+                        (const uint8_t **) &value->value.v_binary.data);
+      break;
+   case BSON_TYPE_OID:
+      bson_oid_copy (bson_iter_oid (iter), &value->value.v_oid);
+      break;
+   case BSON_TYPE_BOOL:
+      value->value.v_bool = bson_iter_bool (iter);
+      break;
+   case BSON_TYPE_DATE_TIME:
+      value->value.v_datetime = bson_iter_date_time (iter);
+      break;
+   case BSON_TYPE_REGEX:
+      value->value.v_regex.regex = (char *) bson_iter_regex (
+         iter, (const char **) &value->value.v_regex.options);
+      break;
+   case BSON_TYPE_DBPOINTER: {
+      const bson_oid_t *oid;
+
+      bson_iter_dbpointer (iter,
+                           &value->value.v_dbpointer.collection_len,
+                           (const char **) &value->value.v_dbpointer.collection,
+                           &oid);
+      bson_oid_copy (oid, &value->value.v_dbpointer.oid);
+      break;
+   }
+   case BSON_TYPE_CODE:
+      value->value.v_code.code =
+         (char *) bson_iter_code (iter, &value->value.v_code.code_len);
+      break;
+   case BSON_TYPE_SYMBOL:
+      value->value.v_symbol.symbol =
+         (char *) bson_iter_symbol (iter, &value->value.v_symbol.len);
+      break;
+   case BSON_TYPE_CODEWSCOPE:
+      value->value.v_codewscope.code = (char *) bson_iter_codewscope (
+         iter,
+         &value->value.v_codewscope.code_len,
+         &value->value.v_codewscope.scope_len,
+         (const uint8_t **) &value->value.v_codewscope.scope_data);
+      break;
+   case BSON_TYPE_INT32:
+      value->value.v_int32 = bson_iter_int32 (iter);
+      break;
+   case BSON_TYPE_TIMESTAMP:
+      bson_iter_timestamp (iter,
+                           &value->value.v_timestamp.timestamp,
+                           &value->value.v_timestamp.increment);
+      break;
+   case BSON_TYPE_INT64:
+      value->value.v_int64 = bson_iter_int64 (iter);
+      break;
+   case BSON_TYPE_DECIMAL128:
+      bson_iter_decimal128 (iter, &(value->value.v_decimal128));
+      break;
+   case BSON_TYPE_NULL:
+   case BSON_TYPE_UNDEFINED:
+   case BSON_TYPE_MAXKEY:
+   case BSON_TYPE_MINKEY:
+      break;
+   case BSON_TYPE_EOD:
+   default:
+      return NULL;
+   }
+
+   return value;
+}
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-iter.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-iter.h
new file mode 100644
index 0000000000000000000000000000000000000000..42457816c65d4e3183d9cc08391d472b5ea4d2cb
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-iter.h
@@ -0,0 +1,507 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef BSON_ITER_H
+#define BSON_ITER_H
+
+#include "bson.h"
+#include "bson-endian.h"
+#include "bson-macros.h"
+#include "bson-types.h"
+
+
+BSON_BEGIN_DECLS
+
+
+#define BSON_ITER_HOLDS_DOUBLE(iter) \
+   (bson_iter_type ((iter)) == BSON_TYPE_DOUBLE)
+
+#define BSON_ITER_HOLDS_UTF8(iter) (bson_iter_type ((iter)) == BSON_TYPE_UTF8)
+
+#define BSON_ITER_HOLDS_DOCUMENT(iter) \
+   (bson_iter_type ((iter)) == BSON_TYPE_DOCUMENT)
+
+#define BSON_ITER_HOLDS_ARRAY(iter) (bson_iter_type ((iter)) == BSON_TYPE_ARRAY)
+
+#define BSON_ITER_HOLDS_BINARY(iter) \
+   (bson_iter_type ((iter)) == BSON_TYPE_BINARY)
+
+#define BSON_ITER_HOLDS_UNDEFINED(iter) \
+   (bson_iter_type ((iter)) == BSON_TYPE_UNDEFINED)
+
+#define BSON_ITER_HOLDS_OID(iter) (bson_iter_type ((iter)) == BSON_TYPE_OID)
+
+#define BSON_ITER_HOLDS_BOOL(iter) (bson_iter_type ((iter)) == BSON_TYPE_BOOL)
+
+#define BSON_ITER_HOLDS_DATE_TIME(iter) \
+   (bson_iter_type ((iter)) == BSON_TYPE_DATE_TIME)
+
+#define BSON_ITER_HOLDS_NULL(iter) (bson_iter_type ((iter)) == BSON_TYPE_NULL)
+
+#define BSON_ITER_HOLDS_REGEX(iter) (bson_iter_type ((iter)) == BSON_TYPE_REGEX)
+
+#define BSON_ITER_HOLDS_DBPOINTER(iter) \
+   (bson_iter_type ((iter)) == BSON_TYPE_DBPOINTER)
+
+#define BSON_ITER_HOLDS_CODE(iter) (bson_iter_type ((iter)) == BSON_TYPE_CODE)
+
+#define BSON_ITER_HOLDS_SYMBOL(iter) \
+   (bson_iter_type ((iter)) == BSON_TYPE_SYMBOL)
+
+#define BSON_ITER_HOLDS_CODEWSCOPE(iter) \
+   (bson_iter_type ((iter)) == BSON_TYPE_CODEWSCOPE)
+
+#define BSON_ITER_HOLDS_INT32(iter) (bson_iter_type ((iter)) == BSON_TYPE_INT32)
+
+#define BSON_ITER_HOLDS_TIMESTAMP(iter) \
+   (bson_iter_type ((iter)) == BSON_TYPE_TIMESTAMP)
+
+#define BSON_ITER_HOLDS_INT64(iter) (bson_iter_type ((iter)) == BSON_TYPE_INT64)
+
+#define BSON_ITER_HOLDS_DECIMAL128(iter) \
+   (bson_iter_type ((iter)) == BSON_TYPE_DECIMAL128)
+
+#define BSON_ITER_HOLDS_MAXKEY(iter) \
+   (bson_iter_type ((iter)) == BSON_TYPE_MAXKEY)
+
+#define BSON_ITER_HOLDS_MINKEY(iter) \
+   (bson_iter_type ((iter)) == BSON_TYPE_MINKEY)
+
+#define BSON_ITER_HOLDS_INT(iter) \
+   (BSON_ITER_HOLDS_INT32 (iter) || BSON_ITER_HOLDS_INT64 (iter))
+
+#define BSON_ITER_HOLDS_NUMBER(iter) \
+   (BSON_ITER_HOLDS_INT (iter) || BSON_ITER_HOLDS_DOUBLE (iter))
+
+#define BSON_ITER_IS_KEY(iter, key) \
+   (0 == strcmp ((key), bson_iter_key ((iter))))
+
+
+BSON_EXPORT (const bson_value_t *)
+bson_iter_value (bson_iter_t *iter);
+
+
+/**
+ * bson_iter_utf8_len_unsafe:
+ * @iter: a bson_iter_t.
+ *
+ * Returns the length of a string currently pointed to by @iter. This performs
+ * no validation so the is responsible for knowing the BSON is valid. Calling
+ * bson_validate() is one way to do this ahead of time.
+ */
+static BSON_INLINE uint32_t
+bson_iter_utf8_len_unsafe (const bson_iter_t *iter)
+{
+   int32_t val;
+
+   memcpy (&val, iter->raw + iter->d1, sizeof (val));
+   val = BSON_UINT32_FROM_LE (val);
+   return BSON_MAX (0, val - 1);
+}
+
+
+BSON_EXPORT (void)
+bson_iter_array (const bson_iter_t *iter,
+                 uint32_t *array_len,
+                 const uint8_t **array);
+
+
+BSON_EXPORT (void)
+bson_iter_binary (const bson_iter_t *iter,
+                  unsigned int *subtype,
+                  uint32_t *binary_len,
+                  const uint8_t **binary);
+
+
+BSON_EXPORT (const char *)
+bson_iter_code (const bson_iter_t *iter, uint32_t *length);
+
+
+/**
+ * bson_iter_code_unsafe:
+ * @iter: A bson_iter_t.
+ * @length: A location for the length of the resulting string.
+ *
+ * Like bson_iter_code() but performs no integrity checks.
+ *
+ * Returns: A string that should not be modified or freed.
+ */
+static BSON_INLINE const char *
+bson_iter_code_unsafe (const bson_iter_t *iter, uint32_t *length)
+{
+   *length = bson_iter_utf8_len_unsafe (iter);
+   return (const char *) (iter->raw + iter->d2);
+}
+
+
+BSON_EXPORT (const char *)
+bson_iter_codewscope (const bson_iter_t *iter,
+                      uint32_t *length,
+                      uint32_t *scope_len,
+                      const uint8_t **scope);
+
+
+BSON_EXPORT (void)
+bson_iter_dbpointer (const bson_iter_t *iter,
+                     uint32_t *collection_len,
+                     const char **collection,
+                     const bson_oid_t **oid);
+
+
+BSON_EXPORT (void)
+bson_iter_document (const bson_iter_t *iter,
+                    uint32_t *document_len,
+                    const uint8_t **document);
+
+
+BSON_EXPORT (double)
+bson_iter_double (const bson_iter_t *iter);
+
+BSON_EXPORT (double)
+bson_iter_as_double (const bson_iter_t *iter);
+
+/**
+ * bson_iter_double_unsafe:
+ * @iter: A bson_iter_t.
+ *
+ * Similar to bson_iter_double() but does not perform an integrity checking.
+ *
+ * Returns: A double.
+ */
+static BSON_INLINE double
+bson_iter_double_unsafe (const bson_iter_t *iter)
+{
+   double val;
+
+   memcpy (&val, iter->raw + iter->d1, sizeof (val));
+   return BSON_DOUBLE_FROM_LE (val);
+}
+
+
+BSON_EXPORT (bool)
+bson_iter_init (bson_iter_t *iter, const bson_t *bson);
+
+BSON_EXPORT (bool)
+bson_iter_init_from_data (bson_iter_t *iter,
+                          const uint8_t *data,
+                          size_t length);
+
+
+BSON_EXPORT (bool)
+bson_iter_init_find (bson_iter_t *iter, const bson_t *bson, const char *key);
+
+
+BSON_EXPORT (bool)
+bson_iter_init_find_case (bson_iter_t *iter,
+                          const bson_t *bson,
+                          const char *key);
+
+
+BSON_EXPORT (int32_t)
+bson_iter_int32 (const bson_iter_t *iter);
+
+
+/**
+ * bson_iter_int32_unsafe:
+ * @iter: A bson_iter_t.
+ *
+ * Similar to bson_iter_int32() but with no integrity checking.
+ *
+ * Returns: A 32-bit signed integer.
+ */
+static BSON_INLINE int32_t
+bson_iter_int32_unsafe (const bson_iter_t *iter)
+{
+   int32_t val;
+
+   memcpy (&val, iter->raw + iter->d1, sizeof (val));
+   return BSON_UINT32_FROM_LE (val);
+}
+
+
+BSON_EXPORT (int64_t)
+bson_iter_int64 (const bson_iter_t *iter);
+
+
+BSON_EXPORT (int64_t)
+bson_iter_as_int64 (const bson_iter_t *iter);
+
+
+/**
+ * bson_iter_int64_unsafe:
+ * @iter: a bson_iter_t.
+ *
+ * Similar to bson_iter_int64() but without integrity checking.
+ *
+ * Returns: A 64-bit signed integer.
+ */
+static BSON_INLINE int64_t
+bson_iter_int64_unsafe (const bson_iter_t *iter)
+{
+   int64_t val;
+
+   memcpy (&val, iter->raw + iter->d1, sizeof (val));
+   return BSON_UINT64_FROM_LE (val);
+}
+
+
+BSON_EXPORT (bool)
+bson_iter_find (bson_iter_t *iter, const char *key);
+
+
+BSON_EXPORT (bool)
+bson_iter_find_case (bson_iter_t *iter, const char *key);
+
+
+BSON_EXPORT (bool)
+bson_iter_find_descendant (bson_iter_t *iter,
+                           const char *dotkey,
+                           bson_iter_t *descendant);
+
+
+BSON_EXPORT (bool)
+bson_iter_next (bson_iter_t *iter);
+
+
+BSON_EXPORT (const bson_oid_t *)
+bson_iter_oid (const bson_iter_t *iter);
+
+
+/**
+ * bson_iter_oid_unsafe:
+ * @iter: A #bson_iter_t.
+ *
+ * Similar to bson_iter_oid() but performs no integrity checks.
+ *
+ * Returns: A #bson_oid_t that should not be modified or freed.
+ */
+static BSON_INLINE const bson_oid_t *
+bson_iter_oid_unsafe (const bson_iter_t *iter)
+{
+   return (const bson_oid_t *) (iter->raw + iter->d1);
+}
+
+
+BSON_EXPORT (bool)
+bson_iter_decimal128 (const bson_iter_t *iter, bson_decimal128_t *dec);
+
+
+/**
+ * bson_iter_decimal128_unsafe:
+ * @iter: A #bson_iter_t.
+ *
+ * Similar to bson_iter_decimal128() but performs no integrity checks.
+ *
+ * Returns: A #bson_decimal128_t.
+ */
+static BSON_INLINE void
+bson_iter_decimal128_unsafe (const bson_iter_t *iter, bson_decimal128_t *dec)
+{
+   uint64_t low_le;
+   uint64_t high_le;
+
+   memcpy (&low_le, iter->raw + iter->d1, sizeof (low_le));
+   memcpy (&high_le, iter->raw + iter->d1 + 8, sizeof (high_le));
+
+   dec->low = BSON_UINT64_FROM_LE (low_le);
+   dec->high = BSON_UINT64_FROM_LE (high_le);
+}
+
+
+BSON_EXPORT (const char *)
+bson_iter_key (const bson_iter_t *iter);
+
+
+/**
+ * bson_iter_key_unsafe:
+ * @iter: A bson_iter_t.
+ *
+ * Similar to bson_iter_key() but performs no integrity checking.
+ *
+ * Returns: A string that should not be modified or freed.
+ */
+static BSON_INLINE const char *
+bson_iter_key_unsafe (const bson_iter_t *iter)
+{
+   return (const char *) (iter->raw + iter->key);
+}
+
+
+BSON_EXPORT (const char *)
+bson_iter_utf8 (const bson_iter_t *iter, uint32_t *length);
+
+
+/**
+ * bson_iter_utf8_unsafe:
+ *
+ * Similar to bson_iter_utf8() but performs no integrity checking.
+ *
+ * Returns: A string that should not be modified or freed.
+ */
+static BSON_INLINE const char *
+bson_iter_utf8_unsafe (const bson_iter_t *iter, size_t *length)
+{
+   *length = bson_iter_utf8_len_unsafe (iter);
+   return (const char *) (iter->raw + iter->d2);
+}
+
+
+BSON_EXPORT (char *)
+bson_iter_dup_utf8 (const bson_iter_t *iter, uint32_t *length);
+
+
+BSON_EXPORT (int64_t)
+bson_iter_date_time (const bson_iter_t *iter);
+
+
+BSON_EXPORT (time_t)
+bson_iter_time_t (const bson_iter_t *iter);
+
+
+/**
+ * bson_iter_time_t_unsafe:
+ * @iter: A bson_iter_t.
+ *
+ * Similar to bson_iter_time_t() but performs no integrity checking.
+ *
+ * Returns: A time_t containing the number of seconds since UNIX epoch
+ *          in UTC.
+ */
+static BSON_INLINE time_t
+bson_iter_time_t_unsafe (const bson_iter_t *iter)
+{
+   return (time_t) (bson_iter_int64_unsafe (iter) / 1000UL);
+}
+
+
+BSON_EXPORT (void)
+bson_iter_timeval (const bson_iter_t *iter, struct timeval *tv);
+
+
+/**
+ * bson_iter_timeval_unsafe:
+ * @iter: A bson_iter_t.
+ * @tv: A struct timeval.
+ *
+ * Similar to bson_iter_timeval() but performs no integrity checking.
+ */
+static BSON_INLINE void
+bson_iter_timeval_unsafe (const bson_iter_t *iter, struct timeval *tv)
+{
+   int64_t value = bson_iter_int64_unsafe (iter);
+#ifdef BSON_OS_WIN32
+   tv->tv_sec = (long) (value / 1000);
+#else
+   tv->tv_sec = (suseconds_t) (value / 1000);
+#endif
+   tv->tv_usec = (value % 1000) * 1000;
+}
+
+
+BSON_EXPORT (void)
+bson_iter_timestamp (const bson_iter_t *iter,
+                     uint32_t *timestamp,
+                     uint32_t *increment);
+
+
+BSON_EXPORT (bool)
+bson_iter_bool (const bson_iter_t *iter);
+
+
+/**
+ * bson_iter_bool_unsafe:
+ * @iter: A bson_iter_t.
+ *
+ * Similar to bson_iter_bool() but performs no integrity checking.
+ *
+ * Returns: true or false.
+ */
+static BSON_INLINE bool
+bson_iter_bool_unsafe (const bson_iter_t *iter)
+{
+   char val;
+
+   memcpy (&val, iter->raw + iter->d1, 1);
+   return !!val;
+}
+
+
+BSON_EXPORT (bool)
+bson_iter_as_bool (const bson_iter_t *iter);
+
+
+BSON_EXPORT (const char *)
+bson_iter_regex (const bson_iter_t *iter, const char **options);
+
+
+BSON_EXPORT (const char *)
+bson_iter_symbol (const bson_iter_t *iter, uint32_t *length);
+
+
+BSON_EXPORT (bson_type_t)
+bson_iter_type (const bson_iter_t *iter);
+
+
+/**
+ * bson_iter_type_unsafe:
+ * @iter: A bson_iter_t.
+ *
+ * Similar to bson_iter_type() but performs no integrity checking.
+ *
+ * Returns: A bson_type_t.
+ */
+static BSON_INLINE bson_type_t
+bson_iter_type_unsafe (const bson_iter_t *iter)
+{
+   return (bson_type_t) (iter->raw + iter->type)[0];
+}
+
+
+BSON_EXPORT (bool)
+bson_iter_recurse (const bson_iter_t *iter, bson_iter_t *child);
+
+
+BSON_EXPORT (void)
+bson_iter_overwrite_int32 (bson_iter_t *iter, int32_t value);
+
+
+BSON_EXPORT (void)
+bson_iter_overwrite_int64 (bson_iter_t *iter, int64_t value);
+
+
+BSON_EXPORT (void)
+bson_iter_overwrite_double (bson_iter_t *iter, double value);
+
+
+BSON_EXPORT (void)
+bson_iter_overwrite_decimal128 (bson_iter_t *iter, bson_decimal128_t *value);
+
+
+BSON_EXPORT (void)
+bson_iter_overwrite_bool (bson_iter_t *iter, bool value);
+
+
+BSON_EXPORT (bool)
+bson_iter_visit_all (bson_iter_t *iter,
+                     const bson_visitor_t *visitor,
+                     void *data);
+
+
+BSON_END_DECLS
+
+
+#endif /* BSON_ITER_H */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-json.c b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-json.c
new file mode 100644
index 0000000000000000000000000000000000000000..66580761728bab073f1e026aab13d6bc00bc3a38
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-json.c
@@ -0,0 +1,2061 @@
+/*
+ * Copyright 2014 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <math.h>
+
+#include "bson.h"
+#include "bson-config.h"
+#include "bson-json.h"
+#include "bson-iso8601-private.h"
+#include "b64_pton.h"
+
+#include <chaos/common/bson/jsonsl/jsonsl.h>
+
+#ifdef _WIN32
+#include <io.h>
+#include <share.h>
+#endif
+
+#ifndef _MSC_VER
+#include <strings.h>
+#endif
+
+#define STACK_MAX 100
+#define BSON_JSON_DEFAULT_BUF_SIZE (1 << 14)
+#define AT_LEAST_0(x) ((x) >= 0 ? (x) : 0)
+
+
+typedef enum {
+   BSON_JSON_REGULAR,
+   BSON_JSON_DONE,
+   BSON_JSON_ERROR,
+   BSON_JSON_IN_START_MAP,
+   BSON_JSON_IN_BSON_TYPE,
+   BSON_JSON_IN_BSON_TYPE_DATE_NUMBERLONG,
+   BSON_JSON_IN_BSON_TYPE_DATE_ENDMAP,
+   BSON_JSON_IN_BSON_TYPE_TIMESTAMP_STARTMAP,
+   BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES,
+   BSON_JSON_IN_BSON_TYPE_TIMESTAMP_ENDMAP,
+   BSON_JSON_IN_BSON_TYPE_SCOPE_STARTMAP,
+   BSON_JSON_IN_BSON_TYPE_DBPOINTER_STARTMAP,
+   BSON_JSON_IN_SCOPE,
+   BSON_JSON_IN_DBPOINTER,
+} bson_json_read_state_t;
+
+
+typedef enum {
+   BSON_JSON_LF_REGEX,
+   BSON_JSON_LF_OPTIONS,
+   BSON_JSON_LF_CODE,
+   BSON_JSON_LF_SCOPE,
+   BSON_JSON_LF_OID,
+   BSON_JSON_LF_BINARY,
+   BSON_JSON_LF_TYPE,
+   BSON_JSON_LF_DATE,
+   BSON_JSON_LF_TIMESTAMP_T,
+   BSON_JSON_LF_TIMESTAMP_I,
+   BSON_JSON_LF_UNDEFINED,
+   BSON_JSON_LF_MINKEY,
+   BSON_JSON_LF_MAXKEY,
+   BSON_JSON_LF_INT32,
+   BSON_JSON_LF_INT64,
+   BSON_JSON_LF_DOUBLE,
+   BSON_JSON_LF_DECIMAL128,
+   BSON_JSON_LF_DBPOINTER,
+   BSON_JSON_LF_SYMBOL
+} bson_json_read_bson_state_t;
+
+
+typedef struct {
+   uint8_t *buf;
+   size_t n_bytes;
+   size_t len;
+} bson_json_buf_t;
+
+
+typedef struct {
+   int i;
+   bool is_array;
+   bool is_scope;
+   bool is_dbpointer;
+   bson_t bson;
+} bson_json_stack_frame_t;
+
+
+typedef union {
+   struct {
+      bool has_regex;
+      bool has_options;
+   } regex;
+   struct {
+      bool has_oid;
+      bson_oid_t oid;
+   } oid;
+   struct {
+      bool has_binary;
+      bool has_subtype;
+      bson_subtype_t type;
+   } binary;
+   struct {
+      bool has_date;
+      int64_t date;
+   } date;
+   struct {
+      bool has_t;
+      bool has_i;
+      uint32_t t;
+      uint32_t i;
+   } timestamp;
+   struct {
+      bool has_undefined;
+   } undefined;
+   struct {
+      bool has_minkey;
+   } minkey;
+   struct {
+      bool has_maxkey;
+   } maxkey;
+   struct {
+      int32_t value;
+   } v_int32;
+   struct {
+      int64_t value;
+   } v_int64;
+   struct {
+      double value;
+   } v_double;
+   struct {
+      bson_decimal128_t value;
+   } v_decimal128;
+} bson_json_bson_data_t;
+
+
+/* collect info while parsing a {$code: "...", $scope: {...}} object */
+typedef struct {
+   bool has_code;
+   bool has_scope;
+   bool in_scope;
+   bson_json_buf_t key_buf;
+   bson_json_buf_t code_buf;
+} bson_json_code_t;
+
+
+static void
+_bson_json_code_cleanup (bson_json_code_t *code_data)
+{
+   bson_free (code_data->key_buf.buf);
+   bson_free (code_data->code_buf.buf);
+}
+
+
+typedef struct {
+   bson_t *bson;
+   bson_json_stack_frame_t stack[STACK_MAX];
+   int n;
+   const char *key;
+   bson_json_buf_t key_buf;
+   bson_json_buf_t unescaped;
+   bson_json_read_state_t read_state;
+   bson_json_read_bson_state_t bson_state;
+   bson_type_t bson_type;
+   bson_json_buf_t bson_type_buf[3];
+   bson_json_bson_data_t bson_type_data;
+   bson_json_code_t code_data;
+   bson_json_buf_t dbpointer_key;
+} bson_json_reader_bson_t;
+
+
+typedef struct {
+   void *data;
+   bson_json_reader_cb cb;
+   bson_json_destroy_cb dcb;
+   uint8_t *buf;
+   size_t buf_size;
+   size_t bytes_read;
+   size_t bytes_parsed;
+   bool all_whitespace;
+} bson_json_reader_producer_t;
+
+
+struct _bson_json_reader_t {
+   bson_json_reader_producer_t producer;
+   bson_json_reader_bson_t bson;
+   jsonsl_t json;
+   ssize_t json_text_pos;
+   bool should_reset;
+   ssize_t advance;
+   bson_json_buf_t tok_accumulator;
+   bson_error_t *error;
+};
+
+
+typedef struct {
+   int fd;
+   bool do_close;
+} bson_json_reader_handle_fd_t;
+
+
+static void
+_noop (void)
+{
+}
+
+#define STACK_ELE(_delta, _name) (bson->stack[(_delta) + bson->n]._name)
+#define STACK_BSON(_delta) \
+   (((_delta) + bson->n) == 0 ? bson->bson : &STACK_ELE (_delta, bson))
+#define STACK_BSON_PARENT STACK_BSON (-1)
+#define STACK_BSON_CHILD STACK_BSON (0)
+#define STACK_I STACK_ELE (0, i)
+#define STACK_IS_ARRAY STACK_ELE (0, is_array)
+#define STACK_IS_SCOPE STACK_ELE (0, is_scope)
+#define STACK_IS_DBPOINTER STACK_ELE (0, is_dbpointer)
+#define STACK_PUSH_ARRAY(statement)     \
+   do {                                 \
+      if (bson->n >= (STACK_MAX - 1)) { \
+         return;                        \
+      }                                 \
+      bson->n++;                        \
+      STACK_I = 0;                      \
+      STACK_IS_ARRAY = 1;               \
+      STACK_IS_SCOPE = 0;               \
+      STACK_IS_DBPOINTER = 0;           \
+      if (bson->n != 0) {               \
+         statement;                     \
+      }                                 \
+   } while (0)
+#define STACK_PUSH_DOC(statement)       \
+   do {                                 \
+      if (bson->n >= (STACK_MAX - 1)) { \
+         return;                        \
+      }                                 \
+      bson->n++;                        \
+      STACK_IS_ARRAY = 0;               \
+      STACK_IS_SCOPE = 0;               \
+      STACK_IS_DBPOINTER = 0;           \
+      if (bson->n != 0) {               \
+         statement;                     \
+      }                                 \
+   } while (0)
+#define STACK_PUSH_SCOPE(statement)     \
+   do {                                 \
+      if (bson->n >= (STACK_MAX - 1)) { \
+         return;                        \
+      }                                 \
+      bson->n++;                        \
+      STACK_IS_ARRAY = 0;               \
+      STACK_IS_SCOPE = 1;               \
+      STACK_IS_DBPOINTER = 0;           \
+      bson->code_data.in_scope = true;  \
+      if (bson->n != 0) {               \
+         statement;                     \
+      }                                 \
+   } while (0)
+#define STACK_PUSH_DBPOINTER(statement) \
+   do {                                 \
+      if (bson->n >= (STACK_MAX - 1)) { \
+         return;                        \
+      }                                 \
+      bson->n++;                        \
+      STACK_IS_ARRAY = 0;               \
+      STACK_IS_SCOPE = 0;               \
+      STACK_IS_DBPOINTER = 1;           \
+      if (bson->n != 0) {               \
+         statement;                     \
+      }                                 \
+   } while (0)
+#define STACK_POP_ARRAY(statement) \
+   do {                            \
+      if (!STACK_IS_ARRAY) {       \
+         return;                   \
+      }                            \
+      if (bson->n < 0) {           \
+         return;                   \
+      }                            \
+      if (bson->n > 0) {           \
+         statement;                \
+      }                            \
+      bson->n--;                   \
+   } while (0)
+#define STACK_POP_DOC(statement) \
+   do {                          \
+      if (STACK_IS_ARRAY) {      \
+         return;                 \
+      }                          \
+      if (bson->n < 0) {         \
+         return;                 \
+      }                          \
+      if (bson->n > 0) {         \
+         statement;              \
+      }                          \
+      bson->n--;                 \
+   } while (0)
+#define STACK_POP_SCOPE                 \
+   do {                                 \
+      STACK_POP_DOC (_noop ());         \
+      bson->code_data.in_scope = false; \
+   } while (0);
+#define STACK_POP_DBPOINTER STACK_POP_DOC (_noop ())
+#define BASIC_CB_PREAMBLE                         \
+   const char *key;                               \
+   size_t len;                                    \
+   bson_json_reader_bson_t *bson = &reader->bson; \
+   _bson_json_read_fixup_key (bson);              \
+   key = bson->key;                               \
+   len = bson->key_buf.len;
+#define BASIC_CB_BAIL_IF_NOT_NORMAL(_type)                                     \
+   if (bson->read_state != BSON_JSON_REGULAR) {                                \
+      _bson_json_read_set_error (                                              \
+         reader, "Invalid read of %s in state %d", (_type), bson->read_state); \
+      return;                                                                  \
+   } else if (!key) {                                                          \
+      _bson_json_read_set_error (reader,                                       \
+                                 "Invalid read of %s without key in state %d", \
+                                 (_type),                                      \
+                                 bson->read_state);                            \
+      return;                                                                  \
+   }
+#define HANDLE_OPTION(_key, _type, _state)                                  \
+   (len == strlen (_key) && strncmp ((const char *) val, (_key), len) == 0) \
+   {                                                                        \
+      if (bson->bson_type && bson->bson_type != (_type)) {                  \
+         _bson_json_read_set_error (                                        \
+            reader,                                                         \
+            "Invalid key %s.  Looking for values for %d",                   \
+            (_key),                                                         \
+            bson->bson_type);                                               \
+         return;                                                            \
+      }                                                                     \
+      bson->bson_type = (_type);                                            \
+      bson->bson_state = (_state);                                          \
+   }
+
+
+static void
+_bson_json_read_set_error (bson_json_reader_t *reader, const char *fmt, ...)
+   BSON_GNUC_PRINTF (2, 3);
+
+
+static void
+_bson_json_read_set_error (bson_json_reader_t *reader, /* IN */
+                           const char *fmt,            /* IN */
+                           ...)
+{
+   va_list ap;
+
+   if (reader->error) {
+      reader->error->domain = BSON_ERROR_JSON;
+      reader->error->code = BSON_JSON_ERROR_READ_INVALID_PARAM;
+      va_start (ap, fmt);
+      bson_vsnprintf (
+         reader->error->message, sizeof reader->error->message, fmt, ap);
+      va_end (ap);
+      reader->error->message[sizeof reader->error->message - 1] = '\0';
+   }
+
+   reader->bson.read_state = BSON_JSON_ERROR;
+   jsonsl_stop (reader->json);
+}
+
+
+static void
+_bson_json_read_corrupt (bson_json_reader_t *reader, const char *fmt, ...)
+   BSON_GNUC_PRINTF (2, 3);
+
+
+static void
+_bson_json_read_corrupt (bson_json_reader_t *reader, /* IN */
+                         const char *fmt,            /* IN */
+                         ...)
+{
+   va_list ap;
+
+   if (reader->error) {
+      reader->error->domain = BSON_ERROR_JSON;
+      reader->error->code = BSON_JSON_ERROR_READ_CORRUPT_JS;
+      va_start (ap, fmt);
+      bson_vsnprintf (
+         reader->error->message, sizeof reader->error->message, fmt, ap);
+      va_end (ap);
+      reader->error->message[sizeof reader->error->message - 1] = '\0';
+   }
+
+   reader->bson.read_state = BSON_JSON_ERROR;
+   jsonsl_stop (reader->json);
+}
+
+
+static void
+_bson_json_buf_ensure (bson_json_buf_t *buf, /* IN */
+                       size_t len)           /* IN */
+{
+   if (buf->n_bytes < len) {
+      bson_free (buf->buf);
+
+      buf->n_bytes = bson_next_power_of_two (len);
+      buf->buf = bson_malloc (buf->n_bytes);
+   }
+}
+
+
+static void
+_bson_json_buf_set (bson_json_buf_t *buf, const void *from, size_t len)
+{
+   _bson_json_buf_ensure (buf, len + 1);
+   memcpy (buf->buf, from, len);
+   buf->buf[len] = '\0';
+   buf->len = len;
+}
+
+
+static void
+_bson_json_buf_append (bson_json_buf_t *buf, const void *from, size_t len)
+{
+   size_t len_with_null = len + 1;
+
+   if (buf->len == 0) {
+      _bson_json_buf_ensure (buf, len_with_null);
+   } else if (buf->n_bytes < buf->len + len_with_null) {
+      buf->n_bytes = bson_next_power_of_two (buf->len + len_with_null);
+      buf->buf = bson_realloc (buf->buf, buf->n_bytes);
+   }
+
+   memcpy (buf->buf + buf->len, from, len);
+   buf->len += len;
+   buf->buf[buf->len] = '\0';
+}
+
+
+static void
+_bson_json_read_fixup_key (bson_json_reader_bson_t *bson) /* IN */
+{
+   bson_json_read_state_t rs = bson->read_state;
+
+   if (bson->n >= 0 && STACK_IS_ARRAY && rs == BSON_JSON_REGULAR) {
+      _bson_json_buf_ensure (&bson->key_buf, 12);
+      bson->key_buf.len = bson_uint32_to_string (
+         STACK_I, &bson->key, (char *) bson->key_buf.buf, 12);
+      STACK_I++;
+   }
+}
+
+
+static void
+_bson_json_read_null (bson_json_reader_t *reader)
+{
+   BASIC_CB_PREAMBLE;
+   BASIC_CB_BAIL_IF_NOT_NORMAL ("null");
+
+   bson_append_null (STACK_BSON_CHILD, key, (int) len);
+}
+
+
+static void
+_bson_json_read_boolean (bson_json_reader_t *reader, /* IN */
+                         int val)                    /* IN */
+{
+   BASIC_CB_PREAMBLE;
+
+   if (bson->read_state == BSON_JSON_IN_BSON_TYPE &&
+       bson->bson_state == BSON_JSON_LF_UNDEFINED) {
+      bson->bson_type_data.undefined.has_undefined = true;
+      return;
+   }
+
+   BASIC_CB_BAIL_IF_NOT_NORMAL ("boolean");
+
+   bson_append_bool (STACK_BSON_CHILD, key, (int) len, val);
+}
+
+
+static void
+_bson_json_read_integer (bson_json_reader_t *reader, /* IN */
+                         int64_t val)                /* IN */
+{
+   bson_json_read_state_t rs;
+   bson_json_read_bson_state_t bs;
+
+   BASIC_CB_PREAMBLE;
+
+   rs = bson->read_state;
+   bs = bson->bson_state;
+
+   if (rs == BSON_JSON_REGULAR) {
+      BASIC_CB_BAIL_IF_NOT_NORMAL ("integer");
+
+      if (val <= INT32_MAX && val >= INT32_MIN) {
+         bson_append_int32 (STACK_BSON_CHILD, key, (int) len, (int) val);
+      } else {
+         bson_append_int64 (STACK_BSON_CHILD, key, (int) len, val);
+      }
+   } else if (rs == BSON_JSON_IN_BSON_TYPE ||
+              rs == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES) {
+      switch (bs) {
+      case BSON_JSON_LF_DATE:
+         bson->bson_type_data.date.has_date = true;
+         bson->bson_type_data.date.date = val;
+         break;
+      case BSON_JSON_LF_TIMESTAMP_T:
+         bson->bson_type_data.timestamp.has_t = true;
+         bson->bson_type_data.timestamp.t = (uint32_t) val;
+         break;
+      case BSON_JSON_LF_TIMESTAMP_I:
+         bson->bson_type_data.timestamp.has_i = true;
+         bson->bson_type_data.timestamp.i = (uint32_t) val;
+         break;
+      case BSON_JSON_LF_MINKEY:
+         bson->bson_type_data.minkey.has_minkey = true;
+         break;
+      case BSON_JSON_LF_MAXKEY:
+         bson->bson_type_data.maxkey.has_maxkey = true;
+         break;
+      case BSON_JSON_LF_REGEX:
+      case BSON_JSON_LF_OPTIONS:
+      case BSON_JSON_LF_CODE:
+      case BSON_JSON_LF_SCOPE:
+      case BSON_JSON_LF_OID:
+      case BSON_JSON_LF_BINARY:
+      case BSON_JSON_LF_TYPE:
+      case BSON_JSON_LF_UNDEFINED:
+      case BSON_JSON_LF_INT32:
+      case BSON_JSON_LF_INT64:
+      case BSON_JSON_LF_DOUBLE:
+      case BSON_JSON_LF_DECIMAL128:
+      case BSON_JSON_LF_DBPOINTER:
+      case BSON_JSON_LF_SYMBOL:
+      default:
+         _bson_json_read_set_error (
+            reader, "Invalid special type for integer read %d", bs);
+      }
+   } else {
+      _bson_json_read_set_error (
+         reader, "Invalid state for integer read %d", rs);
+   }
+}
+
+
+static bool
+_bson_json_parse_double (bson_json_reader_t *reader,
+                         const char *val,
+                         size_t vlen,
+                         double *d)
+{
+   errno = 0;
+   *d = strtod (val, NULL);
+
+#ifdef _MSC_VER
+   /* Microsoft's strtod parses "NaN", "Infinity", "-Infinity" as 0 */
+   if (*d == 0.0) {
+      if (!_strnicmp (val, "nan", vlen)) {
+#ifdef NAN
+      *d = NAN;
+#else
+         /* Visual Studio 2010 doesn't define NAN or INFINITY
+          * https://msdn.microsoft.com/en-us/library/w22adx1s(v=vs.100).aspx */
+         unsigned long nan[2] = {0xffffffff, 0x7fffffff};
+         *d = *(double *) nan;
+#endif
+         return true;
+      } else if (!_strnicmp (val, "infinity", vlen)) {
+#ifdef INFINITY
+      *d = INFINITY;
+#else
+         unsigned long inf[2] = {0x00000000, 0x7ff00000};
+         *d = *(double *) inf;
+#endif
+         return true;
+      } else if (!_strnicmp (val, "-infinity", vlen)) {
+#ifdef INFINITY
+      *d = -INFINITY;
+#else
+         unsigned long inf[2] = {0x00000000, 0xfff00000};
+         *d = *(double *) inf;
+#endif
+         return true;
+      }
+   }
+
+   if ((*d == HUGE_VAL || *d == -HUGE_VAL) && errno == ERANGE) {
+      _bson_json_read_set_error (
+         reader, "Number \"%.*s\" is out of range", (int) vlen, val);
+
+      return false;
+   }
+#else
+   /* not MSVC -  set err on overflow, but avoid err for infinity */
+   if ((*d == HUGE_VAL || *d == -HUGE_VAL)
+         && errno == ERANGE
+         && strncasecmp (val, "infinity", vlen)
+         && strncasecmp (val, "-infinity", vlen)) {
+      _bson_json_read_set_error (
+         reader, "Number \"%.*s\" is out of range", (int) vlen, val);
+
+      return false;
+   }
+
+#endif /* _MSC_VER */
+   return true;
+}
+
+
+static void
+_bson_json_read_double (bson_json_reader_t *reader, /* IN */
+                        double val)                 /* IN */
+{
+   BASIC_CB_PREAMBLE;
+   BASIC_CB_BAIL_IF_NOT_NORMAL ("double");
+
+   bson_append_double (STACK_BSON_CHILD, key, (int) len, val);
+}
+
+
+static bool
+_bson_json_read_int64 (bson_json_reader_t *reader, /* IN */
+                       const unsigned char *val,   /* IN */
+                       size_t vlen,                /* IN */
+                       int64_t *v64                /* OUT */)
+{
+   bson_json_reader_bson_t *bson = &reader->bson;
+   char *endptr = NULL;
+
+   _bson_json_read_fixup_key (bson);
+   errno = 0;
+   *v64 = bson_ascii_strtoll ((const char *) val, &endptr, 10);
+
+   if (((*v64 == INT64_MIN) || (*v64 == INT64_MAX)) && (errno == ERANGE)) {
+      return false;
+   }
+
+   if (endptr != ((const char *) val + vlen)) {
+      return false;
+   }
+
+   return true;
+}
+
+
+static void
+_bson_json_read_string (bson_json_reader_t *reader, /* IN */
+                        const unsigned char *val,   /* IN */
+                        size_t vlen)                /* IN */
+{
+   bson_json_read_state_t rs;
+   bson_json_read_bson_state_t bs;
+
+   BASIC_CB_PREAMBLE;
+
+   rs = bson->read_state;
+   bs = bson->bson_state;
+
+   if (!bson_utf8_validate ((const char *) val, vlen, true /*allow null*/)) {
+      _bson_json_read_corrupt (reader, "invalid bytes in UTF8 string");
+      return;
+   }
+
+   if (rs == BSON_JSON_REGULAR) {
+      BASIC_CB_BAIL_IF_NOT_NORMAL ("string");
+      bson_append_utf8 (
+         STACK_BSON_CHILD, key, (int) len, (const char *) val, (int) vlen);
+   } else if (rs == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_STARTMAP) {
+      /* new-style "key" : {"$timestamp": "180388626433" } */
+      int64_t v64;
+      if (!_bson_json_read_int64 (reader, val, vlen, &v64)) {
+         _bson_json_read_corrupt (reader, "Invalid timestamp: \"%s\"", val);
+         return;
+      }
+
+      bson->bson_type_data.timestamp.has_t = true;
+      bson->bson_type_data.timestamp.has_i = true;
+      bson->bson_type_data.timestamp.t = (uint32_t) (v64 >> 32);
+      bson->bson_type_data.timestamp.i = (uint32_t) v64;
+   } else if (rs == BSON_JSON_IN_BSON_TYPE_SCOPE_STARTMAP ||
+              rs == BSON_JSON_IN_BSON_TYPE_DBPOINTER_STARTMAP) {
+      _bson_json_read_set_error (
+         reader, "Invalid read of %s in state %d", val, rs);
+   } else if (rs == BSON_JSON_IN_BSON_TYPE ||
+              rs == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES ||
+              rs == BSON_JSON_IN_BSON_TYPE_DATE_NUMBERLONG) {
+      const char *val_w_null;
+      _bson_json_buf_set (&bson->bson_type_buf[2], val, vlen);
+      val_w_null = (const char *) bson->bson_type_buf[2].buf;
+
+      switch (bs) {
+      case BSON_JSON_LF_REGEX:
+         bson->bson_type_data.regex.has_regex = true;
+         _bson_json_buf_set (&bson->bson_type_buf[0], val, vlen);
+         break;
+      case BSON_JSON_LF_OPTIONS:
+         bson->bson_type_data.regex.has_options = true;
+         _bson_json_buf_set (&bson->bson_type_buf[1], val, vlen);
+         break;
+      case BSON_JSON_LF_OID:
+
+         if (vlen != 24) {
+            goto BAD_PARSE;
+         }
+
+         bson->bson_type_data.oid.has_oid = true;
+         bson_oid_init_from_string (&bson->bson_type_data.oid.oid, val_w_null);
+         break;
+      case BSON_JSON_LF_TYPE:
+         bson->bson_type_data.binary.has_subtype = true;
+
+#ifdef _MSC_VER
+#define SSCANF sscanf_s
+#else
+#define SSCANF sscanf
+#endif
+
+         if (SSCANF (val_w_null, "%02x", &bson->bson_type_data.binary.type) !=
+             1) {
+            goto BAD_PARSE;
+         }
+
+#undef SSCANF
+
+         break;
+      case BSON_JSON_LF_BINARY: {
+         int binary_len;
+         bson->bson_type_data.binary.has_binary = true;
+         binary_len = b64_pton (val_w_null, NULL, 0);
+         if (binary_len < 0) {
+            goto BAD_PARSE;
+         }
+
+         _bson_json_buf_ensure (&bson->bson_type_buf[0],
+                                (size_t) binary_len + 1);
+         b64_pton (
+            val_w_null, bson->bson_type_buf[0].buf, (size_t) binary_len + 1);
+         bson->bson_type_buf[0].len = (size_t) binary_len;
+      } break;
+      case BSON_JSON_LF_INT32: {
+         int64_t v64;
+         if (!_bson_json_read_int64 (reader, val, vlen, &v64)) {
+            goto BAD_PARSE;
+         }
+
+         if (v64 < INT32_MIN || v64 > INT32_MAX) {
+            goto BAD_PARSE;
+         }
+
+         if (bson->read_state == BSON_JSON_IN_BSON_TYPE) {
+            bson->bson_type_data.v_int32.value = (int32_t) v64;
+         } else {
+            goto BAD_PARSE;
+         }
+      } break;
+      case BSON_JSON_LF_INT64: {
+         int64_t v64;
+         if (!_bson_json_read_int64 (reader, val, vlen, &v64)) {
+            goto BAD_PARSE;
+         }
+
+         if (bson->read_state == BSON_JSON_IN_BSON_TYPE) {
+            bson->bson_type_data.v_int64.value = v64;
+         } else if (bson->read_state ==
+                    BSON_JSON_IN_BSON_TYPE_DATE_NUMBERLONG) {
+            bson->bson_type_data.date.has_date = true;
+            bson->bson_type_data.date.date = v64;
+         } else {
+            goto BAD_PARSE;
+         }
+      } break;
+      case BSON_JSON_LF_DOUBLE: {
+         _bson_json_parse_double (reader,
+                                  (const char *) val,
+                                  vlen,
+                                  &bson->bson_type_data.v_double.value);
+      } break;
+      case BSON_JSON_LF_DATE: {
+         int64_t v64;
+
+         if (!_bson_iso8601_date_parse (
+                (char *) val, (int) vlen, &v64, reader->error)) {
+            jsonsl_stop (reader->json);
+         } else {
+            bson->bson_type_data.date.has_date = true;
+            bson->bson_type_data.date.date = v64;
+         }
+      } break;
+      case BSON_JSON_LF_DECIMAL128: {
+         bson_decimal128_t decimal128;
+         bson_decimal128_from_string (val_w_null, &decimal128);
+
+         if (bson->read_state == BSON_JSON_IN_BSON_TYPE) {
+            bson->bson_type_data.v_decimal128.value = decimal128;
+         } else {
+            goto BAD_PARSE;
+         }
+      } break;
+      case BSON_JSON_LF_CODE:
+         _bson_json_buf_set (&bson->code_data.code_buf, val, vlen);
+         break;
+      case BSON_JSON_LF_SYMBOL:
+         bson_append_symbol (
+            STACK_BSON_CHILD, key, (int) len, (const char *) val, (int) vlen);
+         break;
+      case BSON_JSON_LF_SCOPE:
+      case BSON_JSON_LF_TIMESTAMP_T:
+      case BSON_JSON_LF_TIMESTAMP_I:
+      case BSON_JSON_LF_UNDEFINED:
+      case BSON_JSON_LF_MINKEY:
+      case BSON_JSON_LF_MAXKEY:
+      case BSON_JSON_LF_DBPOINTER:
+      default:
+         goto BAD_PARSE;
+      }
+
+      return;
+   BAD_PARSE:
+      _bson_json_read_set_error (
+         reader, "Invalid input string %s, looking for %d", val_w_null, bs);
+   } else {
+      _bson_json_read_set_error (
+         reader, "Invalid state to look for string %d", rs);
+   }
+}
+
+
+static void
+_bson_json_read_start_map (bson_json_reader_t *reader) /* IN */
+{
+   BASIC_CB_PREAMBLE;
+
+   if (bson->read_state == BSON_JSON_IN_BSON_TYPE &&
+       bson->bson_state == BSON_JSON_LF_DATE) {
+      bson->read_state = BSON_JSON_IN_BSON_TYPE_DATE_NUMBERLONG;
+   } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_STARTMAP) {
+      bson->read_state = BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES;
+   } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_SCOPE_STARTMAP) {
+      bson->read_state = BSON_JSON_IN_SCOPE;
+   } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_DBPOINTER_STARTMAP) {
+      bson->read_state = BSON_JSON_IN_DBPOINTER;
+   } else {
+      bson->read_state = BSON_JSON_IN_START_MAP;
+   }
+
+   /* silence some warnings */
+   (void) len;
+   (void) key;
+}
+
+
+static bool
+_is_known_key (const char *key, size_t len)
+{
+   bool ret;
+
+#define IS_KEY(k) (len == strlen (k) && (0 == memcmp (k, key, len)))
+
+   ret = (IS_KEY ("$regex") || IS_KEY ("$options") || IS_KEY ("$code") ||
+          IS_KEY ("$scope") || IS_KEY ("$oid") || IS_KEY ("$binary") ||
+          IS_KEY ("$type") || IS_KEY ("$date") || IS_KEY ("$undefined") ||
+          IS_KEY ("$maxKey") || IS_KEY ("$minKey") || IS_KEY ("$timestamp") ||
+          IS_KEY ("$numberInt") || IS_KEY ("$numberLong") ||
+          IS_KEY ("$numberDouble") || IS_KEY ("$numberDecimal") ||
+          IS_KEY ("$numberInt") || IS_KEY ("$numberLong") ||
+          IS_KEY ("$numberDouble") || IS_KEY ("$numberDecimal") ||
+          IS_KEY ("$dbPointer") || IS_KEY ("$symbol"));
+
+#undef IS_KEY
+
+   return ret;
+}
+
+static void
+_bson_json_save_map_key (bson_json_reader_bson_t *bson,
+                         const uint8_t *val,
+                         size_t len)
+{
+   _bson_json_buf_set (&bson->key_buf, val, len);
+   bson->key = (const char *) bson->key_buf.buf;
+}
+
+
+static void
+_bson_json_read_code_or_scope_key (bson_json_reader_bson_t *bson,
+                                   bool is_scope,
+                                   const uint8_t *val,
+                                   size_t len)
+{
+   bson_json_code_t *code = &bson->code_data;
+
+   if (code->in_scope) {
+      /* we're reading something weirdly nested, e.g. we just read "$code" in
+       * "$scope: {x: {$code: {}}}". just create the subdoc within the scope. */
+      bson->read_state = BSON_JSON_REGULAR;
+      STACK_PUSH_DOC (bson_append_document_begin (STACK_BSON_PARENT,
+                                                  bson->key,
+                                                  (int) bson->key_buf.len,
+                                                  STACK_BSON_CHILD));
+      _bson_json_save_map_key (bson, val, len);
+   } else {
+      if (!bson->code_data.key_buf.len) {
+         /* save the key, e.g. {"key": {"$code": "return x", "$scope":{"x":1}}},
+          * in case it is overwritten while parsing scope sub-object */
+         _bson_json_buf_set (
+            &bson->code_data.key_buf, bson->key_buf.buf, bson->key_buf.len);
+      }
+
+      if (is_scope) {
+         bson->bson_type = BSON_TYPE_CODEWSCOPE;
+         bson->read_state = BSON_JSON_IN_BSON_TYPE_SCOPE_STARTMAP;
+         bson->bson_state = BSON_JSON_LF_SCOPE;
+         bson->code_data.has_scope = true;
+      } else {
+         bson->bson_type = BSON_TYPE_CODE;
+         bson->bson_state = BSON_JSON_LF_CODE;
+         bson->code_data.has_code = true;
+      }
+   }
+}
+
+
+static void
+_bson_json_read_map_key (bson_json_reader_t *reader, /* IN */
+                         const uint8_t *val,         /* IN */
+                         size_t len)                 /* IN */
+{
+   bson_json_reader_bson_t *bson = &reader->bson;
+
+   if (!bson_utf8_validate ((const char *) val, len, true /* allow null */)) {
+      _bson_json_read_corrupt (reader, "invalid bytes in UTF8 string");
+      return;
+   }
+
+   if (bson->read_state == BSON_JSON_IN_START_MAP) {
+      if (len > 0 && val[0] == '$' &&
+          _is_known_key ((const char *) val, len) &&
+          bson->n >= 0 /* key is in subdocument */) {
+         bson->read_state = BSON_JSON_IN_BSON_TYPE;
+         bson->bson_type = (bson_type_t) 0;
+         memset (&bson->bson_type_data, 0, sizeof bson->bson_type_data);
+      } else {
+         bson->read_state = BSON_JSON_REGULAR;
+         STACK_PUSH_DOC (bson_append_document_begin (STACK_BSON_PARENT,
+                                                     bson->key,
+                                                     (int) bson->key_buf.len,
+                                                     STACK_BSON_CHILD));
+      }
+   } else if (bson->read_state == BSON_JSON_IN_SCOPE) {
+      /* we've read "key" in {$code: "", $scope: {key: ""}}*/
+      bson->read_state = BSON_JSON_REGULAR;
+      STACK_PUSH_SCOPE (bson_init (STACK_BSON_CHILD));
+      _bson_json_save_map_key (bson, val, len);
+   } else if (bson->read_state == BSON_JSON_IN_DBPOINTER) {
+      /* we've read "$ref" or "$id" in {$dbPointer: {$ref: ..., $id: ...}} */
+      bson->read_state = BSON_JSON_REGULAR;
+      STACK_PUSH_DBPOINTER (bson_init (STACK_BSON_CHILD));
+      _bson_json_save_map_key (bson, val, len);
+   }
+
+   if (bson->read_state == BSON_JSON_IN_BSON_TYPE) {
+      if
+         HANDLE_OPTION ("$regex", BSON_TYPE_REGEX, BSON_JSON_LF_REGEX)
+      else if
+         HANDLE_OPTION ("$options", BSON_TYPE_REGEX, BSON_JSON_LF_OPTIONS)
+      else if
+         HANDLE_OPTION ("$oid", BSON_TYPE_OID, BSON_JSON_LF_OID)
+      else if
+         HANDLE_OPTION ("$binary", BSON_TYPE_BINARY, BSON_JSON_LF_BINARY)
+      else if
+         HANDLE_OPTION ("$type", BSON_TYPE_BINARY, BSON_JSON_LF_TYPE)
+      else if
+         HANDLE_OPTION ("$date", BSON_TYPE_DATE_TIME, BSON_JSON_LF_DATE)
+      else if
+         HANDLE_OPTION (
+            "$undefined", BSON_TYPE_UNDEFINED, BSON_JSON_LF_UNDEFINED)
+      else if
+         HANDLE_OPTION ("$minKey", BSON_TYPE_MINKEY, BSON_JSON_LF_MINKEY)
+      else if
+         HANDLE_OPTION ("$maxKey", BSON_TYPE_MAXKEY, BSON_JSON_LF_MAXKEY)
+      else if
+         HANDLE_OPTION ("$numberInt", BSON_TYPE_INT32, BSON_JSON_LF_INT32)
+      else if
+         HANDLE_OPTION ("$numberLong", BSON_TYPE_INT64, BSON_JSON_LF_INT64)
+      else if
+         HANDLE_OPTION ("$numberDouble", BSON_TYPE_DOUBLE, BSON_JSON_LF_DOUBLE)
+      else if
+         HANDLE_OPTION ("$symbol", BSON_TYPE_SYMBOL, BSON_JSON_LF_SYMBOL)
+      else if
+         HANDLE_OPTION (
+            "$numberDecimal", BSON_TYPE_DECIMAL128, BSON_JSON_LF_DECIMAL128)
+      else if (!strcmp ("$timestamp", (const char *) val)) {
+         bson->bson_type = BSON_TYPE_TIMESTAMP;
+         bson->read_state = BSON_JSON_IN_BSON_TYPE_TIMESTAMP_STARTMAP;
+      } else if (!strcmp ("$dbPointer", (const char *) val)) {
+         /* start parsing "key": {"$dbPointer": ...}, save "key" for later */
+         _bson_json_buf_set (
+            &bson->dbpointer_key, bson->key_buf.buf, bson->key_buf.len);
+
+         bson->bson_type = BSON_TYPE_DBPOINTER;
+         bson->read_state = BSON_JSON_IN_BSON_TYPE_DBPOINTER_STARTMAP;
+      } else if (!strcmp ("$code", (const char *) val)) {
+         _bson_json_read_code_or_scope_key (
+            bson, false /* is_scope */, val, len);
+      } else if (!strcmp ("$scope", (const char *) val)) {
+         _bson_json_read_code_or_scope_key (
+            bson, true /* is_scope */, val, len);
+      } else {
+         _bson_json_read_set_error (
+            reader,
+            "Invalid key %s.  Looking for values for %d",
+            val,
+            bson->bson_type);
+      }
+   } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_DATE_NUMBERLONG) {
+      if
+         HANDLE_OPTION ("$numberLong", BSON_TYPE_DATE_TIME, BSON_JSON_LF_INT64)
+      else {
+         _bson_json_read_set_error (
+            reader,
+            "Invalid key %s.  Looking for values for %d",
+            val,
+            bson->bson_type);
+      }
+   } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES) {
+      if
+         HANDLE_OPTION ("t", BSON_TYPE_TIMESTAMP, BSON_JSON_LF_TIMESTAMP_T)
+      else if
+         HANDLE_OPTION ("i", BSON_TYPE_TIMESTAMP, BSON_JSON_LF_TIMESTAMP_I)
+      else {
+         _bson_json_read_set_error (
+            reader,
+            "Invalid key %s.  Looking for values for %d",
+            val,
+            bson->bson_type);
+      }
+   } else {
+      _bson_json_save_map_key (bson, val, len);
+   }
+}
+
+
+static void
+_bson_json_read_append_binary (bson_json_reader_t *reader,    /* IN */
+                               bson_json_reader_bson_t *bson) /* IN */
+{
+   if (!bson->bson_type_data.binary.has_binary) {
+      _bson_json_read_set_error (
+         reader, "Missing $binary after $type in BSON_TYPE_BINARY");
+   } else if (!bson->bson_type_data.binary.has_subtype) {
+      _bson_json_read_set_error (
+         reader, "Missing $type after $binary in BSON_TYPE_BINARY");
+   } else {
+      if (!bson_append_binary (STACK_BSON_CHILD,
+                               bson->key,
+                               (int) bson->key_buf.len,
+                               bson->bson_type_data.binary.type,
+                               bson->bson_type_buf[0].buf,
+                               (uint32_t) bson->bson_type_buf[0].len)) {
+         _bson_json_read_set_error (reader, "Error storing binary data");
+      }
+   }
+}
+
+
+static void
+_bson_json_read_append_regex (bson_json_reader_t *reader,    /* IN */
+                              bson_json_reader_bson_t *bson) /* IN */
+{
+   char *regex = NULL;
+   char *options = NULL;
+
+   if (!bson->bson_type_data.regex.has_regex) {
+      _bson_json_read_set_error (
+         reader, "Missing $regex after $options in BSON_TYPE_REGEX");
+      return;
+   }
+
+   regex = (char *) bson->bson_type_buf[0].buf;
+
+   if (bson->bson_type_data.regex.has_options) {
+      options = (char *) bson->bson_type_buf[1].buf;
+   }
+
+   if (!bson_append_regex (STACK_BSON_CHILD,
+                           bson->key,
+                           (int) bson->key_buf.len,
+                           regex,
+                           options)) {
+      _bson_json_read_set_error (reader, "Error storing regex");
+   }
+}
+
+
+static void
+_bson_json_read_append_code (bson_json_reader_t *reader,    /* IN */
+                             bson_json_reader_bson_t *bson) /* IN */
+{
+   bson_json_code_t *code_data;
+   char *code = NULL;
+   bson_t *scope = NULL;
+   bool r;
+
+   code_data = &bson->code_data;
+
+   BSON_ASSERT (!code_data->in_scope);
+
+   if (!code_data->has_code) {
+      _bson_json_read_set_error (reader, "Missing $code after $scope");
+      return;
+   }
+
+   code = (char *) code_data->code_buf.buf;
+
+   if (code_data->has_scope) {
+      scope = STACK_BSON (1);
+   }
+
+   /* creates BSON "code" elem, or "code with scope" if scope is not NULL */
+   r = bson_append_code_with_scope (STACK_BSON_CHILD,
+                                    (const char *) code_data->key_buf.buf,
+                                    (int) code_data->key_buf.len,
+                                    code,
+                                    scope);
+
+   if (!r) {
+      _bson_json_read_set_error (reader, "Error storing Javascript code");
+   }
+
+   if (scope) {
+      bson_destroy (scope);
+   }
+
+   /* keep the buffer but truncate it */
+   code_data->key_buf.len = 0;
+   code_data->has_code = code_data->has_scope = false;
+}
+
+
+static void
+_bson_json_read_append_dbpointer (bson_json_reader_t *reader,    /* IN */
+                                  bson_json_reader_bson_t *bson) /* IN */
+{
+   bson_t *db_pointer;
+   bson_iter_t iter;
+   const char *ns = NULL;
+   const bson_oid_t *oid = NULL;
+   bool r;
+
+   BSON_ASSERT (reader->bson.dbpointer_key.buf);
+
+   db_pointer = STACK_BSON (1);
+   if (!bson_iter_init (&iter, db_pointer)) {
+      _bson_json_read_set_error (reader, "Error storing DBPointer");
+      return;
+   }
+
+   while (bson_iter_next (&iter)) {
+      if (!strcmp (bson_iter_key (&iter), "$id")) {
+         if (!BSON_ITER_HOLDS_OID (&iter)) {
+            _bson_json_read_set_error (
+               reader, "$dbPointer.$id must be like {\"$oid\": ...\"}");
+            return;
+         }
+
+         oid = bson_iter_oid (&iter);
+      } else if (!strcmp (bson_iter_key (&iter), "$ref")) {
+         if (!BSON_ITER_HOLDS_UTF8 (&iter)) {
+            _bson_json_read_set_error (
+               reader,
+               "$dbPointer.$ref must be a string like \"db.collection\"");
+            return;
+         }
+
+         ns = bson_iter_utf8 (&iter, NULL);
+      }
+   }
+
+   if (!oid || !ns) {
+      _bson_json_read_set_error (reader,
+                                 "$dbPointer requires both $id and $ref");
+      return;
+   }
+
+   r = bson_append_dbpointer (STACK_BSON_CHILD,
+                              (char *) reader->bson.dbpointer_key.buf,
+                              (int) reader->bson.dbpointer_key.len,
+                              ns,
+                              oid);
+
+   if (!r) {
+      _bson_json_read_set_error (reader, "Error storing DBPointer");
+   }
+}
+
+
+static void
+_bson_json_read_append_oid (bson_json_reader_t *reader,    /* IN */
+                            bson_json_reader_bson_t *bson) /* IN */
+{
+   if (!bson_append_oid (STACK_BSON_CHILD,
+                         bson->key,
+                         (int) bson->key_buf.len,
+                         &bson->bson_type_data.oid.oid)) {
+      _bson_json_read_set_error (reader, "Error storing ObjectId");
+   }
+}
+
+
+static void
+_bson_json_read_append_date_time (bson_json_reader_t *reader,    /* IN */
+                                  bson_json_reader_bson_t *bson) /* IN */
+{
+   if (!bson_append_date_time (STACK_BSON_CHILD,
+                               bson->key,
+                               (int) bson->key_buf.len,
+                               bson->bson_type_data.date.date)) {
+      _bson_json_read_set_error (reader, "Error storing datetime");
+   }
+}
+
+
+static void
+_bson_json_read_append_timestamp (bson_json_reader_t *reader,    /* IN */
+                                  bson_json_reader_bson_t *bson) /* IN */
+{
+   if (!bson->bson_type_data.timestamp.has_t) {
+      _bson_json_read_set_error (
+         reader, "Missing t after $timestamp in BSON_TYPE_TIMESTAMP");
+      return;
+   } else if (!bson->bson_type_data.timestamp.has_i) {
+      _bson_json_read_set_error (
+         reader, "Missing i after $timestamp in BSON_TYPE_TIMESTAMP");
+      return;
+   }
+
+   bson_append_timestamp (STACK_BSON_CHILD,
+                          bson->key,
+                          (int) bson->key_buf.len,
+                          bson->bson_type_data.timestamp.t,
+                          bson->bson_type_data.timestamp.i);
+}
+
+
+static void
+_bad_extended_json (bson_json_reader_t *reader)
+{
+   _bson_json_read_corrupt (reader, "Invalid MongoDB extended JSON");
+}
+
+
+static void
+_bson_json_read_end_map (bson_json_reader_t *reader) /* IN */
+{
+   bson_json_reader_bson_t *bson = &reader->bson;
+
+   if (bson->read_state == BSON_JSON_IN_START_MAP) {
+      bson->read_state = BSON_JSON_REGULAR;
+      STACK_PUSH_DOC (bson_append_document_begin (STACK_BSON_PARENT,
+                                                  bson->key,
+                                                  (int) bson->key_buf.len,
+                                                  STACK_BSON_CHILD));
+   } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_SCOPE_STARTMAP) {
+      bson->read_state = BSON_JSON_REGULAR;
+      STACK_PUSH_SCOPE (bson_init (STACK_BSON_CHILD));
+   } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_DBPOINTER_STARTMAP) {
+      /* we've read last "}" in "{$dbPointer: {$id: ..., $ref: ...}}" */
+      _bson_json_read_append_dbpointer (reader, bson);
+      bson->read_state = BSON_JSON_REGULAR;
+      return;
+   }
+
+   if (bson->read_state == BSON_JSON_IN_BSON_TYPE) {
+      if (!bson->key) {
+         /* invalid, like {$numberLong: "1"} at the document top level */
+         _bad_extended_json (reader);
+         return;
+      }
+
+      bson->read_state = BSON_JSON_REGULAR;
+      switch (bson->bson_type) {
+      case BSON_TYPE_REGEX:
+         _bson_json_read_append_regex (reader, bson);
+         break;
+      case BSON_TYPE_CODE:
+      case BSON_TYPE_CODEWSCOPE:
+         /* we've read the closing "}" in "{$code: ..., $scope: ...}" */
+         _bson_json_read_append_code (reader, bson);
+         break;
+      case BSON_TYPE_OID:
+         _bson_json_read_append_oid (reader, bson);
+         break;
+      case BSON_TYPE_BINARY:
+         _bson_json_read_append_binary (reader, bson);
+         break;
+      case BSON_TYPE_DATE_TIME:
+         _bson_json_read_append_date_time (reader, bson);
+         break;
+      case BSON_TYPE_UNDEFINED:
+         bson_append_undefined (
+            STACK_BSON_CHILD, bson->key, (int) bson->key_buf.len);
+         break;
+      case BSON_TYPE_MINKEY:
+         bson_append_minkey (
+            STACK_BSON_CHILD, bson->key, (int) bson->key_buf.len);
+         break;
+      case BSON_TYPE_MAXKEY:
+         bson_append_maxkey (
+            STACK_BSON_CHILD, bson->key, (int) bson->key_buf.len);
+         break;
+      case BSON_TYPE_INT32:
+         bson_append_int32 (STACK_BSON_CHILD,
+                            bson->key,
+                            (int) bson->key_buf.len,
+                            bson->bson_type_data.v_int32.value);
+         break;
+      case BSON_TYPE_INT64:
+         bson_append_int64 (STACK_BSON_CHILD,
+                            bson->key,
+                            (int) bson->key_buf.len,
+                            bson->bson_type_data.v_int64.value);
+         break;
+      case BSON_TYPE_DOUBLE:
+         bson_append_double (STACK_BSON_CHILD,
+                             bson->key,
+                             (int) bson->key_buf.len,
+                             bson->bson_type_data.v_double.value);
+         break;
+      case BSON_TYPE_DECIMAL128:
+         bson_append_decimal128 (STACK_BSON_CHILD,
+                                 bson->key,
+                                 (int) bson->key_buf.len,
+                                 &bson->bson_type_data.v_decimal128.value);
+         break;
+      case BSON_TYPE_DBPOINTER:
+         /* shouldn't set type to DBPointer unless inside $dbPointer: {...} */
+         _bson_json_read_set_error (
+            reader,
+            "Internal error: shouldn't be in state BSON_TYPE_DBPOINTER");
+         break;
+      case BSON_TYPE_SYMBOL:
+         break;
+      case BSON_TYPE_EOD:
+      case BSON_TYPE_UTF8:
+      case BSON_TYPE_DOCUMENT:
+      case BSON_TYPE_ARRAY:
+      case BSON_TYPE_BOOL:
+      case BSON_TYPE_NULL:
+      case BSON_TYPE_TIMESTAMP:
+      default:
+         _bson_json_read_set_error (reader, "Unknown type %d", bson->bson_type);
+         break;
+      }
+   } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES) {
+      if (!bson->key) {
+         _bad_extended_json (reader);
+         return;
+      }
+
+      bson->read_state = BSON_JSON_IN_BSON_TYPE_TIMESTAMP_ENDMAP;
+
+      _bson_json_read_append_timestamp (reader, bson);
+      return;
+   } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_STARTMAP) {
+      bson_append_timestamp (STACK_BSON_CHILD,
+                             bson->key,
+                             (int) bson->key_buf.len,
+                             bson->bson_type_data.timestamp.t,
+                             bson->bson_type_data.timestamp.i);
+      bson->read_state = BSON_JSON_REGULAR;
+   } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_ENDMAP) {
+      bson->read_state = BSON_JSON_REGULAR;
+   } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_DATE_NUMBERLONG) {
+      if (!bson->key) {
+         _bad_extended_json (reader);
+         return;
+      }
+
+      bson->read_state = BSON_JSON_IN_BSON_TYPE_DATE_ENDMAP;
+
+      _bson_json_read_append_date_time (reader, bson);
+      return;
+   } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_DATE_ENDMAP) {
+      bson->read_state = BSON_JSON_REGULAR;
+   } else if (bson->read_state == BSON_JSON_REGULAR) {
+      if (STACK_IS_SCOPE) {
+         bson->read_state = BSON_JSON_IN_BSON_TYPE;
+         bson->bson_type = BSON_TYPE_CODE;
+         STACK_POP_SCOPE;
+      } else if (STACK_IS_DBPOINTER) {
+         bson->read_state = BSON_JSON_IN_BSON_TYPE_DBPOINTER_STARTMAP;
+         STACK_POP_DBPOINTER;
+      } else {
+         STACK_POP_DOC (
+            bson_append_document_end (STACK_BSON_PARENT, STACK_BSON_CHILD));
+      }
+
+      if (bson->n == -1) {
+         bson->read_state = BSON_JSON_DONE;
+      }
+   } else if (bson->read_state == BSON_JSON_IN_SCOPE) {
+      /* empty $scope */
+      BSON_ASSERT (bson->code_data.has_scope);
+      STACK_PUSH_SCOPE (bson_init (STACK_BSON_CHILD));
+      STACK_POP_SCOPE;
+      bson->read_state = BSON_JSON_IN_BSON_TYPE;
+      bson->bson_type = BSON_TYPE_CODE;
+   } else if (bson->read_state == BSON_JSON_IN_DBPOINTER) {
+      /* empty $dbPointer??? */
+      _bson_json_read_set_error (reader, "Empty $dbPointer");
+   } else {
+      _bson_json_read_set_error (reader, "Invalid state %d", bson->read_state);
+   }
+}
+
+
+static void
+_bson_json_read_start_array (bson_json_reader_t *reader) /* IN */
+{
+   const char *key;
+   size_t len;
+   bson_json_reader_bson_t *bson = &reader->bson;
+
+   if (bson->n < 0) {
+      STACK_PUSH_ARRAY (_noop ());
+   } else {
+      _bson_json_read_fixup_key (bson);
+      key = bson->key;
+      len = bson->key_buf.len;
+
+      BASIC_CB_BAIL_IF_NOT_NORMAL ("[");
+
+      STACK_PUSH_ARRAY (bson_append_array_begin (
+         STACK_BSON_PARENT, key, (int) len, STACK_BSON_CHILD));
+   }
+}
+
+
+static void
+_bson_json_read_end_array (bson_json_reader_t *reader) /* IN */
+{
+   bson_json_reader_bson_t *bson = &reader->bson;
+
+   if (bson->read_state != BSON_JSON_REGULAR) {
+      _bson_json_read_set_error (
+         reader, "Invalid read of %s in state %d", "]", bson->read_state);
+      return;
+   }
+
+   STACK_POP_ARRAY (
+      bson_append_array_end (STACK_BSON_PARENT, STACK_BSON_CHILD));
+   if (bson->n == -1) {
+      bson->read_state = BSON_JSON_DONE;
+   }
+}
+
+
+/* put unescaped text in reader->bson.unescaped, or set reader->error.
+ * json_text has length len and it is not null-terminated. */
+static bool
+_bson_json_unescape (bson_json_reader_t *reader,
+                     struct jsonsl_state_st *state,
+                     const char *json_text,
+                     ssize_t len)
+{
+   bson_json_reader_bson_t *reader_bson;
+   jsonsl_error_t err;
+
+   reader_bson = &reader->bson;
+
+   /* add 1 for NULL */
+   _bson_json_buf_ensure (&reader_bson->unescaped, (size_t) len + 1);
+
+   /* length of unescaped str is always <= len */
+   reader_bson->unescaped.len = jsonsl_util_unescape (
+      json_text, (char *) reader_bson->unescaped.buf, (size_t) len, NULL, &err);
+
+   if (err != JSONSL_ERROR_SUCCESS) {
+      bson_set_error (reader->error,
+                      BSON_ERROR_JSON,
+                      BSON_JSON_ERROR_READ_CORRUPT_JS,
+                      "error near position %d: %s",
+                      (int) state->pos_begin,
+                      jsonsl_strerror (err));
+      return false;
+   }
+
+   reader_bson->unescaped.buf[reader_bson->unescaped.len] = '\0';
+
+   return true;
+}
+
+
+/* read the buffered JSON plus new data, and fill out @len with its length */
+static const char *
+_get_json_text (jsonsl_t json,                 /* IN */
+                struct jsonsl_state_st *state, /* IN */
+                const char *buf /* IN */,
+                ssize_t *len /* OUT */)
+{
+   bson_json_reader_t *reader;
+   ssize_t bytes_available;
+
+   reader = (bson_json_reader_t *) json->data;
+
+   BSON_ASSERT (state->pos_cur > state->pos_begin);
+
+   *len = (ssize_t) (state->pos_cur - state->pos_begin);
+
+   bytes_available = buf - json->base;
+
+   if (*len <= bytes_available) {
+      /* read directly from stream, not from saved JSON */
+      return buf - (size_t) *len;
+   } else {
+      /* combine saved text with new data from the jsonsl_t */
+      ssize_t append = buf - json->base;
+
+      if (append > 0) {
+         _bson_json_buf_append (
+            &reader->tok_accumulator, buf - append, (size_t) append);
+      }
+
+      return (const char *) reader->tok_accumulator.buf;
+   }
+}
+
+
+static void
+_push_callback (jsonsl_t json,
+                jsonsl_action_t action,
+                struct jsonsl_state_st *state,
+                const char *buf)
+{
+   bson_json_reader_t *reader = (bson_json_reader_t *) json->data;
+
+   switch (state->type) {
+   case JSONSL_T_STRING:
+   case JSONSL_T_HKEY:
+   case JSONSL_T_SPECIAL:
+   case JSONSL_T_UESCAPE:
+      reader->json_text_pos = state->pos_begin;
+      break;
+   case JSONSL_T_OBJECT:
+      _bson_json_read_start_map (reader);
+      break;
+   case JSONSL_T_LIST:
+      _bson_json_read_start_array (reader);
+      break;
+   default:
+      break;
+   }
+}
+
+
+static void
+_pop_callback (jsonsl_t json,
+               jsonsl_action_t action,
+               struct jsonsl_state_st *state,
+               const char *buf)
+{
+   bson_json_reader_t *reader;
+   bson_json_reader_bson_t *reader_bson;
+   ssize_t len;
+   double d;
+   const char *obj_text;
+
+   reader = (bson_json_reader_t *) json->data;
+   reader_bson = &reader->bson;
+
+   switch (state->type) {
+   case JSONSL_T_HKEY:
+   case JSONSL_T_STRING:
+      obj_text = _get_json_text (json, state, buf, &len);
+      BSON_ASSERT (obj_text[0] == '"');
+
+      /* remove start/end quotes, replace backslash-escapes, null-terminate */
+      /* you'd think it would be faster to check if state->nescapes > 0 first,
+       * but tests show no improvement */
+      if (!_bson_json_unescape (reader, state, obj_text + 1, len - 1)) {
+         /* reader->error is set */
+         jsonsl_stop (json);
+         break;
+      }
+
+      if (state->type == JSONSL_T_HKEY) {
+         _bson_json_read_map_key (
+            reader, reader_bson->unescaped.buf, reader_bson->unescaped.len);
+      } else {
+         _bson_json_read_string (
+            reader, reader_bson->unescaped.buf, reader_bson->unescaped.len);
+      }
+      break;
+   case JSONSL_T_OBJECT:
+      _bson_json_read_end_map (reader);
+      break;
+   case JSONSL_T_LIST:
+      _bson_json_read_end_array (reader);
+      break;
+   case JSONSL_T_SPECIAL:
+      obj_text = _get_json_text (json, state, buf, &len);
+      if (state->special_flags & JSONSL_SPECIALf_NUMNOINT) {
+         if (_bson_json_parse_double (reader, obj_text, (size_t) len, &d)) {
+            _bson_json_read_double (reader, d);
+         }
+      } else if (state->special_flags & JSONSL_SPECIALf_NUMERIC) {
+         int64_t i = state->nelem;
+         /* jsonsl puts the unsigned value in state->nelem */
+         if (state->special_flags & JSONSL_SPECIALf_SIGNED) {
+            i *= -1;
+         }
+
+         _bson_json_read_integer (reader, i);
+      } else if (state->special_flags & JSONSL_SPECIALf_BOOLEAN) {
+         _bson_json_read_boolean (reader, obj_text[0] == 't' ? 1 : 0);
+      } else if (state->special_flags & JSONSL_SPECIALf_NULL) {
+         _bson_json_read_null (reader);
+      }
+      break;
+   default:
+      break;
+   }
+
+   reader->json_text_pos = -1;
+   reader->tok_accumulator.len = 0;
+}
+
+
+static int
+_error_callback (jsonsl_t json,
+                 jsonsl_error_t err,
+                 struct jsonsl_state_st *state,
+                 char *errat)
+{
+   bson_json_reader_t *reader = (bson_json_reader_t *) json->data;
+
+   if (err == JSONSL_ERROR_CANT_INSERT && *errat == '{') {
+      /* start the next document */
+      reader->should_reset = true;
+      reader->advance = errat - json->base;
+      return 0;
+   } else if (err == JSONSL_ERROR_WEIRD_WHITESPACE && *errat == '\0') {
+      /* embedded NULL is ok */
+      json->pos++;
+      return 1;
+   }
+
+   bson_set_error (reader->error,
+                   BSON_ERROR_JSON,
+                   BSON_JSON_ERROR_READ_CORRUPT_JS,
+                   "Got parse error at '%c', position %d: %s",
+                   *errat,
+                   (int) json->pos,
+                   jsonsl_strerror (err));
+
+   return 0;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_json_reader_read --
+ *
+ *       Read the next json document from @reader and write its value
+ *       into @bson. @bson will be allocated as part of this process.
+ *
+ *       @bson MUST be initialized before calling this function as it
+ *       will not be initialized automatically. The reasoning for this
+ *       is so that you can chain together bson_json_reader_t with
+ *       other components like bson_writer_t.
+ *
+ * Returns:
+ *       1 if successful and data was read.
+ *       0 if successful and no data was read.
+ *       -1 if there was an error and @error is set.
+ *
+ * Side effects:
+ *       @error may be set.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+int
+bson_json_reader_read (bson_json_reader_t *reader, /* IN */
+                       bson_t *bson,               /* IN */
+                       bson_error_t *error)        /* OUT */
+{
+   bson_json_reader_producer_t *p;
+   ssize_t start_pos;
+   ssize_t r;
+   ssize_t buf_offset;
+   ssize_t accum;
+   bson_error_t error_tmp;
+   int ret = 0;
+
+   BSON_ASSERT (reader);
+   BSON_ASSERT (bson);
+
+   p = &reader->producer;
+
+   reader->bson.bson = bson;
+   reader->bson.n = -1;
+   reader->bson.read_state = BSON_JSON_REGULAR;
+   reader->error = error ? error : &error_tmp;
+   memset (reader->error, 0, sizeof (bson_error_t));
+
+   for (;;) {
+      start_pos = reader->json->pos;
+
+      if (p->bytes_read > 0) {
+         /* leftover data from previous JSON doc in the stream */
+         r = p->bytes_read;
+      } else {
+         /* read a chunk of bytes by executing the callback */
+         r = p->cb (p->data, p->buf, p->buf_size);
+      }
+
+      if (r < 0) {
+         if (error) {
+            bson_set_error (error,
+                            BSON_ERROR_JSON,
+                            BSON_JSON_ERROR_READ_CB_FAILURE,
+                            "reader cb failed");
+         }
+         ret = -1;
+         goto cleanup;
+      } else if (r == 0) {
+         break;
+      } else {
+         ret = 1;
+         p->bytes_read = (size_t) r;
+
+         jsonsl_feed (reader->json, (const jsonsl_char_t *) p->buf, (size_t) r);
+
+         if (reader->should_reset) {
+            /* end of a document */
+            jsonsl_reset (reader->json);
+            reader->should_reset = false;
+
+            /* advance past already-parsed data */
+            memmove (p->buf, p->buf + reader->advance, r - reader->advance);
+            p->bytes_read -= reader->advance;
+            ret = 1;
+            goto cleanup;
+         }
+
+         if (reader->error->domain) {
+            ret = -1;
+            goto cleanup;
+         }
+
+         /* accumulate a key or string value */
+         if (reader->json_text_pos != -1) {
+            if (reader->json_text_pos < reader->json->pos) {
+               accum = BSON_MIN (reader->json->pos - reader->json_text_pos, r);
+               /* if this chunk stopped mid-token, buf_offset is how far into
+                * our current chunk the token begins. */
+               buf_offset = AT_LEAST_0 (reader->json_text_pos - start_pos);
+               _bson_json_buf_append (&reader->tok_accumulator,
+                                      p->buf + buf_offset,
+                                      (size_t) accum);
+            }
+         }
+
+         p->bytes_read = 0;
+      }
+   }
+
+cleanup:
+   if (ret == 1 && reader->bson.read_state != BSON_JSON_DONE) {
+      /* data ended in the middle */
+      _bson_json_read_corrupt (reader, "%s", "Incomplete JSON");
+      return -1;
+   }
+
+   return ret;
+}
+
+
+bson_json_reader_t *
+bson_json_reader_new (void *data,               /* IN */
+                      bson_json_reader_cb cb,   /* IN */
+                      bson_json_destroy_cb dcb, /* IN */
+                      bool allow_multiple,      /* unused */
+                      size_t buf_size)          /* IN */
+{
+   bson_json_reader_t *r;
+   bson_json_reader_producer_t *p;
+
+   r = bson_malloc0 (sizeof *r);
+   r->json = jsonsl_new (STACK_MAX);
+   r->json->error_callback = _error_callback;
+   r->json->action_callback_PUSH = _push_callback;
+   r->json->action_callback_POP = _pop_callback;
+   r->json->data = r;
+   r->json_text_pos = -1;
+   jsonsl_enable_all_callbacks (r->json);
+
+   p = &r->producer;
+
+   p->data = data;
+   p->cb = cb;
+   p->dcb = dcb;
+   p->buf_size = buf_size ? buf_size : BSON_JSON_DEFAULT_BUF_SIZE;
+   p->buf = bson_malloc (p->buf_size);
+
+   return r;
+}
+
+
+void
+bson_json_reader_destroy (bson_json_reader_t *reader) /* IN */
+{
+   int i;
+   bson_json_reader_producer_t *p = &reader->producer;
+   bson_json_reader_bson_t *b = &reader->bson;
+
+   if (reader->producer.dcb) {
+      reader->producer.dcb (reader->producer.data);
+   }
+
+   bson_free (p->buf);
+   bson_free (b->key_buf.buf);
+   bson_free (b->unescaped.buf);
+   bson_free (b->dbpointer_key.buf);
+
+   for (i = 0; i < 3; i++) {
+      bson_free (b->bson_type_buf[i].buf);
+   }
+
+   _bson_json_code_cleanup (&b->code_data);
+
+   jsonsl_destroy (reader->json);
+   bson_free (reader->tok_accumulator.buf);
+   bson_free (reader);
+}
+
+
+typedef struct {
+   const uint8_t *data;
+   size_t len;
+   size_t bytes_parsed;
+} bson_json_data_reader_t;
+
+
+static ssize_t
+_bson_json_data_reader_cb (void *_ctx, uint8_t *buf, size_t len)
+{
+   size_t bytes;
+   bson_json_data_reader_t *ctx = (bson_json_data_reader_t *) _ctx;
+
+   if (!ctx->data) {
+      return -1;
+   }
+
+   bytes = BSON_MIN (len, ctx->len - ctx->bytes_parsed);
+
+   memcpy (buf, ctx->data + ctx->bytes_parsed, bytes);
+
+   ctx->bytes_parsed += bytes;
+
+   return bytes;
+}
+
+
+bson_json_reader_t *
+bson_json_data_reader_new (bool allow_multiple, /* IN */
+                           size_t size)         /* IN */
+{
+   bson_json_data_reader_t *dr = bson_malloc0 (sizeof *dr);
+
+   return bson_json_reader_new (
+      dr, &_bson_json_data_reader_cb, &bson_free, allow_multiple, size);
+}
+
+
+void
+bson_json_data_reader_ingest (bson_json_reader_t *reader, /* IN */
+                              const uint8_t *data,        /* IN */
+                              size_t len)                 /* IN */
+{
+   bson_json_data_reader_t *ctx =
+      (bson_json_data_reader_t *) reader->producer.data;
+
+   ctx->data = data;
+   ctx->len = len;
+   ctx->bytes_parsed = 0;
+}
+
+
+bson_t *
+bson_new_from_json (const uint8_t *data, /* IN */
+                    ssize_t len,         /* IN */
+                    bson_error_t *error) /* OUT */
+{
+   bson_json_reader_t *reader;
+   bson_t *bson;
+   int r;
+
+   BSON_ASSERT (data);
+
+   if (len < 0) {
+      len = (ssize_t) strlen ((const char *) data);
+   }
+
+   bson = bson_new ();
+   reader = bson_json_data_reader_new (false, BSON_JSON_DEFAULT_BUF_SIZE);
+   bson_json_data_reader_ingest (reader, data, len);
+   r = bson_json_reader_read (reader, bson, error);
+   bson_json_reader_destroy (reader);
+
+   if (r == 0) {
+      bson_set_error (error,
+                      BSON_ERROR_JSON,
+                      BSON_JSON_ERROR_READ_INVALID_PARAM,
+                      "Empty JSON string");
+   }
+
+   if (r != 1) {
+      bson_destroy (bson);
+      return NULL;
+   }
+
+   return bson;
+}
+
+
+bool
+bson_init_from_json (bson_t *bson,        /* OUT */
+                     const char *data,    /* IN */
+                     ssize_t len,         /* IN */
+                     bson_error_t *error) /* OUT */
+{
+   bson_json_reader_t *reader;
+   int r;
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (data);
+
+   if (len < 0) {
+      len = strlen (data);
+   }
+
+   bson_init (bson);
+
+   reader = bson_json_data_reader_new (false, BSON_JSON_DEFAULT_BUF_SIZE);
+   bson_json_data_reader_ingest (reader, (const uint8_t *) data, len);
+   r = bson_json_reader_read (reader, bson, error);
+   bson_json_reader_destroy (reader);
+
+   if (r == 0) {
+      bson_set_error (error,
+                      BSON_ERROR_JSON,
+                      BSON_JSON_ERROR_READ_INVALID_PARAM,
+                      "Empty JSON string");
+   }
+
+   if (r != 1) {
+      bson_destroy (bson);
+      return false;
+   }
+
+   return true;
+}
+
+
+static void
+_bson_json_reader_handle_fd_destroy (void *handle) /* IN */
+{
+   bson_json_reader_handle_fd_t *fd = handle;
+
+   if (fd) {
+      if ((fd->fd != -1) && fd->do_close) {
+#ifdef _WIN32
+         _close (fd->fd);
+#else
+         close (fd->fd);
+#endif
+      }
+      bson_free (fd);
+   }
+}
+
+
+static ssize_t
+_bson_json_reader_handle_fd_read (void *handle, /* IN */
+                                  uint8_t *buf, /* IN */
+                                  size_t len)   /* IN */
+{
+   bson_json_reader_handle_fd_t *fd = handle;
+   ssize_t ret = -1;
+
+   if (fd && (fd->fd != -1)) {
+   again:
+#ifdef BSON_OS_WIN32
+      ret = _read (fd->fd, buf, (unsigned int) len);
+#else
+      ret = read (fd->fd, buf, len);
+#endif
+      if ((ret == -1) && (errno == EAGAIN)) {
+         goto again;
+      }
+   }
+
+   return ret;
+}
+
+
+bson_json_reader_t *
+bson_json_reader_new_from_fd (int fd,                /* IN */
+                              bool close_on_destroy) /* IN */
+{
+   bson_json_reader_handle_fd_t *handle;
+
+   BSON_ASSERT (fd != -1);
+
+   handle = bson_malloc0 (sizeof *handle);
+   handle->fd = fd;
+   handle->do_close = close_on_destroy;
+
+   return bson_json_reader_new (handle,
+                                _bson_json_reader_handle_fd_read,
+                                _bson_json_reader_handle_fd_destroy,
+                                true,
+                                BSON_JSON_DEFAULT_BUF_SIZE);
+}
+
+
+bson_json_reader_t *
+bson_json_reader_new_from_file (const char *path,    /* IN */
+                                bson_error_t *error) /* OUT */
+{
+   char errmsg_buf[BSON_ERROR_BUFFER_SIZE];
+   char *errmsg;
+   int fd = -1;
+
+   BSON_ASSERT (path);
+
+#ifdef BSON_OS_WIN32
+   _sopen_s (&fd, path, (_O_RDONLY | _O_BINARY), _SH_DENYNO, _S_IREAD);
+#else
+   fd = open (path, O_RDONLY);
+#endif
+
+   if (fd == -1) {
+      errmsg = bson_strerror_r (errno, errmsg_buf, sizeof errmsg_buf);
+      bson_set_error (
+         error, BSON_ERROR_READER, BSON_ERROR_READER_BADFD, "%s", errmsg);
+      return NULL;
+   }
+
+   return bson_json_reader_new_from_fd (fd, true);
+}
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-json.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-json.h
new file mode 100644
index 0000000000000000000000000000000000000000..12ef995894ed96d5375062b234b5e508e911be11
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-json.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2014 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef BSON_JSON_H
+#define BSON_JSON_H
+
+
+#if !defined(BSON_INSIDE) && !defined(BSON_COMPILATION)
+#error "Only <bson.h> can be included directly."
+#endif
+
+
+#include "bson.h"
+
+
+BSON_BEGIN_DECLS
+
+
+typedef struct _bson_json_reader_t bson_json_reader_t;
+
+
+typedef enum {
+   BSON_JSON_ERROR_READ_CORRUPT_JS = 1,
+   BSON_JSON_ERROR_READ_INVALID_PARAM,
+   BSON_JSON_ERROR_READ_CB_FAILURE,
+} bson_json_error_code_t;
+
+
+typedef ssize_t (*bson_json_reader_cb) (void *handle,
+                                        uint8_t *buf,
+                                        size_t count);
+typedef void (*bson_json_destroy_cb) (void *handle);
+
+
+BSON_EXPORT (bson_json_reader_t *)
+bson_json_reader_new (void *data,
+                      bson_json_reader_cb cb,
+                      bson_json_destroy_cb dcb,
+                      bool allow_multiple,
+                      size_t buf_size);
+BSON_EXPORT (bson_json_reader_t *)
+bson_json_reader_new_from_fd (int fd, bool close_on_destroy);
+BSON_EXPORT (bson_json_reader_t *)
+bson_json_reader_new_from_file (const char *filename, bson_error_t *error);
+BSON_EXPORT (void)
+bson_json_reader_destroy (bson_json_reader_t *reader);
+BSON_EXPORT (int)
+bson_json_reader_read (bson_json_reader_t *reader,
+                       bson_t *bson,
+                       bson_error_t *error);
+BSON_EXPORT (bson_json_reader_t *)
+bson_json_data_reader_new (bool allow_multiple, size_t size);
+BSON_EXPORT (void)
+bson_json_data_reader_ingest (bson_json_reader_t *reader,
+                              const uint8_t *data,
+                              size_t len);
+
+
+BSON_END_DECLS
+
+
+#endif /* BSON_JSON_H */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-keys.c b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-keys.c
new file mode 100644
index 0000000000000000000000000000000000000000..ce726093ea3d65931df0c9eb4d8705fb9f889c21
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-keys.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdio.h>
+
+#include "bson-keys.h"
+#include "bson-string.h"
+
+
+static const char *gUint32Strs[] = {
+   "0",   "1",   "2",   "3",   "4",   "5",   "6",   "7",   "8",   "9",   "10",
+   "11",  "12",  "13",  "14",  "15",  "16",  "17",  "18",  "19",  "20",  "21",
+   "22",  "23",  "24",  "25",  "26",  "27",  "28",  "29",  "30",  "31",  "32",
+   "33",  "34",  "35",  "36",  "37",  "38",  "39",  "40",  "41",  "42",  "43",
+   "44",  "45",  "46",  "47",  "48",  "49",  "50",  "51",  "52",  "53",  "54",
+   "55",  "56",  "57",  "58",  "59",  "60",  "61",  "62",  "63",  "64",  "65",
+   "66",  "67",  "68",  "69",  "70",  "71",  "72",  "73",  "74",  "75",  "76",
+   "77",  "78",  "79",  "80",  "81",  "82",  "83",  "84",  "85",  "86",  "87",
+   "88",  "89",  "90",  "91",  "92",  "93",  "94",  "95",  "96",  "97",  "98",
+   "99",  "100", "101", "102", "103", "104", "105", "106", "107", "108", "109",
+   "110", "111", "112", "113", "114", "115", "116", "117", "118", "119", "120",
+   "121", "122", "123", "124", "125", "126", "127", "128", "129", "130", "131",
+   "132", "133", "134", "135", "136", "137", "138", "139", "140", "141", "142",
+   "143", "144", "145", "146", "147", "148", "149", "150", "151", "152", "153",
+   "154", "155", "156", "157", "158", "159", "160", "161", "162", "163", "164",
+   "165", "166", "167", "168", "169", "170", "171", "172", "173", "174", "175",
+   "176", "177", "178", "179", "180", "181", "182", "183", "184", "185", "186",
+   "187", "188", "189", "190", "191", "192", "193", "194", "195", "196", "197",
+   "198", "199", "200", "201", "202", "203", "204", "205", "206", "207", "208",
+   "209", "210", "211", "212", "213", "214", "215", "216", "217", "218", "219",
+   "220", "221", "222", "223", "224", "225", "226", "227", "228", "229", "230",
+   "231", "232", "233", "234", "235", "236", "237", "238", "239", "240", "241",
+   "242", "243", "244", "245", "246", "247", "248", "249", "250", "251", "252",
+   "253", "254", "255", "256", "257", "258", "259", "260", "261", "262", "263",
+   "264", "265", "266", "267", "268", "269", "270", "271", "272", "273", "274",
+   "275", "276", "277", "278", "279", "280", "281", "282", "283", "284", "285",
+   "286", "287", "288", "289", "290", "291", "292", "293", "294", "295", "296",
+   "297", "298", "299", "300", "301", "302", "303", "304", "305", "306", "307",
+   "308", "309", "310", "311", "312", "313", "314", "315", "316", "317", "318",
+   "319", "320", "321", "322", "323", "324", "325", "326", "327", "328", "329",
+   "330", "331", "332", "333", "334", "335", "336", "337", "338", "339", "340",
+   "341", "342", "343", "344", "345", "346", "347", "348", "349", "350", "351",
+   "352", "353", "354", "355", "356", "357", "358", "359", "360", "361", "362",
+   "363", "364", "365", "366", "367", "368", "369", "370", "371", "372", "373",
+   "374", "375", "376", "377", "378", "379", "380", "381", "382", "383", "384",
+   "385", "386", "387", "388", "389", "390", "391", "392", "393", "394", "395",
+   "396", "397", "398", "399", "400", "401", "402", "403", "404", "405", "406",
+   "407", "408", "409", "410", "411", "412", "413", "414", "415", "416", "417",
+   "418", "419", "420", "421", "422", "423", "424", "425", "426", "427", "428",
+   "429", "430", "431", "432", "433", "434", "435", "436", "437", "438", "439",
+   "440", "441", "442", "443", "444", "445", "446", "447", "448", "449", "450",
+   "451", "452", "453", "454", "455", "456", "457", "458", "459", "460", "461",
+   "462", "463", "464", "465", "466", "467", "468", "469", "470", "471", "472",
+   "473", "474", "475", "476", "477", "478", "479", "480", "481", "482", "483",
+   "484", "485", "486", "487", "488", "489", "490", "491", "492", "493", "494",
+   "495", "496", "497", "498", "499", "500", "501", "502", "503", "504", "505",
+   "506", "507", "508", "509", "510", "511", "512", "513", "514", "515", "516",
+   "517", "518", "519", "520", "521", "522", "523", "524", "525", "526", "527",
+   "528", "529", "530", "531", "532", "533", "534", "535", "536", "537", "538",
+   "539", "540", "541", "542", "543", "544", "545", "546", "547", "548", "549",
+   "550", "551", "552", "553", "554", "555", "556", "557", "558", "559", "560",
+   "561", "562", "563", "564", "565", "566", "567", "568", "569", "570", "571",
+   "572", "573", "574", "575", "576", "577", "578", "579", "580", "581", "582",
+   "583", "584", "585", "586", "587", "588", "589", "590", "591", "592", "593",
+   "594", "595", "596", "597", "598", "599", "600", "601", "602", "603", "604",
+   "605", "606", "607", "608", "609", "610", "611", "612", "613", "614", "615",
+   "616", "617", "618", "619", "620", "621", "622", "623", "624", "625", "626",
+   "627", "628", "629", "630", "631", "632", "633", "634", "635", "636", "637",
+   "638", "639", "640", "641", "642", "643", "644", "645", "646", "647", "648",
+   "649", "650", "651", "652", "653", "654", "655", "656", "657", "658", "659",
+   "660", "661", "662", "663", "664", "665", "666", "667", "668", "669", "670",
+   "671", "672", "673", "674", "675", "676", "677", "678", "679", "680", "681",
+   "682", "683", "684", "685", "686", "687", "688", "689", "690", "691", "692",
+   "693", "694", "695", "696", "697", "698", "699", "700", "701", "702", "703",
+   "704", "705", "706", "707", "708", "709", "710", "711", "712", "713", "714",
+   "715", "716", "717", "718", "719", "720", "721", "722", "723", "724", "725",
+   "726", "727", "728", "729", "730", "731", "732", "733", "734", "735", "736",
+   "737", "738", "739", "740", "741", "742", "743", "744", "745", "746", "747",
+   "748", "749", "750", "751", "752", "753", "754", "755", "756", "757", "758",
+   "759", "760", "761", "762", "763", "764", "765", "766", "767", "768", "769",
+   "770", "771", "772", "773", "774", "775", "776", "777", "778", "779", "780",
+   "781", "782", "783", "784", "785", "786", "787", "788", "789", "790", "791",
+   "792", "793", "794", "795", "796", "797", "798", "799", "800", "801", "802",
+   "803", "804", "805", "806", "807", "808", "809", "810", "811", "812", "813",
+   "814", "815", "816", "817", "818", "819", "820", "821", "822", "823", "824",
+   "825", "826", "827", "828", "829", "830", "831", "832", "833", "834", "835",
+   "836", "837", "838", "839", "840", "841", "842", "843", "844", "845", "846",
+   "847", "848", "849", "850", "851", "852", "853", "854", "855", "856", "857",
+   "858", "859", "860", "861", "862", "863", "864", "865", "866", "867", "868",
+   "869", "870", "871", "872", "873", "874", "875", "876", "877", "878", "879",
+   "880", "881", "882", "883", "884", "885", "886", "887", "888", "889", "890",
+   "891", "892", "893", "894", "895", "896", "897", "898", "899", "900", "901",
+   "902", "903", "904", "905", "906", "907", "908", "909", "910", "911", "912",
+   "913", "914", "915", "916", "917", "918", "919", "920", "921", "922", "923",
+   "924", "925", "926", "927", "928", "929", "930", "931", "932", "933", "934",
+   "935", "936", "937", "938", "939", "940", "941", "942", "943", "944", "945",
+   "946", "947", "948", "949", "950", "951", "952", "953", "954", "955", "956",
+   "957", "958", "959", "960", "961", "962", "963", "964", "965", "966", "967",
+   "968", "969", "970", "971", "972", "973", "974", "975", "976", "977", "978",
+   "979", "980", "981", "982", "983", "984", "985", "986", "987", "988", "989",
+   "990", "991", "992", "993", "994", "995", "996", "997", "998", "999"};
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_uint32_to_string --
+ *
+ *       Converts @value to a string.
+ *
+ *       If @value is from 0 to 1000, it will use a constant string in the
+ *       data section of the library.
+ *
+ *       If not, a string will be formatted using @str and snprintf(). This
+ *       is much slower, of course and therefore we try to optimize it out.
+ *
+ *       @strptr will always be set. It will either point to @str or a
+ *       constant string. You will want to use this as your key.
+ *
+ * Parameters:
+ *       @value: A #uint32_t to convert to string.
+ *       @strptr: (out): A pointer to the resulting string.
+ *       @str: (out): Storage for a string made with snprintf.
+ *       @size: Size of @str.
+ *
+ * Returns:
+ *       The number of bytes in the resulting string.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+size_t
+bson_uint32_to_string (uint32_t value,      /* IN */
+                       const char **strptr, /* OUT */
+                       char *str,           /* OUT */
+                       size_t size)         /* IN */
+{
+   if (value < 1000) {
+      *strptr = gUint32Strs[value];
+
+      if (value < 10) {
+         return 1;
+      } else if (value < 100) {
+         return 2;
+      } else {
+         return 3;
+      }
+   }
+
+   *strptr = str;
+
+   return bson_snprintf (str, size, "%u", value);
+}
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-keys.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-keys.h
new file mode 100644
index 0000000000000000000000000000000000000000..a8220ed462475ead10c992cc82bf52f41d1ac0a3
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-keys.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef BSON_KEYS_H
+#define BSON_KEYS_H
+
+
+#include "bson-macros.h"
+#include "bson-types.h"
+
+
+BSON_BEGIN_DECLS
+
+
+BSON_EXPORT (size_t)
+bson_uint32_to_string (uint32_t value,
+                       const char **strptr,
+                       char *str,
+                       size_t size);
+
+
+BSON_END_DECLS
+
+
+#endif /* BSON_KEYS_H */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-macros.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-macros.h
new file mode 100644
index 0000000000000000000000000000000000000000..e31c83000f62b74456bedfedbcf913596212a134
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-macros.h
@@ -0,0 +1,273 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef BSON_MACROS_H
+#define BSON_MACROS_H
+
+#include <stdio.h>
+
+#ifdef __cplusplus
+#include <algorithm>
+#endif
+
+#include "bson-config.h"
+
+
+#if BSON_OS == 1
+#define BSON_OS_UNIX
+#elif BSON_OS == 2
+#define BSON_OS_WIN32
+#else
+#error "Unknown operating system."
+#endif
+
+
+#ifdef __cplusplus
+#define BSON_BEGIN_DECLS extern "C" {
+#define BSON_END_DECLS }
+#else
+#define BSON_BEGIN_DECLS
+#define BSON_END_DECLS
+#endif
+
+
+#define BSON_GNUC_CHECK_VERSION(major, minor) \
+   (defined (__GNUC__) &&                     \
+    ((__GNUC__ > (major)) ||                  \
+     ((__GNUC__ == (major)) && (__GNUC_MINOR__ >= (minor)))))
+
+
+#define BSON_GNUC_IS_VERSION(major, minor) \
+   (defined (__GNUC__) && (__GNUC__ == (major)) && (__GNUC_MINOR__ == (minor)))
+
+
+/* Decorate public functions:
+ * - if BSON_STATIC, we're compiling a program that uses libbson as a static
+ *   library, don't decorate functions
+ * - else if BSON_COMPILATION, we're compiling a static or shared libbson, mark
+ *   public functions for export from the shared lib (which has no effect on
+ *   the static lib)
+ * - else, we're compiling a program that uses libbson as a shared library,
+ *   mark public functions as DLL imports for Microsoft Visual C
+ */
+
+#ifdef _MSC_VER
+/*
+ * Microsoft Visual C
+ */
+#ifdef BSON_STATIC
+#define BSON_API
+#elif defined(BSON_COMPILATION)
+#define BSON_API __declspec(dllexport)
+#else
+#define BSON_API __declspec(dllimport)
+#endif
+#define BSON_CALL __cdecl
+
+#elif defined(__GNUC__)
+/*
+ * GCC
+ */
+#ifdef BSON_STATIC
+#define BSON_API
+#elif defined(BSON_COMPILATION)
+#define BSON_API __attribute__ ((visibility ("default")))
+#else
+#define BSON_API
+#endif
+#define BSON_CALL
+
+#else
+/*
+ * Other compilers
+ */
+#define BSON_API
+#define BSON_CALL
+
+#endif
+
+#define BSON_EXPORT(type) BSON_API type BSON_CALL
+
+
+#ifdef MIN
+#define BSON_MIN MIN
+#elif defined(__cplusplus)
+#define BSON_MIN(a, b) ((std::min) (a, b))
+#elif defined(_MSC_VER)
+#define BSON_MIN(a, b) ((a) < (b) ? (a) : (b))
+#else
+#define BSON_MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+
+#ifdef MAX
+#define BSON_MAX MAX
+#elif defined(__cplusplus)
+#define BSON_MAX(a, b) ((std::max) (a, b))
+#elif defined(_MSC_VER)
+#define BSON_MAX(a, b) ((a) > (b) ? (a) : (b))
+#else
+#define BSON_MAX(a, b) (((a) > (b)) ? (a) : (b))
+#endif
+
+
+#ifdef ABS
+#define BSON_ABS ABS
+#else
+#define BSON_ABS(a) (((a) < 0) ? ((a) * -1) : (a))
+#endif
+
+#ifdef _MSC_VER
+#ifdef _WIN64
+#define BSON_ALIGN_OF_PTR 8
+#else
+#define BSON_ALIGN_OF_PTR 4
+#endif
+#else
+#define BSON_ALIGN_OF_PTR (sizeof (void *))
+#endif
+
+#ifdef BSON_EXTRA_ALIGN
+#if defined(_MSC_VER)
+#define BSON_ALIGNED_BEGIN(_N) __declspec(align (_N))
+#define BSON_ALIGNED_END(_N)
+#else
+#define BSON_ALIGNED_BEGIN(_N)
+#define BSON_ALIGNED_END(_N) __attribute__ ((aligned (_N)))
+#endif
+#else
+#if defined(_MSC_VER)
+#define BSON_ALIGNED_BEGIN(_N) __declspec(align (BSON_ALIGN_OF_PTR))
+#define BSON_ALIGNED_END(_N)
+#else
+#define BSON_ALIGNED_BEGIN(_N)
+#define BSON_ALIGNED_END(_N) \
+   __attribute__ (           \
+      (aligned ((_N) > BSON_ALIGN_OF_PTR ? BSON_ALIGN_OF_PTR : (_N))))
+#endif
+#endif
+
+
+#define bson_str_empty(s) (!s[0])
+#define bson_str_empty0(s) (!s || !s[0])
+
+
+#if defined(_WIN32)
+#define BSON_FUNC __FUNCTION__
+#elif defined(__STDC_VERSION__) && __STDC_VERSION__ < 199901L
+#define BSON_FUNC __FUNCTION__
+#else
+#define BSON_FUNC __func__
+#endif
+
+#define BSON_ASSERT(test)                                  \
+   do {                                                    \
+      if (!(BSON_LIKELY (test))) {                         \
+         fprintf (stderr,                                  \
+                  "%s:%d %s(): precondition failed: %s\n", \
+                  __FILE__,                                \
+                  __LINE__,                                \
+                  BSON_FUNC,                               \
+                  #test);                                  \
+         abort ();                                         \
+      }                                                    \
+   } while (0)
+
+
+#define BSON_STATIC_ASSERT(s) BSON_STATIC_ASSERT_ (s, __LINE__)
+#define BSON_STATIC_ASSERT_JOIN(a, b) BSON_STATIC_ASSERT_JOIN2 (a, b)
+#define BSON_STATIC_ASSERT_JOIN2(a, b) a##b
+#define BSON_STATIC_ASSERT_(s, l)                             \
+   typedef char BSON_STATIC_ASSERT_JOIN (static_assert_test_, \
+                                         __LINE__)[(s) ? 1 : -1]
+
+
+#if defined(__GNUC__)
+#define BSON_GNUC_CONST __attribute__ ((const))
+#define BSON_GNUC_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result))
+#else
+#define BSON_GNUC_CONST
+#define BSON_GNUC_WARN_UNUSED_RESULT
+#endif
+
+
+#if BSON_GNUC_CHECK_VERSION(4, 0) && !defined(_WIN32)
+#define BSON_GNUC_NULL_TERMINATED __attribute__ ((sentinel))
+#define BSON_GNUC_INTERNAL __attribute__ ((visibility ("hidden")))
+#else
+#define BSON_GNUC_NULL_TERMINATED
+#define BSON_GNUC_INTERNAL
+#endif
+
+
+#if defined(__GNUC__)
+#define BSON_LIKELY(x) __builtin_expect (!!(x), 1)
+#define BSON_UNLIKELY(x) __builtin_expect (!!(x), 0)
+#else
+#define BSON_LIKELY(v) v
+#define BSON_UNLIKELY(v) v
+#endif
+
+
+#if defined(__clang__)
+#define BSON_GNUC_PRINTF(f, v) __attribute__ ((format (printf, f, v)))
+#elif BSON_GNUC_CHECK_VERSION(4, 4)
+#define BSON_GNUC_PRINTF(f, v) __attribute__ ((format (gnu_printf, f, v)))
+#else
+#define BSON_GNUC_PRINTF(f, v)
+#endif
+
+
+#if defined(__LP64__) || defined(_LP64)
+#define BSON_WORD_SIZE 64
+#else
+#define BSON_WORD_SIZE 32
+#endif
+
+
+#if defined(_MSC_VER)
+#define BSON_INLINE __inline
+#else
+#define BSON_INLINE __inline__
+#endif
+
+
+#ifdef _MSC_VER
+#define BSON_ENSURE_ARRAY_PARAM_SIZE(_n)
+#define BSON_TYPEOF decltype
+#else
+#define BSON_ENSURE_ARRAY_PARAM_SIZE(_n) static(_n)
+#define BSON_TYPEOF typeof
+#endif
+
+
+#if BSON_GNUC_CHECK_VERSION(3, 1)
+#define BSON_GNUC_DEPRECATED __attribute__ ((__deprecated__))
+#else
+#define BSON_GNUC_DEPRECATED
+#endif
+
+
+#if BSON_GNUC_CHECK_VERSION(4, 5)
+#define BSON_GNUC_DEPRECATED_FOR(f) \
+   __attribute__ ((deprecated ("Use " #f " instead")))
+#else
+#define BSON_GNUC_DEPRECATED_FOR(f) BSON_GNUC_DEPRECATED
+#endif
+
+
+#endif /* BSON_MACROS_H */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-md5.c b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-md5.c
new file mode 100644
index 0000000000000000000000000000000000000000..48cfd9c632e7d430179a4e52f05531dbfe7070ac
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-md5.c
@@ -0,0 +1,397 @@
+/*
+  Copyright (C) 1999, 2000, 2002 Aladdin Enterprises.  All rights reserved.
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  L. Peter Deutsch
+  ghost@aladdin.com
+
+ */
+/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
+/*
+  Independent implementation of MD5 (RFC 1321).
+
+  This code implements the MD5 Algorithm defined in RFC 1321, whose
+  text is available at
+    http://www.ietf.org/rfc/rfc1321.txt
+  The code is derived from the text of the RFC, including the test suite
+  (section A.5) but excluding the rest of Appendix A.  It does not include
+  any code or documentation that is identified in the RFC as being
+  copyrighted.
+
+  The original and principal author of md5.c is L. Peter Deutsch
+  <ghost@aladdin.com>.  Other authors are noted in the change history
+  that follows (in reverse chronological order):
+
+  2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
+    either statically or dynamically; added missing #include <string.h>
+    in library.
+  2002-03-11 lpd Corrected argument list for main(), and added int return
+    type, in test program and T value program.
+  2002-02-21 lpd Added missing #include <stdio.h> in test program.
+  2000-07-03 lpd Patched to eliminate warnings about "constant is
+    unsigned in ANSI C, signed in traditional"; made test program
+    self-checking.
+  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
+  1999-05-03 lpd Original version.
+ */
+
+/*
+ * The following MD5 implementation has been modified to use types as
+ * specified in libbson.
+ */
+
+#include "bson-compat.h"
+
+#include <string.h>
+
+#include "bson-md5.h"
+
+
+#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
+#if BSON_BYTE_ORDER == BSON_BIG_ENDIAN
+#define BYTE_ORDER 1
+#else
+#define BYTE_ORDER -1
+#endif
+
+#define T_MASK ((uint32_t) ~0)
+#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
+#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
+#define T3 0x242070db
+#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
+#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
+#define T6 0x4787c62a
+#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
+#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
+#define T9 0x698098d8
+#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
+#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
+#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
+#define T13 0x6b901122
+#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
+#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
+#define T16 0x49b40821
+#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
+#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
+#define T19 0x265e5a51
+#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
+#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
+#define T22 0x02441453
+#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
+#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
+#define T25 0x21e1cde6
+#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
+#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
+#define T28 0x455a14ed
+#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
+#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
+#define T31 0x676f02d9
+#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
+#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
+#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
+#define T35 0x6d9d6122
+#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
+#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
+#define T38 0x4bdecfa9
+#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
+#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
+#define T41 0x289b7ec6
+#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
+#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
+#define T44 0x04881d05
+#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
+#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
+#define T47 0x1fa27cf8
+#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
+#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
+#define T50 0x432aff97
+#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
+#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
+#define T53 0x655b59c3
+#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
+#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
+#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
+#define T57 0x6fa87e4f
+#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
+#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
+#define T60 0x4e0811a1
+#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
+#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
+#define T63 0x2ad7d2bb
+#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
+
+
+static void
+bson_md5_process (bson_md5_t *md5, const uint8_t *data)
+{
+   uint32_t a = md5->abcd[0];
+   uint32_t b = md5->abcd[1];
+   uint32_t c = md5->abcd[2];
+   uint32_t d = md5->abcd[3];
+   uint32_t t;
+
+#if BYTE_ORDER > 0
+   /* Define storage only for big-endian CPUs. */
+   uint32_t X[16];
+#else
+   /* Define storage for little-endian or both types of CPUs. */
+   uint32_t xbuf[16];
+   const uint32_t *X;
+#endif
+
+   {
+#if BYTE_ORDER == 0
+      /*
+       * Determine dynamically whether this is a big-endian or
+       * little-endian machine, since we can use a more efficient
+       * algorithm on the latter.
+       */
+      static const int w = 1;
+
+      if (*((const uint8_t *) &w)) /* dynamic little-endian */
+#endif
+#if BYTE_ORDER <= 0 /* little-endian */
+      {
+         /*
+          * On little-endian machines, we can process properly aligned
+          * data without copying it.
+          */
+         if (!((data - (const uint8_t *) 0) & 3)) {
+/* data are properly aligned */
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wcast-align"
+#endif
+            X = (const uint32_t *) data;
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+         } else {
+            /* not aligned */
+            memcpy (xbuf, data, sizeof (xbuf));
+            X = xbuf;
+         }
+      }
+#endif
+#if BYTE_ORDER == 0
+      else /* dynamic big-endian */
+#endif
+#if BYTE_ORDER >= 0 /* big-endian */
+      {
+         /*
+          * On big-endian machines, we must arrange the bytes in the
+          * right order.
+          */
+         const uint8_t *xp = data;
+         int i;
+
+#if BYTE_ORDER == 0
+         X = xbuf; /* (dynamic only) */
+#else
+#define xbuf X /* (static only) */
+#endif
+         for (i = 0; i < 16; ++i, xp += 4)
+            xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
+      }
+#endif
+   }
+
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
+
+/* Round 1. */
+/* Let [abcd k s i] denote the operation
+   a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
+#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
+#define SET(a, b, c, d, k, s, Ti)   \
+   t = a + F (b, c, d) + X[k] + Ti; \
+   a = ROTATE_LEFT (t, s) + b
+   /* Do the following 16 operations. */
+   SET (a, b, c, d, 0, 7, T1);
+   SET (d, a, b, c, 1, 12, T2);
+   SET (c, d, a, b, 2, 17, T3);
+   SET (b, c, d, a, 3, 22, T4);
+   SET (a, b, c, d, 4, 7, T5);
+   SET (d, a, b, c, 5, 12, T6);
+   SET (c, d, a, b, 6, 17, T7);
+   SET (b, c, d, a, 7, 22, T8);
+   SET (a, b, c, d, 8, 7, T9);
+   SET (d, a, b, c, 9, 12, T10);
+   SET (c, d, a, b, 10, 17, T11);
+   SET (b, c, d, a, 11, 22, T12);
+   SET (a, b, c, d, 12, 7, T13);
+   SET (d, a, b, c, 13, 12, T14);
+   SET (c, d, a, b, 14, 17, T15);
+   SET (b, c, d, a, 15, 22, T16);
+#undef SET
+
+/* Round 2. */
+/* Let [abcd k s i] denote the operation
+     a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
+#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
+#define SET(a, b, c, d, k, s, Ti)   \
+   t = a + G (b, c, d) + X[k] + Ti; \
+   a = ROTATE_LEFT (t, s) + b
+   /* Do the following 16 operations. */
+   SET (a, b, c, d, 1, 5, T17);
+   SET (d, a, b, c, 6, 9, T18);
+   SET (c, d, a, b, 11, 14, T19);
+   SET (b, c, d, a, 0, 20, T20);
+   SET (a, b, c, d, 5, 5, T21);
+   SET (d, a, b, c, 10, 9, T22);
+   SET (c, d, a, b, 15, 14, T23);
+   SET (b, c, d, a, 4, 20, T24);
+   SET (a, b, c, d, 9, 5, T25);
+   SET (d, a, b, c, 14, 9, T26);
+   SET (c, d, a, b, 3, 14, T27);
+   SET (b, c, d, a, 8, 20, T28);
+   SET (a, b, c, d, 13, 5, T29);
+   SET (d, a, b, c, 2, 9, T30);
+   SET (c, d, a, b, 7, 14, T31);
+   SET (b, c, d, a, 12, 20, T32);
+#undef SET
+
+/* Round 3. */
+/* Let [abcd k s t] denote the operation
+     a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define SET(a, b, c, d, k, s, Ti)   \
+   t = a + H (b, c, d) + X[k] + Ti; \
+   a = ROTATE_LEFT (t, s) + b
+   /* Do the following 16 operations. */
+   SET (a, b, c, d, 5, 4, T33);
+   SET (d, a, b, c, 8, 11, T34);
+   SET (c, d, a, b, 11, 16, T35);
+   SET (b, c, d, a, 14, 23, T36);
+   SET (a, b, c, d, 1, 4, T37);
+   SET (d, a, b, c, 4, 11, T38);
+   SET (c, d, a, b, 7, 16, T39);
+   SET (b, c, d, a, 10, 23, T40);
+   SET (a, b, c, d, 13, 4, T41);
+   SET (d, a, b, c, 0, 11, T42);
+   SET (c, d, a, b, 3, 16, T43);
+   SET (b, c, d, a, 6, 23, T44);
+   SET (a, b, c, d, 9, 4, T45);
+   SET (d, a, b, c, 12, 11, T46);
+   SET (c, d, a, b, 15, 16, T47);
+   SET (b, c, d, a, 2, 23, T48);
+#undef SET
+
+/* Round 4. */
+/* Let [abcd k s t] denote the operation
+     a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
+#define I(x, y, z) ((y) ^ ((x) | ~(z)))
+#define SET(a, b, c, d, k, s, Ti)   \
+   t = a + I (b, c, d) + X[k] + Ti; \
+   a = ROTATE_LEFT (t, s) + b
+   /* Do the following 16 operations. */
+   SET (a, b, c, d, 0, 6, T49);
+   SET (d, a, b, c, 7, 10, T50);
+   SET (c, d, a, b, 14, 15, T51);
+   SET (b, c, d, a, 5, 21, T52);
+   SET (a, b, c, d, 12, 6, T53);
+   SET (d, a, b, c, 3, 10, T54);
+   SET (c, d, a, b, 10, 15, T55);
+   SET (b, c, d, a, 1, 21, T56);
+   SET (a, b, c, d, 8, 6, T57);
+   SET (d, a, b, c, 15, 10, T58);
+   SET (c, d, a, b, 6, 15, T59);
+   SET (b, c, d, a, 13, 21, T60);
+   SET (a, b, c, d, 4, 6, T61);
+   SET (d, a, b, c, 11, 10, T62);
+   SET (c, d, a, b, 2, 15, T63);
+   SET (b, c, d, a, 9, 21, T64);
+#undef SET
+
+   /* Then perform the following additions. (That is increment each
+      of the four registers by the value it had before this block
+      was started.) */
+   md5->abcd[0] += a;
+   md5->abcd[1] += b;
+   md5->abcd[2] += c;
+   md5->abcd[3] += d;
+}
+
+void
+bson_md5_init (bson_md5_t *pms)
+{
+   pms->count[0] = pms->count[1] = 0;
+   pms->abcd[0] = 0x67452301;
+   pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
+   pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
+   pms->abcd[3] = 0x10325476;
+}
+
+void
+bson_md5_append (bson_md5_t *pms, const uint8_t *data, uint32_t nbytes)
+{
+   const uint8_t *p = data;
+   int left = nbytes;
+   int offset = (pms->count[0] >> 3) & 63;
+   uint32_t nbits = (uint32_t) (nbytes << 3);
+
+   if (nbytes <= 0)
+      return;
+
+   /* Update the message length. */
+   pms->count[1] += nbytes >> 29;
+   pms->count[0] += nbits;
+   if (pms->count[0] < nbits)
+      pms->count[1]++;
+
+   /* Process an initial partial block. */
+   if (offset) {
+      int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
+
+      memcpy (pms->buf + offset, p, copy);
+      if (offset + copy < 64)
+         return;
+      p += copy;
+      left -= copy;
+      bson_md5_process (pms, pms->buf);
+   }
+
+   /* Process full blocks. */
+   for (; left >= 64; p += 64, left -= 64)
+      bson_md5_process (pms, p);
+
+   /* Process a final partial block. */
+   if (left)
+      memcpy (pms->buf, p, left);
+}
+
+void
+bson_md5_finish (bson_md5_t *pms, uint8_t digest[16])
+{
+   static const uint8_t pad[64] = {
+      0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+   uint8_t data[8];
+   int i;
+
+   /* Save the length before padding. */
+   for (i = 0; i < 8; ++i)
+      data[i] = (uint8_t) (pms->count[i >> 2] >> ((i & 3) << 3));
+   /* Pad to 56 bytes mod 64. */
+   bson_md5_append (pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
+   /* Append the length. */
+   bson_md5_append (pms, data, sizeof (data));
+   for (i = 0; i < 16; ++i)
+      digest[i] = (uint8_t) (pms->abcd[i >> 2] >> ((i & 3) << 3));
+}
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-md5.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-md5.h
new file mode 100644
index 0000000000000000000000000000000000000000..f7f4f66bc1b73bb83022bb61a607c77f98c6ab16
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-md5.h
@@ -0,0 +1,90 @@
+/*
+  Copyright (C) 1999, 2002 Aladdin Enterprises.  All rights reserved.
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  L. Peter Deutsch
+  ghost@aladdin.com
+
+ */
+/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */
+/*
+  Independent implementation of MD5 (RFC 1321).
+
+  This code implements the MD5 Algorithm defined in RFC 1321, whose
+  text is available at
+    http://www.ietf.org/rfc/rfc1321.txt
+  The code is derived from the text of the RFC, including the test suite
+  (section A.5) but excluding the rest of Appendix A.  It does not include
+  any code or documentation that is identified in the RFC as being
+  copyrighted.
+
+  The original and principal author of md5.h is L. Peter Deutsch
+  <ghost@aladdin.com>.  Other authors are noted in the change history
+  that follows (in reverse chronological order):
+
+  2002-04-13 lpd Removed support for non-ANSI compilers; removed
+    references to Ghostscript; clarified derivation from RFC 1321;
+    now handles byte order either statically or dynamically.
+  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
+    added conditionalization for C++ compilation from Martin
+    Purschke <purschke@bnl.gov>.
+  1999-05-03 lpd Original version.
+ */
+
+
+/*
+ * The following MD5 implementation has been modified to use types as
+ * specified in libbson.
+ */
+
+
+#ifndef BSON_MD5_H
+#define BSON_MD5_H
+
+
+#if !defined(BSON_INSIDE) && !defined(BSON_COMPILATION)
+#error "Only <bson.h> can be included directly."
+#endif
+
+
+#include "bson-endian.h"
+
+
+BSON_BEGIN_DECLS
+
+
+typedef struct {
+   uint32_t count[2]; /* message length in bits, lsw first */
+   uint32_t abcd[4];  /* digest buffer */
+   uint8_t buf[64];   /* accumulate block */
+} bson_md5_t;
+
+
+BSON_EXPORT (void)
+bson_md5_init (bson_md5_t *pms);
+BSON_EXPORT (void)
+bson_md5_append (bson_md5_t *pms, const uint8_t *data, uint32_t nbytes);
+BSON_EXPORT (void)
+bson_md5_finish (bson_md5_t *pms, uint8_t digest[16]);
+
+
+BSON_END_DECLS
+
+
+#endif /* BSON_MD5_H */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-memory.c b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-memory.c
new file mode 100644
index 0000000000000000000000000000000000000000..9b1b49e8ab3cb112b1e07cbaa50def72de5cbf04
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-memory.c
@@ -0,0 +1,306 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "bson-atomic.h"
+#include "bson-config.h"
+#include "bson-memory.h"
+
+
+static bson_mem_vtable_t gMemVtable = {
+   malloc,
+   calloc,
+#ifdef BSON_HAVE_REALLOCF
+   reallocf,
+#else
+   realloc,
+#endif
+   free,
+};
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_malloc --
+ *
+ *       Allocates @num_bytes of memory and returns a pointer to it.  If
+ *       malloc failed to allocate the memory, abort() is called.
+ *
+ *       Libbson does not try to handle OOM conditions as it is beyond the
+ *       scope of this library to handle so appropriately.
+ *
+ * Parameters:
+ *       @num_bytes: The number of bytes to allocate.
+ *
+ * Returns:
+ *       A pointer if successful; otherwise abort() is called and this
+ *       function will never return.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void *
+bson_malloc (size_t num_bytes) /* IN */
+{
+   void *mem = NULL;
+
+   if (BSON_LIKELY (num_bytes)) {
+      if (BSON_UNLIKELY (!(mem = gMemVtable.malloc (num_bytes)))) {
+         abort ();
+      }
+   }
+
+   return mem;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_malloc0 --
+ *
+ *       Like bson_malloc() except the memory is zeroed first. This is
+ *       similar to calloc() except that abort() is called in case of
+ *       failure to allocate memory.
+ *
+ * Parameters:
+ *       @num_bytes: The number of bytes to allocate.
+ *
+ * Returns:
+ *       A pointer if successful; otherwise abort() is called and this
+ *       function will never return.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void *
+bson_malloc0 (size_t num_bytes) /* IN */
+{
+   void *mem = NULL;
+
+   if (BSON_LIKELY (num_bytes)) {
+      if (BSON_UNLIKELY (!(mem = gMemVtable.calloc (1, num_bytes)))) {
+         abort ();
+      }
+   }
+
+   return mem;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_realloc --
+ *
+ *       This function behaves similar to realloc() except that if there is
+ *       a failure abort() is called.
+ *
+ * Parameters:
+ *       @mem: The memory to realloc, or NULL.
+ *       @num_bytes: The size of the new allocation or 0 to free.
+ *
+ * Returns:
+ *       The new allocation if successful; otherwise abort() is called and
+ *       this function never returns.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void *
+bson_realloc (void *mem,        /* IN */
+              size_t num_bytes) /* IN */
+{
+   /*
+    * Not all platforms are guaranteed to free() the memory if a call to
+    * realloc() with a size of zero occurs. Windows, Linux, and FreeBSD do,
+    * however, OS X does not.
+    */
+   if (BSON_UNLIKELY (num_bytes == 0)) {
+      gMemVtable.free (mem);
+      return NULL;
+   }
+
+   mem = gMemVtable.realloc (mem, num_bytes);
+
+   if (BSON_UNLIKELY (!mem)) {
+      abort ();
+   }
+
+   return mem;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_realloc_ctx --
+ *
+ *       This wraps bson_realloc and provides a compatible api for similar
+ *       functions with a context
+ *
+ * Parameters:
+ *       @mem: The memory to realloc, or NULL.
+ *       @num_bytes: The size of the new allocation or 0 to free.
+ *       @ctx: Ignored
+ *
+ * Returns:
+ *       The new allocation if successful; otherwise abort() is called and
+ *       this function never returns.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+
+void *
+bson_realloc_ctx (void *mem,        /* IN */
+                  size_t num_bytes, /* IN */
+                  void *ctx)        /* IN */
+{
+   return bson_realloc (mem, num_bytes);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_free --
+ *
+ *       Frees @mem using the underlying allocator.
+ *
+ *       Currently, this only calls free() directly, but that is subject to
+ *       change.
+ *
+ * Parameters:
+ *       @mem: An allocation to free.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_free (void *mem) /* IN */
+{
+   gMemVtable.free (mem);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_zero_free --
+ *
+ *       Frees @mem using the underlying allocator. @size bytes of @mem will
+ *       be zeroed before freeing the memory. This is useful in scenarios
+ *       where @mem contains passwords or other sensitive information.
+ *
+ * Parameters:
+ *       @mem: An allocation to free.
+ *       @size: The number of bytes in @mem.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_zero_free (void *mem,   /* IN */
+                size_t size) /* IN */
+{
+   if (BSON_LIKELY (mem)) {
+      memset (mem, 0, size);
+      gMemVtable.free (mem);
+   }
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_mem_set_vtable --
+ *
+ *       This function will change our allocationt vtable.
+ *
+ *       It is imperitive that this is called at the beginning of the
+ *       process before any memory has been allocated by the default
+ *       allocator.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_mem_set_vtable (const bson_mem_vtable_t *vtable)
+{
+   BSON_ASSERT (vtable);
+
+   if (!vtable->malloc || !vtable->calloc || !vtable->realloc ||
+       !vtable->free) {
+      fprintf (stderr,
+               "Failure to install BSON vtable, "
+               "missing functions.\n");
+      return;
+   }
+
+   gMemVtable = *vtable;
+}
+
+void
+bson_mem_restore_vtable (void)
+{
+   bson_mem_vtable_t vtable = {
+      malloc,
+      calloc,
+#ifdef BSON_HAVE_REALLOCF
+      reallocf,
+#else
+      realloc,
+#endif
+      free,
+   };
+
+   bson_mem_set_vtable (&vtable);
+}
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-memory.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-memory.h
new file mode 100644
index 0000000000000000000000000000000000000000..5a06dfb14594b5a37cb6dc5045f8e01ca957e61c
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-memory.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef BSON_MEMORY_H
+#define BSON_MEMORY_H
+
+#include "bson-macros.h"
+#include "bson-types.h"
+
+
+BSON_BEGIN_DECLS
+
+
+typedef void *(*bson_realloc_func) (void *mem, size_t num_bytes, void *ctx);
+
+
+typedef struct _bson_mem_vtable_t {
+   void *(*malloc) (size_t num_bytes);
+   void *(*calloc) (size_t n_members, size_t num_bytes);
+   void *(*realloc) (void *mem, size_t num_bytes);
+   void (*free) (void *mem);
+   void *padding[4];
+} bson_mem_vtable_t;
+
+
+BSON_EXPORT (void)
+bson_mem_set_vtable (const bson_mem_vtable_t *vtable);
+BSON_EXPORT (void)
+bson_mem_restore_vtable (void);
+BSON_EXPORT (void *)
+bson_malloc (size_t num_bytes);
+BSON_EXPORT (void *)
+bson_malloc0 (size_t num_bytes);
+BSON_EXPORT (void *)
+bson_realloc (void *mem, size_t num_bytes);
+BSON_EXPORT (void *)
+bson_realloc_ctx (void *mem, size_t num_bytes, void *ctx);
+BSON_EXPORT (void)
+bson_free (void *mem);
+BSON_EXPORT (void)
+bson_zero_free (void *mem, size_t size);
+
+
+BSON_END_DECLS
+
+
+#endif /* BSON_MEMORY_H */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-oid.c b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-oid.c
new file mode 100644
index 0000000000000000000000000000000000000000..bdd10a181ae58a4069cd90c655020e4e3448cb19
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-oid.c
@@ -0,0 +1,517 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "bson-compat.h"
+
+#include <limits.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "bson-context-private.h"
+#include "bson-md5.h"
+#include "bson-oid.h"
+#include "bson-string.h"
+
+
+/*
+ * This table contains an array of two character pairs for every possible
+ * uint8_t. It is used as a lookup table when encoding a bson_oid_t
+ * to hex formatted ASCII. Performing two characters at a time roughly
+ * reduces the number of operations by one-half.
+ */
+static const uint16_t gHexCharPairs[] = {
+#if BSON_BYTE_ORDER == BSON_BIG_ENDIAN
+   12336, 12337, 12338, 12339, 12340, 12341, 12342, 12343, 12344, 12345, 12385,
+   12386, 12387, 12388, 12389, 12390, 12592, 12593, 12594, 12595, 12596, 12597,
+   12598, 12599, 12600, 12601, 12641, 12642, 12643, 12644, 12645, 12646, 12848,
+   12849, 12850, 12851, 12852, 12853, 12854, 12855, 12856, 12857, 12897, 12898,
+   12899, 12900, 12901, 12902, 13104, 13105, 13106, 13107, 13108, 13109, 13110,
+   13111, 13112, 13113, 13153, 13154, 13155, 13156, 13157, 13158, 13360, 13361,
+   13362, 13363, 13364, 13365, 13366, 13367, 13368, 13369, 13409, 13410, 13411,
+   13412, 13413, 13414, 13616, 13617, 13618, 13619, 13620, 13621, 13622, 13623,
+   13624, 13625, 13665, 13666, 13667, 13668, 13669, 13670, 13872, 13873, 13874,
+   13875, 13876, 13877, 13878, 13879, 13880, 13881, 13921, 13922, 13923, 13924,
+   13925, 13926, 14128, 14129, 14130, 14131, 14132, 14133, 14134, 14135, 14136,
+   14137, 14177, 14178, 14179, 14180, 14181, 14182, 14384, 14385, 14386, 14387,
+   14388, 14389, 14390, 14391, 14392, 14393, 14433, 14434, 14435, 14436, 14437,
+   14438, 14640, 14641, 14642, 14643, 14644, 14645, 14646, 14647, 14648, 14649,
+   14689, 14690, 14691, 14692, 14693, 14694, 24880, 24881, 24882, 24883, 24884,
+   24885, 24886, 24887, 24888, 24889, 24929, 24930, 24931, 24932, 24933, 24934,
+   25136, 25137, 25138, 25139, 25140, 25141, 25142, 25143, 25144, 25145, 25185,
+   25186, 25187, 25188, 25189, 25190, 25392, 25393, 25394, 25395, 25396, 25397,
+   25398, 25399, 25400, 25401, 25441, 25442, 25443, 25444, 25445, 25446, 25648,
+   25649, 25650, 25651, 25652, 25653, 25654, 25655, 25656, 25657, 25697, 25698,
+   25699, 25700, 25701, 25702, 25904, 25905, 25906, 25907, 25908, 25909, 25910,
+   25911, 25912, 25913, 25953, 25954, 25955, 25956, 25957, 25958, 26160, 26161,
+   26162, 26163, 26164, 26165, 26166, 26167, 26168, 26169, 26209, 26210, 26211,
+   26212, 26213, 26214
+#else
+   12336, 12592, 12848, 13104, 13360, 13616, 13872, 14128, 14384, 14640, 24880,
+   25136, 25392, 25648, 25904, 26160, 12337, 12593, 12849, 13105, 13361, 13617,
+   13873, 14129, 14385, 14641, 24881, 25137, 25393, 25649, 25905, 26161, 12338,
+   12594, 12850, 13106, 13362, 13618, 13874, 14130, 14386, 14642, 24882, 25138,
+   25394, 25650, 25906, 26162, 12339, 12595, 12851, 13107, 13363, 13619, 13875,
+   14131, 14387, 14643, 24883, 25139, 25395, 25651, 25907, 26163, 12340, 12596,
+   12852, 13108, 13364, 13620, 13876, 14132, 14388, 14644, 24884, 25140, 25396,
+   25652, 25908, 26164, 12341, 12597, 12853, 13109, 13365, 13621, 13877, 14133,
+   14389, 14645, 24885, 25141, 25397, 25653, 25909, 26165, 12342, 12598, 12854,
+   13110, 13366, 13622, 13878, 14134, 14390, 14646, 24886, 25142, 25398, 25654,
+   25910, 26166, 12343, 12599, 12855, 13111, 13367, 13623, 13879, 14135, 14391,
+   14647, 24887, 25143, 25399, 25655, 25911, 26167, 12344, 12600, 12856, 13112,
+   13368, 13624, 13880, 14136, 14392, 14648, 24888, 25144, 25400, 25656, 25912,
+   26168, 12345, 12601, 12857, 13113, 13369, 13625, 13881, 14137, 14393, 14649,
+   24889, 25145, 25401, 25657, 25913, 26169, 12385, 12641, 12897, 13153, 13409,
+   13665, 13921, 14177, 14433, 14689, 24929, 25185, 25441, 25697, 25953, 26209,
+   12386, 12642, 12898, 13154, 13410, 13666, 13922, 14178, 14434, 14690, 24930,
+   25186, 25442, 25698, 25954, 26210, 12387, 12643, 12899, 13155, 13411, 13667,
+   13923, 14179, 14435, 14691, 24931, 25187, 25443, 25699, 25955, 26211, 12388,
+   12644, 12900, 13156, 13412, 13668, 13924, 14180, 14436, 14692, 24932, 25188,
+   25444, 25700, 25956, 26212, 12389, 12645, 12901, 13157, 13413, 13669, 13925,
+   14181, 14437, 14693, 24933, 25189, 25445, 25701, 25957, 26213, 12390, 12646,
+   12902, 13158, 13414, 13670, 13926, 14182, 14438, 14694, 24934, 25190, 25446,
+   25702, 25958, 26214
+#endif
+};
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_oid_init_sequence --
+ *
+ *       Initializes @oid with the next oid in the sequence. The first 4
+ *       bytes contain the current time and the following 8 contain a 64-bit
+ *       integer in big-endian format.
+ *
+ *       The bson_oid_t generated by this function is not guaranteed to be
+ *       globally unique. Only unique within this context. It is however,
+ *       guaranteed to be sequential.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       @oid is initialized.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_oid_init_sequence (bson_oid_t *oid,         /* OUT */
+                        bson_context_t *context) /* IN */
+{
+   uint32_t now = (uint32_t) (time (NULL));
+
+   if (!context) {
+      context = bson_context_get_default ();
+   }
+
+   now = BSON_UINT32_TO_BE (now);
+
+   memcpy (&oid->bytes[0], &now, sizeof (now));
+   context->oid_get_seq64 (context, oid);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_oid_init --
+ *
+ *       Generates bytes for a new bson_oid_t and stores them in @oid. The
+ *       bytes will be generated according to the specification and includes
+ *       the current time, first 3 bytes of MD5(hostname), pid (or tid), and
+ *       monotonic counter.
+ *
+ *       The bson_oid_t generated by this function is not guaranteed to be
+ *       globally unique. Only unique within this context. It is however,
+ *       guaranteed to be sequential.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       @oid is initialized.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_oid_init (bson_oid_t *oid,         /* OUT */
+               bson_context_t *context) /* IN */
+{
+   uint32_t now = (uint32_t) (time (NULL));
+
+   BSON_ASSERT (oid);
+
+   if (!context) {
+      context = bson_context_get_default ();
+   }
+
+   now = BSON_UINT32_TO_BE (now);
+   memcpy (&oid->bytes[0], &now, sizeof (now));
+
+   context->oid_get_host (context, oid);
+   context->oid_get_pid (context, oid);
+   context->oid_get_seq32 (context, oid);
+}
+
+
+/**
+ * bson_oid_init_from_data:
+ * @oid: A bson_oid_t to initialize.
+ * @bytes: A 12-byte buffer to copy into @oid.
+ *
+ */
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_oid_init_from_data --
+ *
+ *       Initializes an @oid from @data. @data MUST be a buffer of at least
+ *       12 bytes. This method is analagous to memcpy()'ing data into @oid.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       @oid is initialized.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_oid_init_from_data (bson_oid_t *oid,     /* OUT */
+                         const uint8_t *data) /* IN */
+{
+   BSON_ASSERT (oid);
+   BSON_ASSERT (data);
+
+   memcpy (oid, data, 12);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_oid_init_from_string --
+ *
+ *       Parses @str containing hex formatted bytes of an object id and
+ *       places the bytes in @oid.
+ *
+ * Parameters:
+ *       @oid: A bson_oid_t
+ *       @str: A string containing at least 24 characters.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       @oid is initialized.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_oid_init_from_string (bson_oid_t *oid, /* OUT */
+                           const char *str) /* IN */
+{
+   BSON_ASSERT (oid);
+   BSON_ASSERT (str);
+
+   bson_oid_init_from_string_unsafe (oid, str);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_oid_get_time_t --
+ *
+ *       Fetches the time for which @oid was created.
+ *
+ * Returns:
+ *       A time_t.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+time_t
+bson_oid_get_time_t (const bson_oid_t *oid) /* IN */
+{
+   BSON_ASSERT (oid);
+
+   return bson_oid_get_time_t_unsafe (oid);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_oid_to_string --
+ *
+ *       Formats a bson_oid_t into a string. @str must contain enough bytes
+ *       for the resulting string which is 25 bytes with a terminating
+ *       NUL-byte.
+ *
+ * Parameters:
+ *       @oid: A bson_oid_t.
+ *       @str: A location to store the resulting string.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_oid_to_string (const bson_oid_t *oid,                       /* IN */
+                    char str[BSON_ENSURE_ARRAY_PARAM_SIZE (25)]) /* OUT */
+{
+#if !defined(__i386__) && !defined(__x86_64__) && !defined(_M_IX86) && \
+   !defined(_M_X64)
+   BSON_ASSERT (oid);
+   BSON_ASSERT (str);
+
+   bson_snprintf (str,
+                  25,
+                  "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+                  oid->bytes[0],
+                  oid->bytes[1],
+                  oid->bytes[2],
+                  oid->bytes[3],
+                  oid->bytes[4],
+                  oid->bytes[5],
+                  oid->bytes[6],
+                  oid->bytes[7],
+                  oid->bytes[8],
+                  oid->bytes[9],
+                  oid->bytes[10],
+                  oid->bytes[11]);
+#else
+   uint16_t *dst;
+   uint8_t *id = (uint8_t *) oid;
+
+   BSON_ASSERT (oid);
+   BSON_ASSERT (str);
+
+   dst = (uint16_t *) (void *) str;
+   dst[0] = gHexCharPairs[id[0]];
+   dst[1] = gHexCharPairs[id[1]];
+   dst[2] = gHexCharPairs[id[2]];
+   dst[3] = gHexCharPairs[id[3]];
+   dst[4] = gHexCharPairs[id[4]];
+   dst[5] = gHexCharPairs[id[5]];
+   dst[6] = gHexCharPairs[id[6]];
+   dst[7] = gHexCharPairs[id[7]];
+   dst[8] = gHexCharPairs[id[8]];
+   dst[9] = gHexCharPairs[id[9]];
+   dst[10] = gHexCharPairs[id[10]];
+   dst[11] = gHexCharPairs[id[11]];
+   str[24] = '\0';
+#endif
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_oid_hash --
+ *
+ *       Hashes the bytes of the provided bson_oid_t using DJB hash.  This
+ *       allows bson_oid_t to be used as keys in a hash table.
+ *
+ * Returns:
+ *       A hash value corresponding to @oid.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+uint32_t
+bson_oid_hash (const bson_oid_t *oid) /* IN */
+{
+   BSON_ASSERT (oid);
+
+   return bson_oid_hash_unsafe (oid);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_oid_compare --
+ *
+ *       A qsort() style compare function that will return less than zero if
+ *       @oid1 is less than @oid2, zero if they are the same, and greater
+ *       than zero if @oid2 is greater than @oid1.
+ *
+ * Returns:
+ *       A qsort() style compare integer.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+int
+bson_oid_compare (const bson_oid_t *oid1, /* IN */
+                  const bson_oid_t *oid2) /* IN */
+{
+   BSON_ASSERT (oid1);
+   BSON_ASSERT (oid2);
+
+   return bson_oid_compare_unsafe (oid1, oid2);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_oid_equal --
+ *
+ *       Compares for equality of @oid1 and @oid2. If they are equal, then
+ *       true is returned, otherwise false.
+ *
+ * Returns:
+ *       A boolean indicating the equality of @oid1 and @oid2.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+bson_oid_equal (const bson_oid_t *oid1, /* IN */
+                const bson_oid_t *oid2) /* IN */
+{
+   BSON_ASSERT (oid1);
+   BSON_ASSERT (oid2);
+
+   return bson_oid_equal_unsafe (oid1, oid2);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_oid_copy --
+ *
+ *       Copies the contents of @src to @dst.
+ *
+ * Parameters:
+ *       @src: A bson_oid_t to copy from.
+ *       @dst: A bson_oid_t to copy to.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       @dst will contain a copy of the data in @src.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_oid_copy (const bson_oid_t *src, /* IN */
+               bson_oid_t *dst)       /* OUT */
+{
+   BSON_ASSERT (src);
+   BSON_ASSERT (dst);
+
+   bson_oid_copy_unsafe (src, dst);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_oid_is_valid --
+ *
+ *       Validates that @str is a valid OID string. @length MUST be 24, but
+ *       is provided as a parameter to simplify calling code.
+ *
+ * Parameters:
+ *       @str: A string to validate.
+ *       @length: The length of @str.
+ *
+ * Returns:
+ *       true if @str can be passed to bson_oid_init_from_string().
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+bson_oid_is_valid (const char *str, /* IN */
+                   size_t length)   /* IN */
+{
+   size_t i;
+
+   BSON_ASSERT (str);
+
+   if ((length == 25) && (str[24] == '\0')) {
+      length = 24;
+   }
+
+   if (length == 24) {
+      for (i = 0; i < length; i++) {
+         switch (str[i]) {
+         case '0':
+         case '1':
+         case '2':
+         case '3':
+         case '4':
+         case '5':
+         case '6':
+         case '7':
+         case '8':
+         case '9':
+         case 'a':
+         case 'b':
+         case 'c':
+         case 'd':
+         case 'e':
+         case 'f':
+         case 'A':
+         case 'B':
+         case 'C':
+         case 'D':
+         case 'E':
+         case 'F':
+            break;
+         default:
+            return false;
+         }
+      }
+      return true;
+   }
+
+   return false;
+}
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-oid.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-oid.h
new file mode 100644
index 0000000000000000000000000000000000000000..1281601179685a0e8d3deab5e09ddd4a10e79cb1
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-oid.h
@@ -0,0 +1,246 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef BSON_OID_H
+#define BSON_OID_H
+
+
+#if !defined(BSON_INSIDE) && !defined(BSON_COMPILATION)
+#error "Only <bson.h> can be included directly."
+#endif
+
+
+#include <time.h>
+
+#include "bson-context.h"
+#include "bson-macros.h"
+#include "bson-types.h"
+#include "bson-endian.h"
+
+
+BSON_BEGIN_DECLS
+
+
+BSON_EXPORT (int)
+bson_oid_compare (const bson_oid_t *oid1, const bson_oid_t *oid2);
+BSON_EXPORT (void)
+bson_oid_copy (const bson_oid_t *src, bson_oid_t *dst);
+BSON_EXPORT (bool)
+bson_oid_equal (const bson_oid_t *oid1, const bson_oid_t *oid2);
+BSON_EXPORT (bool)
+bson_oid_is_valid (const char *str, size_t length);
+BSON_EXPORT (time_t)
+bson_oid_get_time_t (const bson_oid_t *oid);
+BSON_EXPORT (uint32_t)
+bson_oid_hash (const bson_oid_t *oid);
+BSON_EXPORT (void)
+bson_oid_init (bson_oid_t *oid, bson_context_t *context);
+BSON_EXPORT (void)
+bson_oid_init_from_data (bson_oid_t *oid, const uint8_t *data);
+BSON_EXPORT (void)
+bson_oid_init_from_string (bson_oid_t *oid, const char *str);
+BSON_EXPORT (void)
+bson_oid_init_sequence (bson_oid_t *oid, bson_context_t *context);
+BSON_EXPORT (void)
+bson_oid_to_string (const bson_oid_t *oid, char str[25]);
+
+
+/**
+ * bson_oid_compare_unsafe:
+ * @oid1: A bson_oid_t.
+ * @oid2: A bson_oid_t.
+ *
+ * Performs a qsort() style comparison between @oid1 and @oid2.
+ *
+ * This function is meant to be as fast as possible and therefore performs
+ * no argument validation. That is the callers responsibility.
+ *
+ * Returns: An integer < 0 if @oid1 is less than @oid2. Zero if they are equal.
+ *          An integer > 0 if @oid1 is greater than @oid2.
+ */
+static BSON_INLINE int
+bson_oid_compare_unsafe (const bson_oid_t *oid1, const bson_oid_t *oid2)
+{
+   return memcmp (oid1, oid2, sizeof *oid1);
+}
+
+
+/**
+ * bson_oid_equal_unsafe:
+ * @oid1: A bson_oid_t.
+ * @oid2: A bson_oid_t.
+ *
+ * Checks the equality of @oid1 and @oid2.
+ *
+ * This function is meant to be as fast as possible and therefore performs
+ * no checks for argument validity. That is the callers responsibility.
+ *
+ * Returns: true if @oid1 and @oid2 are equal; otherwise false.
+ */
+static BSON_INLINE bool
+bson_oid_equal_unsafe (const bson_oid_t *oid1, const bson_oid_t *oid2)
+{
+   return !memcmp (oid1, oid2, sizeof *oid1);
+}
+
+/**
+ * bson_oid_hash_unsafe:
+ * @oid: A bson_oid_t.
+ *
+ * This function performs a DJB style hash upon the bytes contained in @oid.
+ * The result is a hash key suitable for use in a hashtable.
+ *
+ * This function is meant to be as fast as possible and therefore performs no
+ * validation of arguments. The caller is responsible to ensure they are
+ * passing valid arguments.
+ *
+ * Returns: A uint32_t containing a hash code.
+ */
+static BSON_INLINE uint32_t
+bson_oid_hash_unsafe (const bson_oid_t *oid)
+{
+   uint32_t hash = 5381;
+   uint32_t i;
+
+   for (i = 0; i < sizeof oid->bytes; i++) {
+      hash = ((hash << 5) + hash) + oid->bytes[i];
+   }
+
+   return hash;
+}
+
+
+/**
+ * bson_oid_copy_unsafe:
+ * @src: A bson_oid_t to copy from.
+ * @dst: A bson_oid_t to copy into.
+ *
+ * Copies the contents of @src into @dst. This function is meant to be as
+ * fast as possible and therefore performs no argument checking. It is the
+ * callers responsibility to ensure they are passing valid data into the
+ * function.
+ */
+static BSON_INLINE void
+bson_oid_copy_unsafe (const bson_oid_t *src, bson_oid_t *dst)
+{
+   memcpy (dst, src, sizeof *src);
+}
+
+
+/**
+ * bson_oid_parse_hex_char:
+ * @hex: A character to parse to its integer value.
+ *
+ * This function contains a jump table to return the integer value for a
+ * character containing a hexidecimal value (0-9, a-f, A-F). If the character
+ * is not a hexidecimal character then zero is returned.
+ *
+ * Returns: An integer between 0 and 15.
+ */
+static BSON_INLINE uint8_t
+bson_oid_parse_hex_char (char hex)
+{
+   switch (hex) {
+   case '0':
+      return 0;
+   case '1':
+      return 1;
+   case '2':
+      return 2;
+   case '3':
+      return 3;
+   case '4':
+      return 4;
+   case '5':
+      return 5;
+   case '6':
+      return 6;
+   case '7':
+      return 7;
+   case '8':
+      return 8;
+   case '9':
+      return 9;
+   case 'a':
+   case 'A':
+      return 0xa;
+   case 'b':
+   case 'B':
+      return 0xb;
+   case 'c':
+   case 'C':
+      return 0xc;
+   case 'd':
+   case 'D':
+      return 0xd;
+   case 'e':
+   case 'E':
+      return 0xe;
+   case 'f':
+   case 'F':
+      return 0xf;
+   default:
+      return 0;
+   }
+}
+
+
+/**
+ * bson_oid_init_from_string_unsafe:
+ * @oid: A bson_oid_t to store the result.
+ * @str: A 24-character hexidecimal encoded string.
+ *
+ * Parses a string containing 24 hexidecimal encoded bytes into a bson_oid_t.
+ * This function is meant to be as fast as possible and inlined into your
+ * code. For that purpose, the function does not perform any sort of bounds
+ * checking and it is the callers responsibility to ensure they are passing
+ * valid input to the function.
+ */
+static BSON_INLINE void
+bson_oid_init_from_string_unsafe (bson_oid_t *oid, const char *str)
+{
+   int i;
+
+   for (i = 0; i < 12; i++) {
+      oid->bytes[i] = ((bson_oid_parse_hex_char (str[2 * i]) << 4) |
+                       (bson_oid_parse_hex_char (str[2 * i + 1])));
+   }
+}
+
+
+/**
+ * bson_oid_get_time_t_unsafe:
+ * @oid: A bson_oid_t.
+ *
+ * Fetches the time @oid was generated.
+ *
+ * Returns: A time_t containing the UNIX timestamp of generation.
+ */
+static BSON_INLINE time_t
+bson_oid_get_time_t_unsafe (const bson_oid_t *oid)
+{
+   uint32_t t;
+
+   memcpy (&t, oid, sizeof (t));
+   return BSON_UINT32_FROM_BE (t);
+}
+
+
+BSON_END_DECLS
+
+
+#endif /* BSON_OID_H */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-private.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-private.h
new file mode 100644
index 0000000000000000000000000000000000000000..00267f240f520bcff69f9e31de504564b6a2f7de
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-private.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef BSON_PRIVATE_H
+#define BSON_PRIVATE_H
+
+
+#include "bson-macros.h"
+#include "bson-memory.h"
+#include "bson-types.h"
+
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
+#define BEGIN_IGNORE_DEPRECATIONS  \
+   _Pragma ("GCC diagnostic push") \
+      _Pragma ("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
+#define END_IGNORE_DEPRECATIONS _Pragma ("GCC diagnostic pop")
+#elif defined(__clang__)
+#define BEGIN_IGNORE_DEPRECATIONS    \
+   _Pragma ("clang diagnostic push") \
+      _Pragma ("clang diagnostic ignored \"-Wdeprecated-declarations\"")
+#define END_IGNORE_DEPRECATIONS _Pragma ("clang diagnostic pop")
+#else
+#define BEGIN_IGNORE_DEPRECATIONS
+#define END_IGNORE_DEPRECATIONS
+#endif
+
+
+BSON_BEGIN_DECLS
+
+
+typedef enum {
+   BSON_FLAG_NONE = 0,
+   BSON_FLAG_INLINE = (1 << 0),
+   BSON_FLAG_STATIC = (1 << 1),
+   BSON_FLAG_RDONLY = (1 << 2),
+   BSON_FLAG_CHILD = (1 << 3),
+   BSON_FLAG_IN_CHILD = (1 << 4),
+   BSON_FLAG_NO_FREE = (1 << 5),
+} bson_flags_t;
+
+
+#define BSON_INLINE_DATA_SIZE 120
+
+BSON_ALIGNED_BEGIN (128)
+typedef struct {
+   bson_flags_t flags;
+   uint32_t len;
+   uint8_t data[BSON_INLINE_DATA_SIZE];
+} bson_impl_inline_t BSON_ALIGNED_END (128);
+
+
+BSON_STATIC_ASSERT (sizeof (bson_impl_inline_t) == 128);
+
+
+BSON_ALIGNED_BEGIN (128)
+typedef struct {
+   bson_flags_t flags;        /* flags describing the bson_t */
+   uint32_t len;              /* length of bson document in bytes */
+   bson_t *parent;            /* parent bson if a child */
+   uint32_t depth;            /* Subdocument depth. */
+   uint8_t **buf;             /* pointer to buffer pointer */
+   size_t *buflen;            /* pointer to buffer length */
+   size_t offset;             /* our offset inside *buf  */
+   uint8_t *alloc;            /* buffer that we own. */
+   size_t alloclen;           /* length of buffer that we own. */
+   bson_realloc_func realloc; /* our realloc implementation */
+   void *realloc_func_ctx;    /* context for our realloc func */
+} bson_impl_alloc_t BSON_ALIGNED_END (128);
+
+
+BSON_STATIC_ASSERT (sizeof (bson_impl_alloc_t) <= 128);
+
+
+BSON_END_DECLS
+
+
+#endif /* BSON_PRIVATE_H */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-reader.c b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-reader.c
new file mode 100644
index 0000000000000000000000000000000000000000..8045254f04cae7e16c310c904ce999393ec1a3bc
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-reader.c
@@ -0,0 +1,832 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "bson.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#ifdef BSON_OS_WIN32
+#include <io.h>
+#include <share.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "bson-reader.h"
+#include "bson-memory.h"
+
+
+typedef enum {
+   BSON_READER_HANDLE = 1,
+   BSON_READER_DATA = 2,
+} bson_reader_type_t;
+
+
+typedef struct {
+   bson_reader_type_t type;
+   void *handle;
+   bool done : 1;
+   bool failed : 1;
+   size_t end;
+   size_t len;
+   size_t offset;
+   size_t bytes_read;
+   bson_t inline_bson;
+   uint8_t *data;
+   bson_reader_read_func_t read_func;
+   bson_reader_destroy_func_t destroy_func;
+} bson_reader_handle_t;
+
+
+typedef struct {
+   int fd;
+   bool do_close;
+} bson_reader_handle_fd_t;
+
+
+typedef struct {
+   bson_reader_type_t type;
+   const uint8_t *data;
+   size_t length;
+   size_t offset;
+   bson_t inline_bson;
+} bson_reader_data_t;
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_reader_handle_fill_buffer --
+ *
+ *       Attempt to read as much as possible until the underlying buffer
+ *       in @reader is filled or we have reached end-of-stream or
+ *       read failure.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static void
+_bson_reader_handle_fill_buffer (bson_reader_handle_t *reader) /* IN */
+{
+   ssize_t ret;
+
+   /*
+    * Handle first read specially.
+    */
+   if ((!reader->done) && (!reader->offset) && (!reader->end)) {
+      ret = reader->read_func (reader->handle, &reader->data[0], reader->len);
+
+      if (ret <= 0) {
+         reader->done = true;
+         return;
+      }
+      reader->bytes_read += ret;
+
+      reader->end = ret;
+      return;
+   }
+
+   /*
+    * Move valid data to head.
+    */
+   memmove (&reader->data[0],
+            &reader->data[reader->offset],
+            reader->end - reader->offset);
+   reader->end = reader->end - reader->offset;
+   reader->offset = 0;
+
+   /*
+    * Read in data to fill the buffer.
+    */
+   ret = reader->read_func (
+      reader->handle, &reader->data[reader->end], reader->len - reader->end);
+
+   if (ret <= 0) {
+      reader->done = true;
+      reader->failed = (ret < 0);
+   } else {
+      reader->bytes_read += ret;
+      reader->end += ret;
+   }
+
+   BSON_ASSERT (reader->offset == 0);
+   BSON_ASSERT (reader->end <= reader->len);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_reader_new_from_handle --
+ *
+ *       Allocates and initializes a new bson_reader_t using the opaque
+ *       handle provided.
+ *
+ * Parameters:
+ *       @handle: an opaque handle to use to read data.
+ *       @rf: a function to perform reads on @handle.
+ *       @df: a function to release @handle, or NULL.
+ *
+ * Returns:
+ *       A newly allocated bson_reader_t if successful, otherwise NULL.
+ *       Free the successful result with bson_reader_destroy().
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bson_reader_t *
+bson_reader_new_from_handle (void *handle,
+                             bson_reader_read_func_t rf,
+                             bson_reader_destroy_func_t df)
+{
+   bson_reader_handle_t *real;
+
+   BSON_ASSERT (handle);
+   BSON_ASSERT (rf);
+
+   real = bson_malloc0 (sizeof *real);
+   real->type = BSON_READER_HANDLE;
+   real->data = bson_malloc0 (1024);
+   real->handle = handle;
+   real->len = 1024;
+   real->offset = 0;
+
+   bson_reader_set_read_func ((bson_reader_t *) real, rf);
+
+   if (df) {
+      bson_reader_set_destroy_func ((bson_reader_t *) real, df);
+   }
+
+   _bson_reader_handle_fill_buffer (real);
+
+   return (bson_reader_t *) real;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_reader_handle_fd_destroy --
+ *
+ *       Cleanup allocations associated with state created in
+ *       bson_reader_new_from_fd().
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static void
+_bson_reader_handle_fd_destroy (void *handle) /* IN */
+{
+   bson_reader_handle_fd_t *fd = handle;
+
+   if (fd) {
+      if ((fd->fd != -1) && fd->do_close) {
+#ifdef _WIN32
+         _close (fd->fd);
+#else
+         close (fd->fd);
+#endif
+      }
+      bson_free (fd);
+   }
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_reader_handle_fd_read --
+ *
+ *       Perform read on opaque handle created in
+ *       bson_reader_new_from_fd().
+ *
+ *       The underlying file descriptor is read from the current position
+ *       using the bson_reader_handle_fd_t allocated.
+ *
+ * Returns:
+ *       -1 on failure.
+ *       0 on end of stream.
+ *       Greater than zero on success.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static ssize_t
+_bson_reader_handle_fd_read (void *handle, /* IN */
+                             void *buf,    /* IN */
+                             size_t len)   /* IN */
+{
+   bson_reader_handle_fd_t *fd = handle;
+   ssize_t ret = -1;
+
+   if (fd && (fd->fd != -1)) {
+   again:
+#ifdef BSON_OS_WIN32
+      ret = _read (fd->fd, buf, (unsigned int) len);
+#else
+      ret = read (fd->fd, buf, len);
+#endif
+      if ((ret == -1) && (errno == EAGAIN)) {
+         goto again;
+      }
+   }
+
+   return ret;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_reader_new_from_fd --
+ *
+ *       Create a new bson_reader_t using the file-descriptor provided.
+ *
+ * Parameters:
+ *       @fd: a libc style file-descriptor.
+ *       @close_on_destroy: if close() should be called on @fd when
+ *          bson_reader_destroy() is called.
+ *
+ * Returns:
+ *       A newly allocated bson_reader_t on success; otherwise NULL.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bson_reader_t *
+bson_reader_new_from_fd (int fd,                /* IN */
+                         bool close_on_destroy) /* IN */
+{
+   bson_reader_handle_fd_t *handle;
+
+   BSON_ASSERT (fd != -1);
+
+   handle = bson_malloc0 (sizeof *handle);
+   handle->fd = fd;
+   handle->do_close = close_on_destroy;
+
+   return bson_reader_new_from_handle (
+      handle, _bson_reader_handle_fd_read, _bson_reader_handle_fd_destroy);
+}
+
+
+/**
+ * bson_reader_set_read_func:
+ * @reader: A bson_reader_t.
+ *
+ * Note that @reader must be initialized by bson_reader_init_from_handle(), or
+ * data
+ * will be destroyed.
+ */
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_reader_set_read_func --
+ *
+ *       Set the read func to be provided for @reader.
+ *
+ *       You probably want to use bson_reader_new_from_handle() or
+ *       bson_reader_new_from_fd() instead.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_reader_set_read_func (bson_reader_t *reader,        /* IN */
+                           bson_reader_read_func_t func) /* IN */
+{
+   bson_reader_handle_t *real = (bson_reader_handle_t *) reader;
+
+   BSON_ASSERT (reader->type == BSON_READER_HANDLE);
+
+   real->read_func = func;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_reader_set_destroy_func --
+ *
+ *       Set the function to cleanup state when @reader is destroyed.
+ *
+ *       You probably want bson_reader_new_from_fd() or
+ *       bson_reader_new_from_handle() instead.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_reader_set_destroy_func (bson_reader_t *reader,           /* IN */
+                              bson_reader_destroy_func_t func) /* IN */
+{
+   bson_reader_handle_t *real = (bson_reader_handle_t *) reader;
+
+   BSON_ASSERT (reader->type == BSON_READER_HANDLE);
+
+   real->destroy_func = func;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_reader_handle_grow_buffer --
+ *
+ *       Grow the buffer to the next power of two.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static void
+_bson_reader_handle_grow_buffer (bson_reader_handle_t *reader) /* IN */
+{
+   size_t size;
+
+   size = reader->len * 2;
+   reader->data = bson_realloc (reader->data, size);
+   reader->len = size;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_reader_handle_tell --
+ *
+ *       Tell the current position within the underlying file-descriptor.
+ *
+ * Returns:
+ *       An off_t containing the current offset.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static off_t
+_bson_reader_handle_tell (bson_reader_handle_t *reader) /* IN */
+{
+   off_t off;
+
+   off = (off_t) reader->bytes_read;
+   off -= (off_t) reader->end;
+   off += (off_t) reader->offset;
+
+   return off;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_reader_handle_read --
+ *
+ *       Read the next chunk of data from the underlying file descriptor
+ *       and return a bson_t which should not be modified.
+ *
+ *       There was a failure if NULL is returned and @reached_eof is
+ *       not set to true.
+ *
+ * Returns:
+ *       NULL on failure or end of stream.
+ *
+ * Side effects:
+ *       @reached_eof is set if non-NULL.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static const bson_t *
+_bson_reader_handle_read (bson_reader_handle_t *reader, /* IN */
+                          bool *reached_eof)            /* IN */
+{
+   int32_t blen;
+
+   if (reached_eof) {
+      *reached_eof = false;
+   }
+
+   while (!reader->done) {
+      if ((reader->end - reader->offset) < 4) {
+         _bson_reader_handle_fill_buffer (reader);
+         continue;
+      }
+
+      memcpy (&blen, &reader->data[reader->offset], sizeof blen);
+      blen = BSON_UINT32_FROM_LE (blen);
+
+      if (blen < 5) {
+         return NULL;
+      }
+
+      if (blen > (int32_t) (reader->end - reader->offset)) {
+         if (blen > (int32_t) reader->len) {
+            _bson_reader_handle_grow_buffer (reader);
+         }
+
+         _bson_reader_handle_fill_buffer (reader);
+         continue;
+      }
+
+      if (!bson_init_static (&reader->inline_bson,
+                             &reader->data[reader->offset],
+                             (uint32_t) blen)) {
+         return NULL;
+      }
+
+      reader->offset += blen;
+
+      return &reader->inline_bson;
+   }
+
+   if (reached_eof) {
+      *reached_eof = reader->done && !reader->failed;
+   }
+
+   return NULL;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_reader_new_from_data --
+ *
+ *       Allocates and initializes a new bson_reader_t that reads the memory
+ *       provided as a stream of BSON documents.
+ *
+ * Parameters:
+ *       @data: A buffer to read BSON documents from.
+ *       @length: The length of @data.
+ *
+ * Returns:
+ *       A newly allocated bson_reader_t that should be freed with
+ *       bson_reader_destroy().
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bson_reader_t *
+bson_reader_new_from_data (const uint8_t *data, /* IN */
+                           size_t length)       /* IN */
+{
+   bson_reader_data_t *real;
+
+   BSON_ASSERT (data);
+
+   real = (bson_reader_data_t *) bson_malloc0 (sizeof *real);
+   real->type = BSON_READER_DATA;
+   real->data = data;
+   real->length = length;
+   real->offset = 0;
+
+   return (bson_reader_t *) real;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_reader_data_read --
+ *
+ *       Read the next document from the underlying buffer.
+ *
+ * Returns:
+ *       NULL on failure or end of stream.
+ *       a bson_t which should not be modified.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static const bson_t *
+_bson_reader_data_read (bson_reader_data_t *reader, /* IN */
+                        bool *reached_eof)          /* IN */
+{
+   int32_t blen;
+
+   if (reached_eof) {
+      *reached_eof = false;
+   }
+
+   if ((reader->offset + 4) < reader->length) {
+      memcpy (&blen, &reader->data[reader->offset], sizeof blen);
+      blen = BSON_UINT32_FROM_LE (blen);
+
+      if (blen < 5) {
+         return NULL;
+      }
+
+      if (blen > (int32_t) (reader->length - reader->offset)) {
+         return NULL;
+      }
+
+      if (!bson_init_static (&reader->inline_bson,
+                             &reader->data[reader->offset],
+                             (uint32_t) blen)) {
+         return NULL;
+      }
+
+      reader->offset += blen;
+
+      return &reader->inline_bson;
+   }
+
+   if (reached_eof) {
+      *reached_eof = (reader->offset == reader->length);
+   }
+
+   return NULL;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_reader_data_tell --
+ *
+ *       Tell the current position in the underlying buffer.
+ *
+ * Returns:
+ *       An off_t of the current offset.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static off_t
+_bson_reader_data_tell (bson_reader_data_t *reader) /* IN */
+{
+   return (off_t) reader->offset;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_reader_destroy --
+ *
+ *       Release a bson_reader_t created with bson_reader_new_from_data(),
+ *       bson_reader_new_from_fd(), or bson_reader_new_from_handle().
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_reader_destroy (bson_reader_t *reader) /* IN */
+{
+   BSON_ASSERT (reader);
+
+   switch (reader->type) {
+   case 0:
+      break;
+   case BSON_READER_HANDLE: {
+      bson_reader_handle_t *handle = (bson_reader_handle_t *) reader;
+
+      if (handle->destroy_func) {
+         handle->destroy_func (handle->handle);
+      }
+
+      bson_free (handle->data);
+   } break;
+   case BSON_READER_DATA:
+      break;
+   default:
+      fprintf (stderr, "No such reader type: %02x\n", reader->type);
+      break;
+   }
+
+   reader->type = 0;
+
+   bson_free (reader);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_reader_read --
+ *
+ *       Reads the next bson_t in the underlying memory or storage.  The
+ *       resulting bson_t should not be modified or freed. You may copy it
+ *       and iterate over it.  Functions that take a const bson_t* are safe
+ *       to use.
+ *
+ *       This structure does not survive calls to bson_reader_read() or
+ *       bson_reader_destroy() as it uses memory allocated by the reader or
+ *       underlying storage/memory.
+ *
+ *       If NULL is returned then @reached_eof will be set to true if the
+ *       end of the file or buffer was reached. This indicates if there was
+ *       an error parsing the document stream.
+ *
+ * Returns:
+ *       A const bson_t that should not be modified or freed.
+ *       NULL on failure or end of stream.
+ *
+ * Side effects:
+ *       @reached_eof is set if non-NULL.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+const bson_t *
+bson_reader_read (bson_reader_t *reader, /* IN */
+                  bool *reached_eof)     /* OUT */
+{
+   BSON_ASSERT (reader);
+
+   switch (reader->type) {
+   case BSON_READER_HANDLE:
+      return _bson_reader_handle_read ((bson_reader_handle_t *) reader,
+                                       reached_eof);
+
+   case BSON_READER_DATA:
+      return _bson_reader_data_read ((bson_reader_data_t *) reader,
+                                     reached_eof);
+
+   default:
+      fprintf (stderr, "No such reader type: %02x\n", reader->type);
+      break;
+   }
+
+   return NULL;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_reader_tell --
+ *
+ *       Return the current position in the underlying reader. This will
+ *       always be at the beginning of a bson document or end of file.
+ *
+ * Returns:
+ *       An off_t containing the current offset.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+off_t
+bson_reader_tell (bson_reader_t *reader) /* IN */
+{
+   BSON_ASSERT (reader);
+
+   switch (reader->type) {
+   case BSON_READER_HANDLE:
+      return _bson_reader_handle_tell ((bson_reader_handle_t *) reader);
+
+   case BSON_READER_DATA:
+      return _bson_reader_data_tell ((bson_reader_data_t *) reader);
+
+   default:
+      fprintf (stderr, "No such reader type: %02x\n", reader->type);
+      return -1;
+   }
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_reader_new_from_file --
+ *
+ *       A convenience function to open a file containing sequential
+ *       bson documents and read them using bson_reader_t.
+ *
+ * Returns:
+ *       A new bson_reader_t if successful, otherwise NULL and
+ *       @error is set. Free the non-NULL result with
+ *       bson_reader_destroy().
+ *
+ * Side effects:
+ *       @error may be set.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bson_reader_t *
+bson_reader_new_from_file (const char *path,    /* IN */
+                           bson_error_t *error) /* OUT */
+{
+   char errmsg_buf[BSON_ERROR_BUFFER_SIZE];
+   char *errmsg;
+   int fd;
+
+   BSON_ASSERT (path);
+
+#ifdef BSON_OS_WIN32
+   if (_sopen_s (&fd, path, (_O_RDONLY | _O_BINARY), _SH_DENYNO, 0) != 0) {
+      fd = -1;
+   }
+#else
+   fd = open (path, O_RDONLY);
+#endif
+
+   if (fd == -1) {
+      errmsg = bson_strerror_r (errno, errmsg_buf, sizeof errmsg_buf);
+      bson_set_error (
+         error, BSON_ERROR_READER, BSON_ERROR_READER_BADFD, "%s", errmsg);
+      return NULL;
+   }
+
+   return bson_reader_new_from_fd (fd, true);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_reader_reset --
+ *
+ *       Restore the reader to its initial state. Valid only for readers
+ *       created with bson_reader_new_from_data.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_reader_reset (bson_reader_t *reader)
+{
+   bson_reader_data_t *real = (bson_reader_data_t *) reader;
+
+   if (real->type != BSON_READER_DATA) {
+      fprintf (stderr, "Reader type cannot be reset\n");
+      return;
+   }
+
+   real->offset = 0;
+}
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-reader.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-reader.h
new file mode 100644
index 0000000000000000000000000000000000000000..084ecd10a421fc3f7dc92596f2c9cf551f4c8238
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-reader.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef BSON_READER_H
+#define BSON_READER_H
+
+
+#if !defined(BSON_INSIDE) && !defined(BSON_COMPILATION)
+#error "Only <bson.h> can be included directly."
+#endif
+
+
+#include "bson-compat.h"
+#include "bson-oid.h"
+#include "bson-types.h"
+
+
+BSON_BEGIN_DECLS
+
+
+#define BSON_ERROR_READER_BADFD 1
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_reader_read_func_t --
+ *
+ *       This function is a callback used by bson_reader_t to read the
+ *       next chunk of data from the underlying opaque file descriptor.
+ *
+ *       This function is meant to operate similar to the read() function
+ *       as part of libc on UNIX-like systems.
+ *
+ * Parameters:
+ *       @handle: The handle to read from.
+ *       @buf: The buffer to read into.
+ *       @count: The number of bytes to read.
+ *
+ * Returns:
+ *       0 for end of stream.
+ *       -1 for read failure.
+ *       Greater than zero for number of bytes read into @buf.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+typedef ssize_t (*bson_reader_read_func_t) (void *handle,  /* IN */
+                                            void *buf,     /* IN */
+                                            size_t count); /* IN */
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_reader_destroy_func_t --
+ *
+ *       Destroy callback to release any resources associated with the
+ *       opaque handle.
+ *
+ * Parameters:
+ *       @handle: the handle provided to bson_reader_new_from_handle().
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+typedef void (*bson_reader_destroy_func_t) (void *handle); /* IN */
+
+
+BSON_EXPORT (bson_reader_t *)
+bson_reader_new_from_handle (void *handle,
+                             bson_reader_read_func_t rf,
+                             bson_reader_destroy_func_t df);
+BSON_EXPORT (bson_reader_t *)
+bson_reader_new_from_fd (int fd, bool close_on_destroy);
+BSON_EXPORT (bson_reader_t *)
+bson_reader_new_from_file (const char *path, bson_error_t *error);
+BSON_EXPORT (bson_reader_t *)
+bson_reader_new_from_data (const uint8_t *data, size_t length);
+BSON_EXPORT (void)
+bson_reader_destroy (bson_reader_t *reader);
+BSON_EXPORT (void)
+bson_reader_set_read_func (bson_reader_t *reader, bson_reader_read_func_t func);
+BSON_EXPORT (void)
+bson_reader_set_destroy_func (bson_reader_t *reader,
+                              bson_reader_destroy_func_t func);
+BSON_EXPORT (const bson_t *)
+bson_reader_read (bson_reader_t *reader, bool *reached_eof);
+BSON_EXPORT (off_t)
+bson_reader_tell (bson_reader_t *reader);
+BSON_EXPORT (void)
+bson_reader_reset (bson_reader_t *reader);
+
+BSON_END_DECLS
+
+
+#endif /* BSON_READER_H */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-stdint-win32.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-stdint-win32.h
new file mode 100644
index 0000000000000000000000000000000000000000..eff0cf1344211247f27c720f5c9f10b93b1022fe
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-stdint-win32.h
@@ -0,0 +1,263 @@
+// ISO C9x  compliant stdint.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
+//
+//  Copyright (c) 2006-2013 Alexander Chemeris
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//   1. Redistributions of source code must retain the above copyright notice,
+//      this list of conditions and the following disclaimer.
+//
+//   2. Redistributions in binary form must reproduce the above copyright
+//      notice, this list of conditions and the following disclaimer in the
+//      documentation and/or other materials provided with the distribution.
+//
+//   3. Neither the name of the product nor the names of its contributors may
+//      be used to endorse or promote products derived from this software
+//      without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_STDINT_H_ // [
+#define _MSC_STDINT_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#if _MSC_VER >= 1600 // [
+#include <stdint.h>
+#else // ] _MSC_VER >= 1600 [
+
+#include <limits.h>
+
+// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
+// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
+// or compiler give many errors like this:
+//   error C2733: second C linkage of overloaded function 'wmemchr' not allowed
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <wchar.h>
+#ifdef __cplusplus
+}
+#endif
+
+// Define _W64 macros to mark types changing their size, like intptr_t.
+#ifndef _W64
+#if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
+#define _W64 __w64
+#else
+#define _W64
+#endif
+#endif
+
+
+// 7.18.1 Integer types
+
+// 7.18.1.1 Exact-width integer types
+
+// Visual Studio 6 and Embedded Visual C++ 4 doesn't
+// realize that, e.g. char has the same size as __int8
+// so we give up on __intX for them.
+#if (_MSC_VER < 1300)
+typedef signed char int8_t;
+typedef signed short int16_t;
+typedef signed int int32_t;
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+#else
+typedef signed __int8 int8_t;
+typedef signed __int16 int16_t;
+typedef signed __int32 int32_t;
+typedef unsigned __int8 uint8_t;
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int32 uint32_t;
+#endif
+typedef signed __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+
+// 7.18.1.2 Minimum-width integer types
+typedef int8_t int_least8_t;
+typedef int16_t int_least16_t;
+typedef int32_t int_least32_t;
+typedef int64_t int_least64_t;
+typedef uint8_t uint_least8_t;
+typedef uint16_t uint_least16_t;
+typedef uint32_t uint_least32_t;
+typedef uint64_t uint_least64_t;
+
+// 7.18.1.3 Fastest minimum-width integer types
+typedef int8_t int_fast8_t;
+typedef int16_t int_fast16_t;
+typedef int32_t int_fast32_t;
+typedef int64_t int_fast64_t;
+typedef uint8_t uint_fast8_t;
+typedef uint16_t uint_fast16_t;
+typedef uint32_t uint_fast32_t;
+typedef uint64_t uint_fast64_t;
+
+// 7.18.1.4 Integer types capable of holding object pointers
+#ifdef _WIN64 // [
+typedef signed __int64 intptr_t;
+typedef unsigned __int64 uintptr_t;
+#else         // _WIN64 ][
+typedef _W64 signed int intptr_t;
+typedef _W64 unsigned int uintptr_t;
+#endif        // _WIN64 ]
+
+// 7.18.1.5 Greatest-width integer types
+typedef int64_t intmax_t;
+typedef uint64_t uintmax_t;
+
+
+// 7.18.2 Limits of specified-width integer types
+
+#if !defined(__cplusplus) || \
+   defined(                  \
+      __STDC_LIMIT_MACROS) // [   See footnote 220 at page 257 and footnote
+// 221 at page 259
+
+// 7.18.2.1 Limits of exact-width integer types
+#define INT8_MIN ((int8_t) _I8_MIN)
+#define INT8_MAX _I8_MAX
+#define INT16_MIN ((int16_t) _I16_MIN)
+#define INT16_MAX _I16_MAX
+#define INT32_MIN ((int32_t) _I32_MIN)
+#define INT32_MAX _I32_MAX
+#define INT64_MIN ((int64_t) _I64_MIN)
+#define INT64_MAX _I64_MAX
+#define UINT8_MAX _UI8_MAX
+#define UINT16_MAX _UI16_MAX
+#define UINT32_MAX _UI32_MAX
+#define UINT64_MAX _UI64_MAX
+
+// 7.18.2.2 Limits of minimum-width integer types
+#define INT_LEAST8_MIN INT8_MIN
+#define INT_LEAST8_MAX INT8_MAX
+#define INT_LEAST16_MIN INT16_MIN
+#define INT_LEAST16_MAX INT16_MAX
+#define INT_LEAST32_MIN INT32_MIN
+#define INT_LEAST32_MAX INT32_MAX
+#define INT_LEAST64_MIN INT64_MIN
+#define INT_LEAST64_MAX INT64_MAX
+#define UINT_LEAST8_MAX UINT8_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+// 7.18.2.3 Limits of fastest minimum-width integer types
+#define INT_FAST8_MIN INT8_MIN
+#define INT_FAST8_MAX INT8_MAX
+#define INT_FAST16_MIN INT16_MIN
+#define INT_FAST16_MAX INT16_MAX
+#define INT_FAST32_MIN INT32_MIN
+#define INT_FAST32_MAX INT32_MAX
+#define INT_FAST64_MIN INT64_MIN
+#define INT_FAST64_MAX INT64_MAX
+#define UINT_FAST8_MAX UINT8_MAX
+#define UINT_FAST16_MAX UINT16_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+#define UINT_FAST64_MAX UINT64_MAX
+
+// 7.18.2.4 Limits of integer types capable of holding object pointers
+#ifdef _WIN64 // [
+#define INTPTR_MIN INT64_MIN
+#define INTPTR_MAX INT64_MAX
+#define UINTPTR_MAX UINT64_MAX
+#else // _WIN64 ][
+#define INTPTR_MIN INT32_MIN
+#define INTPTR_MAX INT32_MAX
+#define UINTPTR_MAX UINT32_MAX
+#endif // _WIN64 ]
+
+// 7.18.2.5 Limits of greatest-width integer types
+#define INTMAX_MIN INT64_MIN
+#define INTMAX_MAX INT64_MAX
+#define UINTMAX_MAX UINT64_MAX
+
+// 7.18.3 Limits of other integer types
+
+#ifdef _WIN64 // [
+#define PTRDIFF_MIN _I64_MIN
+#define PTRDIFF_MAX _I64_MAX
+#else // _WIN64 ][
+#define PTRDIFF_MIN _I32_MIN
+#define PTRDIFF_MAX _I32_MAX
+#endif // _WIN64 ]
+
+#define SIG_ATOMIC_MIN INT_MIN
+#define SIG_ATOMIC_MAX INT_MAX
+
+#ifndef SIZE_MAX // [
+#ifdef _WIN64    // [
+#define SIZE_MAX _UI64_MAX
+#else // _WIN64 ][
+#define SIZE_MAX _UI32_MAX
+#endif // _WIN64 ]
+#endif // SIZE_MAX ]
+
+// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
+#ifndef WCHAR_MIN // [
+#define WCHAR_MIN 0
+#endif            // WCHAR_MIN ]
+#ifndef WCHAR_MAX // [
+#define WCHAR_MAX _UI16_MAX
+#endif // WCHAR_MAX ]
+
+#define WINT_MIN 0
+#define WINT_MAX _UI16_MAX
+
+#endif // __STDC_LIMIT_MACROS ]
+
+
+// 7.18.4 Limits of other integer types
+
+#if !defined(__cplusplus) || \
+   defined(__STDC_CONSTANT_MACROS) // [   See footnote 224 at page 260
+
+// 7.18.4.1 Macros for minimum-width integer constants
+
+#define INT8_C(val) val##i8
+#define INT16_C(val) val##i16
+#define INT32_C(val) val##i32
+#define INT64_C(val) val##i64
+
+#define UINT8_C(val) val##ui8
+#define UINT16_C(val) val##ui16
+#define UINT32_C(val) val##ui32
+#define UINT64_C(val) val##ui64
+
+// 7.18.4.2 Macros for greatest-width integer constants
+// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>.
+// Check out Issue 9 for the details.
+#ifndef INTMAX_C //   [
+#define INTMAX_C INT64_C
+#endif            // INTMAX_C    ]
+#ifndef UINTMAX_C //  [
+#define UINTMAX_C UINT64_C
+#endif // UINTMAX_C   ]
+
+#endif // __STDC_CONSTANT_MACROS ]
+
+#endif // _MSC_VER >= 1600 ]
+
+#endif // _MSC_STDINT_H_ ]
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-stdint.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-stdint.h
new file mode 100644
index 0000000000000000000000000000000000000000..9a6118bd8590ca341a8a0addbd21d74e51e51a28
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-stdint.h
@@ -0,0 +1 @@
+#include <stdint.h>
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-string.c b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-string.c
new file mode 100644
index 0000000000000000000000000000000000000000..8e38909da49b35761467519a0fbabd7493c8308d
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-string.c
@@ -0,0 +1,818 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <limits.h>
+#include <stdarg.h>
+
+#include "bson-compat.h"
+#include "bson-string.h"
+#include "bson-memory.h"
+#include "bson-utf8.h"
+
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#else
+#include <string.h>
+#endif
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_string_new --
+ *
+ *       Create a new bson_string_t.
+ *
+ *       bson_string_t is a power-of-2 allocation growing string. Every
+ *       time data is appended the next power of two size is chosen for
+ *       the allocation. Pretty standard stuff.
+ *
+ *       It is UTF-8 aware through the use of bson_string_append_unichar().
+ *       The proper UTF-8 character sequence will be used.
+ *
+ * Parameters:
+ *       @str: a string to copy or NULL.
+ *
+ * Returns:
+ *       A newly allocated bson_string_t that should be freed with
+ *       bson_string_free().
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bson_string_t *
+bson_string_new (const char *str) /* IN */
+{
+   bson_string_t *ret;
+
+   ret = bson_malloc0 (sizeof *ret);
+   ret->len = str ? (int) strlen (str) : 0;
+   ret->alloc = ret->len + 1;
+
+   if (!bson_is_power_of_two (ret->alloc)) {
+      ret->alloc = (uint32_t) bson_next_power_of_two ((size_t) ret->alloc);
+   }
+
+   BSON_ASSERT (ret->alloc >= 1);
+
+   ret->str = bson_malloc (ret->alloc);
+
+   if (str) {
+      memcpy (ret->str, str, ret->len);
+   }
+   ret->str[ret->len] = '\0';
+
+   ret->str[ret->len] = '\0';
+
+   return ret;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_string_free --
+ *
+ *       Free the bson_string_t @string and related allocations.
+ *
+ *       If @free_segment is false, then the strings buffer will be
+ *       returned and is not freed. Otherwise, NULL is returned.
+ *
+ * Returns:
+ *       The string->str if free_segment is false.
+ *       Otherwise NULL.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+char *
+bson_string_free (bson_string_t *string, /* IN */
+                  bool free_segment)     /* IN */
+{
+   char *ret = NULL;
+
+   BSON_ASSERT (string);
+
+   if (!free_segment) {
+      ret = string->str;
+   } else {
+      bson_free (string->str);
+   }
+
+   bson_free (string);
+
+   return ret;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_string_append --
+ *
+ *       Append the UTF-8 string @str to @string.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_string_append (bson_string_t *string, /* IN */
+                    const char *str)       /* IN */
+{
+   uint32_t len;
+
+   BSON_ASSERT (string);
+   BSON_ASSERT (str);
+
+   len = (uint32_t) strlen (str);
+
+   if ((string->alloc - string->len - 1) < len) {
+      string->alloc += len;
+      if (!bson_is_power_of_two (string->alloc)) {
+         string->alloc =
+            (uint32_t) bson_next_power_of_two ((size_t) string->alloc);
+      }
+      string->str = bson_realloc (string->str, string->alloc);
+   }
+
+   memcpy (string->str + string->len, str, len);
+   string->len += len;
+   string->str[string->len] = '\0';
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_string_append_c --
+ *
+ *       Append the ASCII character @c to @string.
+ *
+ *       Do not use this if you are working with UTF-8 sequences,
+ *       use bson_string_append_unichar().
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_string_append_c (bson_string_t *string, /* IN */
+                      char c)                /* IN */
+{
+   char cc[2];
+
+   BSON_ASSERT (string);
+
+   if (BSON_UNLIKELY (string->alloc == (string->len + 1))) {
+      cc[0] = c;
+      cc[1] = '\0';
+      bson_string_append (string, cc);
+      return;
+   }
+
+   string->str[string->len++] = c;
+   string->str[string->len] = '\0';
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_string_append_unichar --
+ *
+ *       Append the bson_unichar_t @unichar to the string @string.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_string_append_unichar (bson_string_t *string,  /* IN */
+                            bson_unichar_t unichar) /* IN */
+{
+   uint32_t len;
+   char str[8];
+
+   BSON_ASSERT (string);
+   BSON_ASSERT (unichar);
+
+   bson_utf8_from_unichar (unichar, str, &len);
+
+   if (len <= 6) {
+      str[len] = '\0';
+      bson_string_append (string, str);
+   }
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_string_append_printf --
+ *
+ *       Format a string according to @format and append it to @string.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_string_append_printf (bson_string_t *string, const char *format, ...)
+{
+   va_list args;
+   char *ret;
+
+   BSON_ASSERT (string);
+   BSON_ASSERT (format);
+
+   va_start (args, format);
+   ret = bson_strdupv_printf (format, args);
+   va_end (args);
+   bson_string_append (string, ret);
+   bson_free (ret);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_string_truncate --
+ *
+ *       Truncate the string @string to @len bytes.
+ *
+ *       The underlying memory will be released via realloc() down to
+ *       the minimum required size specified by @len.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_string_truncate (bson_string_t *string, /* IN */
+                      uint32_t len)          /* IN */
+{
+   uint32_t alloc;
+
+   BSON_ASSERT (string);
+   BSON_ASSERT (len < INT_MAX);
+
+   alloc = len + 1;
+
+   if (alloc < 16) {
+      alloc = 16;
+   }
+
+   if (!bson_is_power_of_two (alloc)) {
+      alloc = (uint32_t) bson_next_power_of_two ((size_t) alloc);
+   }
+
+   string->str = bson_realloc (string->str, alloc);
+   string->alloc = alloc;
+   string->len = len;
+
+   string->str[string->len] = '\0';
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_strdup --
+ *
+ *       Portable strdup().
+ *
+ * Returns:
+ *       A newly allocated string that should be freed with bson_free().
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+char *
+bson_strdup (const char *str) /* IN */
+{
+   long len;
+   char *out;
+
+   if (!str) {
+      return NULL;
+   }
+
+   len = (long) strlen (str);
+   out = bson_malloc (len + 1);
+
+   if (!out) {
+      return NULL;
+   }
+
+   memcpy (out, str, len + 1);
+
+   return out;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_strdupv_printf --
+ *
+ *       Like bson_strdup_printf() but takes a va_list.
+ *
+ * Returns:
+ *       A newly allocated string that should be freed with bson_free().
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+char *
+bson_strdupv_printf (const char *format, /* IN */
+                     va_list args)       /* IN */
+{
+   va_list my_args;
+   char *buf;
+   int len = 32;
+   int n;
+
+   BSON_ASSERT (format);
+
+   buf = bson_malloc0 (len);
+
+   while (true) {
+      va_copy (my_args, args);
+      n = bson_vsnprintf (buf, len, format, my_args);
+      va_end (my_args);
+
+      if (n > -1 && n < len) {
+         return buf;
+      }
+
+      if (n > -1) {
+         len = n + 1;
+      } else {
+         len *= 2;
+      }
+
+      buf = bson_realloc (buf, len);
+   }
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_strdup_printf --
+ *
+ *       Convenience function that formats a string according to @format
+ *       and returns a copy of it.
+ *
+ * Returns:
+ *       A newly created string that should be freed with bson_free().
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+char *
+bson_strdup_printf (const char *format, /* IN */
+                    ...)                /* IN */
+{
+   va_list args;
+   char *ret;
+
+   BSON_ASSERT (format);
+
+   va_start (args, format);
+   ret = bson_strdupv_printf (format, args);
+   va_end (args);
+
+   return ret;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_strndup --
+ *
+ *       A portable strndup().
+ *
+ * Returns:
+ *       A newly allocated string that should be freed with bson_free().
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+char *
+bson_strndup (const char *str, /* IN */
+              size_t n_bytes)  /* IN */
+{
+   char *ret;
+
+   BSON_ASSERT (str);
+
+   ret = bson_malloc (n_bytes + 1);
+   bson_strncpy (ret, str, n_bytes + 1);
+
+   return ret;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_strfreev --
+ *
+ *       Frees each string in a NULL terminated array of strings.
+ *       This also frees the underlying array.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_strfreev (char **str) /* IN */
+{
+   int i;
+
+   if (str) {
+      for (i = 0; str[i]; i++)
+         bson_free (str[i]);
+      bson_free (str);
+   }
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_strnlen --
+ *
+ *       A portable strnlen().
+ *
+ * Returns:
+ *       The length of @s up to @maxlen.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+size_t
+bson_strnlen (const char *s, /* IN */
+              size_t maxlen) /* IN */
+{
+#ifdef BSON_HAVE_STRNLEN
+   return strnlen (s, maxlen);
+#else
+   size_t i;
+
+   for (i = 0; i < maxlen; i++) {
+      if (s[i] == '\0') {
+         return i;
+      }
+   }
+
+   return maxlen;
+#endif
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_strncpy --
+ *
+ *       A portable strncpy.
+ *
+ *       Copies @src into @dst, which must be @size bytes or larger.
+ *       The result is guaranteed to be \0 terminated.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_strncpy (char *dst,       /* IN */
+              const char *src, /* IN */
+              size_t size)     /* IN */
+{
+#ifdef _MSC_VER
+   strncpy_s (dst, size, src, _TRUNCATE);
+#else
+   strncpy (dst, src, size);
+   dst[size - 1] = '\0';
+#endif
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_vsnprintf --
+ *
+ *       A portable vsnprintf.
+ *
+ *       If more than @size bytes are required (exluding the null byte),
+ *       then @size bytes will be written to @string and the return value
+ *       is the number of bytes required.
+ *
+ *       This function will always return a NULL terminated string.
+ *
+ * Returns:
+ *       The number of bytes required for @format excluding the null byte.
+ *
+ * Side effects:
+ *       @str is initialized with the formatted string.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+int
+bson_vsnprintf (char *str,          /* IN */
+                size_t size,        /* IN */
+                const char *format, /* IN */
+                va_list ap)         /* IN */
+{
+#ifdef _MSC_VER
+   int r = -1;
+
+   BSON_ASSERT (str);
+
+   if (size != 0) {
+      r = _vsnprintf_s (str, size, _TRUNCATE, format, ap);
+   }
+
+   if (r == -1) {
+      r = _vscprintf (format, ap);
+   }
+
+   str[size - 1] = '\0';
+
+   return r;
+#else
+   int r;
+
+   r = vsnprintf (str, size, format, ap);
+   str[size - 1] = '\0';
+   return r;
+#endif
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_snprintf --
+ *
+ *       A portable snprintf.
+ *
+ *       If @format requires more than @size bytes, then @size bytes are
+ *       written and the result is the number of bytes required (excluding
+ *       the null byte).
+ *
+ *       This function will always return a NULL terminated string.
+ *
+ * Returns:
+ *       The number of bytes required for @format.
+ *
+ * Side effects:
+ *       @str is initialized.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+int
+bson_snprintf (char *str,          /* IN */
+               size_t size,        /* IN */
+               const char *format, /* IN */
+               ...)
+{
+   int r;
+   va_list ap;
+
+   BSON_ASSERT (str);
+
+   va_start (ap, format);
+   r = bson_vsnprintf (str, size, format, ap);
+   va_end (ap);
+
+   return r;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_ascii_strtoll --
+ *
+ *       A portable strtoll.
+ *
+ *       Convert a string to a 64-bit signed integer according to the given
+ *       @base, which must be 16, 10, or 8. Leading whitespace will be ignored.
+ *
+ *       If base is 0 is passed in, the base is inferred from the string's
+ *       leading characters. Base-16 numbers start with "0x" or "0X", base-8
+ *       numbers start with "0", base-10 numbers start with a digit from 1 to 9.
+ *
+ *       If @e is not NULL, it will be assigned the address of the first invalid
+ *       character of @s, or its null terminating byte if the entire string was
+ *       valid.
+ *
+ *       If an invalid value is encountered, errno will be set to EINVAL and
+ *       zero will be returned. If the number is out of range, errno is set to
+ *       ERANGE and LLONG_MAX or LLONG_MIN is returned.
+ *
+ * Returns:
+ *       The result of the conversion.
+ *
+ * Side effects:
+ *       errno will be set on error.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+int64_t
+bson_ascii_strtoll (const char *s, char **e, int base)
+{
+   char *tok = (char *) s;
+   char *digits_start;
+   char c;
+   int64_t number = 0;
+   int64_t sign = 1;
+   int64_t cutoff;
+   int64_t cutlim;
+
+   errno = 0;
+
+   if (!s) {
+      errno = EINVAL;
+      return 0;
+   }
+
+   c = *tok;
+
+   while (isspace (c)) {
+      c = *++tok;
+   }
+
+   if (c == '-') {
+      sign = -1;
+      c = *++tok;
+   } else if (c == '+') {
+      c = *++tok;
+   } else if (!isdigit (c)) {
+      errno = EINVAL;
+      return 0;
+   }
+
+   /* from here down, inspired by NetBSD's strtoll */
+   if ((base == 0 || base == 16) && c == '0' &&
+       (tok[1] == 'x' || tok[1] == 'X')) {
+      tok += 2;
+      c = *tok;
+      base = 16;
+   }
+
+   if (base == 0) {
+      base = c == '0' ? 8 : 10;
+   }
+
+   /* Cutoff is the greatest magnitude we'll be able to multiply by base without
+    * range error. If the current number is past cutoff and we see valid digit,
+    * fail. If the number is *equal* to cutoff, then the next digit must be less
+    * than cutlim, otherwise fail.
+    */
+   cutoff = sign == -1 ? INT64_MIN : INT64_MAX;
+   cutlim = (int) (cutoff % base);
+   cutoff /= base;
+   if (sign == -1) {
+      if (cutlim > 0) {
+         cutlim -= base;
+         cutoff += 1;
+      }
+      cutlim = -cutlim;
+   }
+
+   digits_start = tok;
+
+   while ((c = *tok)) {
+      if (isdigit (c)) {
+         c -= '0';
+      } else if (isalpha (c)) {
+         c -= isupper (c) ? 'A' - 10 : 'a' - 10;
+      } else {
+         /* end of number string */
+         break;
+      }
+
+      if (c >= base) {
+         break;
+      }
+
+      if (sign == -1) {
+         if (number < cutoff || (number == cutoff && c > cutlim)) {
+            number = INT64_MIN;
+            errno = ERANGE;
+            break;
+         } else {
+            number *= base;
+            number -= c;
+         }
+      } else {
+         if (number > cutoff || (number == cutoff && c > cutlim)) {
+            number = INT64_MAX;
+            errno = ERANGE;
+            break;
+         } else {
+            number *= base;
+            number += c;
+         }
+      }
+
+      tok++;
+   }
+
+   /* did we parse any digits at all? */
+   if (e != NULL && tok > digits_start) {
+      *e = tok;
+   }
+
+   return number;
+}
+
+
+int
+bson_strcasecmp (const char *s1, const char *s2)
+{
+#ifdef BSON_OS_WIN32
+   return _stricmp (s1, s2);
+#else
+   return strcasecmp (s1, s2);
+#endif
+}
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-string.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-string.h
new file mode 100644
index 0000000000000000000000000000000000000000..fdcc58cca266853fd6788bed14c3b274ab45d930
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-string.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef BSON_STRING_H
+#define BSON_STRING_H
+
+
+#if !defined(BSON_INSIDE) && !defined(BSON_COMPILATION)
+#error "Only <bson.h> can be included directly."
+#endif
+
+
+#include <stdarg.h>
+
+#include "bson-macros.h"
+#include "bson-types.h"
+
+
+BSON_BEGIN_DECLS
+
+
+typedef struct {
+   char *str;
+   uint32_t len;
+   uint32_t alloc;
+} bson_string_t;
+
+
+BSON_EXPORT (bson_string_t *)
+bson_string_new (const char *str);
+BSON_EXPORT (char *)
+bson_string_free (bson_string_t *string, bool free_segment);
+BSON_EXPORT (void)
+bson_string_append (bson_string_t *string, const char *str);
+BSON_EXPORT (void)
+bson_string_append_c (bson_string_t *string, char str);
+BSON_EXPORT (void)
+bson_string_append_unichar (bson_string_t *string, bson_unichar_t unichar);
+BSON_EXPORT (void)
+bson_string_append_printf (bson_string_t *string, const char *format, ...)
+   BSON_GNUC_PRINTF (2, 3);
+BSON_EXPORT (void)
+bson_string_truncate (bson_string_t *string, uint32_t len);
+BSON_EXPORT (char *)
+bson_strdup (const char *str);
+BSON_EXPORT (char *)
+bson_strdup_printf (const char *format, ...) BSON_GNUC_PRINTF (1, 2);
+BSON_EXPORT (char *)
+bson_strdupv_printf (const char *format, va_list args) BSON_GNUC_PRINTF (1, 0);
+BSON_EXPORT (char *)
+bson_strndup (const char *str, size_t n_bytes);
+BSON_EXPORT (void)
+bson_strncpy (char *dst, const char *src, size_t size);
+BSON_EXPORT (int)
+bson_vsnprintf (char *str, size_t size, const char *format, va_list ap)
+   BSON_GNUC_PRINTF (3, 0);
+BSON_EXPORT (int)
+bson_snprintf (char *str, size_t size, const char *format, ...)
+   BSON_GNUC_PRINTF (3, 4);
+BSON_EXPORT (void)
+bson_strfreev (char **strv);
+BSON_EXPORT (size_t)
+bson_strnlen (const char *s, size_t maxlen);
+BSON_EXPORT (int64_t)
+bson_ascii_strtoll (const char *str, char **endptr, int base);
+BSON_EXPORT (int)
+bson_strcasecmp (const char *s1, const char *s2);
+
+
+BSON_END_DECLS
+
+
+#endif /* BSON_STRING_H */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-thread-private.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-thread-private.h
new file mode 100644
index 0000000000000000000000000000000000000000..41d58d0a99fa254239a1b6a58110899a97e1810c
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-thread-private.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef BSON_THREAD_PRIVATE_H
+#define BSON_THREAD_PRIVATE_H
+
+
+#if !defined(BSON_INSIDE) && !defined(BSON_COMPILATION)
+#error "Only <bson.h> can be included directly."
+#endif
+
+
+#include "bson-compat.h"
+#include "bson-config.h"
+#include "bson-macros.h"
+
+
+BSON_BEGIN_DECLS
+
+
+#if defined(BSON_OS_UNIX)
+#include <pthread.h>
+#define bson_mutex_t pthread_mutex_t
+#define bson_mutex_init(_n) pthread_mutex_init ((_n), NULL)
+#define bson_mutex_lock pthread_mutex_lock
+#define bson_mutex_unlock pthread_mutex_unlock
+#define bson_mutex_destroy pthread_mutex_destroy
+#define bson_thread_t pthread_t
+#define bson_thread_create(_t, _f, _d) pthread_create ((_t), NULL, (_f), (_d))
+#define bson_thread_join(_n) pthread_join ((_n), NULL)
+#define bson_once_t pthread_once_t
+#define bson_once pthread_once
+#define BSON_ONCE_FUN(n) void n (void)
+#define BSON_ONCE_RETURN return
+#ifdef BSON_PTHREAD_ONCE_INIT_NEEDS_BRACES
+#define BSON_ONCE_INIT  \
+   {                    \
+      PTHREAD_ONCE_INIT \
+   }
+#else
+#define BSON_ONCE_INIT PTHREAD_ONCE_INIT
+#endif
+#else
+#define bson_mutex_t CRITICAL_SECTION
+#define bson_mutex_init InitializeCriticalSection
+#define bson_mutex_lock EnterCriticalSection
+#define bson_mutex_unlock LeaveCriticalSection
+#define bson_mutex_destroy DeleteCriticalSection
+#define bson_thread_t HANDLE
+#define bson_thread_create(_t, _f, _d) \
+   (!(*(_t) = CreateThread (NULL, 0, (void *) _f, _d, 0, NULL)))
+#define bson_thread_join(_n) WaitForSingleObject ((_n), INFINITE)
+#define bson_once_t INIT_ONCE
+#define BSON_ONCE_INIT INIT_ONCE_STATIC_INIT
+#define bson_once(o, c) InitOnceExecuteOnce (o, c, NULL, NULL)
+#define BSON_ONCE_FUN(n) \
+   BOOL CALLBACK n (PINIT_ONCE _ignored_a, PVOID _ignored_b, PVOID *_ignored_c)
+#define BSON_ONCE_RETURN return true
+#endif
+
+
+BSON_END_DECLS
+
+
+#endif /* BSON_THREAD_PRIVATE_H */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-timegm-private.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-timegm-private.h
new file mode 100644
index 0000000000000000000000000000000000000000..c39207f39cf96f1e4e27491bce922d7b1ee074b1
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-timegm-private.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2014 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef BSON_TIMEGM_PRIVATE_H
+#define BSON_TIMEGM_PRIVATE_H
+
+
+#include "bson-compat.h"
+#include "bson-macros.h"
+
+
+BSON_BEGIN_DECLS
+
+/* avoid system-dependent struct tm definitions */
+struct bson_tm {
+   int64_t tm_sec;    /* seconds after the minute [0-60] */
+   int64_t tm_min;    /* minutes after the hour [0-59] */
+   int64_t tm_hour;   /* hours since midnight [0-23] */
+   int64_t tm_mday;   /* day of the month [1-31] */
+   int64_t tm_mon;    /* months since January [0-11] */
+   int64_t tm_year;   /* years since 1900 */
+   int64_t tm_wday;   /* days since Sunday [0-6] */
+   int64_t tm_yday;   /* days since January 1 [0-365] */
+   int64_t tm_isdst;  /* Daylight Savings Time flag */
+   int64_t tm_gmtoff; /* offset from CUT in seconds */
+   char *tm_zone;     /* timezone abbreviation */
+};
+
+int64_t
+_bson_timegm (struct bson_tm *const tmp);
+
+BSON_END_DECLS
+
+
+#endif /* BSON_TIMEGM_PRIVATE_H */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-timegm.c b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-timegm.c
new file mode 100644
index 0000000000000000000000000000000000000000..0f7090073f22d042d113148552d4c6d595c9d2b5
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-timegm.c
@@ -0,0 +1,795 @@
+/*
+** The original version of this file is in the public domain, so clarified as of
+** 1996-06-05 by Arthur David Olson.
+*/
+
+/*
+** Leap second handling from Bradley White.
+** POSIX-style TZ environment variable handling from Guy Harris.
+** Updated to use int64_t's instead of system-dependent definitions of int64_t
+** and struct tm by A. Jesse Jiryu Davis for MongoDB, Inc.
+*/
+
+#include "bson-compat.h"
+#include "bson-macros.h"
+#include "bson-timegm-private.h"
+
+#include "errno.h"
+#include "string.h"
+#include <stdint.h> /* for INT64_MAX and INT64_MIN */
+
+/* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX. */
+#define is_digit(c) ((unsigned) (c) - '0' <= 9)
+
+#if 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
+#define ATTRIBUTE_CONST __attribute__ ((const))
+#define ATTRIBUTE_PURE __attribute__ ((__pure__))
+#define ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec))
+#else
+#define ATTRIBUTE_CONST        /* empty */
+#define ATTRIBUTE_PURE         /* empty */
+#define ATTRIBUTE_FORMAT(spec) /* empty */
+#endif
+
+#if !defined _Noreturn && \
+   (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112)
+#if 2 < __GNUC__ + (8 <= __GNUC_MINOR__)
+#define _Noreturn __attribute__((__noreturn__))
+#else
+#define _Noreturn
+#endif
+#endif
+
+#if (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901) && \
+   !defined restrict
+#define restrict /* empty */
+#endif
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunknown-pragmas"
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wshift-negative-value"
+#endif
+
+/* The minimum and maximum finite time values.  */
+static int64_t const time_t_min = INT64_MIN;
+static int64_t const time_t_max = INT64_MAX;
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#pragma clang diagnostic pop
+#endif
+
+#ifndef TZ_MAX_TIMES
+#define TZ_MAX_TIMES 2000
+#endif /* !defined TZ_MAX_TIMES */
+
+#ifndef TZ_MAX_TYPES
+/* This must be at least 17 for Europe/Samara and Europe/Vilnius.  */
+#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
+#endif                   /* !defined TZ_MAX_TYPES */
+
+#ifndef TZ_MAX_CHARS
+#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
+                        /* (limited by what unsigned chars can hold) */
+#endif                  /* !defined TZ_MAX_CHARS */
+
+#ifndef TZ_MAX_LEAPS
+#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
+#endif                  /* !defined TZ_MAX_LEAPS */
+
+#define SECSPERMIN 60
+#define MINSPERHOUR 60
+#define HOURSPERDAY 24
+#define DAYSPERWEEK 7
+#define DAYSPERNYEAR 365
+#define DAYSPERLYEAR 366
+#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
+#define SECSPERDAY ((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
+#define MONSPERYEAR 12
+
+#define TM_SUNDAY 0
+#define TM_MONDAY 1
+#define TM_TUESDAY 2
+#define TM_WEDNESDAY 3
+#define TM_THURSDAY 4
+#define TM_FRIDAY 5
+#define TM_SATURDAY 6
+
+#define TM_JANUARY 0
+#define TM_FEBRUARY 1
+#define TM_MARCH 2
+#define TM_APRIL 3
+#define TM_MAY 4
+#define TM_JUNE 5
+#define TM_JULY 6
+#define TM_AUGUST 7
+#define TM_SEPTEMBER 8
+#define TM_OCTOBER 9
+#define TM_NOVEMBER 10
+#define TM_DECEMBER 11
+
+#define TM_YEAR_BASE 1900
+
+#define EPOCH_YEAR 1970
+#define EPOCH_WDAY TM_THURSDAY
+
+#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
+
+/*
+** Since everything in isleap is modulo 400 (or a factor of 400), we know that
+**	isleap(y) == isleap(y % 400)
+** and so
+**	isleap(a + b) == isleap((a + b) % 400)
+** or
+**	isleap(a + b) == isleap(a % 400 + b % 400)
+** This is true even if % means modulo rather than Fortran remainder
+** (which is allowed by C89 but not C99).
+** We use this to avoid addition overflow problems.
+*/
+
+#define isleap_sum(a, b) isleap ((a) % 400 + (b) % 400)
+
+#ifndef TZ_ABBR_MAX_LEN
+#define TZ_ABBR_MAX_LEN 16
+#endif /* !defined TZ_ABBR_MAX_LEN */
+
+#ifndef TZ_ABBR_CHAR_SET
+#define TZ_ABBR_CHAR_SET \
+   "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
+#endif /* !defined TZ_ABBR_CHAR_SET */
+
+#ifndef TZ_ABBR_ERR_CHAR
+#define TZ_ABBR_ERR_CHAR '_'
+#endif /* !defined TZ_ABBR_ERR_CHAR */
+
+#ifndef WILDABBR
+/*
+** Someone might make incorrect use of a time zone abbreviation:
+**	1.	They might reference tzname[0] before calling tzset (explicitly
+**		or implicitly).
+**	2.	They might reference tzname[1] before calling tzset (explicitly
+**		or implicitly).
+**	3.	They might reference tzname[1] after setting to a time zone
+**		in which Daylight Saving Time is never observed.
+**	4.	They might reference tzname[0] after setting to a time zone
+**		in which Standard Time is never observed.
+**	5.	They might reference tm.TM_ZONE after calling offtime.
+** What's best to do in the above cases is open to debate;
+** for now, we just set things up so that in any of the five cases
+** WILDABBR is used. Another possibility: initialize tzname[0] to the
+** string "tzname[0] used before set", and similarly for the other cases.
+** And another: initialize tzname[0] to "ERA", with an explanation in the
+** manual page of what this "time zone abbreviation" means (doing this so
+** that tzname[0] has the "normal" length of three characters).
+*/
+#define WILDABBR "   "
+#endif /* !defined WILDABBR */
+
+#ifdef TM_ZONE
+static const char wildabbr[] = WILDABBR;
+static const char gmt[] = "GMT";
+#endif
+
+struct ttinfo {            /* time type information */
+   int_fast32_t tt_gmtoff; /* UT offset in seconds */
+   int tt_isdst;           /* used to set tm_isdst */
+   int tt_abbrind;         /* abbreviation list index */
+   int tt_ttisstd;         /* true if transition is std time */
+   int tt_ttisgmt;         /* true if transition is UT */
+};
+
+struct lsinfo {          /* leap second information */
+   int64_t ls_trans;      /* transition time */
+   int_fast64_t ls_corr; /* correction to apply */
+};
+
+#define BIGGEST(a, b) (((a) > (b)) ? (a) : (b))
+
+#ifdef TZNAME_MAX
+#define MY_TZNAME_MAX TZNAME_MAX
+#endif /* defined TZNAME_MAX */
+#ifndef TZNAME_MAX
+#define MY_TZNAME_MAX 255
+#endif /* !defined TZNAME_MAX */
+
+struct state {
+   int leapcnt;
+   int timecnt;
+   int typecnt;
+   int charcnt;
+   int goback;
+   int goahead;
+   int64_t ats[TZ_MAX_TIMES];
+   unsigned char types[TZ_MAX_TIMES];
+   struct ttinfo ttis[TZ_MAX_TYPES];
+   char chars[BIGGEST (TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))];
+   struct lsinfo lsis[TZ_MAX_LEAPS];
+   int defaulttype; /* for early times or if no transitions */
+};
+
+struct rule {
+   int r_type;          /* type of rule--see below */
+   int r_day;           /* day number of rule */
+   int r_week;          /* week number of rule */
+   int r_mon;           /* month number of rule */
+   int_fast32_t r_time; /* transition time of rule */
+};
+
+#define JULIAN_DAY 0            /* Jn - Julian day */
+#define DAY_OF_YEAR 1           /* n - day of year */
+#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
+
+/*
+** Prototypes for static functions.
+*/
+
+static void
+gmtload (struct state *sp);
+static struct bson_tm *
+gmtsub (const int64_t *timep, int_fast32_t offset, struct bson_tm *tmp);
+static int64_t
+increment_overflow (int64_t *number, int64_t delta);
+static int64_t
+leaps_thru_end_of (int64_t y) ATTRIBUTE_PURE;
+static int64_t
+increment_overflow32 (int_fast32_t *number, int64_t delta);
+static int64_t
+normalize_overflow32 (int_fast32_t *tensptr, int64_t *unitsptr, int64_t base);
+static int64_t
+normalize_overflow (int64_t *tensptr, int64_t *unitsptr, int64_t base);
+static int64_t
+time1 (struct bson_tm *tmp,
+       struct bson_tm *(*funcp) (const int64_t *, int_fast32_t, struct bson_tm *),
+       int_fast32_t offset);
+static int64_t
+time2 (struct bson_tm *tmp,
+       struct bson_tm *(*funcp) (const int64_t *, int_fast32_t, struct bson_tm *),
+       int_fast32_t offset,
+       int64_t *okayp);
+static int64_t
+time2sub (struct bson_tm *tmp,
+          struct bson_tm *(*funcp) (const int64_t *, int_fast32_t, struct bson_tm *),
+          int_fast32_t offset,
+          int64_t *okayp,
+          int64_t do_norm_secs);
+static struct bson_tm *
+timesub (const int64_t *timep,
+         int_fast32_t offset,
+         const struct state *sp,
+         struct bson_tm *tmp);
+static int64_t
+tmcomp (const struct bson_tm *atmp, const struct bson_tm *btmp);
+
+static struct state gmtmem;
+#define gmtptr (&gmtmem)
+
+static int gmt_is_set;
+
+static const int mon_lengths[2][MONSPERYEAR] = {
+   {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
+   {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
+
+static const int year_lengths[2] = {DAYSPERNYEAR, DAYSPERLYEAR};
+
+static void
+gmtload (struct state *const sp)
+{
+   memset (sp, 0, sizeof (struct state));
+   sp->typecnt = 1;
+   sp->charcnt = 4;
+   sp->chars[0] = 'G';
+   sp->chars[1] = 'M';
+   sp->chars[2] = 'T';
+}
+
+/*
+** gmtsub is to gmtime as localsub is to localtime.
+*/
+
+static struct bson_tm *
+gmtsub (const int64_t *const timep,
+        const int_fast32_t offset,
+        struct bson_tm *const tmp)
+{
+   register struct bson_tm *result;
+
+   if (!gmt_is_set) {
+      gmt_is_set = true;
+      gmtload (gmtptr);
+   }
+   result = timesub (timep, offset, gmtptr, tmp);
+#ifdef TM_ZONE
+   /*
+   ** Could get fancy here and deliver something such as
+   ** "UT+xxxx" or "UT-xxxx" if offset is non-zero,
+   ** but this is no time for a treasure hunt.
+   */
+   tmp->TM_ZONE = offset ? wildabbr : gmtptr ? gmtptr->chars : gmt;
+#endif /* defined TM_ZONE */
+   return result;
+}
+
+/*
+** Return the number of leap years through the end of the given year
+** where, to make the math easy, the answer for year zero is defined as zero.
+*/
+
+static int64_t
+leaps_thru_end_of (register const int64_t y)
+{
+   return (y >= 0) ? (y / 4 - y / 100 + y / 400)
+                   : -(leaps_thru_end_of (-(y + 1)) + 1);
+}
+
+static struct bson_tm *
+timesub (const int64_t *const timep,
+         const int_fast32_t offset,
+         register const struct state *const sp,
+         register struct bson_tm *const tmp)
+{
+   register const struct lsinfo *lp;
+   register int64_t tdays;
+   register int64_t idays; /* unsigned would be so 2003 */
+   register int_fast64_t rem;
+   int64_t y;
+   register const int *ip;
+   register int_fast64_t corr;
+   register int64_t hit;
+   register int64_t i;
+
+   corr = 0;
+   hit = 0;
+   i = (sp == NULL) ? 0 : sp->leapcnt;
+   while (--i >= 0) {
+      lp = &sp->lsis[i];
+      if (*timep >= lp->ls_trans) {
+         if (*timep == lp->ls_trans) {
+            hit = ((i == 0 && lp->ls_corr > 0) ||
+                   lp->ls_corr > sp->lsis[i - 1].ls_corr);
+            if (hit)
+               while (i > 0 &&
+                      sp->lsis[i].ls_trans == sp->lsis[i - 1].ls_trans + 1 &&
+                      sp->lsis[i].ls_corr == sp->lsis[i - 1].ls_corr + 1) {
+                  ++hit;
+                  --i;
+               }
+         }
+         corr = lp->ls_corr;
+         break;
+      }
+   }
+   y = EPOCH_YEAR;
+   tdays = *timep / SECSPERDAY;
+   rem = *timep - tdays * SECSPERDAY;
+   while (tdays < 0 || tdays >= year_lengths[isleap (y)]) {
+      int64_t newy;
+      register int64_t tdelta;
+      register int64_t idelta;
+      register int64_t leapdays;
+
+      tdelta = tdays / DAYSPERLYEAR;
+      idelta = tdelta;
+      if (idelta == 0)
+         idelta = (tdays < 0) ? -1 : 1;
+      newy = y;
+      if (increment_overflow (&newy, idelta))
+         return NULL;
+      leapdays = leaps_thru_end_of (newy - 1) - leaps_thru_end_of (y - 1);
+      tdays -= ((int64_t) newy - y) * DAYSPERNYEAR;
+      tdays -= leapdays;
+      y = newy;
+   }
+   {
+      register int_fast32_t seconds;
+
+      seconds = (int_fast32_t) (tdays * SECSPERDAY);
+      tdays = seconds / SECSPERDAY;
+      rem += seconds - tdays * SECSPERDAY;
+   }
+   /*
+   ** Given the range, we can now fearlessly cast...
+   */
+   idays = (int64_t) tdays;
+   rem += offset - corr;
+   while (rem < 0) {
+      rem += SECSPERDAY;
+      --idays;
+   }
+   while (rem >= SECSPERDAY) {
+      rem -= SECSPERDAY;
+      ++idays;
+   }
+   while (idays < 0) {
+      if (increment_overflow (&y, -1))
+         return NULL;
+      idays += year_lengths[isleap (y)];
+   }
+   while (idays >= year_lengths[isleap (y)]) {
+      idays -= year_lengths[isleap (y)];
+      if (increment_overflow (&y, 1))
+         return NULL;
+   }
+   tmp->tm_year = y;
+   if (increment_overflow (&tmp->tm_year, -TM_YEAR_BASE))
+      return NULL;
+   tmp->tm_yday = idays;
+   /*
+   ** The "extra" mods below avoid overflow problems.
+   */
+   tmp->tm_wday =
+      EPOCH_WDAY +
+      ((y - EPOCH_YEAR) % DAYSPERWEEK) * (DAYSPERNYEAR % DAYSPERWEEK) +
+      leaps_thru_end_of (y - 1) - leaps_thru_end_of (EPOCH_YEAR - 1) + idays;
+   tmp->tm_wday %= DAYSPERWEEK;
+   if (tmp->tm_wday < 0)
+      tmp->tm_wday += DAYSPERWEEK;
+   tmp->tm_hour = (int64_t) (rem / SECSPERHOUR);
+   rem %= SECSPERHOUR;
+   tmp->tm_min = (int64_t) (rem / SECSPERMIN);
+   /*
+   ** A positive leap second requires a special
+   ** representation. This uses "... ??:59:60" et seq.
+   */
+   tmp->tm_sec = (int64_t) (rem % SECSPERMIN) + hit;
+   ip = mon_lengths[isleap (y)];
+   for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
+      idays -= ip[tmp->tm_mon];
+   tmp->tm_mday = (int64_t) (idays + 1);
+   tmp->tm_isdst = 0;
+#ifdef TM_GMTOFF
+   tmp->TM_GMTOFF = offset;
+#endif /* defined TM_GMTOFF */
+   return tmp;
+}
+
+/*
+** Adapted from code provided by Robert Elz, who writes:
+**	The "best" way to do mktime I think is based on an idea of Bob
+**	Kridle's (so its said...) from a long time ago.
+**	It does a binary search of the int64_t space. Since int64_t's are
+**	just 32 bits, its a max of 32 iterations (even at 64 bits it
+**	would still be very reasonable).
+*/
+
+#ifndef WRONG
+#define WRONG (-1)
+#endif /* !defined WRONG */
+
+/*
+** Normalize logic courtesy Paul Eggert.
+*/
+
+static int64_t
+increment_overflow (int64_t *const ip, int64_t j)
+{
+   register int64_t const i = *ip;
+
+   /*
+   ** If i >= 0 there can only be overflow if i + j > INT_MAX
+   ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
+   ** If i < 0 there can only be overflow if i + j < INT_MIN
+   ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
+   */
+   if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
+      return true;
+   *ip += j;
+   return false;
+}
+
+static int64_t
+increment_overflow32 (int_fast32_t *const lp, int64_t const m)
+{
+   register int_fast32_t const l = *lp;
+
+   if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l))
+      return true;
+   *lp += m;
+   return false;
+}
+
+static int64_t
+normalize_overflow (int64_t *const tensptr, int64_t *const unitsptr, const int64_t base)
+{
+   register int64_t tensdelta;
+
+   tensdelta =
+      (*unitsptr >= 0) ? (*unitsptr / base) : (-1 - (-1 - *unitsptr) / base);
+   *unitsptr -= tensdelta * base;
+   return increment_overflow (tensptr, tensdelta);
+}
+
+static int64_t
+normalize_overflow32 (int_fast32_t *const tensptr,
+                      int64_t *const unitsptr,
+                      const int64_t base)
+{
+   register int64_t tensdelta;
+
+   tensdelta =
+      (*unitsptr >= 0) ? (*unitsptr / base) : (-1 - (-1 - *unitsptr) / base);
+   *unitsptr -= tensdelta * base;
+   return increment_overflow32 (tensptr, tensdelta);
+}
+
+static int64_t
+tmcomp (register const struct bson_tm *const atmp,
+        register const struct bson_tm *const btmp)
+{
+   register int64_t result;
+
+   if (atmp->tm_year != btmp->tm_year)
+      return atmp->tm_year < btmp->tm_year ? -1 : 1;
+   if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
+       (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
+       (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
+       (result = (atmp->tm_min - btmp->tm_min)) == 0)
+      result = atmp->tm_sec - btmp->tm_sec;
+   return result;
+}
+
+static int64_t
+time2sub (struct bson_tm *const tmp,
+          struct bson_tm *(*const funcp) (const int64_t *, int_fast32_t, struct bson_tm *),
+          const int_fast32_t offset,
+          int64_t *const okayp,
+          const int64_t do_norm_secs)
+{
+   register const struct state *sp;
+   register int64_t dir;
+   register int64_t i, j;
+   register int64_t saved_seconds;
+   register int_fast32_t li;
+   register int64_t lo;
+   register int64_t hi;
+   int_fast32_t y;
+   int64_t newt;
+   int64_t t;
+   struct bson_tm yourtm, mytm;
+
+   *okayp = false;
+   yourtm = *tmp;
+   if (do_norm_secs) {
+      if (normalize_overflow (&yourtm.tm_min, &yourtm.tm_sec, SECSPERMIN))
+         return WRONG;
+   }
+   if (normalize_overflow (&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))
+      return WRONG;
+   if (normalize_overflow (&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
+      return WRONG;
+   y = (int_fast32_t) yourtm.tm_year;
+   if (normalize_overflow32 (&y, &yourtm.tm_mon, MONSPERYEAR))
+      return WRONG;
+   /*
+   ** Turn y into an actual year number for now.
+   ** It is converted back to an offset from TM_YEAR_BASE later.
+   */
+   if (increment_overflow32 (&y, TM_YEAR_BASE))
+      return WRONG;
+   while (yourtm.tm_mday <= 0) {
+      if (increment_overflow32 (&y, -1))
+         return WRONG;
+      li = y + (1 < yourtm.tm_mon);
+      yourtm.tm_mday += year_lengths[isleap (li)];
+   }
+   while (yourtm.tm_mday > DAYSPERLYEAR) {
+      li = y + (1 < yourtm.tm_mon);
+      yourtm.tm_mday -= year_lengths[isleap (li)];
+      if (increment_overflow32 (&y, 1))
+         return WRONG;
+   }
+   for (;;) {
+      i = mon_lengths[isleap (y)][yourtm.tm_mon];
+      if (yourtm.tm_mday <= i)
+         break;
+      yourtm.tm_mday -= i;
+      if (++yourtm.tm_mon >= MONSPERYEAR) {
+         yourtm.tm_mon = 0;
+         if (increment_overflow32 (&y, 1))
+            return WRONG;
+      }
+   }
+   if (increment_overflow32 (&y, -TM_YEAR_BASE))
+      return WRONG;
+   yourtm.tm_year = y;
+   if (yourtm.tm_year != y)
+      return WRONG;
+   if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
+      saved_seconds = 0;
+   else if (y + TM_YEAR_BASE < EPOCH_YEAR) {
+      /*
+      ** We can't set tm_sec to 0, because that might push the
+      ** time below the minimum representable time.
+      ** Set tm_sec to 59 instead.
+      ** This assumes that the minimum representable time is
+      ** not in the same minute that a leap second was deleted from,
+      ** which is a safer assumption than using 58 would be.
+      */
+      if (increment_overflow (&yourtm.tm_sec, 1 - SECSPERMIN))
+         return WRONG;
+      saved_seconds = yourtm.tm_sec;
+      yourtm.tm_sec = SECSPERMIN - 1;
+   } else {
+      saved_seconds = yourtm.tm_sec;
+      yourtm.tm_sec = 0;
+   }
+   /*
+   ** Do a binary search.
+   */
+   lo = INT64_MIN;
+   hi = INT64_MAX;
+
+   for (;;) {
+      t = lo / 2 + hi / 2;
+      if (t < lo)
+         t = lo;
+      else if (t > hi)
+         t = hi;
+      if ((*funcp) (&t, offset, &mytm) == NULL) {
+         /*
+         ** Assume that t is too extreme to be represented in
+         ** a struct bson_tm; arrange things so that it is less
+         ** extreme on the next pass.
+         */
+         dir = (t > 0) ? 1 : -1;
+      } else
+         dir = tmcomp (&mytm, &yourtm);
+      if (dir != 0) {
+         if (t == lo) {
+            if (t == time_t_max)
+               return WRONG;
+            ++t;
+            ++lo;
+         } else if (t == hi) {
+            if (t == time_t_min)
+               return WRONG;
+            --t;
+            --hi;
+         }
+         if (lo > hi)
+            return WRONG;
+         if (dir > 0)
+            hi = t;
+         else
+            lo = t;
+         continue;
+      }
+      if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
+         break;
+      /*
+      ** Right time, wrong type.
+      ** Hunt for right time, right type.
+      ** It's okay to guess wrong since the guess
+      ** gets checked.
+      */
+      sp = (const struct state *) gmtptr;
+      if (sp == NULL)
+         return WRONG;
+      for (i = sp->typecnt - 1; i >= 0; --i) {
+         if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
+            continue;
+         for (j = sp->typecnt - 1; j >= 0; --j) {
+            if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
+               continue;
+            newt = t + sp->ttis[j].tt_gmtoff - sp->ttis[i].tt_gmtoff;
+            if ((*funcp) (&newt, offset, &mytm) == NULL)
+               continue;
+            if (tmcomp (&mytm, &yourtm) != 0)
+               continue;
+            if (mytm.tm_isdst != yourtm.tm_isdst)
+               continue;
+            /*
+            ** We have a match.
+            */
+            t = newt;
+            goto label;
+         }
+      }
+      return WRONG;
+   }
+label:
+   newt = t + saved_seconds;
+   if ((newt < t) != (saved_seconds < 0))
+      return WRONG;
+   t = newt;
+   if ((*funcp) (&t, offset, tmp))
+      *okayp = true;
+   return t;
+}
+
+static int64_t
+time2 (struct bson_tm *const tmp,
+       struct bson_tm *(*const funcp) (const int64_t *, int_fast32_t, struct bson_tm *),
+       const int_fast32_t offset,
+       int64_t *const okayp)
+{
+   int64_t t;
+
+   /*
+   ** First try without normalization of seconds
+   ** (in case tm_sec contains a value associated with a leap second).
+   ** If that fails, try with normalization of seconds.
+   */
+   t = time2sub (tmp, funcp, offset, okayp, false);
+   return *okayp ? t : time2sub (tmp, funcp, offset, okayp, true);
+}
+
+static int64_t
+time1 (struct bson_tm *const tmp,
+       struct bson_tm *(*const funcp) (const int64_t *, int_fast32_t, struct bson_tm *),
+       const int_fast32_t offset)
+{
+   register int64_t t;
+   register const struct state *sp;
+   register int64_t samei, otheri;
+   register int64_t sameind, otherind;
+   register int64_t i;
+   register int64_t nseen;
+   int64_t seen[TZ_MAX_TYPES];
+   int64_t types[TZ_MAX_TYPES];
+   int64_t okay;
+
+   if (tmp == NULL) {
+      errno = EINVAL;
+      return WRONG;
+   }
+   if (tmp->tm_isdst > 1)
+      tmp->tm_isdst = 1;
+   t = time2 (tmp, funcp, offset, &okay);
+   if (okay)
+      return t;
+   if (tmp->tm_isdst < 0)
+#ifdef PCTS
+      /*
+      ** POSIX Conformance Test Suite code courtesy Grant Sullivan.
+      */
+      tmp->tm_isdst = 0; /* reset to std and try again */
+#else
+      return t;
+#endif /* !defined PCTS */
+   /*
+   ** We're supposed to assume that somebody took a time of one type
+   ** and did some math on it that yielded a "struct tm" that's bad.
+   ** We try to divine the type they started from and adjust to the
+   ** type they need.
+   */
+   sp = (const struct state *) gmtptr;
+   if (sp == NULL)
+      return WRONG;
+   for (i = 0; i < sp->typecnt; ++i)
+      seen[i] = false;
+   nseen = 0;
+   for (i = sp->timecnt - 1; i >= 0; --i)
+      if (!seen[sp->types[i]]) {
+         seen[sp->types[i]] = true;
+         types[nseen++] = sp->types[i];
+      }
+   for (sameind = 0; sameind < nseen; ++sameind) {
+      samei = types[sameind];
+      if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
+         continue;
+      for (otherind = 0; otherind < nseen; ++otherind) {
+         otheri = types[otherind];
+         if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
+            continue;
+         tmp->tm_sec += sp->ttis[otheri].tt_gmtoff - sp->ttis[samei].tt_gmtoff;
+         tmp->tm_isdst = !tmp->tm_isdst;
+         t = time2 (tmp, funcp, offset, &okay);
+         if (okay)
+            return t;
+         tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff - sp->ttis[samei].tt_gmtoff;
+         tmp->tm_isdst = !tmp->tm_isdst;
+      }
+   }
+   return WRONG;
+}
+
+int64_t
+_bson_timegm (struct bson_tm *const tmp)
+{
+   if (tmp != NULL)
+      tmp->tm_isdst = 0;
+   return time1 (tmp, gmtsub, 0L);
+}
+
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-types.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-types.h
new file mode 100644
index 0000000000000000000000000000000000000000..667054484f4d9cbcb7278701ad2e7964e142f4f6
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-types.h
@@ -0,0 +1,540 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef BSON_TYPES_H
+#define BSON_TYPES_H
+
+#include <stdlib.h>
+#include <sys/types.h>
+
+#include "bson-macros.h"
+#include "bson-config.h"
+#include "bson-compat.h"
+#include "bson-endian.h"
+
+BSON_BEGIN_DECLS
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_unichar_t --
+ *
+ *       bson_unichar_t provides an unsigned 32-bit type for containing
+ *       unicode characters. When iterating UTF-8 sequences, this should
+ *       be used to avoid losing the high-bits of non-ascii characters.
+ *
+ * See also:
+ *       bson_string_append_unichar()
+ *
+ *--------------------------------------------------------------------------
+ */
+
+typedef uint32_t bson_unichar_t;
+
+
+/**
+ * bson_context_flags_t:
+ *
+ * This enumeration is used to configure a bson_context_t.
+ *
+ * %BSON_CONTEXT_NONE: Use default options.
+ * %BSON_CONTEXT_THREAD_SAFE: Context will be called from multiple threads.
+ * %BSON_CONTEXT_DISABLE_PID_CACHE: Call getpid() instead of caching the
+ *   result of getpid() when initializing the context.
+ * %BSON_CONTEXT_DISABLE_HOST_CACHE: Call gethostname() instead of caching the
+ *   result of gethostname() when initializing the context.
+ */
+typedef enum {
+   BSON_CONTEXT_NONE = 0,
+   BSON_CONTEXT_THREAD_SAFE = (1 << 0),
+   BSON_CONTEXT_DISABLE_HOST_CACHE = (1 << 1),
+   BSON_CONTEXT_DISABLE_PID_CACHE = (1 << 2),
+#ifdef BSON_HAVE_SYSCALL_TID
+   BSON_CONTEXT_USE_TASK_ID = (1 << 3),
+#endif
+} bson_context_flags_t;
+
+
+/**
+ * bson_context_t:
+ *
+ * This structure manages context for the bson library. It handles
+ * configuration for thread-safety and other performance related requirements.
+ * Consumers will create a context and may use multiple under a variety of
+ * situations.
+ *
+ * If your program calls fork(), you should initialize a new bson_context_t
+ * using bson_context_init().
+ *
+ * If you are using threading, it is suggested that you use a bson_context_t
+ * per thread for best performance. Alternatively, you can initialize the
+ * bson_context_t with BSON_CONTEXT_THREAD_SAFE, although a performance penalty
+ * will be incurred.
+ *
+ * Many functions will require that you provide a bson_context_t such as OID
+ * generation.
+ *
+ * This structure is oqaque in that you cannot see the contents of the
+ * structure. However, it is stack allocatable in that enough padding is
+ * provided in _bson_context_t to hold the structure.
+ */
+typedef struct _bson_context_t bson_context_t;
+
+
+/**
+ * bson_t:
+ *
+ * This structure manages a buffer whose contents are a properly formatted
+ * BSON document. You may perform various transforms on the BSON documents.
+ * Additionally, it can be iterated over using bson_iter_t.
+ *
+ * See bson_iter_init() for iterating the contents of a bson_t.
+ *
+ * When building a bson_t structure using the various append functions,
+ * memory allocations may occur. That is performed using power of two
+ * allocations and realloc().
+ *
+ * See http://bsonspec.org for the BSON document spec.
+ *
+ * This structure is meant to fit in two sequential 64-byte cachelines.
+ */
+BSON_ALIGNED_BEGIN (128)
+typedef struct _bson_t {
+   uint32_t flags;       /* Internal flags for the bson_t. */
+   uint32_t len;         /* Length of BSON data. */
+   uint8_t padding[120]; /* Padding for stack allocation. */
+} bson_t BSON_ALIGNED_END (128);
+
+
+/**
+ * BSON_INITIALIZER:
+ *
+ * This macro can be used to initialize a #bson_t structure on the stack
+ * without calling bson_init().
+ *
+ * |[
+ * bson_t b = BSON_INITIALIZER;
+ * ]|
+ */
+#define BSON_INITIALIZER \
+   {                     \
+      3, 5,              \
+      {                  \
+         5               \
+      }                  \
+   }
+
+
+BSON_STATIC_ASSERT (sizeof (bson_t) == 128);
+
+
+/**
+ * bson_oid_t:
+ *
+ * This structure contains the binary form of a BSON Object Id as specified
+ * on http://bsonspec.org. If you would like the bson_oid_t in string form
+ * see bson_oid_to_string() or bson_oid_to_string_r().
+ */
+typedef struct {
+   uint8_t bytes[12];
+} bson_oid_t;
+
+BSON_STATIC_ASSERT (sizeof (bson_oid_t) == 12);
+
+/**
+ * bson_decimal128_t:
+ *
+ * @high The high-order bytes of the decimal128.  This field contains sign,
+ *       combination bits, exponent, and part of the coefficient continuation.
+ * @low  The low-order bytes of the decimal128.  This field contains the second
+ *       part of the coefficient continuation.
+ *
+ * This structure is a boxed type containing the value for the BSON decimal128
+ * type.  The structure stores the 128 bits such that they correspond to the
+ * native format for the IEEE decimal128 type, if it is implemented.
+ **/
+typedef struct {
+#if BSON_BYTE_ORDER == BSON_LITTLE_ENDIAN
+   uint64_t low;
+   uint64_t high;
+#elif BSON_BYTE_ORDER == BSON_BIG_ENDIAN
+   uint64_t high;
+   uint64_t low;
+#endif
+} bson_decimal128_t;
+
+
+/**
+ * bson_validate_flags_t:
+ *
+ * This enumeration is used for validation of BSON documents. It allows
+ * selective control on what you wish to validate.
+ *
+ * %BSON_VALIDATE_NONE: No additional validation occurs.
+ * %BSON_VALIDATE_UTF8: Check that strings are valid UTF-8.
+ * %BSON_VALIDATE_DOLLAR_KEYS: Check that keys do not start with $.
+ * %BSON_VALIDATE_DOT_KEYS: Check that keys do not contain a period.
+ * %BSON_VALIDATE_UTF8_ALLOW_NULL: Allow NUL bytes in UTF-8 text.
+ * %BSON_VALIDATE_EMPTY_KEYS: Prohibit zero-length field names
+ */
+typedef enum {
+   BSON_VALIDATE_NONE = 0,
+   BSON_VALIDATE_UTF8 = (1 << 0),
+   BSON_VALIDATE_DOLLAR_KEYS = (1 << 1),
+   BSON_VALIDATE_DOT_KEYS = (1 << 2),
+   BSON_VALIDATE_UTF8_ALLOW_NULL = (1 << 3),
+   BSON_VALIDATE_EMPTY_KEYS = (1 << 4),
+} bson_validate_flags_t;
+
+
+/**
+ * bson_type_t:
+ *
+ * This enumeration contains all of the possible types within a BSON document.
+ * Use bson_iter_type() to fetch the type of a field while iterating over it.
+ */
+typedef enum {
+   BSON_TYPE_EOD = 0x00,
+   BSON_TYPE_DOUBLE = 0x01,
+   BSON_TYPE_UTF8 = 0x02,
+   BSON_TYPE_DOCUMENT = 0x03,
+   BSON_TYPE_ARRAY = 0x04,
+   BSON_TYPE_BINARY = 0x05,
+   BSON_TYPE_UNDEFINED = 0x06,
+   BSON_TYPE_OID = 0x07,
+   BSON_TYPE_BOOL = 0x08,
+   BSON_TYPE_DATE_TIME = 0x09,
+   BSON_TYPE_NULL = 0x0A,
+   BSON_TYPE_REGEX = 0x0B,
+   BSON_TYPE_DBPOINTER = 0x0C,
+   BSON_TYPE_CODE = 0x0D,
+   BSON_TYPE_SYMBOL = 0x0E,
+   BSON_TYPE_CODEWSCOPE = 0x0F,
+   BSON_TYPE_INT32 = 0x10,
+   BSON_TYPE_TIMESTAMP = 0x11,
+   BSON_TYPE_INT64 = 0x12,
+   BSON_TYPE_DECIMAL128 = 0x13,
+   BSON_TYPE_MAXKEY = 0x7F,
+   BSON_TYPE_MINKEY = 0xFF,
+} bson_type_t;
+
+
+/**
+ * bson_subtype_t:
+ *
+ * This enumeration contains the various subtypes that may be used in a binary
+ * field. See http://bsonspec.org for more information.
+ */
+typedef enum {
+   BSON_SUBTYPE_BINARY = 0x00,
+   BSON_SUBTYPE_FUNCTION = 0x01,
+   BSON_SUBTYPE_BINARY_DEPRECATED = 0x02,
+   BSON_SUBTYPE_UUID_DEPRECATED = 0x03,
+   BSON_SUBTYPE_UUID = 0x04,
+   BSON_SUBTYPE_MD5 = 0x05,
+   BSON_SUBTYPE_USER = 0x80,
+} bson_subtype_t;
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_value_t --
+ *
+ *       A boxed type to contain various bson_type_t types.
+ *
+ * See also:
+ *       bson_value_copy()
+ *       bson_value_destroy()
+ *
+ *--------------------------------------------------------------------------
+ */
+
+BSON_ALIGNED_BEGIN (8)
+typedef struct _bson_value_t {
+   bson_type_t value_type;
+   int32_t padding;
+   union {
+      bson_oid_t v_oid;
+      int64_t v_int64;
+      int32_t v_int32;
+      int8_t v_int8;
+      double v_double;
+      bool v_bool;
+      int64_t v_datetime;
+      struct {
+         uint32_t timestamp;
+         uint32_t increment;
+      } v_timestamp;
+      struct {
+         char *str;
+         uint32_t len;
+      } v_utf8;
+      struct {
+         uint8_t *data;
+         uint32_t data_len;
+      } v_doc;
+      struct {
+         uint8_t *data;
+         uint32_t data_len;
+         bson_subtype_t subtype;
+      } v_binary;
+      struct {
+         char *regex;
+         char *options;
+      } v_regex;
+      struct {
+         char *collection;
+         uint32_t collection_len;
+         bson_oid_t oid;
+      } v_dbpointer;
+      struct {
+         char *code;
+         uint32_t code_len;
+      } v_code;
+      struct {
+         char *code;
+         uint8_t *scope_data;
+         uint32_t code_len;
+         uint32_t scope_len;
+      } v_codewscope;
+      struct {
+         char *symbol;
+         uint32_t len;
+      } v_symbol;
+      bson_decimal128_t v_decimal128;
+   } value;
+} bson_value_t BSON_ALIGNED_END (8);
+
+
+/**
+ * bson_iter_t:
+ *
+ * This structure manages iteration over a bson_t structure. It keeps track
+ * of the location of the current key and value within the buffer. Using the
+ * various functions to get the value of the iter will read from these
+ * locations.
+ *
+ * This structure is safe to discard on the stack. No cleanup is necessary
+ * after using it.
+ */
+BSON_ALIGNED_BEGIN (128)
+typedef struct {
+   const uint8_t *raw; /* The raw buffer being iterated. */
+   uint32_t len;       /* The length of raw. */
+   uint32_t off;       /* The offset within the buffer. */
+   uint32_t type;      /* The offset of the type byte. */
+   uint32_t key;       /* The offset of the key byte. */
+   uint32_t d1;        /* The offset of the first data byte. */
+   uint32_t d2;        /* The offset of the second data byte. */
+   uint32_t d3;        /* The offset of the third data byte. */
+   uint32_t d4;        /* The offset of the fourth data byte. */
+   uint32_t next_off;  /* The offset of the next field. */
+   uint32_t err_off;   /* The offset of the error. */
+   bson_value_t value; /* Internal value for various state. */
+} bson_iter_t BSON_ALIGNED_END (128);
+
+
+/**
+ * bson_reader_t:
+ *
+ * This structure is used to iterate over a sequence of BSON documents. It
+ * allows for them to be iterated with the possibility of no additional
+ * memory allocations under certain circumstances such as reading from an
+ * incoming mongo packet.
+ */
+
+BSON_ALIGNED_BEGIN (BSON_ALIGN_OF_PTR)
+typedef struct {
+   uint32_t type;
+   /*< private >*/
+} bson_reader_t BSON_ALIGNED_END (BSON_ALIGN_OF_PTR);
+
+
+/**
+ * bson_visitor_t:
+ *
+ * This structure contains a series of pointers that can be executed for
+ * each field of a BSON document based on the field type.
+ *
+ * For example, if an int32 field is found, visit_int32 will be called.
+ *
+ * When visiting each field using bson_iter_visit_all(), you may provide a
+ * data pointer that will be provided with each callback. This might be useful
+ * if you are marshaling to another language.
+ *
+ * You may pre-maturely stop the visitation of fields by returning true in your
+ * visitor. Returning false will continue visitation to further fields.
+ */
+BSON_ALIGNED_BEGIN (8)
+typedef struct {
+   /* run before / after descending into a document */
+   bool (*visit_before) (const bson_iter_t *iter, const char *key, void *data);
+   bool (*visit_after) (const bson_iter_t *iter, const char *key, void *data);
+   /* corrupt BSON, or unsupported type and visit_unsupported_type not set */
+   void (*visit_corrupt) (const bson_iter_t *iter, void *data);
+   /* normal bson field callbacks */
+   bool (*visit_double) (const bson_iter_t *iter,
+                         const char *key,
+                         double v_double,
+                         void *data);
+   bool (*visit_utf8) (const bson_iter_t *iter,
+                       const char *key,
+                       size_t v_utf8_len,
+                       const char *v_utf8,
+                       void *data);
+   bool (*visit_document) (const bson_iter_t *iter,
+                           const char *key,
+                           const bson_t *v_document,
+                           void *data);
+   bool (*visit_array) (const bson_iter_t *iter,
+                        const char *key,
+                        const bson_t *v_array,
+                        void *data);
+   bool (*visit_binary) (const bson_iter_t *iter,
+                         const char *key,
+                         bson_subtype_t v_subtype,
+                         size_t v_binary_len,
+                         const uint8_t *v_binary,
+                         void *data);
+   /* normal field with deprecated "Undefined" BSON type */
+   bool (*visit_undefined) (const bson_iter_t *iter,
+                            const char *key,
+                            void *data);
+   bool (*visit_oid) (const bson_iter_t *iter,
+                      const char *key,
+                      const bson_oid_t *v_oid,
+                      void *data);
+   bool (*visit_bool) (const bson_iter_t *iter,
+                       const char *key,
+                       bool v_bool,
+                       void *data);
+   bool (*visit_date_time) (const bson_iter_t *iter,
+                            const char *key,
+                            int64_t msec_since_epoch,
+                            void *data);
+   bool (*visit_null) (const bson_iter_t *iter, const char *key, void *data);
+   bool (*visit_regex) (const bson_iter_t *iter,
+                        const char *key,
+                        const char *v_regex,
+                        const char *v_options,
+                        void *data);
+   bool (*visit_dbpointer) (const bson_iter_t *iter,
+                            const char *key,
+                            size_t v_collection_len,
+                            const char *v_collection,
+                            const bson_oid_t *v_oid,
+                            void *data);
+   bool (*visit_code) (const bson_iter_t *iter,
+                       const char *key,
+                       size_t v_code_len,
+                       const char *v_code,
+                       void *data);
+   bool (*visit_symbol) (const bson_iter_t *iter,
+                         const char *key,
+                         size_t v_symbol_len,
+                         const char *v_symbol,
+                         void *data);
+   bool (*visit_codewscope) (const bson_iter_t *iter,
+                             const char *key,
+                             size_t v_code_len,
+                             const char *v_code,
+                             const bson_t *v_scope,
+                             void *data);
+   bool (*visit_int32) (const bson_iter_t *iter,
+                        const char *key,
+                        int32_t v_int32,
+                        void *data);
+   bool (*visit_timestamp) (const bson_iter_t *iter,
+                            const char *key,
+                            uint32_t v_timestamp,
+                            uint32_t v_increment,
+                            void *data);
+   bool (*visit_int64) (const bson_iter_t *iter,
+                        const char *key,
+                        int64_t v_int64,
+                        void *data);
+   bool (*visit_maxkey) (const bson_iter_t *iter, const char *key, void *data);
+   bool (*visit_minkey) (const bson_iter_t *iter, const char *key, void *data);
+   /* if set, called instead of visit_corrupt when an apparently valid BSON
+    * includes an unrecognized field type (reading future version of BSON) */
+   void (*visit_unsupported_type) (const bson_iter_t *iter,
+                                   const char *key,
+                                   uint32_t type_code,
+                                   void *data);
+   bool (*visit_decimal128) (const bson_iter_t *iter,
+                             const char *key,
+                             const bson_decimal128_t *v_decimal128,
+                             void *data);
+
+   void *padding[7];
+} bson_visitor_t BSON_ALIGNED_END (8);
+
+#define BSON_ERROR_BUFFER_SIZE 504
+
+BSON_ALIGNED_BEGIN (8)
+typedef struct _bson_error_t {
+   uint32_t domain;
+   uint32_t code;
+   char message[BSON_ERROR_BUFFER_SIZE];
+} bson_error_t BSON_ALIGNED_END (8);
+
+
+BSON_STATIC_ASSERT (sizeof (bson_error_t) == 512);
+
+
+/**
+ * bson_next_power_of_two:
+ * @v: A 32-bit unsigned integer of required bytes.
+ *
+ * Determines the next larger power of two for the value of @v
+ * in a constant number of operations.
+ *
+ * It is up to the caller to guarantee this will not overflow.
+ *
+ * Returns: The next power of 2 from @v.
+ */
+static BSON_INLINE size_t
+bson_next_power_of_two (size_t v)
+{
+   v--;
+   v |= v >> 1;
+   v |= v >> 2;
+   v |= v >> 4;
+   v |= v >> 8;
+   v |= v >> 16;
+#if BSON_WORD_SIZE == 64
+   v |= v >> 32;
+#endif
+   v++;
+
+   return v;
+}
+
+
+static BSON_INLINE bool
+bson_is_power_of_two (uint32_t v)
+{
+   return ((v != 0) && ((v & (v - 1)) == 0));
+}
+
+
+BSON_END_DECLS
+
+
+#endif /* BSON_TYPES_H */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-utf8.c b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-utf8.c
new file mode 100644
index 0000000000000000000000000000000000000000..d0ce792848d055422851c84d531d2ec9ea022137
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-utf8.c
@@ -0,0 +1,476 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <string.h>
+
+#include "bson-memory.h"
+#include "bson-string.h"
+#include "bson-utf8.h"
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_utf8_get_sequence --
+ *
+ *       Determine the sequence length of the first UTF-8 character in
+ *       @utf8. The sequence length is stored in @seq_length and the mask
+ *       for the first character is stored in @first_mask.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       @seq_length is set.
+ *       @first_mask is set.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static BSON_INLINE void
+_bson_utf8_get_sequence (const char *utf8,    /* IN */
+                         uint8_t *seq_length, /* OUT */
+                         uint8_t *first_mask) /* OUT */
+{
+   unsigned char c = *(const unsigned char *) utf8;
+   uint8_t m;
+   uint8_t n;
+
+   /*
+    * See the following[1] for a description of what the given multi-byte
+    * sequences will be based on the bits set of the first byte. We also need
+    * to mask the first byte based on that.  All subsequent bytes are masked
+    * against 0x3F.
+    *
+    * [1] http://www.joelonsoftware.com/articles/Unicode.html
+    */
+
+   if ((c & 0x80) == 0) {
+      n = 1;
+      m = 0x7F;
+   } else if ((c & 0xE0) == 0xC0) {
+      n = 2;
+      m = 0x1F;
+   } else if ((c & 0xF0) == 0xE0) {
+      n = 3;
+      m = 0x0F;
+   } else if ((c & 0xF8) == 0xF0) {
+      n = 4;
+      m = 0x07;
+   } else if ((c & 0xFC) == 0xF8) {
+      n = 5;
+      m = 0x03;
+   } else if ((c & 0xFE) == 0xFC) {
+      n = 6;
+      m = 0x01;
+   } else {
+      n = 0;
+      m = 0;
+   }
+
+   *seq_length = n;
+   *first_mask = m;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_utf8_validate --
+ *
+ *       Validates that @utf8 is a valid UTF-8 string.
+ *
+ *       If @allow_null is true, then \0 is allowed within @utf8_len bytes
+ *       of @utf8.  Generally, this is bad practice since the main point of
+ *       UTF-8 strings is that they can be used with strlen() and friends.
+ *       However, some languages such as Python can send UTF-8 encoded
+ *       strings with NUL's in them.
+ *
+ * Parameters:
+ *       @utf8: A UTF-8 encoded string.
+ *       @utf8_len: The length of @utf8 in bytes.
+ *       @allow_null: If \0 is allowed within @utf8, exclusing trailing \0.
+ *
+ * Returns:
+ *       true if @utf8 is valid UTF-8. otherwise false.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+bson_utf8_validate (const char *utf8, /* IN */
+                    size_t utf8_len,  /* IN */
+                    bool allow_null)  /* IN */
+{
+   bson_unichar_t c;
+   uint8_t first_mask;
+   uint8_t seq_length;
+   unsigned i;
+   unsigned j;
+
+   BSON_ASSERT (utf8);
+
+   for (i = 0; i < utf8_len; i += seq_length) {
+      _bson_utf8_get_sequence (&utf8[i], &seq_length, &first_mask);
+
+      /*
+       * Ensure we have a valid multi-byte sequence length.
+       */
+      if (!seq_length) {
+         return false;
+      }
+
+      /*
+       * Ensure we have enough bytes left.
+       */
+      if ((utf8_len - i) < seq_length) {
+         return false;
+      }
+
+      /*
+       * Also calculate the next char as a unichar so we can
+       * check code ranges for non-shortest form.
+       */
+      c = utf8[i] & first_mask;
+
+      /*
+       * Check the high-bits for each additional sequence byte.
+       */
+      for (j = i + 1; j < (i + seq_length); j++) {
+         c = (c << 6) | (utf8[j] & 0x3F);
+         if ((utf8[j] & 0xC0) != 0x80) {
+            return false;
+         }
+      }
+
+      /*
+       * Check for NULL bytes afterwards.
+       *
+       * Hint: if you want to optimize this function, starting here to do
+       * this in the same pass as the data above would probably be a good
+       * idea. You would add a branch into the inner loop, but save possibly
+       * on cache-line bouncing on larger strings. Just a thought.
+       */
+      if (!allow_null) {
+         for (j = 0; j < seq_length; j++) {
+            if (((i + j) > utf8_len) || !utf8[i + j]) {
+               return false;
+            }
+         }
+      }
+
+      /*
+       * Code point wont fit in utf-16, not allowed.
+       */
+      if (c > 0x0010FFFF) {
+         return false;
+      }
+
+      /*
+       * Byte is in reserved range for UTF-16 high-marks
+       * for surrogate pairs.
+       */
+      if ((c & 0xFFFFF800) == 0xD800) {
+         return false;
+      }
+
+      /*
+       * Check non-shortest form unicode.
+       */
+      switch (seq_length) {
+      case 1:
+         if (c <= 0x007F) {
+            continue;
+         }
+         return false;
+
+      case 2:
+         if ((c >= 0x0080) && (c <= 0x07FF)) {
+            continue;
+         } else if (c == 0) {
+            /* Two-byte representation for NULL. */
+            continue;
+         }
+         return false;
+
+      case 3:
+         if (((c >= 0x0800) && (c <= 0x0FFF)) ||
+             ((c >= 0x1000) && (c <= 0xFFFF))) {
+            continue;
+         }
+         return false;
+
+      case 4:
+         if (((c >= 0x10000) && (c <= 0x3FFFF)) ||
+             ((c >= 0x40000) && (c <= 0xFFFFF)) ||
+             ((c >= 0x100000) && (c <= 0x10FFFF))) {
+            continue;
+         }
+         return false;
+
+      default:
+         return false;
+      }
+   }
+
+   return true;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_utf8_escape_for_json --
+ *
+ *       Allocates a new string matching @utf8 except that special
+ *       characters in JSON will be escaped. The resulting string is also
+ *       UTF-8 encoded.
+ *
+ *       Both " and \ characters will be escaped. Additionally, if a NUL
+ *       byte is found before @utf8_len bytes, it will be converted to the
+ *       two byte UTF-8 sequence.
+ *
+ * Parameters:
+ *       @utf8: A UTF-8 encoded string.
+ *       @utf8_len: The length of @utf8 in bytes or -1 if NUL terminated.
+ *
+ * Returns:
+ *       A newly allocated string that should be freed with bson_free().
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+char *
+bson_utf8_escape_for_json (const char *utf8, /* IN */
+                           ssize_t utf8_len) /* IN */
+{
+   bson_unichar_t c;
+   bson_string_t *str;
+   bool length_provided = true;
+   const char *end;
+
+   BSON_ASSERT (utf8);
+
+   str = bson_string_new (NULL);
+
+   if (utf8_len < 0) {
+      length_provided = false;
+      utf8_len = strlen (utf8);
+   }
+
+   end = utf8 + utf8_len;
+
+   while (utf8 < end) {
+      c = bson_utf8_get_char (utf8);
+
+      switch (c) {
+      case '\\':
+      case '"':
+      case '/':
+         bson_string_append_c (str, '\\');
+         bson_string_append_unichar (str, c);
+         break;
+      case '\b':
+         bson_string_append (str, "\\b");
+         break;
+      case '\f':
+         bson_string_append (str, "\\f");
+         break;
+      case '\n':
+         bson_string_append (str, "\\n");
+         break;
+      case '\r':
+         bson_string_append (str, "\\r");
+         break;
+      case '\t':
+         bson_string_append (str, "\\t");
+         break;
+      default:
+         if (c < ' ') {
+            bson_string_append_printf (str, "\\u%04u", (unsigned) c);
+         } else {
+            bson_string_append_unichar (str, c);
+         }
+         break;
+      }
+
+      if (c) {
+         utf8 = bson_utf8_next_char (utf8);
+      } else {
+         if (length_provided && !*utf8) {
+            /* we escaped nil as '\u0000', now advance past it */
+            utf8++;
+         } else {
+            /* invalid UTF-8 */
+            bson_string_free (str, true);
+            return NULL;
+         }
+      }
+   }
+
+   return bson_string_free (str, false);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_utf8_get_char --
+ *
+ *       Fetches the next UTF-8 character from the UTF-8 sequence.
+ *
+ * Parameters:
+ *       @utf8: A string containing validated UTF-8.
+ *
+ * Returns:
+ *       A 32-bit bson_unichar_t reprsenting the multi-byte sequence.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bson_unichar_t
+bson_utf8_get_char (const char *utf8) /* IN */
+{
+   bson_unichar_t c;
+   uint8_t mask;
+   uint8_t num;
+   int i;
+
+   BSON_ASSERT (utf8);
+
+   _bson_utf8_get_sequence (utf8, &num, &mask);
+   c = (*utf8) & mask;
+
+   for (i = 1; i < num; i++) {
+      c = (c << 6) | (utf8[i] & 0x3F);
+   }
+
+   return c;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_utf8_next_char --
+ *
+ *       Returns an incremented pointer to the beginning of the next
+ *       multi-byte sequence in @utf8.
+ *
+ * Parameters:
+ *       @utf8: A string containing validated UTF-8.
+ *
+ * Returns:
+ *       An incremented pointer in @utf8.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+const char *
+bson_utf8_next_char (const char *utf8) /* IN */
+{
+   uint8_t mask;
+   uint8_t num;
+
+   BSON_ASSERT (utf8);
+
+   _bson_utf8_get_sequence (utf8, &num, &mask);
+
+   return utf8 + num;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_utf8_from_unichar --
+ *
+ *       Converts the unichar to a sequence of utf8 bytes and stores those
+ *       in @utf8. The number of bytes in the sequence are stored in @len.
+ *
+ * Parameters:
+ *       @unichar: A bson_unichar_t.
+ *       @utf8: A location for the multi-byte sequence.
+ *       @len: A location for number of bytes stored in @utf8.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       @utf8 is set.
+ *       @len is set.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_utf8_from_unichar (bson_unichar_t unichar,                      /* IN */
+                        char utf8[BSON_ENSURE_ARRAY_PARAM_SIZE (6)], /* OUT */
+                        uint32_t *len)                               /* OUT */
+{
+   BSON_ASSERT (utf8);
+   BSON_ASSERT (len);
+
+   if (unichar <= 0x7F) {
+      utf8[0] = unichar;
+      *len = 1;
+   } else if (unichar <= 0x7FF) {
+      *len = 2;
+      utf8[0] = 0xC0 | ((unichar >> 6) & 0x3F);
+      utf8[1] = 0x80 | ((unichar) &0x3F);
+   } else if (unichar <= 0xFFFF) {
+      *len = 3;
+      utf8[0] = 0xE0 | ((unichar >> 12) & 0xF);
+      utf8[1] = 0x80 | ((unichar >> 6) & 0x3F);
+      utf8[2] = 0x80 | ((unichar) &0x3F);
+   } else if (unichar <= 0x1FFFFF) {
+      *len = 4;
+      utf8[0] = 0xF0 | ((unichar >> 18) & 0x7);
+      utf8[1] = 0x80 | ((unichar >> 12) & 0x3F);
+      utf8[2] = 0x80 | ((unichar >> 6) & 0x3F);
+      utf8[3] = 0x80 | ((unichar) &0x3F);
+   } else if (unichar <= 0x3FFFFFF) {
+      *len = 5;
+      utf8[0] = 0xF8 | ((unichar >> 24) & 0x3);
+      utf8[1] = 0x80 | ((unichar >> 18) & 0x3F);
+      utf8[2] = 0x80 | ((unichar >> 12) & 0x3F);
+      utf8[3] = 0x80 | ((unichar >> 6) & 0x3F);
+      utf8[4] = 0x80 | ((unichar) &0x3F);
+   } else if (unichar <= 0x7FFFFFFF) {
+      *len = 6;
+      utf8[0] = 0xFC | ((unichar >> 31) & 0x1);
+      utf8[1] = 0x80 | ((unichar >> 25) & 0x3F);
+      utf8[2] = 0x80 | ((unichar >> 19) & 0x3F);
+      utf8[3] = 0x80 | ((unichar >> 13) & 0x3F);
+      utf8[4] = 0x80 | ((unichar >> 7) & 0x3F);
+      utf8[5] = 0x80 | ((unichar) &0x1);
+   } else {
+      *len = 0;
+   }
+}
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-utf8.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-utf8.h
new file mode 100644
index 0000000000000000000000000000000000000000..72918acf5e3a7a7778333e61178945d409dbfcb5
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-utf8.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef BSON_UTF8_H
+#define BSON_UTF8_H
+
+
+#if !defined(BSON_INSIDE) && !defined(BSON_COMPILATION)
+#error "Only <bson.h> can be included directly."
+#endif
+
+
+#include "bson-macros.h"
+#include "bson-types.h"
+
+
+BSON_BEGIN_DECLS
+
+
+BSON_EXPORT (bool)
+bson_utf8_validate (const char *utf8, size_t utf8_len, bool allow_null);
+BSON_EXPORT (char *)
+bson_utf8_escape_for_json (const char *utf8, ssize_t utf8_len);
+BSON_EXPORT (bson_unichar_t)
+bson_utf8_get_char (const char *utf8);
+BSON_EXPORT (const char *)
+bson_utf8_next_char (const char *utf8);
+BSON_EXPORT (void)
+bson_utf8_from_unichar (bson_unichar_t unichar, char utf8[6], uint32_t *len);
+
+
+BSON_END_DECLS
+
+
+#endif /* BSON_UTF8_H */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-value.c b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-value.c
new file mode 100644
index 0000000000000000000000000000000000000000..c491194f4cd6d84e4d99b4b8a248d18bbf71663f
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-value.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2014 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include "bson-memory.h"
+#include "bson-string.h"
+#include "bson-value.h"
+#include "bson-oid.h"
+
+
+void
+bson_value_copy (const bson_value_t *src, /* IN */
+                 bson_value_t *dst)       /* OUT */
+{
+   BSON_ASSERT (src);
+   BSON_ASSERT (dst);
+
+   dst->value_type = src->value_type;
+
+   switch (src->value_type) {
+   case BSON_TYPE_DOUBLE:
+      dst->value.v_double = src->value.v_double;
+      break;
+   case BSON_TYPE_UTF8:
+      dst->value.v_utf8.len = src->value.v_utf8.len;
+      dst->value.v_utf8.str = bson_malloc (src->value.v_utf8.len + 1);
+      memcpy (
+         dst->value.v_utf8.str, src->value.v_utf8.str, dst->value.v_utf8.len);
+      dst->value.v_utf8.str[dst->value.v_utf8.len] = '\0';
+      break;
+   case BSON_TYPE_DOCUMENT:
+   case BSON_TYPE_ARRAY:
+      dst->value.v_doc.data_len = src->value.v_doc.data_len;
+      dst->value.v_doc.data = bson_malloc (src->value.v_doc.data_len);
+      memcpy (dst->value.v_doc.data,
+              src->value.v_doc.data,
+              dst->value.v_doc.data_len);
+      break;
+   case BSON_TYPE_BINARY:
+      dst->value.v_binary.subtype = src->value.v_binary.subtype;
+      dst->value.v_binary.data_len = src->value.v_binary.data_len;
+      dst->value.v_binary.data = bson_malloc (src->value.v_binary.data_len);
+      memcpy (dst->value.v_binary.data,
+              src->value.v_binary.data,
+              dst->value.v_binary.data_len);
+      break;
+   case BSON_TYPE_OID:
+      bson_oid_copy (&src->value.v_oid, &dst->value.v_oid);
+      break;
+   case BSON_TYPE_BOOL:
+      dst->value.v_bool = src->value.v_bool;
+      break;
+   case BSON_TYPE_DATE_TIME:
+      dst->value.v_datetime = src->value.v_datetime;
+      break;
+   case BSON_TYPE_REGEX:
+      dst->value.v_regex.regex = bson_strdup (src->value.v_regex.regex);
+      dst->value.v_regex.options = bson_strdup (src->value.v_regex.options);
+      break;
+   case BSON_TYPE_DBPOINTER:
+      dst->value.v_dbpointer.collection_len =
+         src->value.v_dbpointer.collection_len;
+      dst->value.v_dbpointer.collection =
+         bson_malloc (src->value.v_dbpointer.collection_len + 1);
+      memcpy (dst->value.v_dbpointer.collection,
+              src->value.v_dbpointer.collection,
+              dst->value.v_dbpointer.collection_len);
+      dst->value.v_dbpointer.collection[dst->value.v_dbpointer.collection_len] =
+         '\0';
+      bson_oid_copy (&src->value.v_dbpointer.oid, &dst->value.v_dbpointer.oid);
+      break;
+   case BSON_TYPE_CODE:
+      dst->value.v_code.code_len = src->value.v_code.code_len;
+      dst->value.v_code.code = bson_malloc (src->value.v_code.code_len + 1);
+      memcpy (dst->value.v_code.code,
+              src->value.v_code.code,
+              dst->value.v_code.code_len);
+      dst->value.v_code.code[dst->value.v_code.code_len] = '\0';
+      break;
+   case BSON_TYPE_SYMBOL:
+      dst->value.v_symbol.len = src->value.v_symbol.len;
+      dst->value.v_symbol.symbol = bson_malloc (src->value.v_symbol.len + 1);
+      memcpy (dst->value.v_symbol.symbol,
+              src->value.v_symbol.symbol,
+              dst->value.v_symbol.len);
+      dst->value.v_symbol.symbol[dst->value.v_symbol.len] = '\0';
+      break;
+   case BSON_TYPE_CODEWSCOPE:
+      dst->value.v_codewscope.code_len = src->value.v_codewscope.code_len;
+      dst->value.v_codewscope.code =
+         bson_malloc (src->value.v_codewscope.code_len + 1);
+      memcpy (dst->value.v_codewscope.code,
+              src->value.v_codewscope.code,
+              dst->value.v_codewscope.code_len);
+      dst->value.v_codewscope.code[dst->value.v_codewscope.code_len] = '\0';
+      dst->value.v_codewscope.scope_len = src->value.v_codewscope.scope_len;
+      dst->value.v_codewscope.scope_data =
+         bson_malloc (src->value.v_codewscope.scope_len);
+      memcpy (dst->value.v_codewscope.scope_data,
+              src->value.v_codewscope.scope_data,
+              dst->value.v_codewscope.scope_len);
+      break;
+   case BSON_TYPE_INT32:
+      dst->value.v_int32 = src->value.v_int32;
+      break;
+   case BSON_TYPE_TIMESTAMP:
+      dst->value.v_timestamp.timestamp = src->value.v_timestamp.timestamp;
+      dst->value.v_timestamp.increment = src->value.v_timestamp.increment;
+      break;
+   case BSON_TYPE_INT64:
+      dst->value.v_int64 = src->value.v_int64;
+      break;
+   case BSON_TYPE_DECIMAL128:
+      dst->value.v_decimal128 = src->value.v_decimal128;
+      break;
+   case BSON_TYPE_UNDEFINED:
+   case BSON_TYPE_NULL:
+   case BSON_TYPE_MAXKEY:
+   case BSON_TYPE_MINKEY:
+      break;
+   case BSON_TYPE_EOD:
+   default:
+      BSON_ASSERT (false);
+      return;
+   }
+}
+
+
+void
+bson_value_destroy (bson_value_t *value) /* IN */
+{
+   switch (value->value_type) {
+   case BSON_TYPE_UTF8:
+      bson_free (value->value.v_utf8.str);
+      break;
+   case BSON_TYPE_DOCUMENT:
+   case BSON_TYPE_ARRAY:
+      bson_free (value->value.v_doc.data);
+      break;
+   case BSON_TYPE_BINARY:
+      bson_free (value->value.v_binary.data);
+      break;
+   case BSON_TYPE_REGEX:
+      bson_free (value->value.v_regex.regex);
+      bson_free (value->value.v_regex.options);
+      break;
+   case BSON_TYPE_DBPOINTER:
+      bson_free (value->value.v_dbpointer.collection);
+      break;
+   case BSON_TYPE_CODE:
+      bson_free (value->value.v_code.code);
+      break;
+   case BSON_TYPE_SYMBOL:
+      bson_free (value->value.v_symbol.symbol);
+      break;
+   case BSON_TYPE_CODEWSCOPE:
+      bson_free (value->value.v_codewscope.code);
+      bson_free (value->value.v_codewscope.scope_data);
+      break;
+   case BSON_TYPE_DOUBLE:
+   case BSON_TYPE_UNDEFINED:
+   case BSON_TYPE_OID:
+   case BSON_TYPE_BOOL:
+   case BSON_TYPE_DATE_TIME:
+   case BSON_TYPE_NULL:
+   case BSON_TYPE_INT32:
+   case BSON_TYPE_TIMESTAMP:
+   case BSON_TYPE_INT64:
+   case BSON_TYPE_DECIMAL128:
+   case BSON_TYPE_MAXKEY:
+   case BSON_TYPE_MINKEY:
+   case BSON_TYPE_EOD:
+   default:
+      break;
+   }
+}
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-value.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-value.h
new file mode 100644
index 0000000000000000000000000000000000000000..141bcee3e2612021ba4e44db5226f7ae3e4de664
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-value.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2014 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef BSON_VALUE_H
+#define BSON_VALUE_H
+
+
+#include "bson-macros.h"
+#include "bson-types.h"
+
+
+BSON_BEGIN_DECLS
+
+
+BSON_EXPORT (void)
+bson_value_copy (const bson_value_t *src, bson_value_t *dst);
+BSON_EXPORT (void)
+bson_value_destroy (bson_value_t *value);
+
+
+BSON_END_DECLS
+
+
+#endif /* BSON_VALUE_H */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-writer.c b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-writer.c
new file mode 100644
index 0000000000000000000000000000000000000000..dcce06ade6da71a5425fe6d6d18481935d789f75
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-writer.c
@@ -0,0 +1,271 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include "bson-private.h"
+#include "bson-writer.h"
+
+
+struct _bson_writer_t {
+   bool ready;
+   uint8_t **buf;
+   size_t *buflen;
+   size_t offset;
+   bson_realloc_func realloc_func;
+   void *realloc_func_ctx;
+   bson_t b;
+};
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_writer_new --
+ *
+ *       Creates a new instance of bson_writer_t using the buffer, length,
+ *       offset, and realloc() function supplied.
+ *
+ *       The caller is expected to clean up the structure when finished
+ *       using bson_writer_destroy().
+ *
+ * Parameters:
+ *       @buf: (inout): A pointer to a target buffer.
+ *       @buflen: (inout): A pointer to the buffer length.
+ *       @offset: The offset in the target buffer to start from.
+ *       @realloc_func: A realloc() style function or NULL.
+ *
+ * Returns:
+ *       A newly allocated bson_writer_t that should be freed with
+ *       bson_writer_destroy().
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bson_writer_t *
+bson_writer_new (uint8_t **buf,                  /* IN */
+                 size_t *buflen,                 /* IN */
+                 size_t offset,                  /* IN */
+                 bson_realloc_func realloc_func, /* IN */
+                 void *realloc_func_ctx)         /* IN */
+{
+   bson_writer_t *writer;
+
+   writer = bson_malloc0 (sizeof *writer);
+   writer->buf = buf;
+   writer->buflen = buflen;
+   writer->offset = offset;
+   writer->realloc_func = realloc_func;
+   writer->realloc_func_ctx = realloc_func_ctx;
+   writer->ready = true;
+
+   return writer;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_writer_destroy --
+ *
+ *       Cleanup after @writer and release any allocated memory. Note that
+ *       the buffer supplied to bson_writer_new() is NOT freed from this
+ *       method.  The caller is responsible for that.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_writer_destroy (bson_writer_t *writer) /* IN */
+{
+   bson_free (writer);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_writer_get_length --
+ *
+ *       Fetches the current length of the content written by the buffer
+ *       (including the initial offset). This includes a partly written
+ *       document currently being written.
+ *
+ *       This is useful if you want to check to see if you've passed a given
+ *       memory boundry that cannot be sent in a packet. See
+ *       bson_writer_rollback() to abort the current document being written.
+ *
+ * Returns:
+ *       The number of bytes written plus initial offset.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+size_t
+bson_writer_get_length (bson_writer_t *writer) /* IN */
+{
+   return writer->offset + writer->b.len;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_writer_begin --
+ *
+ *       Begins writing a new document. The caller may use the bson
+ *       structure to write out a new BSON document. When completed, the
+ *       caller must call either bson_writer_end() or
+ *       bson_writer_rollback().
+ *
+ * Parameters:
+ *       @writer: A bson_writer_t.
+ *       @bson: (out): A location for a bson_t*.
+ *
+ * Returns:
+ *       true if the underlying realloc was successful; otherwise false.
+ *
+ * Side effects:
+ *       @bson is initialized if true is returned.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+bson_writer_begin (bson_writer_t *writer, /* IN */
+                   bson_t **bson)         /* OUT */
+{
+   bson_impl_alloc_t *b;
+   bool grown = false;
+
+   BSON_ASSERT (writer);
+   BSON_ASSERT (writer->ready);
+   BSON_ASSERT (bson);
+
+   writer->ready = false;
+
+   memset (&writer->b, 0, sizeof (bson_t));
+
+   b = (bson_impl_alloc_t *) &writer->b;
+   b->flags = BSON_FLAG_STATIC | BSON_FLAG_NO_FREE;
+   b->len = 5;
+   b->parent = NULL;
+   b->buf = writer->buf;
+   b->buflen = writer->buflen;
+   b->offset = writer->offset;
+   b->alloc = NULL;
+   b->alloclen = 0;
+   b->realloc = writer->realloc_func;
+   b->realloc_func_ctx = writer->realloc_func_ctx;
+
+   while ((writer->offset + writer->b.len) > *writer->buflen) {
+      if (!writer->realloc_func) {
+         memset (&writer->b, 0, sizeof (bson_t));
+         writer->ready = true;
+         return false;
+      }
+      grown = true;
+
+      if (!*writer->buflen) {
+         *writer->buflen = 64;
+      } else {
+         (*writer->buflen) *= 2;
+      }
+   }
+
+   if (grown) {
+      *writer->buf = writer->realloc_func (
+         *writer->buf, *writer->buflen, writer->realloc_func_ctx);
+   }
+
+   memset ((*writer->buf) + writer->offset + 1, 0, 5);
+   (*writer->buf)[writer->offset] = 5;
+
+   *bson = &writer->b;
+
+   return true;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_writer_end --
+ *
+ *       Complete writing of a bson_writer_t to the buffer supplied.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_writer_end (bson_writer_t *writer) /* IN */
+{
+   BSON_ASSERT (writer);
+   BSON_ASSERT (!writer->ready);
+
+   writer->offset += writer->b.len;
+   memset (&writer->b, 0, sizeof (bson_t));
+   writer->ready = true;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_writer_rollback --
+ *
+ *       Abort the appending of the current bson_t to the memory region
+ *       managed by @writer.  This is useful if you detected that you went
+ *       past a particular memory limit.  For example, MongoDB has 48MB
+ *       message limits.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+void
+bson_writer_rollback (bson_writer_t *writer) /* IN */
+{
+   BSON_ASSERT (writer);
+
+   if (writer->b.len) {
+      memset (&writer->b, 0, sizeof (bson_t));
+   }
+
+   writer->ready = true;
+}
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-writer.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-writer.h
new file mode 100644
index 0000000000000000000000000000000000000000..9fd6548acdfc9e5290a6f057179dc713ebf8e447
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson-writer.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef BSON_WRITER_H
+#define BSON_WRITER_H
+
+
+#include "bson.h"
+
+
+BSON_BEGIN_DECLS
+
+
+/**
+ * bson_writer_t:
+ *
+ * The bson_writer_t structure is a helper for writing a series of BSON
+ * documents to a single malloc() buffer. You can provide a realloc() style
+ * function to grow the buffer as you go.
+ *
+ * This is useful if you want to build a series of BSON documents right into
+ * the target buffer for an outgoing packet. The offset parameter allows you to
+ * start at an offset of the target buffer.
+ */
+typedef struct _bson_writer_t bson_writer_t;
+
+
+BSON_EXPORT (bson_writer_t *)
+bson_writer_new (uint8_t **buf,
+                 size_t *buflen,
+                 size_t offset,
+                 bson_realloc_func realloc_func,
+                 void *realloc_func_ctx);
+BSON_EXPORT (void)
+bson_writer_destroy (bson_writer_t *writer);
+BSON_EXPORT (size_t)
+bson_writer_get_length (bson_writer_t *writer);
+BSON_EXPORT (bool)
+bson_writer_begin (bson_writer_t *writer, bson_t **bson);
+BSON_EXPORT (void)
+bson_writer_end (bson_writer_t *writer);
+BSON_EXPORT (void)
+bson_writer_rollback (bson_writer_t *writer);
+
+
+BSON_END_DECLS
+
+
+#endif /* BSON_WRITER_H */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson.c b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson.c
new file mode 100644
index 0000000000000000000000000000000000000000..d5483d3e2dd6b659fba417cf55a9dbdd99c1abe1
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson.c
@@ -0,0 +1,3565 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include "bson.h"
+#include "bson-config.h"
+#include "b64_ntop.h"
+#include "bson-private.h"
+#include "bson-string.h"
+
+#include <string.h>
+#include <math.h>
+
+
+#ifndef BSON_MAX_RECURSION
+#define BSON_MAX_RECURSION 200
+#endif
+
+
+typedef enum {
+   BSON_VALIDATE_PHASE_START,
+   BSON_VALIDATE_PHASE_TOP,
+   BSON_VALIDATE_PHASE_LF_REF_KEY,
+   BSON_VALIDATE_PHASE_LF_REF_UTF8,
+   BSON_VALIDATE_PHASE_LF_ID_KEY,
+   BSON_VALIDATE_PHASE_LF_DB_KEY,
+   BSON_VALIDATE_PHASE_LF_DB_UTF8,
+   BSON_VALIDATE_PHASE_NOT_DBREF,
+} bson_validate_phase_t;
+
+
+/*
+ * Structures.
+ */
+typedef struct {
+   bson_validate_flags_t flags;
+   ssize_t err_offset;
+   bson_validate_phase_t phase;
+   bson_error_t error;
+} bson_validate_state_t;
+
+
+typedef struct {
+   uint32_t count;
+   bool keys;
+   ssize_t *err_offset;
+   uint32_t depth;
+   bson_string_t *str;
+} bson_json_state_t;
+
+
+/*
+ * Forward declarations.
+ */
+static bool
+_bson_as_extended_json_visit_array (const bson_iter_t *iter,
+                                    const char *key,
+                                    const bson_t *v_array,
+                                    void *data);
+static bool
+_bson_as_json_visit_array (const bson_iter_t *iter,
+                           const char *key,
+                           const bson_t *v_array,
+                           void *data);
+static bool
+_bson_as_extended_json_visit_document (const bson_iter_t *iter,
+                                       const char *key,
+                                       const bson_t *v_document,
+                                       void *data);
+static bool
+_bson_as_json_visit_document (const bson_iter_t *iter,
+                              const char *key,
+                              const bson_t *v_document,
+                              void *data);
+
+
+static uint64_t
+_int64_timestamp (uint32_t timestamp, uint32_t increment)
+{
+   return (((uint64_t) timestamp) << 32) | (uint64_t) increment;
+}
+
+
+/*
+ * Globals.
+ */
+static const uint8_t gZero;
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_impl_inline_grow --
+ *
+ *       Document growth implementation for documents that currently
+ *       contain stack based buffers. The document may be switched to
+ *       a malloc based buffer.
+ *
+ * Returns:
+ *       true if successful; otherwise false indicating INT_MAX overflow.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static bool
+_bson_impl_inline_grow (bson_impl_inline_t *impl, /* IN */
+                        size_t size)              /* IN */
+{
+   bson_impl_alloc_t *alloc = (bson_impl_alloc_t *) impl;
+   uint8_t *data;
+   size_t req;
+
+   if (((size_t) impl->len + size) <= sizeof impl->data) {
+      return true;
+   }
+
+   req = bson_next_power_of_two (impl->len + size);
+
+   if (req <= INT32_MAX) {
+      data = bson_malloc (req);
+
+      memcpy (data, impl->data, impl->len);
+      alloc->flags &= ~BSON_FLAG_INLINE;
+      alloc->parent = NULL;
+      alloc->depth = 0;
+      alloc->buf = &alloc->alloc;
+      alloc->buflen = &alloc->alloclen;
+      alloc->offset = 0;
+      alloc->alloc = data;
+      alloc->alloclen = req;
+      alloc->realloc = bson_realloc_ctx;
+      alloc->realloc_func_ctx = NULL;
+
+      return true;
+   }
+
+   return false;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_impl_alloc_grow --
+ *
+ *       Document growth implementation for documents containing malloc
+ *       based buffers.
+ *
+ * Returns:
+ *       true if successful; otherwise false indicating INT_MAX overflow.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static bool
+_bson_impl_alloc_grow (bson_impl_alloc_t *impl, /* IN */
+                       size_t size)             /* IN */
+{
+   size_t req;
+
+   /*
+    * Determine how many bytes we need for this document in the buffer
+    * including necessary trailing bytes for parent documents.
+    */
+   req = (impl->offset + impl->len + size + impl->depth);
+
+   if (req <= *impl->buflen) {
+      return true;
+   }
+
+   req = bson_next_power_of_two (req);
+
+   if ((req <= INT32_MAX) && impl->realloc) {
+      *impl->buf = impl->realloc (*impl->buf, req, impl->realloc_func_ctx);
+      *impl->buflen = req;
+      return true;
+   }
+
+   return false;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_grow --
+ *
+ *       Grows the bson_t structure to be large enough to contain @size
+ *       bytes.
+ *
+ * Returns:
+ *       true if successful, false if the size would overflow.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static bool
+_bson_grow (bson_t *bson,  /* IN */
+            uint32_t size) /* IN */
+{
+   if ((bson->flags & BSON_FLAG_INLINE)) {
+      return _bson_impl_inline_grow ((bson_impl_inline_t *) bson, size);
+   }
+
+   return _bson_impl_alloc_grow ((bson_impl_alloc_t *) bson, size);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_data --
+ *
+ *       A helper function to return the contents of the bson document
+ *       taking into account the polymorphic nature of bson_t.
+ *
+ * Returns:
+ *       A buffer which should not be modified or freed.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static BSON_INLINE uint8_t *
+_bson_data (const bson_t *bson) /* IN */
+{
+   if ((bson->flags & BSON_FLAG_INLINE)) {
+      return ((bson_impl_inline_t *) bson)->data;
+   } else {
+      bson_impl_alloc_t *impl = (bson_impl_alloc_t *) bson;
+      return (*impl->buf) + impl->offset;
+   }
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_encode_length --
+ *
+ *       Helper to encode the length of the bson_t in the first 4 bytes
+ *       of the bson document. Little endian format is used as specified
+ *       by bsonspec.
+ *
+ * Returns:
+ *       None.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static BSON_INLINE void
+_bson_encode_length (bson_t *bson) /* IN */
+{
+#if BSON_BYTE_ORDER == BSON_LITTLE_ENDIAN
+   memcpy (_bson_data (bson), &bson->len, sizeof (bson->len));
+#else
+   uint32_t length_le = BSON_UINT32_TO_LE (bson->len);
+   memcpy (_bson_data (bson), &length_le, sizeof (length_le));
+#endif
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_append_va --
+ *
+ *       Appends the length,buffer pairs to the bson_t. @n_bytes is an
+ *       optimization to perform one array growth rather than many small
+ *       growths.
+ *
+ *       @bson: A bson_t
+ *       @n_bytes: The number of bytes to append to the document.
+ *       @n_pairs: The number of length,buffer pairs.
+ *       @first_len: Length of first buffer.
+ *       @first_data: First buffer.
+ *       @args: va_list of additional tuples.
+ *
+ * Returns:
+ *       true if the bytes were appended successfully.
+ *       false if it bson would overflow INT_MAX.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static BSON_INLINE bool
+_bson_append_va (bson_t *bson,              /* IN */
+                 uint32_t n_bytes,          /* IN */
+                 uint32_t n_pairs,          /* IN */
+                 uint32_t first_len,        /* IN */
+                 const uint8_t *first_data, /* IN */
+                 va_list args)              /* IN */
+{
+   const uint8_t *data;
+   uint32_t data_len;
+   uint8_t *buf;
+
+   BSON_ASSERT (!(bson->flags & BSON_FLAG_IN_CHILD));
+   BSON_ASSERT (!(bson->flags & BSON_FLAG_RDONLY));
+
+   if (BSON_UNLIKELY (!_bson_grow (bson, n_bytes))) {
+      return false;
+   }
+
+   data = first_data;
+   data_len = first_len;
+
+   buf = _bson_data (bson) + bson->len - 1;
+
+   do {
+      n_pairs--;
+      memcpy (buf, data, data_len);
+      bson->len += data_len;
+      buf += data_len;
+
+      if (n_pairs) {
+         data_len = va_arg (args, uint32_t);
+         data = va_arg (args, const uint8_t *);
+      }
+   } while (n_pairs);
+
+   _bson_encode_length (bson);
+
+   *buf = '\0';
+
+   return true;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_append --
+ *
+ *       Variadic function to append length,buffer pairs to a bson_t. If the
+ *       append would cause the bson_t to overflow a 32-bit length, it will
+ *       return false and no append will have occurred.
+ *
+ * Parameters:
+ *       @bson: A bson_t.
+ *       @n_pairs: Number of length,buffer pairs.
+ *       @n_bytes: the total number of bytes being appended.
+ *       @first_len: Length of first buffer.
+ *       @first_data: First buffer.
+ *
+ * Returns:
+ *       true if successful; otherwise false indicating INT_MAX overflow.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static bool
+_bson_append (bson_t *bson,              /* IN */
+              uint32_t n_pairs,          /* IN */
+              uint32_t n_bytes,          /* IN */
+              uint32_t first_len,        /* IN */
+              const uint8_t *first_data, /* IN */
+              ...)
+{
+   va_list args;
+   bool ok;
+
+   BSON_ASSERT (n_pairs);
+   BSON_ASSERT (first_len);
+   BSON_ASSERT (first_data);
+
+   /*
+    * Check to see if this append would overflow 32-bit signed integer. I know
+    * what you're thinking. BSON uses a signed 32-bit length field? Yeah. It
+    * does.
+    */
+   if (BSON_UNLIKELY (n_bytes > (BSON_MAX_SIZE - bson->len))) {
+      return false;
+   }
+
+   va_start (args, first_data);
+   ok = _bson_append_va (bson, n_bytes, n_pairs, first_len, first_data, args);
+   va_end (args);
+
+   return ok;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_append_bson_begin --
+ *
+ *       Begin appending a subdocument or subarray to the document using
+ *       the key provided by @key.
+ *
+ *       If @key_length is < 0, then strlen() will be called on @key
+ *       to determine the length.
+ *
+ *       @key_type MUST be either BSON_TYPE_DOCUMENT or BSON_TYPE_ARRAY.
+ *
+ * Returns:
+ *       true if successful; otherwise false indicating INT_MAX overflow.
+ *
+ * Side effects:
+ *       @child is initialized if true is returned.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static bool
+_bson_append_bson_begin (bson_t *bson,           /* IN */
+                         const char *key,        /* IN */
+                         int key_length,         /* IN */
+                         bson_type_t child_type, /* IN */
+                         bson_t *child)          /* OUT */
+{
+   const uint8_t type = child_type;
+   const uint8_t empty[5] = {5};
+   bson_impl_alloc_t *aparent = (bson_impl_alloc_t *) bson;
+   bson_impl_alloc_t *achild = (bson_impl_alloc_t *) child;
+
+   BSON_ASSERT (!(bson->flags & BSON_FLAG_RDONLY));
+   BSON_ASSERT (!(bson->flags & BSON_FLAG_IN_CHILD));
+   BSON_ASSERT (key);
+   BSON_ASSERT ((child_type == BSON_TYPE_DOCUMENT) ||
+                (child_type == BSON_TYPE_ARRAY));
+   BSON_ASSERT (child);
+
+   if (key_length < 0) {
+      key_length = (int) strlen (key);
+   }
+
+   /*
+    * If the parent is an inline bson_t, then we need to convert
+    * it to a heap allocated buffer. This makes extending buffers
+    * of child bson documents much simpler logic, as they can just
+    * realloc the *buf pointer.
+    */
+   if ((bson->flags & BSON_FLAG_INLINE)) {
+      BSON_ASSERT (bson->len <= 120);
+      if (!_bson_grow (bson, 128 - bson->len)) {
+         return false;
+      }
+      BSON_ASSERT (!(bson->flags & BSON_FLAG_INLINE));
+   }
+
+   /*
+    * Append the type and key for the field.
+    */
+   if (!_bson_append (bson,
+                      4,
+                      (1 + key_length + 1 + 5),
+                      1,
+                      &type,
+                      key_length,
+                      key,
+                      1,
+                      &gZero,
+                      5,
+                      empty)) {
+      return false;
+   }
+
+   /*
+    * Mark the document as working on a child document so that no
+    * further modifications can happen until the caller has called
+    * bson_append_{document,array}_end().
+    */
+   bson->flags |= BSON_FLAG_IN_CHILD;
+
+   /*
+    * Initialize the child bson_t structure and point it at the parents
+    * buffers. This allows us to realloc directly from the child without
+    * walking up to the parent bson_t.
+    */
+   achild->flags = (BSON_FLAG_CHILD | BSON_FLAG_NO_FREE | BSON_FLAG_STATIC);
+
+   if ((bson->flags & BSON_FLAG_CHILD)) {
+      achild->depth = ((bson_impl_alloc_t *) bson)->depth + 1;
+   } else {
+      achild->depth = 1;
+   }
+
+   achild->parent = bson;
+   achild->buf = aparent->buf;
+   achild->buflen = aparent->buflen;
+   achild->offset = aparent->offset + aparent->len - 1 - 5;
+   achild->len = 5;
+   achild->alloc = NULL;
+   achild->alloclen = 0;
+   achild->realloc = aparent->realloc;
+   achild->realloc_func_ctx = aparent->realloc_func_ctx;
+
+   return true;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * _bson_append_bson_end --
+ *
+ *       Complete a call to _bson_append_bson_begin.
+ *
+ * Returns:
+ *       true if successful.
+ *
+ * Side effects:
+ *       @child is destroyed and no longer valid after calling this
+ *       function.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+static bool
+_bson_append_bson_end (bson_t *bson,  /* IN */
+                       bson_t *child) /* IN */
+{
+   BSON_ASSERT (bson);
+   BSON_ASSERT ((bson->flags & BSON_FLAG_IN_CHILD));
+   BSON_ASSERT (!(child->flags & BSON_FLAG_IN_CHILD));
+
+   /*
+    * Unmark the IN_CHILD flag.
+    */
+   bson->flags &= ~BSON_FLAG_IN_CHILD;
+
+   /*
+    * Now that we are done building the sub-document, add the size to the
+    * parent, not including the default 5 byte empty document already added.
+    */
+   bson->len = (bson->len + child->len - 5);
+
+   /*
+    * Ensure we have a \0 byte at the end and proper length encoded at
+    * the beginning of the document.
+    */
+   _bson_data (bson)[bson->len - 1] = '\0';
+   _bson_encode_length (bson);
+
+   return true;
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_append_array_begin --
+ *
+ *       Start appending a new array.
+ *
+ *       Use @child to append to the data area for the given field.
+ *
+ *       It is a programming error to call any other bson function on
+ *       @bson until bson_append_array_end() has been called. It is
+ *       valid to call bson_append*() functions on @child.
+ *
+ *       This function is useful to allow building nested documents using
+ *       a single buffer owned by the top-level bson document.
+ *
+ * Returns:
+ *       true if successful; otherwise false and @child is invalid.
+ *
+ * Side effects:
+ *       @child is initialized if true is returned.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+bson_append_array_begin (bson_t *bson,    /* IN */
+                         const char *key, /* IN */
+                         int key_length,  /* IN */
+                         bson_t *child)   /* IN */
+{
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+   BSON_ASSERT (child);
+
+   return _bson_append_bson_begin (
+      bson, key, key_length, BSON_TYPE_ARRAY, child);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_append_array_end --
+ *
+ *       Complete a call to bson_append_array_begin().
+ *
+ *       It is safe to append other fields to @bson after calling this
+ *       function.
+ *
+ * Returns:
+ *       true if successful.
+ *
+ * Side effects:
+ *       @child is invalid after calling this function.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+bson_append_array_end (bson_t *bson,  /* IN */
+                       bson_t *child) /* IN */
+{
+   BSON_ASSERT (bson);
+   BSON_ASSERT (child);
+
+   return _bson_append_bson_end (bson, child);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_append_document_begin --
+ *
+ *       Start appending a new document.
+ *
+ *       Use @child to append to the data area for the given field.
+ *
+ *       It is a programming error to call any other bson function on
+ *       @bson until bson_append_document_end() has been called. It is
+ *       valid to call bson_append*() functions on @child.
+ *
+ *       This function is useful to allow building nested documents using
+ *       a single buffer owned by the top-level bson document.
+ *
+ * Returns:
+ *       true if successful; otherwise false and @child is invalid.
+ *
+ * Side effects:
+ *       @child is initialized if true is returned.
+ *
+ *--------------------------------------------------------------------------
+ */
+bool
+bson_append_document_begin (bson_t *bson,    /* IN */
+                            const char *key, /* IN */
+                            int key_length,  /* IN */
+                            bson_t *child)   /* IN */
+{
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+   BSON_ASSERT (child);
+
+   return _bson_append_bson_begin (
+      bson, key, key_length, BSON_TYPE_DOCUMENT, child);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_append_document_end --
+ *
+ *       Complete a call to bson_append_document_begin().
+ *
+ *       It is safe to append new fields to @bson after calling this
+ *       function, if true is returned.
+ *
+ * Returns:
+ *       true if successful; otherwise false indicating INT_MAX overflow.
+ *
+ * Side effects:
+ *       @child is destroyed and invalid after calling this function.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+bson_append_document_end (bson_t *bson,  /* IN */
+                          bson_t *child) /* IN */
+{
+   BSON_ASSERT (bson);
+   BSON_ASSERT (child);
+
+   return _bson_append_bson_end (bson, child);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_append_array --
+ *
+ *       Append an array to @bson.
+ *
+ *       Generally, bson_append_array_begin() will result in faster code
+ *       since few buffers need to be malloced.
+ *
+ * Returns:
+ *       true if successful; otherwise false indicating INT_MAX overflow.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+bson_append_array (bson_t *bson,        /* IN */
+                   const char *key,     /* IN */
+                   int key_length,      /* IN */
+                   const bson_t *array) /* IN */
+{
+   static const uint8_t type = BSON_TYPE_ARRAY;
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+   BSON_ASSERT (array);
+
+   if (key_length < 0) {
+      key_length = (int) strlen (key);
+   }
+
+   /*
+    * Let's be a bit pedantic and ensure the array has properly formatted key
+    * names.  We will verify this simply by checking the first element for "0"
+    * if the array is non-empty.
+    */
+   if (array && !bson_empty (array)) {
+      bson_iter_t iter;
+
+      if (bson_iter_init (&iter, array) && bson_iter_next (&iter)) {
+         if (0 != strcmp ("0", bson_iter_key (&iter))) {
+            fprintf (stderr,
+                     "%s(): invalid array detected. first element of array "
+                     "parameter is not \"0\".\n",
+                     BSON_FUNC);
+         }
+      }
+   }
+
+   return _bson_append (bson,
+                        4,
+                        (1 + key_length + 1 + array->len),
+                        1,
+                        &type,
+                        key_length,
+                        key,
+                        1,
+                        &gZero,
+                        array->len,
+                        _bson_data (array));
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_append_binary --
+ *
+ *       Append binary data to @bson. The field will have the
+ *       BSON_TYPE_BINARY type.
+ *
+ * Parameters:
+ *       @subtype: the BSON Binary Subtype. See bsonspec.org for more
+ *                 information.
+ *       @binary: a pointer to the raw binary data.
+ *       @length: the size of @binary in bytes.
+ *
+ * Returns:
+ *       true if successful; otherwise false.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+bson_append_binary (bson_t *bson,           /* IN */
+                    const char *key,        /* IN */
+                    int key_length,         /* IN */
+                    unsigned int   subtype, /* IN */
+                    const uint8_t *binary,  /* IN */
+                    uint32_t length)        /* IN */
+{
+   static const uint8_t type = BSON_TYPE_BINARY;
+   uint32_t length_le;
+   uint32_t deprecated_length_le;
+   uint8_t subtype8 = 0;
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+   BSON_ASSERT (binary);
+
+   if (key_length < 0) {
+      key_length = (int) strlen (key);
+   }
+
+   subtype8 = subtype;
+
+   if (subtype == BSON_SUBTYPE_BINARY_DEPRECATED) {
+      length_le = BSON_UINT32_TO_LE (length + 4);
+      deprecated_length_le = BSON_UINT32_TO_LE (length);
+
+      return _bson_append (bson,
+                           7,
+                           (1 + key_length + 1 + 4 + 1 + 4 + length),
+                           1,
+                           &type,
+                           key_length,
+                           key,
+                           1,
+                           &gZero,
+                           4,
+                           &length_le,
+                           1,
+                           &subtype8,
+                           4,
+                           &deprecated_length_le,
+                           length,
+                           binary);
+   } else {
+      length_le = BSON_UINT32_TO_LE (length);
+
+      return _bson_append (bson,
+                           6,
+                           (1 + key_length + 1 + 4 + 1 + length),
+                           1,
+                           &type,
+                           key_length,
+                           key,
+                           1,
+                           &gZero,
+                           4,
+                           &length_le,
+                           1,
+                           &subtype8,
+                           length,
+                           binary);
+   }
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_append_bool --
+ *
+ *       Append a new field to @bson with the name @key. The value is
+ *       a boolean indicated by @value.
+ *
+ * Returns:
+ *       true if succesful; otherwise false.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+bson_append_bool (bson_t *bson,    /* IN */
+                  const char *key, /* IN */
+                  int key_length,  /* IN */
+                  bool value)      /* IN */
+{
+   static const uint8_t type = BSON_TYPE_BOOL;
+   uint8_t abyte = !!value;
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+
+   if (key_length < 0) {
+      key_length = (int) strlen (key);
+   }
+
+   return _bson_append (bson,
+                        4,
+                        (1 + key_length + 1 + 1),
+                        1,
+                        &type,
+                        key_length,
+                        key,
+                        1,
+                        &gZero,
+                        1,
+                        &abyte);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_append_code --
+ *
+ *       Append a new field to @bson containing javascript code.
+ *
+ *       @javascript MUST be a zero terminated UTF-8 string. It MUST NOT
+ *       containing embedded \0 characters.
+ *
+ * Returns:
+ *       true if successful; otherwise false.
+ *
+ * Side effects:
+ *       None.
+ *
+ * See also:
+ *       bson_append_code_with_scope().
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+bson_append_code (bson_t *bson,           /* IN */
+                  const char *key,        /* IN */
+                  int key_length,         /* IN */
+                  const char *javascript) /* IN */
+{
+   static const uint8_t type = BSON_TYPE_CODE;
+   uint32_t length;
+   uint32_t length_le;
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+   BSON_ASSERT (javascript);
+
+   if (key_length < 0) {
+      key_length = (int) strlen (key);
+   }
+
+   length = (int) strlen (javascript) + 1;
+   length_le = BSON_UINT32_TO_LE (length);
+
+   return _bson_append (bson,
+                        5,
+                        (1 + key_length + 1 + 4 + length),
+                        1,
+                        &type,
+                        key_length,
+                        key,
+                        1,
+                        &gZero,
+                        4,
+                        &length_le,
+                        length,
+                        javascript);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_append_code_with_scope --
+ *
+ *       Append a new field to @bson containing javascript code with
+ *       supplied scope.
+ *
+ * Returns:
+ *       true if successful; otherwise false.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+bson_append_code_with_scope (bson_t *bson,           /* IN */
+                             const char *key,        /* IN */
+                             int key_length,         /* IN */
+                             const char *javascript, /* IN */
+                             const bson_t *scope)    /* IN */
+{
+   static const uint8_t type = BSON_TYPE_CODEWSCOPE;
+   uint32_t codews_length_le;
+   uint32_t codews_length;
+   uint32_t js_length_le;
+   uint32_t js_length;
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+   BSON_ASSERT (javascript);
+
+   if (scope == NULL) {
+      return bson_append_code (bson, key, key_length, javascript);
+   }
+
+   if (key_length < 0) {
+      key_length = (int) strlen (key);
+   }
+
+   js_length = (int) strlen (javascript) + 1;
+   js_length_le = BSON_UINT32_TO_LE (js_length);
+
+   codews_length = 4 + 4 + js_length + scope->len;
+   codews_length_le = BSON_UINT32_TO_LE (codews_length);
+
+   return _bson_append (bson,
+                        7,
+                        (1 + key_length + 1 + 4 + 4 + js_length + scope->len),
+                        1,
+                        &type,
+                        key_length,
+                        key,
+                        1,
+                        &gZero,
+                        4,
+                        &codews_length_le,
+                        4,
+                        &js_length_le,
+                        js_length,
+                        javascript,
+                        scope->len,
+                        _bson_data (scope));
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_append_dbpointer --
+ *
+ *       This BSON data type is DEPRECATED.
+ *
+ *       Append a BSON dbpointer field to @bson.
+ *
+ * Returns:
+ *       true if successful; otherwise false.
+ *
+ * Side effects:
+ *       None.
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+bson_append_dbpointer (bson_t *bson,           /* IN */
+                       const char *key,        /* IN */
+                       int key_length,         /* IN */
+                       const char *collection, /* IN */
+                       const bson_oid_t *oid)
+{
+   static const uint8_t type = BSON_TYPE_DBPOINTER;
+   uint32_t length;
+   uint32_t length_le;
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+   BSON_ASSERT (collection);
+   BSON_ASSERT (oid);
+
+   if (key_length < 0) {
+      key_length = (int) strlen (key);
+   }
+
+   length = (int) strlen (collection) + 1;
+   length_le = BSON_UINT32_TO_LE (length);
+
+   return _bson_append (bson,
+                        6,
+                        (1 + key_length + 1 + 4 + length + 12),
+                        1,
+                        &type,
+                        key_length,
+                        key,
+                        1,
+                        &gZero,
+                        4,
+                        &length_le,
+                        length,
+                        collection,
+                        12,
+                        oid);
+}
+
+
+/*
+ *--------------------------------------------------------------------------
+ *
+ * bson_append_document --
+ *
+ *       Append a new field to @bson containing a BSON document.
+ *
+ *       In general, using bson_append_document_begin() results in faster
+ *       code and less memory fragmentation.
+ *
+ * Returns:
+ *       true if successful; otherwise false.
+ *
+ * Side effects:
+ *       None.
+ *
+ * See also:
+ *       bson_append_document_begin().
+ *
+ *--------------------------------------------------------------------------
+ */
+
+bool
+bson_append_document (bson_t *bson,        /* IN */
+                      const char *key,     /* IN */
+                      int key_length,      /* IN */
+                      const bson_t *value) /* IN */
+{
+   static const uint8_t type = BSON_TYPE_DOCUMENT;
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+   BSON_ASSERT (value);
+
+   if (key_length < 0) {
+      key_length = (int) strlen (key);
+   }
+
+   return _bson_append (bson,
+                        4,
+                        (1 + key_length + 1 + value->len),
+                        1,
+                        &type,
+                        key_length,
+                        key,
+                        1,
+                        &gZero,
+                        value->len,
+                        _bson_data (value));
+}
+
+
+bool
+bson_append_double (bson_t *bson, const char *key, int key_length, double value)
+{
+   static const uint8_t type = BSON_TYPE_DOUBLE;
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+
+   if (key_length < 0) {
+      key_length = (int) strlen (key);
+   }
+
+#if BSON_BYTE_ORDER == BSON_BIG_ENDIAN
+   value = BSON_DOUBLE_TO_LE (value);
+#endif
+
+   return _bson_append (bson,
+                        4,
+                        (1 + key_length + 1 + 8),
+                        1,
+                        &type,
+                        key_length,
+                        key,
+                        1,
+                        &gZero,
+                        8,
+                        &value);
+}
+
+
+bool
+bson_append_int32 (bson_t *bson, const char *key, int key_length, int32_t value)
+{
+   static const uint8_t type = BSON_TYPE_INT32;
+   uint32_t value_le;
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+
+   if (key_length < 0) {
+      key_length = (int) strlen (key);
+   }
+
+   value_le = BSON_UINT32_TO_LE (value);
+
+   return _bson_append (bson,
+                        4,
+                        (1 + key_length + 1 + 4),
+                        1,
+                        &type,
+                        key_length,
+                        key,
+                        1,
+                        &gZero,
+                        4,
+                        &value_le);
+}
+
+
+bool
+bson_append_int64 (bson_t *bson, const char *key, int key_length, int64_t value)
+{
+   static const uint8_t type = BSON_TYPE_INT64;
+   uint64_t value_le;
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+
+   if (key_length < 0) {
+      key_length = (int) strlen (key);
+   }
+
+   value_le = BSON_UINT64_TO_LE (value);
+
+   return _bson_append (bson,
+                        4,
+                        (1 + key_length + 1 + 8),
+                        1,
+                        &type,
+                        key_length,
+                        key,
+                        1,
+                        &gZero,
+                        8,
+                        &value_le);
+}
+
+
+bool
+bson_append_decimal128 (bson_t *bson,
+                        const char *key,
+                        int key_length,
+                        const bson_decimal128_t *value)
+{
+   static const uint8_t type = BSON_TYPE_DECIMAL128;
+   uint64_t value_le[2];
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+   BSON_ASSERT (value);
+
+   if (key_length < 0) {
+      key_length = (int) strlen (key);
+   }
+
+   value_le[0] = BSON_UINT64_TO_LE (value->low);
+   value_le[1] = BSON_UINT64_TO_LE (value->high);
+
+   return _bson_append (bson,
+                        4,
+                        (1 + key_length + 1 + 16),
+                        1,
+                        &type,
+                        key_length,
+                        key,
+                        1,
+                        &gZero,
+                        16,
+                        value_le);
+}
+
+
+bool
+bson_append_iter (bson_t *bson,
+                  const char *key,
+                  int key_length,
+                  const bson_iter_t *iter)
+{
+   bool ret = false;
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (iter);
+
+   if (!key) {
+      key = bson_iter_key (iter);
+      key_length = -1;
+   }
+
+   switch (bson_iter_type_unsafe (iter)) {
+   case BSON_TYPE_EOD:
+      return false;
+   case BSON_TYPE_DOUBLE:
+      ret = bson_append_double (bson, key, key_length, bson_iter_double (iter));
+      break;
+   case BSON_TYPE_UTF8: {
+      uint32_t len = 0;
+      const char *str;
+
+      str = bson_iter_utf8 (iter, &len);
+      ret = bson_append_utf8 (bson, key, key_length, str, len);
+   } break;
+   case BSON_TYPE_DOCUMENT: {
+      const uint8_t *buf = NULL;
+      uint32_t len = 0;
+      bson_t doc;
+
+      bson_iter_document (iter, &len, &buf);
+
+      if (bson_init_static (&doc, buf, len)) {
+         ret = bson_append_document (bson, key, key_length, &doc);
+         bson_destroy (&doc);
+      }
+   } break;
+   case BSON_TYPE_ARRAY: {
+      const uint8_t *buf = NULL;
+      uint32_t len = 0;
+      bson_t doc;
+
+      bson_iter_array (iter, &len, &buf);
+
+      if (bson_init_static (&doc, buf, len)) {
+         ret = bson_append_array (bson, key, key_length, &doc);
+         bson_destroy (&doc);
+      }
+   } break;
+   case BSON_TYPE_BINARY: {
+      const uint8_t *binary = NULL;
+      bson_subtype_t subtype = BSON_SUBTYPE_BINARY;
+      uint32_t len = 0;
+
+      bson_iter_binary (iter, &subtype, &len, &binary);
+      ret = bson_append_binary (bson, key, key_length, subtype, binary, len);
+   } break;
+   case BSON_TYPE_UNDEFINED:
+      ret = bson_append_undefined (bson, key, key_length);
+      break;
+   case BSON_TYPE_OID:
+      ret = bson_append_oid (bson, key, key_length, bson_iter_oid (iter));
+      break;
+   case BSON_TYPE_BOOL:
+      ret = bson_append_bool (bson, key, key_length, bson_iter_bool (iter));
+      break;
+   case BSON_TYPE_DATE_TIME:
+      ret = bson_append_date_time (
+         bson, key, key_length, bson_iter_date_time (iter));
+      break;
+   case BSON_TYPE_NULL:
+      ret = bson_append_null (bson, key, key_length);
+      break;
+   case BSON_TYPE_REGEX: {
+      const char *regex;
+      const char *options;
+
+      regex = bson_iter_regex (iter, &options);
+      ret = bson_append_regex (bson, key, key_length, regex, options);
+   } break;
+   case BSON_TYPE_DBPOINTER: {
+      const bson_oid_t *oid;
+      uint32_t len;
+      const char *collection;
+
+      bson_iter_dbpointer (iter, &len, &collection, &oid);
+      ret = bson_append_dbpointer (bson, key, key_length, collection, oid);
+   } break;
+   case BSON_TYPE_CODE: {
+      uint32_t len;
+      const char *code;
+
+      code = bson_iter_code (iter, &len);
+      ret = bson_append_code (bson, key, key_length, code);
+   } break;
+   case BSON_TYPE_SYMBOL: {
+      uint32_t len;
+      const char *symbol;
+
+      symbol = bson_iter_symbol (iter, &len);
+      ret = bson_append_symbol (bson, key, key_length, symbol, len);
+   } break;
+   case BSON_TYPE_CODEWSCOPE: {
+      const uint8_t *scope = NULL;
+      uint32_t scope_len = 0;
+      uint32_t len = 0;
+      const char *javascript = NULL;
+      bson_t doc;
+
+      javascript = bson_iter_codewscope (iter, &len, &scope_len, &scope);
+
+      if (bson_init_static (&doc, scope, scope_len)) {
+         ret = bson_append_code_with_scope (
+            bson, key, key_length, javascript, &doc);
+         bson_destroy (&doc);
+      }
+   } break;
+   case BSON_TYPE_INT32:
+      ret = bson_append_int32 (bson, key, key_length, bson_iter_int32 (iter));
+      break;
+   case BSON_TYPE_TIMESTAMP: {
+      uint32_t ts;
+      uint32_t inc;
+
+      bson_iter_timestamp (iter, &ts, &inc);
+      ret = bson_append_timestamp (bson, key, key_length, ts, inc);
+   } break;
+   case BSON_TYPE_INT64:
+      ret = bson_append_int64 (bson, key, key_length, bson_iter_int64 (iter));
+      break;
+   case BSON_TYPE_DECIMAL128: {
+      bson_decimal128_t dec;
+
+      if (!bson_iter_decimal128 (iter, &dec)) {
+         return false;
+      }
+
+      ret = bson_append_decimal128 (bson, key, key_length, &dec);
+   } break;
+   case BSON_TYPE_MAXKEY:
+      ret = bson_append_maxkey (bson, key, key_length);
+      break;
+   case BSON_TYPE_MINKEY:
+      ret = bson_append_minkey (bson, key, key_length);
+      break;
+   default:
+      break;
+   }
+
+   return ret;
+}
+
+
+bool
+bson_append_maxkey (bson_t *bson, const char *key, int key_length)
+{
+   static const uint8_t type = BSON_TYPE_MAXKEY;
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+
+   if (key_length < 0) {
+      key_length = (int) strlen (key);
+   }
+
+   return _bson_append (
+      bson, 3, (1 + key_length + 1), 1, &type, key_length, key, 1, &gZero);
+}
+
+
+bool
+bson_append_minkey (bson_t *bson, const char *key, int key_length)
+{
+   static const uint8_t type = BSON_TYPE_MINKEY;
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+
+   if (key_length < 0) {
+      key_length = (int) strlen (key);
+   }
+
+   return _bson_append (
+      bson, 3, (1 + key_length + 1), 1, &type, key_length, key, 1, &gZero);
+}
+
+
+bool
+bson_append_null (bson_t *bson, const char *key, int key_length)
+{
+   static const uint8_t type = BSON_TYPE_NULL;
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+
+   if (key_length < 0) {
+      key_length = (int) strlen (key);
+   }
+
+   return _bson_append (
+      bson, 3, (1 + key_length + 1), 1, &type, key_length, key, 1, &gZero);
+}
+
+
+bool
+bson_append_oid (bson_t *bson,
+                 const char *key,
+                 int key_length,
+                 const bson_oid_t *value)
+{
+   static const uint8_t type = BSON_TYPE_OID;
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+   BSON_ASSERT (value);
+
+   if (key_length < 0) {
+      key_length = (int) strlen (key);
+   }
+
+   return _bson_append (bson,
+                        4,
+                        (1 + key_length + 1 + 12),
+                        1,
+                        &type,
+                        key_length,
+                        key,
+                        1,
+                        &gZero,
+                        12,
+                        value);
+}
+
+
+bool
+bson_append_regex (bson_t *bson,
+                   const char *key,
+                   int key_length,
+                   const char *regex,
+                   const char *options)
+{
+   static const uint8_t type = BSON_TYPE_REGEX;
+   uint32_t regex_len;
+   uint32_t options_len;
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+
+   if (key_length < 0) {
+      key_length = (int) strlen (key);
+   }
+
+   if (!regex) {
+      regex = "";
+   }
+
+   if (!options) {
+      options = "";
+   }
+
+   regex_len = (int) strlen (regex) + 1;
+   options_len = (int) strlen (options) + 1;
+
+   return _bson_append (bson,
+                        5,
+                        (1 + key_length + 1 + regex_len + options_len),
+                        1,
+                        &type,
+                        key_length,
+                        key,
+                        1,
+                        &gZero,
+                        regex_len,
+                        regex,
+                        options_len,
+                        options);
+}
+
+
+bool
+bson_append_utf8 (
+   bson_t *bson, const char *key, int key_length, const char *value, int length)
+{
+   static const uint8_t type = BSON_TYPE_UTF8;
+   uint32_t length_le;
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+
+   if (BSON_UNLIKELY (!value)) {
+      return bson_append_null (bson, key, key_length);
+   }
+
+   if (BSON_UNLIKELY (key_length < 0)) {
+      key_length = (int) strlen (key);
+   }
+
+   if (BSON_UNLIKELY (length < 0)) {
+      length = (int) strlen (value);
+   }
+
+   length_le = BSON_UINT32_TO_LE (length + 1);
+
+   return _bson_append (bson,
+                        6,
+                        (1 + key_length + 1 + 4 + length + 1),
+                        1,
+                        &type,
+                        key_length,
+                        key,
+                        1,
+                        &gZero,
+                        4,
+                        &length_le,
+                        length,
+                        value,
+                        1,
+                        &gZero);
+}
+
+
+bool
+bson_append_symbol (
+   bson_t *bson, const char *key, int key_length, const char *value, int length)
+{
+   static const uint8_t type = BSON_TYPE_SYMBOL;
+   uint32_t length_le;
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+
+   if (!value) {
+      return bson_append_null (bson, key, key_length);
+   }
+
+   if (key_length < 0) {
+      key_length = (int) strlen (key);
+   }
+
+   if (length < 0) {
+      length = (int) strlen (value);
+   }
+
+   length_le = BSON_UINT32_TO_LE (length + 1);
+
+   return _bson_append (bson,
+                        6,
+                        (1 + key_length + 1 + 4 + length + 1),
+                        1,
+                        &type,
+                        key_length,
+                        key,
+                        1,
+                        &gZero,
+                        4,
+                        &length_le,
+                        length,
+                        value,
+                        1,
+                        &gZero);
+}
+
+
+bool
+bson_append_time_t (bson_t *bson, const char *key, int key_length, time_t value)
+{
+#ifdef BSON_OS_WIN32
+   struct timeval tv = {(long) value, 0};
+#else
+   struct timeval tv = {value, 0};
+#endif
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+
+   return bson_append_timeval (bson, key, key_length, &tv);
+}
+
+
+bool
+bson_append_timestamp (bson_t *bson,
+                       const char *key,
+                       int key_length,
+                       uint32_t timestamp,
+                       uint32_t increment)
+{
+   static const uint8_t type = BSON_TYPE_TIMESTAMP;
+   uint64_t value;
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+
+   if (key_length < 0) {
+      key_length = (int) strlen (key);
+   }
+
+   value = BSON_UINT64_TO_LE (_int64_timestamp (timestamp, increment));
+
+   return _bson_append (bson,
+                        4,
+                        (1 + key_length + 1 + 8),
+                        1,
+                        &type,
+                        key_length,
+                        key,
+                        1,
+                        &gZero,
+                        8,
+                        &value);
+}
+
+
+bool
+bson_append_now_utc (bson_t *bson, const char *key, int key_length)
+{
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+   BSON_ASSERT (key_length >= -1);
+
+   return bson_append_time_t (bson, key, key_length, time (NULL));
+}
+
+
+bool
+bson_append_date_time (bson_t *bson,
+                       const char *key,
+                       int key_length,
+                       int64_t value)
+{
+   static const uint8_t type = BSON_TYPE_DATE_TIME;
+   uint64_t value_le;
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+
+   if (key_length < 0) {
+      key_length = (int) strlen (key);
+   }
+
+   value_le = BSON_UINT64_TO_LE (value);
+
+   return _bson_append (bson,
+                        4,
+                        (1 + key_length + 1 + 8),
+                        1,
+                        &type,
+                        key_length,
+                        key,
+                        1,
+                        &gZero,
+                        8,
+                        &value_le);
+}
+
+
+bool
+bson_append_timeval (bson_t *bson,
+                     const char *key,
+                     int key_length,
+                     struct timeval *value)
+{
+   uint64_t unix_msec;
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+   BSON_ASSERT (value);
+
+   unix_msec =
+      (((uint64_t) value->tv_sec) * 1000UL) + (value->tv_usec / 1000UL);
+   return bson_append_date_time (bson, key, key_length, unix_msec);
+}
+
+
+bool
+bson_append_undefined (bson_t *bson, const char *key, int key_length)
+{
+   static const uint8_t type = BSON_TYPE_UNDEFINED;
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+
+   if (key_length < 0) {
+      key_length = (int) strlen (key);
+   }
+
+   return _bson_append (
+      bson, 3, (1 + key_length + 1), 1, &type, key_length, key, 1, &gZero);
+}
+
+
+bool
+bson_append_value (bson_t *bson,
+                   const char *key,
+                   int key_length,
+                   const bson_value_t *value)
+{
+   bson_t local;
+   bool ret = false;
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+   BSON_ASSERT (value);
+
+   switch (value->value_type) {
+   case BSON_TYPE_DOUBLE:
+      ret = bson_append_double (bson, key, key_length, value->value.v_double);
+      break;
+   case BSON_TYPE_UTF8:
+      ret = bson_append_utf8 (bson,
+                              key,
+                              key_length,
+                              value->value.v_utf8.str,
+                              value->value.v_utf8.len);
+      break;
+   case BSON_TYPE_DOCUMENT:
+      if (bson_init_static (
+             &local, value->value.v_doc.data, value->value.v_doc.data_len)) {
+         ret = bson_append_document (bson, key, key_length, &local);
+         bson_destroy (&local);
+      }
+      break;
+   case BSON_TYPE_ARRAY:
+      if (bson_init_static (
+             &local, value->value.v_doc.data, value->value.v_doc.data_len)) {
+         ret = bson_append_array (bson, key, key_length, &local);
+         bson_destroy (&local);
+      }
+      break;
+   case BSON_TYPE_BINARY:
+      ret = bson_append_binary (bson,
+                                key,
+                                key_length,
+                                value->value.v_binary.subtype,
+                                value->value.v_binary.data,
+                                value->value.v_binary.data_len);
+      break;
+   case BSON_TYPE_UNDEFINED:
+      ret = bson_append_undefined (bson, key, key_length);
+      break;
+   case BSON_TYPE_OID:
+      ret = bson_append_oid (bson, key, key_length, &value->value.v_oid);
+      break;
+   case BSON_TYPE_BOOL:
+      ret = bson_append_bool (bson, key, key_length, value->value.v_bool);
+      break;
+   case BSON_TYPE_DATE_TIME:
+      ret =
+         bson_append_date_time (bson, key, key_length, value->value.v_datetime);
+      break;
+   case BSON_TYPE_NULL:
+      ret = bson_append_null (bson, key, key_length);
+      break;
+   case BSON_TYPE_REGEX:
+      ret = bson_append_regex (bson,
+                               key,
+                               key_length,
+                               value->value.v_regex.regex,
+                               value->value.v_regex.options);
+      break;
+   case BSON_TYPE_DBPOINTER:
+      ret = bson_append_dbpointer (bson,
+                                   key,
+                                   key_length,
+                                   value->value.v_dbpointer.collection,
+                                   &value->value.v_dbpointer.oid);
+      break;
+   case BSON_TYPE_CODE:
+      ret = bson_append_code (bson, key, key_length, value->value.v_code.code);
+      break;
+   case BSON_TYPE_SYMBOL:
+      ret = bson_append_symbol (bson,
+                                key,
+                                key_length,
+                                value->value.v_symbol.symbol,
+                                value->value.v_symbol.len);
+      break;
+   case BSON_TYPE_CODEWSCOPE:
+      if (bson_init_static (&local,
+                            value->value.v_codewscope.scope_data,
+                            value->value.v_codewscope.scope_len)) {
+         ret = bson_append_code_with_scope (
+            bson, key, key_length, value->value.v_codewscope.code, &local);
+         bson_destroy (&local);
+      }
+      break;
+   case BSON_TYPE_INT32:
+      ret = bson_append_int32 (bson, key, key_length, value->value.v_int32);
+      break;
+   case BSON_TYPE_TIMESTAMP:
+      ret = bson_append_timestamp (bson,
+                                   key,
+                                   key_length,
+                                   value->value.v_timestamp.timestamp,
+                                   value->value.v_timestamp.increment);
+      break;
+   case BSON_TYPE_INT64:
+      ret = bson_append_int64 (bson, key, key_length, value->value.v_int64);
+      break;
+   case BSON_TYPE_DECIMAL128:
+      ret = bson_append_decimal128 (
+         bson, key, key_length, &(value->value.v_decimal128));
+      break;
+   case BSON_TYPE_MAXKEY:
+      ret = bson_append_maxkey (bson, key, key_length);
+      break;
+   case BSON_TYPE_MINKEY:
+      ret = bson_append_minkey (bson, key, key_length);
+      break;
+   case BSON_TYPE_EOD:
+   default:
+      break;
+   }
+
+   return ret;
+}
+
+
+void
+bson_init (bson_t *bson)
+{
+   bson_impl_inline_t *impl = (bson_impl_inline_t *) bson;
+
+   BSON_ASSERT (bson);
+
+   impl->flags = BSON_FLAG_INLINE | BSON_FLAG_STATIC;
+   impl->len = 5;
+   impl->data[0] = 5;
+   impl->data[1] = 0;
+   impl->data[2] = 0;
+   impl->data[3] = 0;
+   impl->data[4] = 0;
+}
+
+
+void
+bson_reinit (bson_t *bson)
+{
+   uint8_t *data;
+
+   BSON_ASSERT (bson);
+
+   data = _bson_data (bson);
+
+   bson->len = 5;
+
+   data[0] = 5;
+   data[1] = 0;
+   data[2] = 0;
+   data[3] = 0;
+   data[4] = 0;
+}
+
+
+bool
+bson_init_static (bson_t *bson, const uint8_t *data, size_t length)
+{
+   bson_impl_alloc_t *impl = (bson_impl_alloc_t *) bson;
+   uint32_t len_le;
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (data);
+
+   if ((length < 5) || (length > INT_MAX)) {
+      return false;
+   }
+
+   memcpy (&len_le, data, sizeof (len_le));
+
+   if ((size_t) BSON_UINT32_FROM_LE (len_le) != length) {
+      return false;
+   }
+
+   if (data[length - 1]) {
+      return false;
+   }
+
+   impl->flags = BSON_FLAG_STATIC | BSON_FLAG_RDONLY;
+   impl->len = (uint32_t) length;
+   impl->parent = NULL;
+   impl->depth = 0;
+   impl->buf = &impl->alloc;
+   impl->buflen = &impl->alloclen;
+   impl->offset = 0;
+   impl->alloc = (uint8_t *) data;
+   impl->alloclen = length;
+   impl->realloc = NULL;
+   impl->realloc_func_ctx = NULL;
+
+   return true;
+}
+
+
+bson_t *
+bson_new (void)
+{
+   bson_impl_inline_t *impl;
+   bson_t *bson;
+
+   bson = bson_malloc (sizeof *bson);
+
+   impl = (bson_impl_inline_t *) bson;
+   impl->flags = BSON_FLAG_INLINE;
+   impl->len = 5;
+   impl->data[0] = 5;
+   impl->data[1] = 0;
+   impl->data[2] = 0;
+   impl->data[3] = 0;
+   impl->data[4] = 0;
+
+   return bson;
+}
+
+
+bson_t *
+bson_sized_new (size_t size)
+{
+   bson_impl_alloc_t *impl_a;
+   bson_t *b;
+
+   BSON_ASSERT (size <= INT32_MAX);
+
+   b = bson_malloc (sizeof *b);
+   impl_a = (bson_impl_alloc_t *) b;
+
+   if (size <= BSON_INLINE_DATA_SIZE) {
+      bson_init (b);
+      b->flags &= ~BSON_FLAG_STATIC;
+   } else {
+      impl_a->flags = BSON_FLAG_NONE;
+      impl_a->len = 5;
+      impl_a->parent = NULL;
+      impl_a->depth = 0;
+      impl_a->buf = &impl_a->alloc;
+      impl_a->buflen = &impl_a->alloclen;
+      impl_a->offset = 0;
+      impl_a->alloclen = BSON_MAX (5, size);
+      impl_a->alloc = bson_malloc (impl_a->alloclen);
+      impl_a->alloc[0] = 5;
+      impl_a->alloc[1] = 0;
+      impl_a->alloc[2] = 0;
+      impl_a->alloc[3] = 0;
+      impl_a->alloc[4] = 0;
+      impl_a->realloc = bson_realloc_ctx;
+      impl_a->realloc_func_ctx = NULL;
+   }
+
+   return b;
+}
+
+
+bson_t *
+bson_new_from_data (const uint8_t *data, size_t length)
+{
+   uint32_t len_le;
+   bson_t *bson;
+
+   BSON_ASSERT (data);
+
+   if ((length < 5) || (length > INT_MAX) || data[length - 1]) {
+      return NULL;
+   }
+
+   memcpy (&len_le, data, sizeof (len_le));
+
+   if (length != (size_t) BSON_UINT32_FROM_LE (len_le)) {
+      return NULL;
+   }
+
+   bson = bson_sized_new (length);
+   memcpy (_bson_data (bson), data, length);
+   bson->len = (uint32_t) length;
+
+   return bson;
+}
+
+
+bson_t *
+bson_new_from_buffer (uint8_t **buf,
+                      size_t *buf_len,
+                      bson_realloc_func realloc_func,
+                      void *realloc_func_ctx)
+{
+   bson_impl_alloc_t *impl;
+   uint32_t len_le;
+   uint32_t length;
+   bson_t *bson;
+
+   BSON_ASSERT (buf);
+   BSON_ASSERT (buf_len);
+
+   if (!realloc_func) {
+      realloc_func = bson_realloc_ctx;
+   }
+
+   bson = bson_malloc0 (sizeof *bson);
+   impl = (bson_impl_alloc_t *) bson;
+
+   if (!*buf) {
+      length = 5;
+      len_le = BSON_UINT32_TO_LE (length);
+      *buf_len = 5;
+      *buf = realloc_func (*buf, *buf_len, realloc_func_ctx);
+      memcpy (*buf, &len_le, sizeof (len_le));
+      (*buf)[4] = '\0';
+   } else {
+      if ((*buf_len < 5) || (*buf_len > INT_MAX)) {
+         bson_free (bson);
+         return NULL;
+      }
+
+      memcpy (&len_le, *buf, sizeof (len_le));
+      length = BSON_UINT32_FROM_LE (len_le);
+   }
+
+   if ((*buf)[length - 1]) {
+      bson_free (bson);
+      return NULL;
+   }
+
+   impl->flags = BSON_FLAG_NO_FREE;
+   impl->len = length;
+   impl->buf = buf;
+   impl->buflen = buf_len;
+   impl->realloc = realloc_func;
+   impl->realloc_func_ctx = realloc_func_ctx;
+
+   return bson;
+}
+
+
+bson_t *
+bson_copy (const bson_t *bson)
+{
+   const uint8_t *data;
+
+   BSON_ASSERT (bson);
+
+   data = _bson_data (bson);
+   return bson_new_from_data (data, bson->len);
+}
+
+
+void
+bson_copy_to (const bson_t *src, bson_t *dst)
+{
+   const uint8_t *data;
+   bson_impl_alloc_t *adst;
+   size_t len;
+
+   BSON_ASSERT (src);
+   BSON_ASSERT (dst);
+
+   if ((src->flags & BSON_FLAG_INLINE)) {
+      memcpy (dst, src, sizeof *dst);
+      dst->flags = (BSON_FLAG_STATIC | BSON_FLAG_INLINE);
+      return;
+   }
+
+   data = _bson_data (src);
+   len = bson_next_power_of_two ((size_t) src->len);
+
+   adst = (bson_impl_alloc_t *) dst;
+   adst->flags = BSON_FLAG_STATIC;
+   adst->len = src->len;
+   adst->parent = NULL;
+   adst->depth = 0;
+   adst->buf = &adst->alloc;
+   adst->buflen = &adst->alloclen;
+   adst->offset = 0;
+   adst->alloc = bson_malloc (len);
+   adst->alloclen = len;
+   adst->realloc = bson_realloc_ctx;
+   adst->realloc_func_ctx = NULL;
+   memcpy (adst->alloc, data, src->len);
+}
+
+
+static bool
+should_ignore (const char *first_exclude, va_list args, const char *name)
+{
+   bool ret = false;
+   const char *exclude = first_exclude;
+   va_list args_copy;
+
+   va_copy (args_copy, args);
+
+   do {
+      if (!strcmp (name, exclude)) {
+         ret = true;
+         break;
+      }
+   } while ((exclude = va_arg (args_copy, const char *)));
+
+   va_end (args_copy);
+
+   return ret;
+}
+
+
+static void
+_bson_copy_to_excluding_va (const bson_t *src,
+                            bson_t *dst,
+                            const char *first_exclude,
+                            va_list args)
+{
+   bson_iter_t iter;
+
+   if (bson_iter_init (&iter, src)) {
+      while (bson_iter_next (&iter)) {
+         if (!should_ignore (first_exclude, args, bson_iter_key (&iter))) {
+            if (!bson_append_iter (dst, NULL, 0, &iter)) {
+               /*
+                * This should not be able to happen since we are copying
+                * from within a valid bson_t.
+                */
+               BSON_ASSERT (false);
+               return;
+            }
+         }
+      }
+   }
+}
+
+
+void
+bson_copy_to_excluding (const bson_t *src,
+                        bson_t *dst,
+                        const char *first_exclude,
+                        ...)
+{
+   va_list args;
+
+   BSON_ASSERT (src);
+   BSON_ASSERT (dst);
+   BSON_ASSERT (first_exclude);
+
+   bson_init (dst);
+
+   va_start (args, first_exclude);
+   _bson_copy_to_excluding_va (src, dst, first_exclude, args);
+   va_end (args);
+}
+
+void
+bson_copy_to_excluding_noinit (const bson_t *src,
+                               bson_t *dst,
+                               const char *first_exclude,
+                               ...)
+{
+   va_list args;
+
+   BSON_ASSERT (src);
+   BSON_ASSERT (dst);
+   BSON_ASSERT (first_exclude);
+
+   va_start (args, first_exclude);
+   _bson_copy_to_excluding_va (src, dst, first_exclude, args);
+   va_end (args);
+}
+
+
+void
+bson_destroy (bson_t *bson)
+{
+   BSON_ASSERT (bson);
+
+   if (!(bson->flags &
+         (BSON_FLAG_RDONLY | BSON_FLAG_INLINE | BSON_FLAG_NO_FREE))) {
+      bson_free (*((bson_impl_alloc_t *) bson)->buf);
+   }
+
+   if (!(bson->flags & BSON_FLAG_STATIC)) {
+      bson_free (bson);
+   }
+}
+
+
+uint8_t *
+bson_reserve_buffer (bson_t *bson, uint32_t size)
+{
+   if (bson->flags &
+       (BSON_FLAG_CHILD | BSON_FLAG_IN_CHILD | BSON_FLAG_RDONLY)) {
+      return NULL;
+   }
+
+   if (!_bson_grow (bson, size)) {
+      return NULL;
+   }
+
+   if (bson->flags & BSON_FLAG_INLINE) {
+      /* bson_grow didn't spill over */
+      ((bson_impl_inline_t *) bson)->len = size;
+   } else {
+      ((bson_impl_alloc_t *) bson)->len = size;
+   }
+
+   return _bson_data (bson);
+}
+
+
+bool
+bson_steal (bson_t *dst, bson_t *src)
+{
+   bson_impl_inline_t *src_inline;
+   bson_impl_inline_t *dst_inline;
+   bson_impl_alloc_t *alloc;
+
+   BSON_ASSERT (dst);
+   BSON_ASSERT (src);
+
+   bson_init (dst);
+
+   if (src->flags & (BSON_FLAG_CHILD | BSON_FLAG_IN_CHILD | BSON_FLAG_RDONLY)) {
+      return false;
+   }
+
+   if (src->flags & BSON_FLAG_INLINE) {
+      src_inline = (bson_impl_inline_t *) src;
+      dst_inline = (bson_impl_inline_t *) dst;
+      dst_inline->len = src_inline->len;
+      memcpy (dst_inline->data, src_inline->data, sizeof src_inline->data);
+
+      /* for consistency, src is always invalid after steal, even if inline */
+      src->len = 0;
+   } else {
+      memcpy (dst, src, sizeof (bson_t));
+      alloc = (bson_impl_alloc_t *) dst;
+      alloc->flags |= BSON_FLAG_STATIC;
+      alloc->buf = &alloc->alloc;
+      alloc->buflen = &alloc->alloclen;
+   }
+
+   if (!(src->flags & BSON_FLAG_STATIC)) {
+      bson_free (src);
+   } else {
+      /* src is invalid after steal */
+      src->len = 0;
+   }
+
+   return true;
+}
+
+
+uint8_t *
+bson_destroy_with_steal (bson_t *bson, bool steal, uint32_t *length)
+{
+   uint8_t *ret = NULL;
+
+   BSON_ASSERT (bson);
+
+   if (length) {
+      *length = bson->len;
+   }
+
+   if (!steal) {
+      bson_destroy (bson);
+      return NULL;
+   }
+
+   if ((bson->flags &
+        (BSON_FLAG_CHILD | BSON_FLAG_IN_CHILD | BSON_FLAG_RDONLY))) {
+      /* Do nothing */
+   } else if ((bson->flags & BSON_FLAG_INLINE)) {
+      bson_impl_inline_t *inl;
+
+      inl = (bson_impl_inline_t *) bson;
+      ret = bson_malloc (bson->len);
+      memcpy (ret, inl->data, bson->len);
+   } else {
+      bson_impl_alloc_t *alloc;
+
+      alloc = (bson_impl_alloc_t *) bson;
+      ret = *alloc->buf;
+      *alloc->buf = NULL;
+   }
+
+   bson_destroy (bson);
+
+   return ret;
+}
+
+
+const uint8_t *
+bson_get_data (const bson_t *bson)
+{
+   BSON_ASSERT (bson);
+
+   return _bson_data (bson);
+}
+
+
+uint32_t
+bson_count_keys (const bson_t *bson)
+{
+   uint32_t count = 0;
+   bson_iter_t iter;
+
+   BSON_ASSERT (bson);
+
+   if (bson_iter_init (&iter, bson)) {
+      while (bson_iter_next (&iter)) {
+         count++;
+      }
+   }
+
+   return count;
+}
+
+
+bool
+bson_has_field (const bson_t *bson, const char *key)
+{
+   bson_iter_t iter;
+   bson_iter_t child;
+
+   BSON_ASSERT (bson);
+   BSON_ASSERT (key);
+
+   if (NULL != strchr (key, '.')) {
+      return (bson_iter_init (&iter, bson) &&
+              bson_iter_find_descendant (&iter, key, &child));
+   }
+
+   return bson_iter_init_find (&iter, bson, key);
+}
+
+
+int
+bson_compare (const bson_t *bson, const bson_t *other)
+{
+   const uint8_t *data1;
+   const uint8_t *data2;
+   size_t len1;
+   size_t len2;
+   int64_t ret;
+
+   data1 = _bson_data (bson) + 4;
+   len1 = bson->len - 4;
+
+   data2 = _bson_data (other) + 4;
+   len2 = other->len - 4;
+
+   if (len1 == len2) {
+      return memcmp (data1, data2, len1);
+   }
+
+   ret = memcmp (data1, data2, BSON_MIN (len1, len2));
+
+   if (ret == 0) {
+      ret = (int64_t) (len1 - len2);
+   }
+
+   return (ret < 0) ? -1 : (ret > 0);
+}
+
+
+bool
+bson_equal (const bson_t *bson, const bson_t *other)
+{
+   return !bson_compare (bson, other);
+}
+
+
+static bool
+_bson_as_json_visit_utf8 (const bson_iter_t *iter,
+                          const char *key,
+                          size_t v_utf8_len,
+                          const char *v_utf8,
+                          void *data)
+{
+   bson_json_state_t *state = data;
+   char *escaped;
+
+   escaped = bson_utf8_escape_for_json (v_utf8, v_utf8_len);
+
+   if (escaped) {
+      bson_string_append (state->str, "\"");
+      bson_string_append (state->str, escaped);
+      bson_string_append (state->str, "\"");
+      bson_free (escaped);
+      return false;
+   }
+
+   return true;
+}
+
+
+static bool
+_bson_as_extended_json_visit_int32 (const bson_iter_t *iter,
+                                    const char *key,
+                                    int32_t v_int32,
+                                    void *data)
+{
+   bson_json_state_t *state = data;
+
+   bson_string_append_printf (
+      state->str, "{ \"$numberInt\" : \"%" PRId32 "\" }", v_int32);
+
+   return false;
+}
+
+
+static bool
+_bson_as_json_visit_int32 (const bson_iter_t *iter,
+                           const char *key,
+                           int32_t v_int32,
+                           void *data)
+{
+   bson_json_state_t *state = data;
+
+   bson_string_append_printf (state->str, "%" PRId32, v_int32);
+
+   return false;
+}
+
+
+static bool
+_bson_as_extended_json_visit_int64 (const bson_iter_t *iter,
+                                    const char *key,
+                                    int64_t v_int64,
+                                    void *data)
+{
+   bson_json_state_t *state = data;
+
+   bson_string_append_printf (
+      state->str, "{ \"$numberLong\" : \"%" PRId64 "\"}", v_int64);
+
+   return false;
+}
+
+
+static bool
+_bson_as_json_visit_int64 (const bson_iter_t *iter,
+                           const char *key,
+                           int64_t v_int64,
+                           void *data)
+{
+   bson_json_state_t *state = data;
+
+   bson_string_append_printf (state->str, "%" PRId64, v_int64);
+
+   return false;
+}
+
+
+static bool
+_bson_as_json_visit_decimal128 (const bson_iter_t *iter,
+                                const char *key,
+                                const bson_decimal128_t *value,
+                                void *data)
+{
+   bson_json_state_t *state = data;
+   char decimal128_string[BSON_DECIMAL128_STRING];
+   bson_decimal128_to_string (value, decimal128_string);
+
+   bson_string_append (state->str, "{ \"$numberDecimal\" : \"");
+   bson_string_append (state->str, decimal128_string);
+   bson_string_append (state->str, "\" }");
+
+   return false;
+}
+
+
+static bool
+_bson_as_json_visit_double_common (const bson_iter_t *iter,
+                                   const char *key,
+                                   double v_double,
+                                   void *data,
+                                   bool legacy)
+{
+   bson_json_state_t *state = data;
+   bson_string_t *str = state->str;
+   uint32_t start_len;
+
+   if (!legacy) {
+      bson_string_append (state->str, "{ \"$numberDouble\" : \"");
+   }
+
+   /* portable: some old platforms have no isinf or isnan */
+   if (v_double != v_double) {
+      bson_string_append (str, "NaN");
+   } else if (v_double * 0 != 0) {
+      if (v_double > 0) {
+         bson_string_append (str, "Infinity");
+      } else {
+         bson_string_append (str, "-Infinity");
+      }
+   } else {
+      start_len = str->len;
+      bson_string_append_printf (str, "%.20g", v_double);
+
+      /* ensure trailing ".0" to distinguish "3" from "3.0" */
+      if (strspn (&str->str[start_len], "0123456789-") ==
+          str->len - start_len) {
+         bson_string_append (str, ".0");
+      }
+   }
+
+   if (!legacy) {
+      bson_string_append (state->str, "\" }");
+   }
+
+   return false;
+}
+
+
+static bool
+_bson_as_extended_json_visit_double (const bson_iter_t *iter,
+                                     const char *key,
+                                     double v_double,
+                                     void *data)
+{
+   return _bson_as_json_visit_double_common (
+      iter, key, v_double, data, false /* legacy */);
+}
+
+
+static bool
+_bson_as_json_visit_double (const bson_iter_t *iter,
+                            const char *key,
+                            double v_double,
+                            void *data)
+{
+   return _bson_as_json_visit_double_common (
+      iter, key, v_double, data, true /* legacy */);
+}
+
+
+static bool
+_bson_as_json_visit_undefined (const bson_iter_t *iter,
+                               const char *key,
+                               void *data)
+{
+   bson_json_state_t *state = data;
+
+   bson_string_append (state->str, "{ \"$undefined\" : true }");
+
+   return false;
+}
+
+
+static bool
+_bson_as_json_visit_null (const bson_iter_t *iter, const char *key, void *data)
+{
+   bson_json_state_t *state = data;
+
+   bson_string_append (state->str, "null");
+
+   return false;
+}
+
+
+static bool
+_bson_as_json_visit_oid (const bson_iter_t *iter,
+                         const char *key,
+                         const bson_oid_t *oid,
+                         void *data)
+{
+   bson_json_state_t *state = data;
+   char str[25];
+
+   bson_oid_to_string (oid, str);
+   bson_string_append (state->str, "{ \"$oid\" : \"");
+   bson_string_append (state->str, str);
+   bson_string_append (state->str, "\" }");
+
+   return false;
+}
+
+
+static bool
+_bson_as_json_visit_binary (const bson_iter_t *iter,
+                            const char *key,
+                            bson_subtype_t v_subtype,
+                            size_t v_binary_len,
+                            const uint8_t *v_binary,
+                            void *data)
+{
+   bson_json_state_t *state = data;
+   size_t b64_len;
+   char *b64;
+
+   b64_len = (v_binary_len / 3 + 1) * 4 + 1;
+   b64 = bson_malloc0 (b64_len);
+   b64_ntop (v_binary, v_binary_len, b64, b64_len);
+
+   bson_string_append (state->str, "{ \"$binary\" : \"");
+   bson_string_append (state->str, b64);
+   bson_string_append (state->str, "\", \"$type\" : \"");
+   bson_string_append_printf (state->str, "%02x", v_subtype);
+   bson_string_append (state->str, "\" }");
+   bson_free (b64);
+
+   return false;
+}
+
+
+static bool
+_bson_as_json_visit_bool (const bson_iter_t *iter,
+                          const char *key,
+                          bool v_bool,
+                          void *data)
+{
+   bson_json_state_t *state = data;
+
+   bson_string_append (state->str, v_bool ? "true" : "false");
+
+   return false;
+}
+
+
+static bool
+_bson_as_extended_json_visit_date_time (const bson_iter_t *iter,
+                                        const char *key,
+                                        int64_t msec_since_epoch,
+                                        void *data)
+{
+   bson_json_state_t *state = data;
+
+   bson_string_append (state->str, "{ \"$date\" : { \"$numberLong\" : \"");
+   bson_string_append_printf (state->str, "%" PRId64, msec_since_epoch);
+   bson_string_append (state->str, "\" } }");
+
+   return false;
+}
+
+
+static bool
+_bson_as_json_visit_date_time (const bson_iter_t *iter,
+                               const char *key,
+                               int64_t msec_since_epoch,
+                               void *data)
+{
+   bson_json_state_t *state = data;
+
+   bson_string_append (state->str, "{ \"$date\" : ");
+   bson_string_append_printf (state->str, "%" PRId64, msec_since_epoch);
+   bson_string_append (state->str, " }");
+
+   return false;
+}
+
+
+static bool
+_bson_as_json_visit_regex (const bson_iter_t *iter,
+                           const char *key,
+                           const char *v_regex,
+                           const char *v_options,
+                           void *data)
+{
+   bson_json_state_t *state = data;
+   const char *c;
+
+   bson_string_append (state->str, "{ \"$regex\" : \"");
+   bson_string_append (state->str, v_regex);
+   bson_string_append (state->str, "\", \"$options\" : \"");
+
+   /* sort the options */
+   for (c = "ilmsux"; *c; c++) {
+      if (strchr (v_options, *c)) {
+         bson_string_append_c (state->str, *c);
+      }
+   }
+
+   bson_string_append (state->str, "\" }");
+
+   return false;
+}
+
+
+static bool
+_bson_as_extended_json_visit_timestamp (const bson_iter_t *iter,
+                                        const char *key,
+                                        uint32_t v_timestamp,
+                                        uint32_t v_increment,
+                                        void *data)
+{
+   bson_json_state_t *state = data;
+
+   bson_string_append_printf (state->str,
+                              "{ \"$timestamp\" : \"%" PRIu64 "\" }",
+                              _int64_timestamp (v_timestamp, v_increment));
+
+   return false;
+}
+
+
+static bool
+_bson_as_json_visit_timestamp (const bson_iter_t *iter,
+                               const char *key,
+                               uint32_t v_timestamp,
+                               uint32_t v_increment,
+                               void *data)
+{
+   bson_json_state_t *state = data;
+
+   bson_string_append (state->str, "{ \"$timestamp\" : { \"t\" : ");
+   bson_string_append_printf (state->str, "%u", v_timestamp);
+   bson_string_append (state->str, ", \"i\" : ");
+   bson_string_append_printf (state->str, "%u", v_increment);
+   bson_string_append (state->str, " } }");
+
+   return false;
+}
+
+
+static bool
+_bson_as_extended_json_visit_dbpointer (const bson_iter_t *iter,
+                                        const char *key,
+                                        size_t v_collection_len,
+                                        const char *v_collection,
+                                        const bson_oid_t *v_oid,
+                                        void *data)
+{
+   bson_json_state_t *state = data;
+   char str[25];
+
+   bson_string_append (state->str, "{ \"$dbPointer\" : { \"$ref\" : \"");
+   bson_string_append (state->str, v_collection);
+   bson_string_append (state->str, "\"");
+
+   if (v_oid) {
+      bson_oid_to_string (v_oid, str);
+      bson_string_append (state->str, ", \"$id\" : { \"$oid\" : \"");
+      bson_string_append (state->str, str);
+      bson_string_append (state->str, "\" }");
+   }
+
+   bson_string_append (state->str, " } }");
+
+   return false;
+}
+
+static bool
+_bson_as_json_visit_dbpointer (const bson_iter_t *iter,
+                               const char *key,
+                               size_t v_collection_len,
+                               const char *v_collection,
+                               const bson_oid_t *v_oid,
+                               void *data)
+{
+   bson_json_state_t *state = data;
+   char str[25];
+
+   bson_string_append (state->str, "{ \"$ref\" : \"");
+   bson_string_append (state->str, v_collection);
+   bson_string_append (state->str, "\"");
+
+   if (v_oid) {
+      bson_oid_to_string (v_oid, str);
+      bson_string_append (state->str, ", \"$id\" : \"");
+      bson_string_append (state->str, str);
+      bson_string_append (state->str, "\"");
+   }
+
+   bson_string_append (state->str, " }");
+
+   return false;
+}
+
+
+static bool
+_bson_as_json_visit_minkey (const bson_iter_t *iter,
+                            const char *key,
+                            void *data)
+{
+   bson_json_state_t *state = data;
+
+   bson_string_append (state->str, "{ \"$minKey\" : 1 }");
+
+   return false;
+}
+
+
+static bool
+_bson_as_json_visit_maxkey (const bson_iter_t *iter,
+                            const char *key,
+                            void *data)
+{
+   bson_json_state_t *state = data;
+
+   bson_string_append (state->str, "{ \"$maxKey\" : 1 }");
+
+   return false;
+}
+
+
+static bool
+_bson_as_json_visit_before (const bson_iter_t *iter,
+                            const char *key,
+                            void *data)
+{
+   bson_json_state_t *state = data;
+   char *escaped;
+
+   if (state->count) {
+      bson_string_append (state->str, ", ");
+   }
+
+   if (state->keys) {
+      escaped = bson_utf8_escape_for_json (key, -1);
+      if (escaped) {
+         bson_string_append (state->str, "\"");
+         bson_string_append (state->str, escaped);
+         bson_string_append (state->str, "\" : ");
+         bson_free (escaped);
+      } else {
+         return true;
+      }
+   }
+
+   state->count++;
+
+   return false;
+}
+
+
+static void
+_bson_as_json_visit_corrupt (const bson_iter_t *iter, void *data)
+{
+   *(((bson_json_state_t *) data)->err_offset) = iter->off;
+}
+
+
+static bool
+_bson_as_json_visit_code (const bson_iter_t *iter,
+                          const char *key,
+                          size_t v_code_len,
+                          const char *v_code,
+                          void *data)
+{
+   bson_json_state_t *state = data;
+   char *escaped;
+
+   escaped = bson_utf8_escape_for_json (v_code, v_code_len);
+
+   if (escaped) {
+      bson_string_append (state->str, "{ \"$code\" : \"");
+      bson_string_append (state->str, escaped);
+      bson_string_append (state->str, "\" }");
+      bson_free (escaped);
+      return false;
+   }
+
+   return true;
+}
+
+
+static bool
+_bson_as_extended_json_visit_symbol (const bson_iter_t *iter,
+                                     const char *key,
+                                     size_t v_symbol_len,
+                                     const char *v_symbol,
+                                     void *data)
+{
+   bson_json_state_t *state = data;
+
+   bson_string_append (state->str, "{ \"$symbol\" : \"");
+   bson_string_append (state->str, v_symbol);
+   bson_string_append (state->str, "\" }");
+
+   return false;
+}
+
+
+static bool
+_bson_as_json_visit_symbol (const bson_iter_t *iter,
+                            const char *key,
+                            size_t v_symbol_len,
+                            const char *v_symbol,
+                            void *data)
+{
+   bson_json_state_t *state = data;
+
+   bson_string_append (state->str, "\"");
+   bson_string_append (state->str, v_symbol);
+   bson_string_append (state->str, "\"");
+
+   return false;
+}
+
+
+static bool
+_bson_as_json_visit_codewscope_common (const bson_iter_t *iter,
+                                       const char *key,
+                                       size_t v_code_len,
+                                       const char *v_code,
+                                       const bson_t *v_scope,
+                                       void *data,
+                                       bool legacy)
+{
+   bson_json_state_t *state = data;
+   char *code_escaped;
+   char *scope;
+
+   code_escaped = bson_utf8_escape_for_json (v_code, v_code_len);
+   if (!code_escaped) {
+      return true;
+   }
+
+   if (legacy) {
+      scope = bson_as_json (v_scope, NULL);
+   } else {
+      scope = bson_as_extended_json (v_scope, NULL);
+   }
+
+   if (!scope) {
+      bson_free (code_escaped);
+      return true;
+   }
+
+   bson_string_append (state->str, "{ \"$code\" : \"");
+   bson_string_append (state->str, code_escaped);
+   bson_string_append (state->str, "\", \"$scope\" : ");
+   bson_string_append (state->str, scope);
+   bson_string_append (state->str, " }");
+
+   bson_free (code_escaped);
+   bson_free (scope);
+
+   return false;
+}
+
+
+static bool
+_bson_as_extended_json_visit_codewscope (const bson_iter_t *iter,
+                                         const char *key,
+                                         size_t v_code_len,
+                                         const char *v_code,
+                                         const bson_t *v_scope,
+                                         void *data)
+{
+   return _bson_as_json_visit_codewscope_common (
+      iter, key, v_code_len, v_code, v_scope, data, false /* legacy */);
+}
+
+
+static bool
+_bson_as_json_visit_codewscope (const bson_iter_t *iter,
+                                const char *key,
+                                size_t v_code_len,
+                                const char *v_code,
+                                const bson_t *v_scope,
+                                void *data)
+{
+   return _bson_as_json_visit_codewscope_common (
+      iter, key, v_code_len, v_code, v_scope, data, true /* legacy */);
+}
+
+
+/* canonical MongoDB Extended JSON format, complying with the spec */
+static const bson_visitor_t bson_as_extended_json_visitors = {
+   _bson_as_json_visit_before,
+   NULL, /* visit_after */
+   _bson_as_json_visit_corrupt,
+   _bson_as_extended_json_visit_double,
+   _bson_as_json_visit_utf8,
+   _bson_as_extended_json_visit_document,
+   _bson_as_extended_json_visit_array,
+   _bson_as_json_visit_binary,
+   _bson_as_json_visit_undefined,
+   _bson_as_json_visit_oid,
+   _bson_as_json_visit_bool,
+   _bson_as_extended_json_visit_date_time,
+   _bson_as_json_visit_null,
+   _bson_as_json_visit_regex,
+   _bson_as_extended_json_visit_dbpointer,
+   _bson_as_json_visit_code,
+   _bson_as_extended_json_visit_symbol,
+   _bson_as_extended_json_visit_codewscope,
+   _bson_as_extended_json_visit_int32,
+   _bson_as_extended_json_visit_timestamp,
+   _bson_as_extended_json_visit_int64,
+   _bson_as_json_visit_maxkey,
+   _bson_as_json_visit_minkey,
+   NULL, /* visit_unsupported_type */
+   _bson_as_json_visit_decimal128,
+};
+
+/* legacy JSON format */
+static const bson_visitor_t bson_as_json_visitors = {
+   _bson_as_json_visit_before,     NULL, /* visit_after */
+   _bson_as_json_visit_corrupt,    _bson_as_json_visit_double,
+   _bson_as_json_visit_utf8,       _bson_as_json_visit_document,
+   _bson_as_json_visit_array,      _bson_as_json_visit_binary,
+   _bson_as_json_visit_undefined,  _bson_as_json_visit_oid,
+   _bson_as_json_visit_bool,       _bson_as_json_visit_date_time,
+   _bson_as_json_visit_null,       _bson_as_json_visit_regex,
+   _bson_as_json_visit_dbpointer,  _bson_as_json_visit_code,
+   _bson_as_json_visit_symbol,     _bson_as_json_visit_codewscope,
+   _bson_as_json_visit_int32,      _bson_as_json_visit_timestamp,
+   _bson_as_json_visit_int64,      _bson_as_json_visit_maxkey,
+   _bson_as_json_visit_minkey,     NULL, /* visit_unsupported_type */
+   _bson_as_json_visit_decimal128,
+};
+
+
+static bool
+_bson_as_json_visit_document_with_visitors (const bson_iter_t *iter,
+                                            const char *key,
+                                            const bson_t *v_document,
+                                            void *data,
+                                            const bson_visitor_t *visitor)
+{
+   bson_json_state_t *state = data;
+   bson_json_state_t child_state = {0, true, state->err_offset};
+   bson_iter_t child;
+
+   if (state->depth >= BSON_MAX_RECURSION) {
+      bson_string_append (state->str, "{ ... }");
+      return false;
+   }
+
+   if (bson_iter_init (&child, v_document)) {
+      child_state.str = bson_string_new ("{ ");
+      child_state.depth = state->depth + 1;
+      if (bson_iter_visit_all (&child, visitor, &child_state)) {
+         return true;
+      }
+
+      bson_string_append (child_state.str, " }");
+      bson_string_append (state->str, child_state.str->str);
+      bson_string_free (child_state.str, true);
+   }
+
+   return false;
+}
+
+
+static bool
+_bson_as_json_visit_document (const bson_iter_t *iter,
+                              const char *key,
+                              const bson_t *v_document,
+                              void *data)
+{
+   return _bson_as_json_visit_document_with_visitors (
+      iter, key, v_document, data, &bson_as_json_visitors);
+}
+
+
+static bool
+_bson_as_extended_json_visit_document (const bson_iter_t *iter,
+                                       const char *key,
+                                       const bson_t *v_document,
+                                       void *data)
+{
+   return _bson_as_json_visit_document_with_visitors (
+      iter, key, v_document, data, &bson_as_extended_json_visitors);
+}
+
+
+static bool
+_bson_as_json_visit_array_with_visitors (const bson_iter_t *iter,
+                                         const char *key,
+                                         const bson_t *v_array,
+                                         void *data,
+                                         const bson_visitor_t *visitor)
+{
+   bson_json_state_t *state = data;
+   bson_json_state_t child_state = {0, false, state->err_offset};
+   bson_iter_t child;
+
+   if (state->depth >= BSON_MAX_RECURSION) {
+      bson_string_append (state->str, "{ ... }");
+      return false;
+   }
+
+   if (bson_iter_init (&child, v_array)) {
+      child_state.str = bson_string_new ("[ ");
+      child_state.depth = state->depth + 1;
+      if (bson_iter_visit_all (&child, visitor, &child_state)) {
+         return true;
+      }
+
+      bson_string_append (child_state.str, " ]");
+      bson_string_append (state->str, child_state.str->str);
+      bson_string_free (child_state.str, true);
+   }
+
+   return false;
+}
+
+
+static bool
+_bson_as_json_visit_array (const bson_iter_t *iter,
+                           const char *key,
+                           const bson_t *v_array,
+                           void *data)
+{
+   return _bson_as_json_visit_array_with_visitors (
+      iter, key, v_array, data, &bson_as_json_visitors);
+}
+
+
+static bool
+_bson_as_extended_json_visit_array (const bson_iter_t *iter,
+                                    const char *key,
+                                    const bson_t *v_array,
+                                    void *data)
+{
+   return _bson_as_json_visit_array_with_visitors (
+      iter, key, v_array, data, &bson_as_extended_json_visitors);
+}
+
+
+static char *
+_bson_as_json_visit_all (const bson_t *bson,
+                         size_t *length,
+                         const bson_visitor_t *visitors)
+{
+   bson_json_state_t state;
+   bson_iter_t iter;
+   ssize_t err_offset = -1;
+
+   BSON_ASSERT (bson);
+
+   if (length) {
+      *length = 0;
+   }
+
+   if (bson_empty0 (bson)) {
+      if (length) {
+         *length = 3;
+      }
+
+      return bson_strdup ("{ }");
+   }
+
+   if (!bson_iter_init (&iter, bson)) {
+      return NULL;
+   }
+
+   state.count = 0;
+   state.keys = true;
+   state.str = bson_string_new ("{ ");
+   state.depth = 0;
+   state.err_offset = &err_offset;
+
+   if (bson_iter_visit_all (&iter, visitors, &state) || err_offset != -1) {
+      /*
+       * We were prematurely exited due to corruption or failed visitor.
+       */
+      bson_string_free (state.str, true);
+      if (length) {
+         *length = 0;
+      }
+      return NULL;
+   }
+
+   bson_string_append (state.str, " }");
+
+   if (length) {
+      *length = state.str->len;
+   }
+
+   return bson_string_free (state.str, false);
+}
+
+
+char *
+bson_as_extended_json (const bson_t *bson, size_t *length)
+{
+   return _bson_as_json_visit_all (
+      bson, length, &bson_as_extended_json_visitors);
+}
+
+
+char *
+bson_as_json (const bson_t *bson, size_t *length)
+{
+   return _bson_as_json_visit_all (bson, length, &bson_as_json_visitors);
+}
+
+
+char *
+bson_array_as_json (const bson_t *bson, size_t *length)
+{
+   bson_json_state_t state;
+   bson_iter_t iter;
+   ssize_t err_offset = -1;
+
+   BSON_ASSERT (bson);
+
+   if (length) {
+      *length = 0;
+   }
+
+   if (bson_empty0 (bson)) {
+      if (length) {
+         *length = 3;
+      }
+
+      return bson_strdup ("[ ]");
+   }
+
+   if (!bson_iter_init (&iter, bson)) {
+      return NULL;
+   }
+
+   state.count = 0;
+   state.keys = false;
+   state.str = bson_string_new ("[ ");
+   state.depth = 0;
+   state.err_offset = &err_offset;
+   bson_iter_visit_all (&iter, &bson_as_json_visitors, &state);
+
+   if (bson_iter_visit_all (&iter, &bson_as_json_visitors, &state) ||
+       err_offset != -1) {
+      /*
+       * We were prematurely exited due to corruption or failed visitor.
+       */
+      bson_string_free (state.str, true);
+      if (length) {
+         *length = 0;
+      }
+      return NULL;
+   }
+
+   bson_string_append (state.str, " ]");
+
+   if (length) {
+      *length = state.str->len;
+   }
+
+   return bson_string_free (state.str, false);
+}
+
+
+#define VALIDATION_ERR(_flag, _msg, ...) \
+   bson_set_error (&state->error, BSON_ERROR_INVALID, _flag, _msg, __VA_ARGS__)
+
+static bool
+_bson_iter_validate_utf8 (const bson_iter_t *iter,
+                          const char *key,
+                          size_t v_utf8_len,
+                          const char *v_utf8,
+                          void *data)
+{
+   bson_validate_state_t *state = data;
+   bool allow_null;
+
+   if ((state->flags & BSON_VALIDATE_UTF8)) {
+      allow_null = !!(state->flags & BSON_VALIDATE_UTF8_ALLOW_NULL);
+
+      if (!bson_utf8_validate (v_utf8, v_utf8_len, allow_null)) {
+         state->err_offset = iter->off;
+         VALIDATION_ERR (
+            BSON_VALIDATE_UTF8, "invalid utf8 string for key \"%s\"", key);
+         return true;
+      }
+   }
+
+   if ((state->flags & BSON_VALIDATE_DOLLAR_KEYS)) {
+      if (state->phase == BSON_VALIDATE_PHASE_LF_REF_UTF8) {
+         state->phase = BSON_VALIDATE_PHASE_LF_ID_KEY;
+      } else if (state->phase == BSON_VALIDATE_PHASE_LF_DB_UTF8) {
+         state->phase = BSON_VALIDATE_PHASE_NOT_DBREF;
+      }
+   }
+
+   return false;
+}
+
+
+static void
+_bson_iter_validate_corrupt (const bson_iter_t *iter, void *data)
+{
+   bson_validate_state_t *state = data;
+
+   state->err_offset = iter->err_off;
+   VALIDATION_ERR (BSON_VALIDATE_NONE, "%s", "corrupt BSON");
+}
+
+
+static bool
+_bson_iter_validate_before (const bson_iter_t *iter,
+                            const char *key,
+                            void *data)
+{
+   bson_validate_state_t *state = data;
+
+   if ((state->flags & BSON_VALIDATE_EMPTY_KEYS)) {
+      if (key[0] == '\0') {
+         state->err_offset = iter->off;
+         VALIDATION_ERR (BSON_VALIDATE_EMPTY_KEYS, "%s", "empty key");
+         return true;
+      }
+   }
+
+   if ((state->flags & BSON_VALIDATE_DOLLAR_KEYS)) {
+      if (key[0] == '$') {
+         if (state->phase == BSON_VALIDATE_PHASE_LF_REF_KEY &&
+             strcmp (key, "$ref") == 0) {
+            state->phase = BSON_VALIDATE_PHASE_LF_REF_UTF8;
+         } else if (state->phase == BSON_VALIDATE_PHASE_LF_ID_KEY &&
+                    strcmp (key, "$id") == 0) {
+            state->phase = BSON_VALIDATE_PHASE_LF_DB_KEY;
+         } else if (state->phase == BSON_VALIDATE_PHASE_LF_DB_KEY &&
+                    strcmp (key, "$db") == 0) {
+            state->phase = BSON_VALIDATE_PHASE_LF_DB_UTF8;
+         } else {
+            state->err_offset = iter->off;
+            VALIDATION_ERR (BSON_VALIDATE_DOLLAR_KEYS,
+                            "keys cannot begin with \"$\": \"%s\"",
+                            key);
+            return true;
+         }
+      } else if (state->phase == BSON_VALIDATE_PHASE_LF_ID_KEY ||
+                 state->phase == BSON_VALIDATE_PHASE_LF_REF_UTF8 ||
+                 state->phase == BSON_VALIDATE_PHASE_LF_DB_UTF8) {
+         state->err_offset = iter->off;
+         VALIDATION_ERR (BSON_VALIDATE_DOLLAR_KEYS,
+                         "invalid key within DBRef subdocument: \"%s\"",
+                         key);
+         return true;
+      } else {
+         state->phase = BSON_VALIDATE_PHASE_NOT_DBREF;
+      }
+   }
+
+   if ((state->flags & BSON_VALIDATE_DOT_KEYS)) {
+      if (strstr (key, ".")) {
+         state->err_offset = iter->off;
+         VALIDATION_ERR (
+            BSON_VALIDATE_DOT_KEYS, "keys cannot contain \".\": \"%s\"", key);
+         return true;
+      }
+   }
+
+   return false;
+}
+
+
+static bool
+_bson_iter_validate_codewscope (const bson_iter_t *iter,
+                                const char *key,
+                                size_t v_code_len,
+                                const char *v_code,
+                                const bson_t *v_scope,
+                                void *data)
+{
+   bson_validate_state_t *state = data;
+   size_t offset = 0;
+
+   if (!bson_validate (v_scope, state->flags, &offset)) {
+      state->err_offset = iter->off + offset;
+      VALIDATION_ERR (BSON_VALIDATE_NONE, "%s", "corrupt code-with-scope");
+      return false;
+   }
+
+   return true;
+}
+
+
+static bool
+_bson_iter_validate_document (const bson_iter_t *iter,
+                              const char *key,
+                              const bson_t *v_document,
+                              void *data);
+
+
+static const bson_visitor_t bson_validate_funcs = {
+   _bson_iter_validate_before,
+   NULL, /* visit_after */
+   _bson_iter_validate_corrupt,
+   NULL, /* visit_double */
+   _bson_iter_validate_utf8,
+   _bson_iter_validate_document,
+   _bson_iter_validate_document, /* visit_array */
+   NULL,                         /* visit_binary */
+   NULL,                         /* visit_undefined */
+   NULL,                         /* visit_oid */
+   NULL,                         /* visit_bool */
+   NULL,                         /* visit_date_time */
+   NULL,                         /* visit_null */
+   NULL,                         /* visit_regex */
+   NULL,                         /* visit_dbpoint */
+   NULL,                         /* visit_code */
+   NULL,                         /* visit_symbol */
+   _bson_iter_validate_codewscope,
+};
+
+
+static bool
+_bson_iter_validate_document (const bson_iter_t *iter,
+                              const char *key,
+                              const bson_t *v_document,
+                              void *data)
+{
+   bson_validate_state_t *state = data;
+   bson_iter_t child;
+   bson_validate_phase_t phase = state->phase;
+
+   if (!bson_iter_init (&child, v_document)) {
+      state->err_offset = iter->off;
+      return true;
+   }
+
+   if (state->phase == BSON_VALIDATE_PHASE_START) {
+      state->phase = BSON_VALIDATE_PHASE_TOP;
+   } else {
+      state->phase = BSON_VALIDATE_PHASE_LF_REF_KEY;
+   }
+
+   bson_iter_visit_all (&child, &bson_validate_funcs, state);
+
+   if (state->phase == BSON_VALIDATE_PHASE_LF_ID_KEY ||
+       state->phase == BSON_VALIDATE_PHASE_LF_REF_UTF8 ||
+       state->phase == BSON_VALIDATE_PHASE_LF_DB_UTF8) {
+      if (state->err_offset <= 0) {
+         state->err_offset = iter->off;
+      }
+
+      return true;
+   }
+
+   state->phase = phase;
+
+   return false;
+}
+
+
+static void
+_bson_validate_internal (const bson_t *bson, bson_validate_state_t *state)
+{
+   bson_iter_t iter;
+
+   state->err_offset = -1;
+   state->phase = BSON_VALIDATE_PHASE_START;
+   memset (&state->error, 0, sizeof state->error);
+
+   if (!bson_iter_init (&iter, bson)) {
+      state->err_offset = 0;
+      VALIDATION_ERR (BSON_VALIDATE_NONE, "%s", "corrupt BSON");
+   } else {
+      _bson_iter_validate_document (&iter, NULL, bson, state);
+   }
+}
+
+
+bool
+bson_validate (const bson_t *bson, bson_validate_flags_t flags, size_t *offset)
+{
+   bson_validate_state_t state;
+
+   state.flags = flags;
+   _bson_validate_internal (bson, &state);
+
+   if (state.err_offset > 0 && offset) {
+      *offset = (size_t) state.err_offset;
+   }
+
+   return state.err_offset < 0;
+}
+
+
+bool
+bson_validate_with_error (const bson_t *bson,
+                          bson_validate_flags_t flags,
+                          bson_error_t *error)
+{
+   bson_validate_state_t state;
+
+   state.flags = flags;
+   _bson_validate_internal (bson, &state);
+
+   if (state.err_offset > 0 && error) {
+      memcpy (error, &state.error, sizeof *error);
+   }
+
+   return state.err_offset < 0;
+}
+
+
+bool
+bson_concat (bson_t *dst, const bson_t *src)
+{
+   BSON_ASSERT (dst);
+   BSON_ASSERT (src);
+
+   if (!bson_empty (src)) {
+      return _bson_append (
+         dst, 1, src->len - 5, src->len - 5, _bson_data (src) + 4);
+   }
+
+   return true;
+}
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/bson/bson.h b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson.h
new file mode 100644
index 0000000000000000000000000000000000000000..6d619f590c4d73f1369506bc6d528b43a288298c
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/bson/bson.h
@@ -0,0 +1,1084 @@
+/*
+ * Copyright 2013 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef BSON_H
+#define BSON_H
+
+#define BSON_INSIDE
+
+#include "bson-compat.h"
+
+#include <string.h>
+#include <time.h>
+
+#include "bson-macros.h"
+#include "bson-config.h"
+#include "bson-atomic.h"
+#include "bson-context.h"
+#include "bson-clock.h"
+#include "bson-decimal128.h"
+#include "bson-error.h"
+#include "bson-iter.h"
+#include "bson-json.h"
+#include "bson-keys.h"
+#include "bson-md5.h"
+#include "bson-memory.h"
+#include "bson-oid.h"
+#include "bson-reader.h"
+#include "bson-string.h"
+#include "bson-types.h"
+#include "bson-utf8.h"
+#include "bson-value.h"
+#include "bson-writer.h"
+#include "bcon.h"
+
+#undef BSON_INSIDE
+
+
+BSON_BEGIN_DECLS
+
+
+/**
+ * bson_empty:
+ * @b: a bson_t.
+ *
+ * Checks to see if @b is an empty BSON document. An empty BSON document is
+ * a 5 byte document which contains the length (4 bytes) and a single NUL
+ * byte indicating end of fields.
+ */
+#define bson_empty(b) (((b)->len == 5) || !bson_get_data ((b))[4])
+
+
+/**
+ * bson_empty0:
+ *
+ * Like bson_empty() but treats NULL the same as an empty bson_t document.
+ */
+#define bson_empty0(b) (!(b) || bson_empty (b))
+
+
+/**
+ * bson_clear:
+ *
+ * Easily free a bson document and set it to NULL. Use like:
+ *
+ * bson_t *doc = bson_new();
+ * bson_clear (&doc);
+ * BSON_ASSERT (doc == NULL);
+ */
+#define bson_clear(bptr)         \
+   do {                          \
+      if (*(bptr)) {             \
+         bson_destroy (*(bptr)); \
+         *(bptr) = NULL;         \
+      }                          \
+   } while (0)
+
+
+/**
+ * BSON_MAX_SIZE:
+ *
+ * The maximum size in bytes of a BSON document.
+ */
+#define BSON_MAX_SIZE ((size_t) ((1U << 31) - 1))
+
+
+#define BSON_APPEND_ARRAY(b, key, val) \
+   bson_append_array (b, key, (int) strlen (key), val)
+
+#define BSON_APPEND_ARRAY_BEGIN(b, key, child) \
+   bson_append_array_begin (b, key, (int) strlen (key), child)
+
+#define BSON_APPEND_BINARY(b, key, subtype, val, len) \
+   bson_append_binary (b, key, (int) strlen (key), subtype, val, len)
+
+#define BSON_APPEND_BOOL(b, key, val) \
+   bson_append_bool (b, key, (int) strlen (key), val)
+
+#define BSON_APPEND_CODE(b, key, val) \
+   bson_append_code (b, key, (int) strlen (key), val)
+
+#define BSON_APPEND_CODE_WITH_SCOPE(b, key, val, scope) \
+   bson_append_code_with_scope (b, key, (int) strlen (key), val, scope)
+
+#define BSON_APPEND_DBPOINTER(b, key, coll, oid) \
+   bson_append_dbpointer (b, key, (int) strlen (key), coll, oid)
+
+#define BSON_APPEND_DOCUMENT_BEGIN(b, key, child) \
+   bson_append_document_begin (b, key, (int) strlen (key), child)
+
+#define BSON_APPEND_DOUBLE(b, key, val) \
+   bson_append_double (b, key, (int) strlen (key), val)
+
+#define BSON_APPEND_DOCUMENT(b, key, val) \
+   bson_append_document (b, key, (int) strlen (key), val)
+
+#define BSON_APPEND_INT32(b, key, val) \
+   bson_append_int32 (b, key, (int) strlen (key), val)
+
+#define BSON_APPEND_INT64(b, key, val) \
+   bson_append_int64 (b, key, (int) strlen (key), val)
+
+#define BSON_APPEND_MINKEY(b, key) \
+   bson_append_minkey (b, key, (int) strlen (key))
+
+#define BSON_APPEND_DECIMAL128(b, key, val) \
+   bson_append_decimal128 (b, key, (int) strlen (key), val)
+
+#define BSON_APPEND_MAXKEY(b, key) \
+   bson_append_maxkey (b, key, (int) strlen (key))
+
+#define BSON_APPEND_NULL(b, key) bson_append_null (b, key, (int) strlen (key))
+
+#define BSON_APPEND_OID(b, key, val) \
+   bson_append_oid (b, key, (int) strlen (key), val)
+
+#define BSON_APPEND_REGEX(b, key, val, opt) \
+   bson_append_regex (b, key, (int) strlen (key), val, opt)
+
+#define BSON_APPEND_UTF8(b, key, val) \
+   bson_append_utf8 (b, key, (int) strlen (key), val, (int) strlen (val))
+
+#define BSON_APPEND_SYMBOL(b, key, val) \
+   bson_append_symbol (b, key, (int) strlen (key), val, (int) strlen (val))
+
+#define BSON_APPEND_TIME_T(b, key, val) \
+   bson_append_time_t (b, key, (int) strlen (key), val)
+
+#define BSON_APPEND_TIMEVAL(b, key, val) \
+   bson_append_timeval (b, key, (int) strlen (key), val)
+
+#define BSON_APPEND_DATE_TIME(b, key, val) \
+   bson_append_date_time (b, key, (int) strlen (key), val)
+
+#define BSON_APPEND_TIMESTAMP(b, key, val, inc) \
+   bson_append_timestamp (b, key, (int) strlen (key), val, inc)
+
+#define BSON_APPEND_UNDEFINED(b, key) \
+   bson_append_undefined (b, key, (int) strlen (key))
+
+#define BSON_APPEND_VALUE(b, key, val) \
+   bson_append_value (b, key, (int) strlen (key), (val))
+
+
+/**
+ * bson_new:
+ *
+ * Allocates a new bson_t structure. Call the various bson_append_*()
+ * functions to add fields to the bson. You can iterate the bson_t at any
+ * time using a bson_iter_t and bson_iter_init().
+ *
+ * Returns: A newly allocated bson_t that should be freed with bson_destroy().
+ */
+BSON_EXPORT (bson_t *)
+bson_new (void);
+
+
+BSON_EXPORT (bson_t *)
+bson_new_from_json (const uint8_t *data, ssize_t len, bson_error_t *error);
+
+
+BSON_EXPORT (bool)
+bson_init_from_json (bson_t *bson,
+                     const char *data,
+                     ssize_t len,
+                     bson_error_t *error);
+
+
+/**
+ * bson_init_static:
+ * @b: A pointer to a bson_t.
+ * @data: The data buffer to use.
+ * @length: The length of @data.
+ *
+ * Initializes a bson_t using @data and @length. This is ideal if you would
+ * like to use a stack allocation for your bson and do not need to grow the
+ * buffer. @data must be valid for the life of @b.
+ *
+ * Returns: true if initialized successfully; otherwise false.
+ */
+BSON_EXPORT (bool)
+bson_init_static (bson_t *b, const uint8_t *data, size_t length);
+
+
+/**
+ * bson_init:
+ * @b: A pointer to a bson_t.
+ *
+ * Initializes a bson_t for use. This function is useful to those that want a
+ * stack allocated bson_t. The usefulness of a stack allocated bson_t is
+ * marginal as the target buffer for content will still require heap
+ * allocations. It can help reduce heap fragmentation on allocators that do
+ * not employ SLAB/magazine semantics.
+ *
+ * You must call bson_destroy() with @b to release resources when you are done
+ * using @b.
+ */
+BSON_EXPORT (void)
+bson_init (bson_t *b);
+
+
+/**
+ * bson_reinit:
+ * @b: (inout): A bson_t.
+ *
+ * This is equivalent to calling bson_destroy() and bson_init() on a #bson_t.
+ * However, it will try to persist the existing malloc'd buffer if one exists.
+ * This is useful in cases where you want to reduce malloc overhead while
+ * building many documents.
+ */
+BSON_EXPORT (void)
+bson_reinit (bson_t *b);
+
+
+/**
+ * bson_new_from_data:
+ * @data: A buffer containing a serialized bson document.
+ * @length: The length of the document in bytes.
+ *
+ * Creates a new bson_t structure using the data provided. @data should contain
+ * at least @length bytes that can be copied into the new bson_t structure.
+ *
+ * Returns: A newly allocated bson_t that should be freed with bson_destroy().
+ *   If the first four bytes (little-endian) of data do not match @length,
+ *   then NULL will be returned.
+ */
+BSON_EXPORT (bson_t *)
+bson_new_from_data (const uint8_t *data, size_t length);
+
+
+/**
+ * bson_new_from_buffer:
+ * @buf: A pointer to a buffer containing a serialized bson document.
+ * @buf_len: The length of the buffer in bytes.
+ * @realloc_fun: a realloc like function
+ * @realloc_fun_ctx: a context for the realloc function
+ *
+ * Creates a new bson_t structure using the data provided. @buf should contain
+ * a bson document, or null pointer should be passed for new allocations.
+ *
+ * Returns: A newly allocated bson_t that should be freed with bson_destroy().
+ *          The underlying buffer will be used and not be freed in destroy.
+ */
+BSON_EXPORT (bson_t *)
+bson_new_from_buffer (uint8_t **buf,
+                      size_t *buf_len,
+                      bson_realloc_func realloc_func,
+                      void *realloc_func_ctx);
+
+
+/**
+ * bson_sized_new:
+ * @size: A size_t containing the number of bytes to allocate.
+ *
+ * This will allocate a new bson_t with enough bytes to hold a buffer
+ * sized @size. @size must be smaller than INT_MAX bytes.
+ *
+ * Returns: A newly allocated bson_t that should be freed with bson_destroy().
+ */
+BSON_EXPORT (bson_t *)
+bson_sized_new (size_t size);
+
+
+/**
+ * bson_copy:
+ * @bson: A bson_t.
+ *
+ * Copies @bson into a newly allocated bson_t. You must call bson_destroy()
+ * when you are done with the resulting value to free its resources.
+ *
+ * Returns: A newly allocated bson_t that should be free'd with bson_destroy()
+ */
+BSON_EXPORT (bson_t *)
+bson_copy (const bson_t *bson);
+
+
+/**
+ * bson_copy_to:
+ * @src: The source bson_t.
+ * @dst: The destination bson_t.
+ *
+ * Initializes @dst and copies the content from @src into @dst.
+ */
+BSON_EXPORT (void)
+bson_copy_to (const bson_t *src, bson_t *dst);
+
+
+/**
+ * bson_copy_to_excluding:
+ * @src: A bson_t.
+ * @dst: A bson_t to initialize and copy into.
+ * @first_exclude: First field name to exclude.
+ *
+ * Copies @src into @dst excluding any field that is provided.
+ * This is handy for situations when you need to remove one or
+ * more fields in a bson_t. Note that bson_init() will be called
+ * on dst.
+ */
+BSON_EXPORT (void)
+bson_copy_to_excluding (const bson_t *src,
+                        bson_t *dst,
+                        const char *first_exclude,
+                        ...) BSON_GNUC_NULL_TERMINATED
+   BSON_GNUC_DEPRECATED_FOR (bson_copy_to_excluding_noinit);
+
+/**
+ * bson_copy_to_excluding_noinit:
+ * @src: A bson_t.
+ * @dst: A bson_t to initialize and copy into.
+ * @first_exclude: First field name to exclude.
+ *
+ * The same as bson_copy_to_excluding, but does not call bson_init()
+ * on the dst. This version should be preferred in new code, but the
+ * old function is left for backwards compatibility.
+ */
+BSON_EXPORT (void)
+bson_copy_to_excluding_noinit (const bson_t *src,
+                               bson_t *dst,
+                               const char *first_exclude,
+                               ...) BSON_GNUC_NULL_TERMINATED;
+
+/**
+ * bson_destroy:
+ * @bson: A bson_t.
+ *
+ * Frees the resources associated with @bson.
+ */
+BSON_EXPORT (void)
+bson_destroy (bson_t *bson);
+
+BSON_EXPORT (uint8_t *)
+bson_reserve_buffer (bson_t *bson, uint32_t size);
+
+BSON_EXPORT (bool)
+bson_steal (bson_t *dst, bson_t *src);
+
+
+/**
+ * bson_destroy_with_steal:
+ * @bson: A #bson_t.
+ * @steal: If ownership of the data buffer should be transferred to caller.
+ * @length: (out): location for the length of the buffer.
+ *
+ * Destroys @bson similar to calling bson_destroy() except that the underlying
+ * buffer will be returned and ownership transferred to the caller if @steal
+ * is non-zero.
+ *
+ * If length is non-NULL, the length of @bson will be stored in @length.
+ *
+ * It is a programming error to call this function with any bson that has
+ * been initialized static, or is being used to create a subdocument with
+ * functions such as bson_append_document_begin() or bson_append_array_begin().
+ *
+ * Returns: a buffer owned by the caller if @steal is true. Otherwise NULL.
+ *    If there was an error, NULL is returned.
+ */
+BSON_EXPORT (uint8_t *)
+bson_destroy_with_steal (bson_t *bson, bool steal, uint32_t *length);
+
+
+/**
+ * bson_get_data:
+ * @bson: A bson_t.
+ *
+ * Fetched the data buffer for @bson of @bson->len bytes in length.
+ *
+ * Returns: A buffer that should not be modified or freed.
+ */
+BSON_EXPORT (const uint8_t *)
+bson_get_data (const bson_t *bson);
+
+
+/**
+ * bson_count_keys:
+ * @bson: A bson_t.
+ *
+ * Counts the number of elements found in @bson.
+ */
+BSON_EXPORT (uint32_t)
+bson_count_keys (const bson_t *bson);
+
+
+/**
+ * bson_has_field:
+ * @bson: A bson_t.
+ * @key: The key to lookup.
+ *
+ * Checks to see if @bson contains a field named @key.
+ *
+ * This function is case-sensitive.
+ *
+ * Returns: true if @key exists in @bson; otherwise false.
+ */
+BSON_EXPORT (bool)
+bson_has_field (const bson_t *bson, const char *key);
+
+
+/**
+ * bson_compare:
+ * @bson: A bson_t.
+ * @other: A bson_t.
+ *
+ * Compares @bson to @other in a qsort() style comparison.
+ * See qsort() for information on how this function works.
+ *
+ * Returns: Less than zero, zero, or greater than zero.
+ */
+BSON_EXPORT (int)
+bson_compare (const bson_t *bson, const bson_t *other);
+
+/*
+ * bson_compare:
+ * @bson: A bson_t.
+ * @other: A bson_t.
+ *
+ * Checks to see if @bson and @other are equal.
+ *
+ * Returns: true if equal; otherwise false.
+ */
+BSON_EXPORT (bool)
+bson_equal (const bson_t *bson, const bson_t *other);
+
+
+/**
+ * bson_validate:
+ * @bson: A bson_t.
+ * @offset: A location for the error offset.
+ *
+ * Validates a BSON document by walking through the document and inspecting
+ * the fields for valid content.
+ *
+ * Returns: true if @bson is valid; otherwise false and @offset is set.
+ */
+BSON_EXPORT (bool)
+bson_validate (const bson_t *bson, bson_validate_flags_t flags, size_t *offset);
+
+
+/**
+ * bson_validate_with_error:
+ * @bson: A bson_t.
+ * @error: A location for the error info.
+ *
+ * Validates a BSON document by walking through the document and inspecting
+ * the fields for valid content.
+ *
+ * Returns: true if @bson is valid; otherwise false and @error is filled out.
+ */
+BSON_EXPORT (bool)
+bson_validate_with_error (const bson_t *bson,
+                          bson_validate_flags_t flags,
+                          bson_error_t *error);
+
+/**
+ * bson_as_extended_json:
+ * @bson: A bson_t.
+ * @length: A location for the string length, or NULL.
+ *
+ * Creates a new string containing @bson in extended JSON format, conforming to
+ * the MongoDB Extended JSON Spec:
+ *
+ * github.com/mongodb/specifications/blob/master/source/extended-json.rst
+ *
+ * The caller is responsible for freeing the resulting string. If @length is
+ * non-NULL, then the length of the resulting string will be placed in @length.
+ *
+ * See http://docs.mongodb.org/manual/reference/mongodb-extended-json/ for
+ * more information on extended JSON.
+ *
+ * Returns: A newly allocated string that should be freed with bson_free().
+ */
+BSON_EXPORT (char *)
+bson_as_extended_json (const bson_t *bson, size_t *length);
+
+
+/**
+ * bson_as_json:
+ * @bson: A bson_t.
+ * @length: A location for the string length, or NULL.
+ *
+ * Creates a new string containing @bson in libbson's legacy JSON format.
+ * Superseded by bson_as_extended_json. The caller is responsible for freeing
+ * the resulting string. If @length is non-NULL, then the length of the
+ * resulting string will be placed in @length.
+ *
+ * Returns: A newly allocated string that should be freed with bson_free().
+ */
+BSON_EXPORT (char *)
+bson_as_json (const bson_t *bson, size_t *length);
+
+
+/* like bson_as_json() but for outermost arrays. */
+BSON_EXPORT (char *)
+bson_array_as_json (const bson_t *bson, size_t *length);
+
+
+BSON_EXPORT (bool)
+bson_append_value (bson_t *bson,
+                   const char *key,
+                   int key_length,
+                   const bson_value_t *value);
+
+
+/**
+ * bson_append_array:
+ * @bson: A bson_t.
+ * @key: The key for the field.
+ * @array: A bson_t containing the array.
+ *
+ * Appends a BSON array to @bson. BSON arrays are like documents where the
+ * key is the string version of the index. For example, the first item of the
+ * array would have the key "0". The second item would have the index "1".
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_array (bson_t *bson,
+                   const char *key,
+                   int key_length,
+                   const bson_t *array);
+
+
+/**
+ * bson_append_binary:
+ * @bson: A bson_t to append.
+ * @key: The key for the field.
+ * @subtype: The bson_subtype_t of the binary.
+ * @binary: The binary buffer to append.
+ * @length: The length of @binary.
+ *
+ * Appends a binary buffer to the BSON document.
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_binary (bson_t *bson,
+                    const char *key,
+                    int key_length,
+                    unsigned int subtype,
+                    const uint8_t *binary,
+                    uint32_t length);
+
+
+/**
+ * bson_append_bool:
+ * @bson: A bson_t.
+ * @key: The key for the field.
+ * @value: The boolean value.
+ *
+ * Appends a new field to @bson of type BSON_TYPE_BOOL.
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_bool (bson_t *bson, const char *key, int key_length, bool value);
+
+
+/**
+ * bson_append_code:
+ * @bson: A bson_t.
+ * @key: The key for the document.
+ * @javascript: JavaScript code to be executed.
+ *
+ * Appends a field of type BSON_TYPE_CODE to the BSON document. @javascript
+ * should contain a script in javascript to be executed.
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_code (bson_t *bson,
+                  const char *key,
+                  int key_length,
+                  const char *javascript);
+
+
+/**
+ * bson_append_code_with_scope:
+ * @bson: A bson_t.
+ * @key: The key for the document.
+ * @javascript: JavaScript code to be executed.
+ * @scope: A bson_t containing the scope for @javascript.
+ *
+ * Appends a field of type BSON_TYPE_CODEWSCOPE to the BSON document.
+ * @javascript should contain a script in javascript to be executed.
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_code_with_scope (bson_t *bson,
+                             const char *key,
+                             int key_length,
+                             const char *javascript,
+                             const bson_t *scope);
+
+
+/**
+ * bson_append_dbpointer:
+ * @bson: A bson_t.
+ * @key: The key for the field.
+ * @collection: The collection name.
+ * @oid: The oid to the reference.
+ *
+ * Appends a new field of type BSON_TYPE_DBPOINTER. This datum type is
+ * deprecated in the BSON spec and should not be used in new code.
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_dbpointer (bson_t *bson,
+                       const char *key,
+                       int key_length,
+                       const char *collection,
+                       const bson_oid_t *oid);
+
+
+/**
+ * bson_append_double:
+ * @bson: A bson_t.
+ * @key: The key for the field.
+ *
+ * Appends a new field to @bson of the type BSON_TYPE_DOUBLE.
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_double (bson_t *bson,
+                    const char *key,
+                    int key_length,
+                    double value);
+
+
+/**
+ * bson_append_document:
+ * @bson: A bson_t.
+ * @key: The key for the field.
+ * @value: A bson_t containing the subdocument.
+ *
+ * Appends a new field to @bson of the type BSON_TYPE_DOCUMENT.
+ * The documents contents will be copied into @bson.
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_document (bson_t *bson,
+                      const char *key,
+                      int key_length,
+                      const bson_t *value);
+
+
+/**
+ * bson_append_document_begin:
+ * @bson: A bson_t.
+ * @key: The key for the field.
+ * @key_length: The length of @key in bytes not including NUL or -1
+ *    if @key_length is NUL terminated.
+ * @child: A location to an uninitialized bson_t.
+ *
+ * Appends a new field named @key to @bson. The field is, however,
+ * incomplete.  @child will be initialized so that you may add fields to the
+ * child document.  Child will use a memory buffer owned by @bson and
+ * therefore grow the parent buffer as additional space is used. This allows
+ * a single malloc'd buffer to be used when building documents which can help
+ * reduce memory fragmentation.
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_document_begin (bson_t *bson,
+                            const char *key,
+                            int key_length,
+                            bson_t *child);
+
+
+/**
+ * bson_append_document_end:
+ * @bson: A bson_t.
+ * @child: A bson_t supplied to bson_append_document_begin().
+ *
+ * Finishes the appending of a document to a @bson. @child is considered
+ * disposed after this call and should not be used any further.
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_document_end (bson_t *bson, bson_t *child);
+
+
+/**
+ * bson_append_array_begin:
+ * @bson: A bson_t.
+ * @key: The key for the field.
+ * @key_length: The length of @key in bytes not including NUL or -1
+ *    if @key_length is NUL terminated.
+ * @child: A location to an uninitialized bson_t.
+ *
+ * Appends a new field named @key to @bson. The field is, however,
+ * incomplete. @child will be initialized so that you may add fields to the
+ * child array. Child will use a memory buffer owned by @bson and
+ * therefore grow the parent buffer as additional space is used. This allows
+ * a single malloc'd buffer to be used when building arrays which can help
+ * reduce memory fragmentation.
+ *
+ * The type of @child will be BSON_TYPE_ARRAY and therefore the keys inside
+ * of it MUST be "0", "1", etc.
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_array_begin (bson_t *bson,
+                         const char *key,
+                         int key_length,
+                         bson_t *child);
+
+
+/**
+ * bson_append_array_end:
+ * @bson: A bson_t.
+ * @child: A bson_t supplied to bson_append_array_begin().
+ *
+ * Finishes the appending of a array to a @bson. @child is considered
+ * disposed after this call and should not be used any further.
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_array_end (bson_t *bson, bson_t *child);
+
+
+/**
+ * bson_append_int32:
+ * @bson: A bson_t.
+ * @key: The key for the field.
+ * @value: The int32_t 32-bit integer value.
+ *
+ * Appends a new field of type BSON_TYPE_INT32 to @bson.
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_int32 (bson_t *bson,
+                   const char *key,
+                   int key_length,
+                   int32_t value);
+
+
+/**
+ * bson_append_int64:
+ * @bson: A bson_t.
+ * @key: The key for the field.
+ * @value: The int64_t 64-bit integer value.
+ *
+ * Appends a new field of type BSON_TYPE_INT64 to @bson.
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_int64 (bson_t *bson,
+                   const char *key,
+                   int key_length,
+                   int64_t value);
+
+
+/**
+ * bson_append_decimal128:
+ * @bson: A bson_t.
+ * @key: The key for the field.
+ * @value: The bson_decimal128_t decimal128 value.
+ *
+ * Appends a new field of type BSON_TYPE_DECIMAL128 to @bson.
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_decimal128 (bson_t *bson,
+                        const char *key,
+                        int key_length,
+                        const bson_decimal128_t *value);
+
+
+/**
+ * bson_append_iter:
+ * @bson: A bson_t to append to.
+ * @key: The key name or %NULL to take current key from @iter.
+ * @key_length: The key length or -1 to use strlen().
+ * @iter: The iter located on the position of the element to append.
+ *
+ * Appends a new field to @bson that is equivalent to the field currently
+ * pointed to by @iter.
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_iter (bson_t *bson,
+                  const char *key,
+                  int key_length,
+                  const bson_iter_t *iter);
+
+
+/**
+ * bson_append_minkey:
+ * @bson: A bson_t.
+ * @key: The key for the field.
+ *
+ * Appends a new field of type BSON_TYPE_MINKEY to @bson. This is a special
+ * type that compares lower than all other possible BSON element values.
+ *
+ * See http://bsonspec.org for more information on this type.
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_minkey (bson_t *bson, const char *key, int key_length);
+
+
+/**
+ * bson_append_maxkey:
+ * @bson: A bson_t.
+ * @key: The key for the field.
+ *
+ * Appends a new field of type BSON_TYPE_MAXKEY to @bson. This is a special
+ * type that compares higher than all other possible BSON element values.
+ *
+ * See http://bsonspec.org for more information on this type.
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_maxkey (bson_t *bson, const char *key, int key_length);
+
+
+/**
+ * bson_append_null:
+ * @bson: A bson_t.
+ * @key: The key for the field.
+ *
+ * Appends a new field to @bson with NULL for the value.
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_null (bson_t *bson, const char *key, int key_length);
+
+
+/**
+ * bson_append_oid:
+ * @bson: A bson_t.
+ * @key: The key for the field.
+ * @oid: bson_oid_t.
+ *
+ * Appends a new field to the @bson of type BSON_TYPE_OID using the contents of
+ * @oid.
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_oid (bson_t *bson,
+                 const char *key,
+                 int key_length,
+                 const bson_oid_t *oid);
+
+
+/**
+ * bson_append_regex:
+ * @bson: A bson_t.
+ * @key: The key of the field.
+ * @regex: The regex to append to the bson.
+ * @options: Options for @regex.
+ *
+ * Appends a new field to @bson of type BSON_TYPE_REGEX. @regex should
+ * be the regex string. @options should contain the options for the regex.
+ *
+ * Valid options for @options are:
+ *
+ *   'i' for case-insensitive.
+ *   'm' for multiple matching.
+ *   'x' for verbose mode.
+ *   'l' to make \w and \W locale dependent.
+ *   's' for dotall mode ('.' matches everything)
+ *   'u' to make \w and \W match unicode.
+ *
+ * For more information on what comprimises a BSON regex, see bsonspec.org.
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_regex (bson_t *bson,
+                   const char *key,
+                   int key_length,
+                   const char *regex,
+                   const char *options);
+
+
+/**
+ * bson_append_utf8:
+ * @bson: A bson_t.
+ * @key: The key for the field.
+ * @value: A UTF-8 encoded string.
+ * @length: The length of @value or -1 if it is NUL terminated.
+ *
+ * Appends a new field to @bson using @key as the key and @value as the UTF-8
+ * encoded value.
+ *
+ * It is the callers responsibility to ensure @value is valid UTF-8. You can
+ * use bson_utf8_validate() to perform this check.
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_utf8 (bson_t *bson,
+                  const char *key,
+                  int key_length,
+                  const char *value,
+                  int length);
+
+
+/**
+ * bson_append_symbol:
+ * @bson: A bson_t.
+ * @key: The key for the field.
+ * @value: The symbol as a string.
+ * @length: The length of @value or -1 if NUL-terminated.
+ *
+ * Appends a new field to @bson of type BSON_TYPE_SYMBOL. This BSON type is
+ * deprecated and should not be used in new code.
+ *
+ * See http://bsonspec.org for more information on this type.
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_symbol (bson_t *bson,
+                    const char *key,
+                    int key_length,
+                    const char *value,
+                    int length);
+
+
+/**
+ * bson_append_time_t:
+ * @bson: A bson_t.
+ * @key: The key for the field.
+ * @value: A time_t.
+ *
+ * Appends a BSON_TYPE_DATE_TIME field to @bson using the time_t @value for the
+ * number of seconds since UNIX epoch in UTC.
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_time_t (bson_t *bson,
+                    const char *key,
+                    int key_length,
+                    time_t value);
+
+
+/**
+ * bson_append_timeval:
+ * @bson: A bson_t.
+ * @key: The key for the field.
+ * @value: A struct timeval containing the date and time.
+ *
+ * Appends a BSON_TYPE_DATE_TIME field to @bson using the struct timeval
+ * provided. The time is persisted in milliseconds since the UNIX epoch in UTC.
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_timeval (bson_t *bson,
+                     const char *key,
+                     int key_length,
+                     struct timeval *value);
+
+
+/**
+ * bson_append_date_time:
+ * @bson: A bson_t.
+ * @key: The key for the field.
+ * @key_length: The length of @key in bytes or -1 if \0 terminated.
+ * @value: The number of milliseconds elapsed since UNIX epoch.
+ *
+ * Appends a new field to @bson of type BSON_TYPE_DATE_TIME.
+ *
+ * Returns: true if sucessful; otherwise false.
+ */
+BSON_EXPORT (bool)
+bson_append_date_time (bson_t *bson,
+                       const char *key,
+                       int key_length,
+                       int64_t value);
+
+
+/**
+ * bson_append_now_utc:
+ * @bson: A bson_t.
+ * @key: The key for the field.
+ * @key_length: The length of @key or -1 if it is NULL terminated.
+ *
+ * Appends a BSON_TYPE_DATE_TIME field to @bson using the current time in UTC
+ * as the field value.
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_now_utc (bson_t *bson, const char *key, int key_length);
+
+/**
+ * bson_append_timestamp:
+ * @bson: A bson_t.
+ * @key: The key for the field.
+ * @timestamp: 4 byte timestamp.
+ * @increment: 4 byte increment for timestamp.
+ *
+ * Appends a field of type BSON_TYPE_TIMESTAMP to @bson. This is a special type
+ * used by MongoDB replication and sharding. If you need generic time and date
+ * fields use bson_append_time_t() or bson_append_timeval().
+ *
+ * Setting @increment and @timestamp to zero has special semantics. See
+ * http://bsonspec.org for more information on this field type.
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_timestamp (bson_t *bson,
+                       const char *key,
+                       int key_length,
+                       uint32_t timestamp,
+                       uint32_t increment);
+
+
+/**
+ * bson_append_undefined:
+ * @bson: A bson_t.
+ * @key: The key for the field.
+ *
+ * Appends a field of type BSON_TYPE_UNDEFINED. This type is deprecated in the
+ * spec and should not be used for new code. However, it is provided for those
+ * needing to interact with legacy systems.
+ *
+ * Returns: true if successful; false if append would overflow max size.
+ */
+BSON_EXPORT (bool)
+bson_append_undefined (bson_t *bson, const char *key, int key_length);
+
+
+BSON_EXPORT (bool)
+bson_concat (bson_t *dst, const bson_t *src);
+
+
+BSON_END_DECLS
+
+
+#endif /* BSON_H */
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/jsonsl/jsonsl.c b/chaos_micro_unit_toolkit/external_lib/bson/jsonsl/jsonsl.c
new file mode 100644
index 0000000000000000000000000000000000000000..642a904a8d807562dfd65c5f85d4ec523388e051
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/jsonsl/jsonsl.c
@@ -0,0 +1,1669 @@
+/* Copyright (C) 2012-2015 Mark Nunberg.
+ *
+ * See included LICENSE file for license details.
+ */
+
+#include "jsonsl.h"
+#include "../bson/bson-memory.h"
+
+#include <limits.h>
+#include <ctype.h>
+
+#ifdef JSONSL_USE_METRICS
+#define XMETRICS \
+    X(STRINGY_INSIGNIFICANT) \
+    X(STRINGY_SLOWPATH) \
+    X(ALLOWED_WHITESPACE) \
+    X(QUOTE_FASTPATH) \
+    X(SPECIAL_FASTPATH) \
+    X(SPECIAL_WSPOP) \
+    X(SPECIAL_SLOWPATH) \
+    X(GENERIC) \
+    X(STRUCTURAL_TOKEN) \
+    X(SPECIAL_SWITCHFIRST) \
+    X(STRINGY_CATCH) \
+    X(NUMBER_FASTPATH) \
+    X(ESCAPES) \
+    X(TOTAL) \
+
+struct jsonsl_metrics_st {
+#define X(m) \
+    unsigned long metric_##m;
+    XMETRICS
+#undef X
+};
+
+static struct jsonsl_metrics_st GlobalMetrics = { 0 };
+static unsigned long GenericCounter[0x100] = { 0 };
+static unsigned long StringyCatchCounter[0x100] = { 0 };
+
+#define INCR_METRIC(m) \
+    GlobalMetrics.metric_##m++;
+
+#define INCR_GENERIC(c) \
+        INCR_METRIC(GENERIC); \
+        GenericCounter[c]++; \
+
+#define INCR_STRINGY_CATCH(c) \
+    INCR_METRIC(STRINGY_CATCH); \
+    StringyCatchCounter[c]++;
+
+JSONSL_API
+void jsonsl_dump_global_metrics(void)
+{
+    int ii;
+    printf("JSONSL Metrics:\n");
+#define X(m) \
+    printf("\t%-30s %20lu (%0.2f%%)\n", #m, GlobalMetrics.metric_##m, \
+           (float)((float)(GlobalMetrics.metric_##m/(float)GlobalMetrics.metric_TOTAL)) * 100);
+    XMETRICS
+#undef X
+    printf("Generic Characters:\n");
+    for (ii = 0; ii < 0xff; ii++) {
+        if (GenericCounter[ii]) {
+            printf("\t[ %c ] %lu\n", ii, GenericCounter[ii]);
+        }
+    }
+    printf("Weird string loop\n");
+    for (ii = 0; ii < 0xff; ii++) {
+        if (StringyCatchCounter[ii]) {
+            printf("\t[ %c ] %lu\n", ii, StringyCatchCounter[ii]);
+        }
+    }
+}
+
+#else
+#define INCR_METRIC(m)
+#define INCR_GENERIC(c)
+#define INCR_STRINGY_CATCH(c)
+JSONSL_API
+void jsonsl_dump_global_metrics(void) { }
+#endif /* JSONSL_USE_METRICS */
+
+#define CASE_DIGITS \
+case '1': \
+case '2': \
+case '3': \
+case '4': \
+case '5': \
+case '6': \
+case '7': \
+case '8': \
+case '9': \
+case '0':
+
+static unsigned extract_special(unsigned);
+static int is_special_end(unsigned);
+static int is_allowed_whitespace(unsigned);
+static int is_allowed_escape(unsigned);
+static int is_simple_char(unsigned);
+static char get_escape_equiv(unsigned);
+
+JSONSL_API
+jsonsl_t jsonsl_new(int nlevels)
+{
+    unsigned int ii;
+    struct jsonsl_st * jsn;
+
+    if (nlevels < 2) {
+        return NULL;
+    }
+
+    jsn = (struct jsonsl_st *)
+            bson_malloc0(sizeof (*jsn) +
+                    ( (nlevels-1) * sizeof (struct jsonsl_state_st) )
+            );
+
+    jsn->levels_max = (unsigned int) nlevels;
+    jsn->max_callback_level = UINT_MAX;
+    jsonsl_reset(jsn);
+    for (ii = 0; ii < jsn->levels_max; ii++) {
+        jsn->stack[ii].level = ii;
+    }
+    return jsn;
+}
+
+JSONSL_API
+void jsonsl_reset(jsonsl_t jsn)
+{
+    jsn->tok_last = 0;
+    jsn->can_insert = 1;
+    jsn->pos = 0;
+    jsn->level = 0;
+    jsn->stopfl = 0;
+    jsn->in_escape = 0;
+    jsn->expecting = 0;
+}
+
+JSONSL_API
+void jsonsl_destroy(jsonsl_t jsn)
+{
+    if (jsn) {
+        bson_free(jsn);
+    }
+}
+
+
+#define FASTPARSE_EXHAUSTED 1
+#define FASTPARSE_BREAK 0
+
+/*
+ * This function is meant to accelerate string parsing, reducing the main loop's
+ * check if we are indeed a string.
+ *
+ * @param jsn the parser
+ * @param[in,out] bytes_p A pointer to the current buffer (i.e. current position)
+ * @param[in,out] nbytes_p A pointer to the current size of the buffer
+ * @return true if all bytes have been exhausted (and thus the main loop can
+ * return), false if a special character was examined which requires greater
+ * examination.
+ */
+static int
+jsonsl__str_fastparse(jsonsl_t jsn,
+                      const jsonsl_uchar_t **bytes_p, size_t *nbytes_p)
+{
+    const jsonsl_uchar_t *bytes = *bytes_p;
+    const jsonsl_uchar_t *end;
+    for (end = bytes + *nbytes_p; bytes != end; bytes++) {
+        if (
+#ifdef JSONSL_USE_WCHAR
+                *bytes >= 0x100 ||
+#endif /* JSONSL_USE_WCHAR */
+                (is_simple_char(*bytes))) {
+            INCR_METRIC(TOTAL);
+            INCR_METRIC(STRINGY_INSIGNIFICANT);
+        } else {
+            /* Once we're done here, re-calculate the position variables */
+            jsn->pos += (bytes - *bytes_p);
+            *nbytes_p -= (bytes - *bytes_p);
+            *bytes_p = bytes;
+            return FASTPARSE_BREAK;
+        }
+    }
+
+    /* Once we're done here, re-calculate the position variables */
+    jsn->pos += (bytes - *bytes_p);
+    return FASTPARSE_EXHAUSTED;
+}
+
+/* Functions exactly like str_fastparse, except it also accepts a 'state'
+ * argument, since the number's value is updated in the state. */
+static int
+jsonsl__num_fastparse(jsonsl_t jsn,
+                      const jsonsl_uchar_t **bytes_p, size_t *nbytes_p,
+                      struct jsonsl_state_st *state)
+{
+    int exhausted = 1;
+    size_t nbytes = *nbytes_p;
+    const jsonsl_uchar_t *bytes = *bytes_p;
+
+    for (; nbytes; nbytes--, bytes++) {
+        jsonsl_uchar_t c = *bytes;
+        if (isdigit(c)) {
+            INCR_METRIC(TOTAL);
+            INCR_METRIC(NUMBER_FASTPATH);
+            state->nelem = (state->nelem * 10) + (c - 0x30);
+        } else {
+            exhausted = 0;
+            break;
+        }
+    }
+    jsn->pos += (*nbytes_p - nbytes);
+    if (exhausted) {
+        return FASTPARSE_EXHAUSTED;
+    }
+    *nbytes_p = nbytes;
+    *bytes_p = bytes;
+    return FASTPARSE_BREAK;
+}
+
+JSONSL_API
+void
+jsonsl_feed(jsonsl_t jsn, const jsonsl_char_t *bytes, size_t nbytes)
+{
+
+#define INVOKE_ERROR(eb) \
+    if (jsn->error_callback(jsn, JSONSL_ERROR_##eb, state, (char*)c)) { \
+        goto GT_AGAIN; \
+    } \
+    return;
+
+#define STACK_PUSH \
+    if (jsn->level >= (levels_max-1)) { \
+        jsn->error_callback(jsn, JSONSL_ERROR_LEVELS_EXCEEDED, state, (char*)c); \
+        return; \
+    } \
+    state = jsn->stack + (++jsn->level); \
+    state->ignore_callback = jsn->stack[jsn->level-1].ignore_callback; \
+    state->pos_begin = jsn->pos;
+
+#define STACK_POP_NOPOS \
+    state->pos_cur = jsn->pos; \
+    state = jsn->stack + (--jsn->level);
+
+
+#define STACK_POP \
+    STACK_POP_NOPOS; \
+    state->pos_cur = jsn->pos;
+
+#define CALLBACK_AND_POP_NOPOS(T) \
+        state->pos_cur = jsn->pos; \
+        DO_CALLBACK(T, POP); \
+        state->nescapes = 0; \
+        state = jsn->stack + (--jsn->level);
+
+#define CALLBACK_AND_POP(T) \
+        CALLBACK_AND_POP_NOPOS(T); \
+        state->pos_cur = jsn->pos;
+
+#define SPECIAL_POP \
+    CALLBACK_AND_POP(SPECIAL); \
+    jsn->expecting = 0; \
+    jsn->tok_last = 0; \
+
+#define CUR_CHAR (*(jsonsl_uchar_t*)c)
+
+#define DO_CALLBACK(T, action) \
+    if (jsn->call_##T && \
+            jsn->max_callback_level > state->level && \
+            state->ignore_callback == 0) { \
+        \
+        if (jsn->action_callback_##action) { \
+            jsn->action_callback_##action(jsn, JSONSL_ACTION_##action, state, (jsonsl_char_t*)c); \
+        } else if (jsn->action_callback) { \
+            jsn->action_callback(jsn, JSONSL_ACTION_##action, state, (jsonsl_char_t*)c); \
+        } \
+        if (jsn->stopfl) { return; } \
+    }
+
+    /**
+     * Verifies that we are able to insert the (non-string) item into a hash.
+     */
+#define ENSURE_HVAL \
+    if (state->nelem % 2 == 0 && state->type == JSONSL_T_OBJECT) { \
+        INVOKE_ERROR(HKEY_EXPECTED); \
+    }
+
+#define VERIFY_SPECIAL(lit) \
+        if (CUR_CHAR != (lit)[jsn->pos - state->pos_begin]) { \
+            INVOKE_ERROR(SPECIAL_EXPECTED); \
+        }
+
+#define VERIFY_SPECIAL_CI(lit) \
+        if (tolower(CUR_CHAR) != (lit)[jsn->pos - state->pos_begin]) { \
+            INVOKE_ERROR(SPECIAL_EXPECTED); \
+        }
+
+#define STATE_SPECIAL_LENGTH \
+    (state)->nescapes
+
+#define IS_NORMAL_NUMBER \
+    ((state)->special_flags == JSONSL_SPECIALf_UNSIGNED || \
+        (state)->special_flags == JSONSL_SPECIALf_SIGNED)
+
+#define STATE_NUM_LAST jsn->tok_last
+
+#define CONTINUE_NEXT_CHAR() continue
+
+    const jsonsl_uchar_t *c = (jsonsl_uchar_t*)bytes;
+    size_t levels_max = jsn->levels_max;
+    struct jsonsl_state_st *state = jsn->stack + jsn->level;
+    jsn->base = bytes;
+
+    for (; nbytes; nbytes--, jsn->pos++, c++) {
+        unsigned state_type;
+        INCR_METRIC(TOTAL);
+
+        GT_AGAIN:
+        state_type = state->type;
+        /* Most common type is typically a string: */
+        if (state_type & JSONSL_Tf_STRINGY) {
+            /* Special escape handling for some stuff */
+            if (jsn->in_escape) {
+                jsn->in_escape = 0;
+                if (!is_allowed_escape(CUR_CHAR)) {
+                    INVOKE_ERROR(ESCAPE_INVALID);
+                } else if (CUR_CHAR == 'u') {
+                    DO_CALLBACK(UESCAPE, UESCAPE);
+                    if (jsn->return_UESCAPE) {
+                        return;
+                    }
+                }
+                CONTINUE_NEXT_CHAR();
+            }
+
+            if (jsonsl__str_fastparse(jsn, &c, &nbytes) ==
+                    FASTPARSE_EXHAUSTED) {
+                /* No need to readjust variables as we've exhausted the iterator */
+                return;
+            } else {
+                if (CUR_CHAR == '"') {
+                    goto GT_QUOTE;
+                } else if (CUR_CHAR == '\\') {
+                    goto GT_ESCAPE;
+                } else {
+                    INVOKE_ERROR(WEIRD_WHITESPACE);
+                }
+            }
+            INCR_METRIC(STRINGY_SLOWPATH);
+
+        } else if (state_type == JSONSL_T_SPECIAL) {
+            /* Fast track for signed/unsigned */
+            if (IS_NORMAL_NUMBER) {
+                if (jsonsl__num_fastparse(jsn, &c, &nbytes, state) ==
+                        FASTPARSE_EXHAUSTED) {
+                    return;
+                } else {
+                    goto GT_SPECIAL_NUMERIC;
+                }
+            } else if (state->special_flags == JSONSL_SPECIALf_DASH) {
+#ifdef JSONSL_PARSE_NAN
+                if (CUR_CHAR == 'I' || CUR_CHAR == 'i') {
+                    /* parsing -Infinity? */
+                    state->special_flags = JSONSL_SPECIALf_NEG_INF;
+                    CONTINUE_NEXT_CHAR();
+                }
+#endif
+
+                if (!isdigit(CUR_CHAR)) {
+                    INVOKE_ERROR(INVALID_NUMBER);
+                }
+
+                if (CUR_CHAR == '0') {
+                    state->special_flags = JSONSL_SPECIALf_ZERO|JSONSL_SPECIALf_SIGNED;
+                } else if (isdigit(CUR_CHAR)) {
+                    state->special_flags = JSONSL_SPECIALf_SIGNED;
+                    state->nelem = CUR_CHAR - 0x30;
+                } else {
+                    INVOKE_ERROR(INVALID_NUMBER);
+                }
+                CONTINUE_NEXT_CHAR();
+
+            } else if (state->special_flags == JSONSL_SPECIALf_ZERO) {
+                if (isdigit(CUR_CHAR)) {
+                    /* Following a zero! */
+                    INVOKE_ERROR(INVALID_NUMBER);
+                }
+                /* Unset the 'zero' flag: */
+                if (state->special_flags & JSONSL_SPECIALf_SIGNED) {
+                    state->special_flags = JSONSL_SPECIALf_SIGNED;
+                } else {
+                    state->special_flags = JSONSL_SPECIALf_UNSIGNED;
+                }
+                goto GT_SPECIAL_NUMERIC;
+            }
+
+            if ((state->special_flags & JSONSL_SPECIALf_NUMERIC) &&
+                    !(state->special_flags & JSONSL_SPECIALf_INF)) {
+                GT_SPECIAL_NUMERIC:
+                switch (CUR_CHAR) {
+                CASE_DIGITS
+                    STATE_NUM_LAST = '1';
+                    CONTINUE_NEXT_CHAR();
+
+                case '.':
+                    if (state->special_flags & JSONSL_SPECIALf_FLOAT) {
+                        INVOKE_ERROR(INVALID_NUMBER);
+                    }
+                    state->special_flags |= JSONSL_SPECIALf_FLOAT;
+                    STATE_NUM_LAST = '.';
+                    CONTINUE_NEXT_CHAR();
+
+                case 'e':
+                case 'E':
+                    if (state->special_flags & JSONSL_SPECIALf_EXPONENT) {
+                        INVOKE_ERROR(INVALID_NUMBER);
+                    }
+                    state->special_flags |= JSONSL_SPECIALf_EXPONENT;
+                    STATE_NUM_LAST = 'e';
+                    CONTINUE_NEXT_CHAR();
+
+                case '-':
+                case '+':
+                    if (STATE_NUM_LAST != 'e') {
+                        INVOKE_ERROR(INVALID_NUMBER);
+                    }
+                    STATE_NUM_LAST = '-';
+                    CONTINUE_NEXT_CHAR();
+
+                default:
+                    if (is_special_end(CUR_CHAR)) {
+                        goto GT_SPECIAL_POP;
+                    }
+                    INVOKE_ERROR(INVALID_NUMBER);
+                    break;
+                }
+            }
+            /* else if (!NUMERIC) */
+            if (!is_special_end(CUR_CHAR)) {
+                STATE_SPECIAL_LENGTH++;
+
+                /* Verify TRUE, FALSE, NULL */
+                if (state->special_flags == JSONSL_SPECIALf_TRUE) {
+                    VERIFY_SPECIAL("true");
+                } else if (state->special_flags == JSONSL_SPECIALf_FALSE) {
+                    VERIFY_SPECIAL("false");
+                } else if (state->special_flags == JSONSL_SPECIALf_NULL) {
+                    VERIFY_SPECIAL("null");
+#ifdef JSONSL_PARSE_NAN
+                } else if (state->special_flags == JSONSL_SPECIALf_POS_INF) {
+                    VERIFY_SPECIAL_CI("infinity");
+                } else if (state->special_flags == JSONSL_SPECIALf_NEG_INF) {
+                    VERIFY_SPECIAL_CI("-infinity");
+                } else if (state->special_flags == JSONSL_SPECIALf_NAN) {
+                    VERIFY_SPECIAL_CI("nan");
+                } else if (state->special_flags & JSONSL_SPECIALf_NULL ||
+                           state->special_flags & JSONSL_SPECIALf_NAN) {
+                   /* previous char was "n", are we parsing null or nan? */
+                   if (CUR_CHAR != 'u') {
+                      state->special_flags &= ~JSONSL_SPECIALf_NULL;
+                   }
+
+                   if (tolower(CUR_CHAR) != 'a') {
+                      state->special_flags &= ~JSONSL_SPECIALf_NAN;
+                   }
+#endif
+                }
+                INCR_METRIC(SPECIAL_FASTPATH);
+                CONTINUE_NEXT_CHAR();
+            }
+
+            GT_SPECIAL_POP:
+            jsn->can_insert = 0;
+            if (IS_NORMAL_NUMBER) {
+                /* Nothing */
+            } else if (state->special_flags == JSONSL_SPECIALf_ZERO ||
+                    state->special_flags == (JSONSL_SPECIALf_ZERO|JSONSL_SPECIALf_SIGNED)) {
+                /* 0 is unsigned! */
+                state->special_flags = JSONSL_SPECIALf_UNSIGNED;
+            } else if (state->special_flags == JSONSL_SPECIALf_DASH) {
+                /* Still in dash! */
+                INVOKE_ERROR(INVALID_NUMBER);
+            } else if (state->special_flags & JSONSL_SPECIALf_INF) {
+                if (STATE_SPECIAL_LENGTH != 8) {
+                    INVOKE_ERROR(SPECIAL_INCOMPLETE);
+                }
+                state->nelem = 1;
+            } else if (state->special_flags & JSONSL_SPECIALf_NUMERIC) {
+                /* Check that we're not at the end of a token */
+                if (STATE_NUM_LAST != '1') {
+                    INVOKE_ERROR(INVALID_NUMBER);
+                }
+            } else if (state->special_flags == JSONSL_SPECIALf_TRUE) {
+                if (STATE_SPECIAL_LENGTH != 4) {
+                    INVOKE_ERROR(SPECIAL_INCOMPLETE);
+                }
+                state->nelem = 1;
+            } else if (state->special_flags == JSONSL_SPECIALf_FALSE) {
+                if (STATE_SPECIAL_LENGTH != 5) {
+                    INVOKE_ERROR(SPECIAL_INCOMPLETE);
+                }
+            } else if (state->special_flags == JSONSL_SPECIALf_NULL) {
+                if (STATE_SPECIAL_LENGTH != 4) {
+                    INVOKE_ERROR(SPECIAL_INCOMPLETE);
+                }
+            }
+            SPECIAL_POP;
+            jsn->expecting = ',';
+            if (is_allowed_whitespace(CUR_CHAR)) {
+                CONTINUE_NEXT_CHAR();
+            }
+            /**
+             * This works because we have a non-whitespace token
+             * which is not a special token. If this is a structural
+             * character then it will be gracefully handled by the
+             * switch statement. Otherwise it will default to the 'special'
+             * state again,
+             */
+            goto GT_STRUCTURAL_TOKEN;
+        } else if (is_allowed_whitespace(CUR_CHAR)) {
+            INCR_METRIC(ALLOWED_WHITESPACE);
+            /* So we're not special. Harmless insignificant whitespace
+             * passthrough
+             */
+            CONTINUE_NEXT_CHAR();
+        } else if (extract_special(CUR_CHAR)) {
+            /* not a string, whitespace, or structural token. must be special */
+            goto GT_SPECIAL_BEGIN;
+        }
+
+        INCR_GENERIC(CUR_CHAR);
+
+        if (CUR_CHAR == '"') {
+            GT_QUOTE:
+            jsn->can_insert = 0;
+            switch (state_type) {
+
+            /* the end of a string or hash key */
+            case JSONSL_T_STRING:
+                CALLBACK_AND_POP(STRING);
+                CONTINUE_NEXT_CHAR();
+            case JSONSL_T_HKEY:
+                CALLBACK_AND_POP(HKEY);
+                CONTINUE_NEXT_CHAR();
+
+            case JSONSL_T_OBJECT:
+                state->nelem++;
+                if ( (state->nelem-1) % 2 ) {
+                    /* Odd, this must be a hash value */
+                    if (jsn->tok_last != ':') {
+                        INVOKE_ERROR(MISSING_TOKEN);
+                    }
+                    jsn->expecting = ','; /* Can't figure out what to expect next */
+                    jsn->tok_last = 0;
+
+                    STACK_PUSH;
+                    state->type = JSONSL_T_STRING;
+                    DO_CALLBACK(STRING, PUSH);
+
+                } else {
+                    /* hash key */
+                    if (jsn->expecting != '"') {
+                        INVOKE_ERROR(STRAY_TOKEN);
+                    }
+                    jsn->tok_last = 0;
+                    jsn->expecting = ':';
+
+                    STACK_PUSH;
+                    state->type = JSONSL_T_HKEY;
+                    DO_CALLBACK(HKEY, PUSH);
+                }
+                CONTINUE_NEXT_CHAR();
+
+            case JSONSL_T_LIST:
+                state->nelem++;
+                STACK_PUSH;
+                state->type = JSONSL_T_STRING;
+                jsn->expecting = ',';
+                jsn->tok_last = 0;
+                DO_CALLBACK(STRING, PUSH);
+                CONTINUE_NEXT_CHAR();
+
+            case JSONSL_T_SPECIAL:
+                INVOKE_ERROR(STRAY_TOKEN);
+                break;
+
+            default:
+                INVOKE_ERROR(STRING_OUTSIDE_CONTAINER);
+                break;
+            } /* switch(state->type) */
+        } else if (CUR_CHAR == '\\') {
+            GT_ESCAPE:
+            INCR_METRIC(ESCAPES);
+        /* Escape */
+            if ( (state->type & JSONSL_Tf_STRINGY) == 0 ) {
+                INVOKE_ERROR(ESCAPE_OUTSIDE_STRING);
+            }
+            state->nescapes++;
+            jsn->in_escape = 1;
+            CONTINUE_NEXT_CHAR();
+        } /* " or \ */
+
+        GT_STRUCTURAL_TOKEN:
+        switch (CUR_CHAR) {
+        case ':':
+            INCR_METRIC(STRUCTURAL_TOKEN);
+            if (jsn->expecting != CUR_CHAR) {
+                INVOKE_ERROR(STRAY_TOKEN);
+            }
+            jsn->tok_last = ':';
+            jsn->can_insert = 1;
+            jsn->expecting = '"';
+            CONTINUE_NEXT_CHAR();
+
+        case ',':
+            INCR_METRIC(STRUCTURAL_TOKEN);
+            /**
+             * The comma is one of the more generic tokens.
+             * In the context of an OBJECT, the can_insert flag
+             * should never be set, and no other action is
+             * necessary.
+             */
+            if (jsn->expecting != CUR_CHAR) {
+                /* make this branch execute only when we haven't manually
+                 * just placed the ',' in the expecting register.
+                 */
+                INVOKE_ERROR(STRAY_TOKEN);
+            }
+
+            if (state->type == JSONSL_T_OBJECT) {
+                /* end of hash value, expect a string as a hash key */
+                jsn->expecting = '"';
+            } else {
+                jsn->can_insert = 1;
+            }
+
+            jsn->tok_last = ',';
+            jsn->expecting = '"';
+            CONTINUE_NEXT_CHAR();
+
+            /* new list or object */
+            /* hashes are more common */
+        case '{':
+        case '[':
+            INCR_METRIC(STRUCTURAL_TOKEN);
+            if (!jsn->can_insert) {
+                INVOKE_ERROR(CANT_INSERT);
+            }
+
+            ENSURE_HVAL;
+            state->nelem++;
+
+            STACK_PUSH;
+            /* because the constants match the opening delimiters, we can do this: */
+            state->type = CUR_CHAR;
+            state->nelem = 0;
+            jsn->can_insert = 1;
+            if (CUR_CHAR == '{') {
+                /* If we're a hash, we expect a key first, which is quouted */
+                jsn->expecting = '"';
+            }
+            if (CUR_CHAR == JSONSL_T_OBJECT) {
+                DO_CALLBACK(OBJECT, PUSH);
+            } else {
+                DO_CALLBACK(LIST, PUSH);
+            }
+            jsn->tok_last = 0;
+            CONTINUE_NEXT_CHAR();
+
+            /* closing of list or object */
+        case '}':
+        case ']':
+            INCR_METRIC(STRUCTURAL_TOKEN);
+            if (jsn->tok_last == ',' && jsn->options.allow_trailing_comma == 0) {
+                INVOKE_ERROR(TRAILING_COMMA);
+            }
+
+            jsn->can_insert = 0;
+            jsn->level--;
+            jsn->expecting = ',';
+            jsn->tok_last = 0;
+            if (CUR_CHAR == ']') {
+                if (state->type != '[') {
+                    INVOKE_ERROR(BRACKET_MISMATCH);
+                }
+                DO_CALLBACK(LIST, POP);
+            } else {
+                if (state->type != '{') {
+                    INVOKE_ERROR(BRACKET_MISMATCH);
+                } else if (state->nelem && state->nelem % 2 != 0) {
+                    INVOKE_ERROR(VALUE_EXPECTED);
+                }
+                DO_CALLBACK(OBJECT, POP);
+            }
+            state = jsn->stack + jsn->level;
+            state->pos_cur = jsn->pos;
+            CONTINUE_NEXT_CHAR();
+
+        default:
+            GT_SPECIAL_BEGIN:
+            /**
+             * Not a string, not a structural token, and not benign whitespace.
+             * Technically we should iterate over the character always, but since
+             * we are not doing full numerical/value decoding anyway (but only hinting),
+             * we only check upon entry.
+             */
+            if (state->type != JSONSL_T_SPECIAL) {
+                int special_flags = extract_special(CUR_CHAR);
+                if (!special_flags) {
+                    /**
+                     * Try to do some heuristics here anyway to figure out what kind of
+                     * error this is. The 'special' case is a fallback scenario anyway.
+                     */
+                    if (CUR_CHAR == '\0') {
+                        INVOKE_ERROR(FOUND_NULL_BYTE);
+                    } else if (CUR_CHAR < 0x20) {
+                        INVOKE_ERROR(WEIRD_WHITESPACE);
+                    } else {
+                        INVOKE_ERROR(SPECIAL_EXPECTED);
+                    }
+                }
+                ENSURE_HVAL;
+                state->nelem++;
+                if (!jsn->can_insert) {
+                    INVOKE_ERROR(CANT_INSERT);
+                }
+                STACK_PUSH;
+                state->type = JSONSL_T_SPECIAL;
+                state->special_flags = special_flags;
+                STATE_SPECIAL_LENGTH = 1;
+
+                if (special_flags == JSONSL_SPECIALf_UNSIGNED) {
+                    state->nelem = CUR_CHAR - 0x30;
+                    STATE_NUM_LAST = '1';
+                } else {
+                    STATE_NUM_LAST = '-';
+                    state->nelem = 0;
+                }
+                DO_CALLBACK(SPECIAL, PUSH);
+            }
+            CONTINUE_NEXT_CHAR();
+        }
+    }
+}
+
+JSONSL_API
+const char* jsonsl_strerror(jsonsl_error_t err)
+{
+    if (err == JSONSL_ERROR_SUCCESS) {
+        return "SUCCESS";
+    }
+#define X(t) \
+    if (err == JSONSL_ERROR_##t) \
+        return #t;
+    JSONSL_XERR;
+#undef X
+    return "<UNKNOWN_ERROR>";
+}
+
+JSONSL_API
+const char *jsonsl_strtype(jsonsl_type_t type)
+{
+#define X(o,c) \
+    if (type == JSONSL_T_##o) \
+        return #o;
+    JSONSL_XTYPE
+#undef X
+    return "UNKNOWN TYPE";
+
+}
+
+/*
+ *
+ * JPR/JSONPointer functions
+ *
+ *
+ */
+#ifndef JSONSL_NO_JPR
+static
+jsonsl_jpr_type_t
+populate_component(char *in,
+                   struct jsonsl_jpr_component_st *component,
+                   char **next,
+                   jsonsl_error_t *errp)
+{
+    unsigned long pctval;
+    char *c = NULL, *outp = NULL, *end = NULL;
+    size_t input_len;
+    jsonsl_jpr_type_t ret = JSONSL_PATH_NONE;
+
+    if (*next == NULL || *(*next) == '\0') {
+        return JSONSL_PATH_NONE;
+    }
+
+    /* Replace the next / with a NULL */
+    *next = strstr(in, "/");
+    if (*next != NULL) {
+        *(*next) = '\0'; /* drop the forward slash */
+        input_len = *next - in;
+        end = *next;
+        *next += 1; /* next character after the '/' */
+    } else {
+        input_len = strlen(in);
+        end = in + input_len + 1;
+    }
+
+    component->pstr = in;
+
+    /* Check for special components of interest */
+    if (*in == JSONSL_PATH_WILDCARD_CHAR && input_len == 1) {
+        /* Lone wildcard */
+        ret = JSONSL_PATH_WILDCARD;
+        goto GT_RET;
+    } else if (isdigit(*in)) {
+        /* ASCII Numeric */
+        char *endptr;
+        component->idx = strtoul(in, &endptr, 10);
+        if (endptr && *endptr == '\0') {
+            ret = JSONSL_PATH_NUMERIC;
+            goto GT_RET;
+        }
+    }
+
+    /* Default, it's a string */
+    ret = JSONSL_PATH_STRING;
+    for (c = outp = in; c < end; c++, outp++) {
+        char origc;
+        if (*c != '%') {
+            goto GT_ASSIGN;
+        }
+        /*
+         * c = { [+0] = '%', [+1] = 'b', [+2] = 'e', [+3] = '\0' }
+         */
+
+        /* Need %XX */
+        if (c+2 >= end) {
+            *errp = JSONSL_ERROR_PERCENT_BADHEX;
+            return JSONSL_PATH_INVALID;
+        }
+        if (! (isxdigit(*(c+1)) && isxdigit(*(c+2))) ) {
+            *errp = JSONSL_ERROR_PERCENT_BADHEX;
+            return JSONSL_PATH_INVALID;
+        }
+
+        /* Temporarily null-terminate the characters */
+        origc = *(c+3);
+        *(c+3) = '\0';
+        pctval = strtoul(c+1, NULL, 16);
+        *(c+3) = origc;
+
+        *outp = (char) pctval;
+        c += 2;
+        continue;
+
+        GT_ASSIGN:
+        *outp = *c;
+    }
+    /* Null-terminate the string */
+    for (; outp < c; outp++) {
+        *outp = '\0';
+    }
+
+    GT_RET:
+    component->ptype = ret;
+    if (ret != JSONSL_PATH_WILDCARD) {
+        component->len = strlen(component->pstr);
+    }
+    return ret;
+}
+
+JSONSL_API
+jsonsl_jpr_t
+jsonsl_jpr_new(const char *path, jsonsl_error_t *errp)
+{
+    char *my_copy = NULL;
+    int count, curidx;
+    struct jsonsl_jpr_st *ret = NULL;
+    struct jsonsl_jpr_component_st *components = NULL;
+    size_t origlen;
+    jsonsl_error_t errstacked;
+
+#define JPR_BAIL(err) *errp = err; goto GT_ERROR;
+
+    if (errp == NULL) {
+        errp = &errstacked;
+    }
+
+    if (path == NULL || *path != '/') {
+        JPR_BAIL(JSONSL_ERROR_JPR_NOROOT);
+    }
+
+    count = 1;
+    path++;
+    {
+        const char *c = path;
+        for (; *c; c++) {
+            if (*c == '/') {
+                count++;
+                if (*(c+1) == '/') {
+                    JPR_BAIL(JSONSL_ERROR_JPR_DUPSLASH);
+                }
+            }
+        }
+    }
+    if(*path) {
+        count++;
+    }
+
+    components = (struct jsonsl_jpr_component_st *)
+            malloc(sizeof(*components) * count);
+    if (!components) {
+        JPR_BAIL(JSONSL_ERROR_ENOMEM);
+    }
+
+    my_copy = (char *)malloc(strlen(path) + 1);
+    if (!my_copy) {
+        JPR_BAIL(JSONSL_ERROR_ENOMEM);
+    }
+
+    strcpy(my_copy, path);
+
+    components[0].ptype = JSONSL_PATH_ROOT;
+
+    if (*my_copy) {
+        char *cur = my_copy;
+        int pathret = JSONSL_PATH_STRING;
+        curidx = 1;
+        while (pathret > 0 && curidx < count) {
+            pathret = populate_component(cur, components + curidx, &cur, errp);
+            if (pathret > 0) {
+                curidx++;
+            } else {
+                break;
+            }
+        }
+
+        if (pathret == JSONSL_PATH_INVALID) {
+            JPR_BAIL(JSONSL_ERROR_JPR_BADPATH);
+        }
+    } else {
+        curidx = 1;
+    }
+
+    path--; /*revert path to leading '/' */
+    origlen = strlen(path) + 1;
+    ret = (struct jsonsl_jpr_st *)malloc(sizeof(*ret));
+    if (!ret) {
+        JPR_BAIL(JSONSL_ERROR_ENOMEM);
+    }
+    ret->orig = (char *)malloc(origlen);
+    if (!ret->orig) {
+        JPR_BAIL(JSONSL_ERROR_ENOMEM);
+    }
+    ret->components = components;
+    ret->ncomponents = curidx;
+    ret->basestr = my_copy;
+    ret->norig = origlen-1;
+    strcpy(ret->orig, path);
+
+    return ret;
+
+    GT_ERROR:
+    free(my_copy);
+    free(components);
+    if (ret) {
+        free(ret->orig);
+    }
+    free(ret);
+    return NULL;
+#undef JPR_BAIL
+}
+
+void jsonsl_jpr_destroy(jsonsl_jpr_t jpr)
+{
+    free(jpr->components);
+    free(jpr->basestr);
+    free(jpr->orig);
+    free(jpr);
+}
+
+/**
+ * Call when there is a possibility of a match, either as a final match or
+ * as a path within a match
+ * @param jpr The JPR path
+ * @param component Component corresponding to the current element
+ * @param prlevel The level of the *parent*
+ * @param chtype The type of the child
+ * @return Match status
+ */
+static jsonsl_jpr_match_t
+jsonsl__match_continue(jsonsl_jpr_t jpr,
+                       const struct jsonsl_jpr_component_st *component,
+                       unsigned prlevel, unsigned chtype)
+{
+    const struct jsonsl_jpr_component_st *next_comp = component + 1;
+    if (prlevel == jpr->ncomponents - 1) {
+        /* This is the match. Check the expected type of the match against
+         * the child */
+        if (jpr->match_type == 0 || jpr->match_type == chtype) {
+            return JSONSL_MATCH_COMPLETE;
+        } else {
+            return JSONSL_MATCH_TYPE_MISMATCH;
+        }
+    }
+    if (chtype == JSONSL_T_LIST) {
+        if (next_comp->ptype == JSONSL_PATH_NUMERIC) {
+            return JSONSL_MATCH_POSSIBLE;
+        } else {
+            return JSONSL_MATCH_TYPE_MISMATCH;
+        }
+    } else if (chtype == JSONSL_T_OBJECT) {
+        if (next_comp->ptype == JSONSL_PATH_NUMERIC) {
+            return JSONSL_MATCH_TYPE_MISMATCH;
+        } else {
+            return JSONSL_MATCH_POSSIBLE;
+        }
+    } else {
+        return JSONSL_MATCH_TYPE_MISMATCH;
+    }
+}
+
+JSONSL_API
+jsonsl_jpr_match_t
+jsonsl_path_match(jsonsl_jpr_t jpr,
+                  const struct jsonsl_state_st *parent,
+                  const struct jsonsl_state_st *child,
+                  const char *key, size_t nkey)
+{
+    const struct jsonsl_jpr_component_st *comp;
+    if (!parent) {
+        /* No parent. Return immediately since it's always a match */
+        return jsonsl__match_continue(jpr, jpr->components, 0, child->type);
+    }
+
+    comp = jpr->components + parent->level;
+
+    /* note that we don't need to verify the type of the match, this is
+     * always done through the previous call to jsonsl__match_continue.
+     * If we are in a POSSIBLE tree then we can be certain the types (at
+     * least at this level) are correct */
+    if (parent->type == JSONSL_T_OBJECT) {
+        if (comp->len != nkey || strncmp(key, comp->pstr, nkey) != 0) {
+            return JSONSL_MATCH_NOMATCH;
+        }
+    } else {
+        if (comp->idx != parent->nelem - 1) {
+            return JSONSL_MATCH_NOMATCH;
+        }
+    }
+    return jsonsl__match_continue(jpr, comp, parent->level, child->type);
+}
+
+JSONSL_API
+jsonsl_jpr_match_t
+jsonsl_jpr_match(jsonsl_jpr_t jpr,
+                   unsigned int parent_type,
+                   unsigned int parent_level,
+                   const char *key,
+                   size_t nkey)
+{
+    /* find our current component. This is the child level */
+    int cmpret;
+    struct jsonsl_jpr_component_st *p_component;
+    p_component = jpr->components + parent_level;
+
+    if (parent_level >= jpr->ncomponents) {
+        return JSONSL_MATCH_NOMATCH;
+    }
+
+    /* Lone query for 'root' element. Always matches */
+    if (parent_level == 0) {
+        if (jpr->ncomponents == 1) {
+            return JSONSL_MATCH_COMPLETE;
+        } else {
+            return JSONSL_MATCH_POSSIBLE;
+        }
+    }
+
+    /* Wildcard, always matches */
+    if (p_component->ptype == JSONSL_PATH_WILDCARD) {
+        if (parent_level == jpr->ncomponents-1) {
+            return JSONSL_MATCH_COMPLETE;
+        } else {
+            return JSONSL_MATCH_POSSIBLE;
+        }
+    }
+
+    /* Check numeric array index. This gets its special block so we can avoid
+     * string comparisons */
+    if (p_component->ptype == JSONSL_PATH_NUMERIC) {
+        if (parent_type == JSONSL_T_LIST) {
+            if (p_component->idx != nkey) {
+                /* Wrong index */
+                return JSONSL_MATCH_NOMATCH;
+            } else {
+                if (parent_level == jpr->ncomponents-1) {
+                    /* This is the last element of the path */
+                    return JSONSL_MATCH_COMPLETE;
+                } else {
+                    /* Intermediate element */
+                    return JSONSL_MATCH_POSSIBLE;
+                }
+            }
+        } else if (p_component->is_arridx) {
+            /* Numeric and an array index (set explicitly by user). But not
+             * a list for a parent */
+            return JSONSL_MATCH_TYPE_MISMATCH;
+        }
+    } else if (parent_type == JSONSL_T_LIST) {
+        return JSONSL_MATCH_TYPE_MISMATCH;
+    }
+
+    /* Check lengths */
+    if (p_component->len != nkey) {
+        return JSONSL_MATCH_NOMATCH;
+    }
+
+    /* Check string comparison */
+    cmpret = strncmp(p_component->pstr, key, nkey);
+    if (cmpret == 0) {
+        if (parent_level == jpr->ncomponents-1) {
+            return JSONSL_MATCH_COMPLETE;
+        } else {
+            return JSONSL_MATCH_POSSIBLE;
+        }
+    }
+
+    return JSONSL_MATCH_NOMATCH;
+}
+
+JSONSL_API
+void jsonsl_jpr_match_state_init(jsonsl_t jsn,
+                                 jsonsl_jpr_t *jprs,
+                                 size_t njprs)
+{
+    size_t ii, *firstjmp;
+    if (njprs == 0) {
+        return;
+    }
+    jsn->jprs = (jsonsl_jpr_t *)malloc(sizeof(jsonsl_jpr_t) * njprs);
+    jsn->jpr_count = njprs;
+    jsn->jpr_root = (size_t*)calloc(1, sizeof(size_t) * njprs * jsn->levels_max);
+    memcpy(jsn->jprs, jprs, sizeof(jsonsl_jpr_t) * njprs);
+    /* Set the initial jump table values */
+
+    firstjmp = jsn->jpr_root;
+    for (ii = 0; ii < njprs; ii++) {
+        firstjmp[ii] = ii+1;
+    }
+}
+
+JSONSL_API
+void jsonsl_jpr_match_state_cleanup(jsonsl_t jsn)
+{
+    if (jsn->jpr_count == 0) {
+        return;
+    }
+
+    free(jsn->jpr_root);
+    free(jsn->jprs);
+    jsn->jprs = NULL;
+    jsn->jpr_root = NULL;
+    jsn->jpr_count = 0;
+}
+
+/**
+ * This function should be called exactly once on each element...
+ * This should also be called in recursive order, since we rely
+ * on the parent having been initalized for a match.
+ *
+ * Since the parent is checked for a match as well, we maintain a 'serial' counter.
+ * Whenever we traverse an element, we expect the serial to be the same as a global
+ * integer. If they do not match, we re-initialize the context, and set the serial.
+ *
+ * This ensures a type of consistency without having a proactive reset by the
+ * main lexer itself.
+ *
+ */
+JSONSL_API
+jsonsl_jpr_t jsonsl_jpr_match_state(jsonsl_t jsn,
+                                    struct jsonsl_state_st *state,
+                                    const char *key,
+                                    size_t nkey,
+                                    jsonsl_jpr_match_t *out)
+{
+    struct jsonsl_state_st *parent_state;
+    jsonsl_jpr_t ret = NULL;
+
+    /* Jump and JPR tables for our own state and the parent state */
+    size_t *jmptable, *pjmptable;
+    size_t jmp_cur, ii, ourjmpidx;
+
+    if (!jsn->jpr_root) {
+        *out = JSONSL_MATCH_NOMATCH;
+        return NULL;
+    }
+
+    pjmptable = jsn->jpr_root + (jsn->jpr_count * (state->level-1));
+    jmptable = pjmptable + jsn->jpr_count;
+
+    /* If the parent cannot match, then invalidate it */
+    if (*pjmptable == 0) {
+        *jmptable = 0;
+        *out = JSONSL_MATCH_NOMATCH;
+        return NULL;
+    }
+
+    parent_state = jsn->stack + state->level - 1;
+
+    if (parent_state->type == JSONSL_T_LIST) {
+        nkey = (size_t) parent_state->nelem;
+    }
+
+    *jmptable = 0;
+    ourjmpidx = 0;
+    memset(jmptable, 0, sizeof(int) * jsn->jpr_count);
+
+    for (ii = 0; ii <  jsn->jpr_count; ii++) {
+        jmp_cur = pjmptable[ii];
+        if (jmp_cur) {
+            jsonsl_jpr_t jpr = jsn->jprs[jmp_cur-1];
+            *out = jsonsl_jpr_match(jpr,
+                                    parent_state->type,
+                                    parent_state->level,
+                                    key, nkey);
+            if (*out == JSONSL_MATCH_COMPLETE) {
+                ret = jpr;
+                *jmptable = 0;
+                return ret;
+            } else if (*out == JSONSL_MATCH_POSSIBLE) {
+                jmptable[ourjmpidx] = ii+1;
+                ourjmpidx++;
+            }
+        } else {
+            break;
+        }
+    }
+    if (!*jmptable) {
+        *out = JSONSL_MATCH_NOMATCH;
+    }
+    return NULL;
+}
+
+JSONSL_API
+const char *jsonsl_strmatchtype(jsonsl_jpr_match_t match)
+{
+#define X(T,v) \
+    if ( match == JSONSL_MATCH_##T ) \
+        return #T;
+    JSONSL_XMATCH
+#undef X
+    return "<UNKNOWN>";
+}
+
+#endif /* JSONSL_WITH_JPR */
+
+static char *
+jsonsl__writeutf8(uint32_t pt, char *out)
+{
+    #define ADD_OUTPUT(c) *out = (char)(c); out++;
+
+    if (pt < 0x80) {
+        ADD_OUTPUT(pt);
+    } else if (pt < 0x800) {
+        ADD_OUTPUT((pt >> 6) | 0xC0);
+        ADD_OUTPUT((pt & 0x3F) | 0x80);
+    } else if (pt < 0x10000) {
+        ADD_OUTPUT((pt >> 12) | 0xE0);
+        ADD_OUTPUT(((pt >> 6) & 0x3F) | 0x80);
+        ADD_OUTPUT((pt & 0x3F) | 0x80);
+    } else {
+        ADD_OUTPUT((pt >> 18) | 0xF0);
+        ADD_OUTPUT(((pt >> 12) & 0x3F) | 0x80);
+        ADD_OUTPUT(((pt >> 6) & 0x3F) | 0x80);
+        ADD_OUTPUT((pt & 0x3F) | 0x80);
+    }
+    return out;
+    #undef ADD_OUTPUT
+}
+
+/* Thanks snej (https://github.com/mnunberg/jsonsl/issues/9) */
+static int
+jsonsl__digit2int(char ch) {
+    int d = ch - '0';
+    if ((unsigned) d < 10) {
+        return d;
+    }
+    d = ch - 'a';
+    if ((unsigned) d < 6) {
+        return d + 10;
+    }
+    d = ch - 'A';
+    if ((unsigned) d < 6) {
+        return d + 10;
+    }
+    return -1;
+}
+
+/* Assume 's' is at least 4 bytes long */
+static int
+jsonsl__get_uescape_16(const char *s)
+{
+    int ret = 0;
+    int cur;
+
+    #define GET_DIGIT(off) \
+        cur = jsonsl__digit2int(s[off]); \
+        if (cur == -1) { return -1; } \
+        ret |= (cur << (12 - (off * 4)));
+
+    GET_DIGIT(0);
+    GET_DIGIT(1);
+    GET_DIGIT(2);
+    GET_DIGIT(3);
+    #undef GET_DIGIT
+    return ret;
+}
+
+/**
+ * Utility function to convert escape sequences
+ */
+JSONSL_API
+size_t jsonsl_util_unescape_ex(const char *in,
+                               char *out,
+                               size_t len,
+                               const int toEscape[128],
+                               unsigned *oflags,
+                               jsonsl_error_t *err,
+                               const char **errat)
+{
+    const unsigned char *c = (const unsigned char*)in;
+    char *begin_p = out;
+    unsigned oflags_s;
+    uint16_t last_codepoint = 0;
+
+    if (!oflags) {
+        oflags = &oflags_s;
+    }
+    *oflags = 0;
+
+    #define UNESCAPE_BAIL(e,offset) \
+        *err = JSONSL_ERROR_##e; \
+        if (errat) { \
+            *errat = (const char*)(c+ (ptrdiff_t)(offset)); \
+        } \
+        return 0;
+
+    for (; len; len--, c++, out++) {
+        int uescval;
+        if (*c != '\\') {
+            /* Not an escape, so we don't care about this */
+            goto GT_ASSIGN;
+        }
+
+        if (len < 2) {
+            UNESCAPE_BAIL(ESCAPE_INVALID, 0);
+        }
+        if (!is_allowed_escape(c[1])) {
+            UNESCAPE_BAIL(ESCAPE_INVALID, 1)
+        }
+        if ((toEscape && toEscape[(unsigned char)c[1] & 0x7f] == 0 &&
+                c[1] != '\\' && c[1] != '"')) {
+            /* if we don't want to unescape this string, write the escape sequence to the output */
+            *out++ = *c++;
+            if (--len == 0)
+                break;
+            goto GT_ASSIGN;
+        }
+
+        if (c[1] != 'u') {
+            /* simple skip-and-replace using pre-defined maps.
+             * TODO: should the maps actually reflect the desired
+             * replacement character in toEscape?
+             */
+            char esctmp = get_escape_equiv(c[1]);
+            if (esctmp) {
+                /* Check if there is a corresponding replacement */
+                *out = esctmp;
+            } else {
+                /* Just gobble up the 'reverse-solidus' */
+                *out = c[1];
+            }
+            len--;
+            c++;
+            /* do not assign, just continue */
+            continue;
+        }
+
+        /* next == 'u' */
+        if (len < 6) {
+            /* Need at least six characters.. */
+            UNESCAPE_BAIL(UESCAPE_TOOSHORT, 2);
+        }
+
+        uescval = jsonsl__get_uescape_16((const char *)c + 2);
+        if (uescval == -1) {
+            UNESCAPE_BAIL(PERCENT_BADHEX, -1);
+        }
+
+        if (last_codepoint) {
+            uint16_t w1 = last_codepoint, w2 = (uint16_t)uescval;
+            uint32_t cp;
+
+            if (uescval < 0xDC00 || uescval > 0xDFFF) {
+                UNESCAPE_BAIL(INVALID_CODEPOINT, -1);
+            }
+
+            cp = (w1 & 0x3FF) << 10;
+            cp |= (w2 & 0x3FF);
+            cp += 0x10000;
+
+            out = jsonsl__writeutf8(cp, out) - 1;
+            last_codepoint = 0;
+
+        } else if (uescval < 0xD800 || uescval > 0xDFFF) {
+            *oflags |= JSONSL_SPECIALf_NONASCII;
+            out = jsonsl__writeutf8(uescval, out) - 1;
+
+        } else if (uescval > 0xD7FF && uescval < 0xDC00) {
+            *oflags |= JSONSL_SPECIALf_NONASCII;
+            last_codepoint = (uint16_t)uescval;
+            out--;
+        } else {
+            UNESCAPE_BAIL(INVALID_CODEPOINT, 2);
+        }
+
+        /* Post uescape cleanup */
+        len -= 5; /* Gobble up 5 chars after 'u' */
+        c += 5;
+        continue;
+
+        /* Only reached by previous branches */
+        GT_ASSIGN:
+        *out = *c;
+    }
+
+    if (last_codepoint) {
+        *err = JSONSL_ERROR_INVALID_CODEPOINT;
+        return 0;
+    }
+
+    *err = JSONSL_ERROR_SUCCESS;
+    return out - begin_p;
+}
+
+/**
+ * Character Table definitions.
+ * These were all generated via srcutil/genchartables.pl
+ */
+
+/**
+ * This table contains the beginnings of non-string
+ * allowable (bareword) values.
+ */
+static unsigned short Special_Table[0x100] = {
+        /* 0x00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x1f */
+        /* 0x20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x2c */
+        /* 0x2d */ JSONSL_SPECIALf_DASH /* <-> */, /* 0x2d */
+        /* 0x2e */ 0,0, /* 0x2f */
+        /* 0x30 */ JSONSL_SPECIALf_ZERO /* <0> */, /* 0x30 */
+        /* 0x31 */ JSONSL_SPECIALf_UNSIGNED /* <1> */, /* 0x31 */
+        /* 0x32 */ JSONSL_SPECIALf_UNSIGNED /* <2> */, /* 0x32 */
+        /* 0x33 */ JSONSL_SPECIALf_UNSIGNED /* <3> */, /* 0x33 */
+        /* 0x34 */ JSONSL_SPECIALf_UNSIGNED /* <4> */, /* 0x34 */
+        /* 0x35 */ JSONSL_SPECIALf_UNSIGNED /* <5> */, /* 0x35 */
+        /* 0x36 */ JSONSL_SPECIALf_UNSIGNED /* <6> */, /* 0x36 */
+        /* 0x37 */ JSONSL_SPECIALf_UNSIGNED /* <7> */, /* 0x37 */
+        /* 0x38 */ JSONSL_SPECIALf_UNSIGNED /* <8> */, /* 0x38 */
+        /* 0x39 */ JSONSL_SPECIALf_UNSIGNED /* <9> */, /* 0x39 */
+        /* 0x3a */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x48 */
+        /* 0x49 */ JSONSL__INF_PROXY /* <I> */, /* 0x49 */
+        /* 0x4a */ 0,0,0,0, /* 0x4d */
+        /* 0x4e */ JSONSL__NAN_PROXY /* <N> */, /* 0x4e */
+        /* 0x4f */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x65 */
+        /* 0x66 */ JSONSL_SPECIALf_FALSE /* <f> */, /* 0x66 */
+        /* 0x67 */ 0,0, /* 0x68 */
+        /* 0x69 */ JSONSL__INF_PROXY /* <i> */, /* 0x69 */
+        /* 0x6a */ 0,0,0,0, /* 0x6d */
+        /* 0x6e */ JSONSL_SPECIALf_NULL|JSONSL__NAN_PROXY /* <n> */, /* 0x6e */
+        /* 0x6f */ 0,0,0,0,0, /* 0x73 */
+        /* 0x74 */ JSONSL_SPECIALf_TRUE /* <t> */, /* 0x74 */
+        /* 0x75 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x94 */
+        /* 0x95 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xb4 */
+        /* 0xb5 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xd4 */
+        /* 0xd5 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xf4 */
+        /* 0xf5 */ 0,0,0,0,0,0,0,0,0,0, /* 0xfe */
+};
+
+/**
+ * Contains characters which signal the termination of any of the 'special' bareword
+ * values.
+ */
+static int Special_Endings[0x100] = {
+        /* 0x00 */ 0,0,0,0,0,0,0,0,0, /* 0x08 */
+        /* 0x09 */ 1 /* <TAB> */, /* 0x09 */
+        /* 0x0a */ 1 /* <LF> */, /* 0x0a */
+        /* 0x0b */ 0,0, /* 0x0c */
+        /* 0x0d */ 1 /* <CR> */, /* 0x0d */
+        /* 0x0e */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x1f */
+        /* 0x20 */ 1 /* <SP> */, /* 0x20 */
+        /* 0x21 */ 0, /* 0x21 */
+        /* 0x22 */ 1 /* " */, /* 0x22 */
+        /* 0x23 */ 0,0,0,0,0,0,0,0,0, /* 0x2b */
+        /* 0x2c */ 1 /* , */, /* 0x2c */
+        /* 0x2d */ 0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x39 */
+        /* 0x3a */ 1 /* : */, /* 0x3a */
+        /* 0x3b */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x5a */
+        /* 0x5b */ 1 /* [ */, /* 0x5b */
+        /* 0x5c */ 1 /* \ */, /* 0x5c */
+        /* 0x5d */ 1 /* ] */, /* 0x5d */
+        /* 0x5e */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x7a */
+        /* 0x7b */ 1 /* { */, /* 0x7b */
+        /* 0x7c */ 0, /* 0x7c */
+        /* 0x7d */ 1 /* } */, /* 0x7d */
+        /* 0x7e */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x9d */
+        /* 0x9e */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xbd */
+        /* 0xbe */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xdd */
+        /* 0xde */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xfd */
+        /* 0xfe */ 0 /* 0xfe */
+};
+
+/**
+ * This table contains entries for the allowed whitespace as per RFC 4627
+ */
+static int Allowed_Whitespace[0x100] = {
+        /* 0x00 */ 0,0,0,0,0,0,0,0,0, /* 0x08 */
+        /* 0x09 */ 1 /* <TAB> */, /* 0x09 */
+        /* 0x0a */ 1 /* <LF> */, /* 0x0a */
+        /* 0x0b */ 0,0, /* 0x0c */
+        /* 0x0d */ 1 /* <CR> */, /* 0x0d */
+        /* 0x0e */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x1f */
+        /* 0x20 */ 1 /* <SP> */, /* 0x20 */
+        /* 0x21 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x40 */
+        /* 0x41 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x60 */
+        /* 0x61 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x80 */
+        /* 0x81 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xa0 */
+        /* 0xa1 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xc0 */
+        /* 0xc1 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xe0 */
+        /* 0xe1 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* 0xfe */
+};
+
+static const int String_No_Passthrough[0x100] = {
+        /* 0x00 */ 1 /* <NUL> */, /* 0x00 */
+        /* 0x01 */ 1 /* <SOH> */, /* 0x01 */
+        /* 0x02 */ 1 /* <STX> */, /* 0x02 */
+        /* 0x03 */ 1 /* <ETX> */, /* 0x03 */
+        /* 0x04 */ 1 /* <EOT> */, /* 0x04 */
+        /* 0x05 */ 1 /* <ENQ> */, /* 0x05 */
+        /* 0x06 */ 1 /* <ACK> */, /* 0x06 */
+        /* 0x07 */ 1 /* <BEL> */, /* 0x07 */
+        /* 0x08 */ 1 /* <BS> */, /* 0x08 */
+        /* 0x09 */ 1 /* <HT> */, /* 0x09 */
+        /* 0x0a */ 1 /* <LF> */, /* 0x0a */
+        /* 0x0b */ 1 /* <VT> */, /* 0x0b */
+        /* 0x0c */ 1 /* <FF> */, /* 0x0c */
+        /* 0x0d */ 1 /* <CR> */, /* 0x0d */
+        /* 0x0e */ 1 /* <SO> */, /* 0x0e */
+        /* 0x0f */ 1 /* <SI> */, /* 0x0f */
+        /* 0x10 */ 1 /* <DLE> */, /* 0x10 */
+        /* 0x11 */ 1 /* <DC1> */, /* 0x11 */
+        /* 0x12 */ 1 /* <DC2> */, /* 0x12 */
+        /* 0x13 */ 1 /* <DC3> */, /* 0x13 */
+        /* 0x14 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x21 */
+        /* 0x22 */ 1 /* <"> */, /* 0x22 */
+        /* 0x23 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x42 */
+        /* 0x43 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x5b */
+        /* 0x5c */ 1 /* <\> */, /* 0x5c */
+        /* 0x5d */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x7c */
+        /* 0x7d */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x9c */
+        /* 0x9d */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xbc */
+        /* 0xbd */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xdc */
+        /* 0xdd */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xfc */
+        /* 0xfd */ 0,0, /* 0xfe */
+};
+
+/**
+ * Allowable two-character 'common' escapes:
+ */
+static int Allowed_Escapes[0x100] = {
+        /* 0x00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x1f */
+        /* 0x20 */ 0,0, /* 0x21 */
+        /* 0x22 */ 1 /* <"> */, /* 0x22 */
+        /* 0x23 */ 0,0,0,0,0,0,0,0,0,0,0,0, /* 0x2e */
+        /* 0x2f */ 1 /* </> */, /* 0x2f */
+        /* 0x30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x4f */
+        /* 0x50 */ 0,0,0,0,0,0,0,0,0,0,0,0, /* 0x5b */
+        /* 0x5c */ 1 /* <\> */, /* 0x5c */
+        /* 0x5d */ 0,0,0,0,0, /* 0x61 */
+        /* 0x62 */ 1 /* <b> */, /* 0x62 */
+        /* 0x63 */ 0,0,0, /* 0x65 */
+        /* 0x66 */ 1 /* <f> */, /* 0x66 */
+        /* 0x67 */ 0,0,0,0,0,0,0, /* 0x6d */
+        /* 0x6e */ 1 /* <n> */, /* 0x6e */
+        /* 0x6f */ 0,0,0, /* 0x71 */
+        /* 0x72 */ 1 /* <r> */, /* 0x72 */
+        /* 0x73 */ 0, /* 0x73 */
+        /* 0x74 */ 1 /* <t> */, /* 0x74 */
+        /* 0x75 */ 1 /* <u> */, /* 0x75 */
+        /* 0x76 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x95 */
+        /* 0x96 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xb5 */
+        /* 0xb6 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xd5 */
+        /* 0xd6 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xf5 */
+        /* 0xf6 */ 0,0,0,0,0,0,0,0,0, /* 0xfe */
+};
+
+/**
+ * This table contains the _values_ for a given (single) escaped character.
+ */
+static unsigned char Escape_Equivs[0x100] = {
+        /* 0x00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x1f */
+        /* 0x20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x3f */
+        /* 0x40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x5f */
+        /* 0x60 */ 0,0, /* 0x61 */
+        /* 0x62 */ 8 /* <b> */, /* 0x62 */
+        /* 0x63 */ 0,0,0, /* 0x65 */
+        /* 0x66 */ 12 /* <f> */, /* 0x66 */
+        /* 0x67 */ 0,0,0,0,0,0,0, /* 0x6d */
+        /* 0x6e */ 10 /* <n> */, /* 0x6e */
+        /* 0x6f */ 0,0,0, /* 0x71 */
+        /* 0x72 */ 13 /* <r> */, /* 0x72 */
+        /* 0x73 */ 0, /* 0x73 */
+        /* 0x74 */ 9 /* <t> */, /* 0x74 */
+        /* 0x75 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x94 */
+        /* 0x95 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xb4 */
+        /* 0xb5 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xd4 */
+        /* 0xd5 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xf4 */
+        /* 0xf5 */ 0,0,0,0,0,0,0,0,0,0 /* 0xfe */
+};
+
+/* Definitions of above-declared static functions */
+static char get_escape_equiv(unsigned c) {
+    return Escape_Equivs[c & 0xff];
+}
+static unsigned extract_special(unsigned c) {
+    return Special_Table[c & 0xff];
+}
+static int is_special_end(unsigned c) {
+    return Special_Endings[c & 0xff];
+}
+static int is_allowed_whitespace(unsigned c) {
+    return c == ' ' || Allowed_Whitespace[c & 0xff];
+}
+static int is_allowed_escape(unsigned c) {
+    return Allowed_Escapes[c & 0xff];
+}
+static int is_simple_char(unsigned c) {
+    return !String_No_Passthrough[c & 0xff];
+}
+
+/* Clean up all our macros! */
+#undef INCR_METRIC
+#undef INCR_GENERIC
+#undef INCR_STRINGY_CATCH
+#undef CASE_DIGITS
+#undef INVOKE_ERROR
+#undef STACK_PUSH
+#undef STACK_POP_NOPOS
+#undef STACK_POP
+#undef CALLBACK_AND_POP_NOPOS
+#undef CALLBACK_AND_POP
+#undef SPECIAL_POP
+#undef CUR_CHAR
+#undef DO_CALLBACK
+#undef ENSURE_HVAL
+#undef VERIFY_SPECIAL
+#undef STATE_SPECIAL_LENGTH
+#undef IS_NORMAL_NUMBER
+#undef STATE_NUM_LAST
+#undef FASTPARSE_EXHAUSTED
+#undef FASTPARSE_BREAK
diff --git a/chaos_micro_unit_toolkit/external_lib/bson/jsonsl/jsonsl.h b/chaos_micro_unit_toolkit/external_lib/bson/jsonsl/jsonsl.h
new file mode 100644
index 0000000000000000000000000000000000000000..ee1d39cbc4d96afca18ef58c1d6275e9d6f82f3d
--- /dev/null
+++ b/chaos_micro_unit_toolkit/external_lib/bson/jsonsl/jsonsl.h
@@ -0,0 +1,1004 @@
+/**
+ * JSON Simple/Stacked/Stateful Lexer.
+ * - Does not buffer data
+ * - Maintains state
+ * - Callback oriented
+ * - Lightweight and fast. One source file and one header file
+ *
+ * Copyright (C) 2012-2015 Mark Nunberg
+ * See included LICENSE file for license details.
+ */
+
+#ifndef JSONSL_H_
+#define JSONSL_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <sys/types.h>
+#include <wchar.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifdef JSONSL_USE_WCHAR
+typedef jsonsl_char_t wchar_t;
+typedef jsonsl_uchar_t unsigned wchar_t;
+#else
+typedef char jsonsl_char_t;
+typedef unsigned char jsonsl_uchar_t;
+#endif /* JSONSL_USE_WCHAR */
+
+#ifdef JSONSL_PARSE_NAN
+#define JSONSL__NAN_PROXY JSONSL_SPECIALf_NAN
+#define JSONSL__INF_PROXY JSONSL_SPECIALf_INF
+#else
+#define JSONSL__NAN_PROXY 0
+#define JSONSL__INF_PROXY 0
+#endif
+
+/* Stolen from http-parser.h, and possibly others */
+#if defined(_WIN32) && !defined(__MINGW32__) && (!defined(_MSC_VER) || _MSC_VER<1600)
+typedef __int8 int8_t;
+typedef unsigned __int8 uint8_t;
+typedef __int16 int16_t;
+typedef unsigned __int16 uint16_t;
+typedef __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#if !defined(_MSC_VER) || _MSC_VER<1400
+typedef unsigned int size_t;
+typedef int ssize_t;
+#endif
+#else
+#include <stdint.h>
+#endif
+
+
+#if (!defined(JSONSL_STATE_GENERIC)) && (!defined(JSONSL_STATE_USER_FIELDS))
+#define JSONSL_STATE_GENERIC
+#endif /* !defined JSONSL_STATE_GENERIC */
+
+#ifdef JSONSL_STATE_GENERIC
+#define JSONSL_STATE_USER_FIELDS
+#endif /* JSONSL_STATE_GENERIC */
+
+/* Additional fields for component object */
+#ifndef JSONSL_JPR_COMPONENT_USER_FIELDS
+#define JSONSL_JPR_COMPONENT_USER_FIELDS
+#endif
+
+#ifndef JSONSL_API
+/**
+ * We require a /DJSONSL_DLL so that users already using this as a static
+ * or embedded library don't get confused
+ */
+#if defined(_WIN32) && defined(JSONSL_DLL)
+#define JSONSL_API __declspec(dllexport)
+#else
+#define JSONSL_API
+#endif /* _WIN32 */
+
+#endif /* !JSONSL_API */
+
+#ifndef JSONSL_INLINE
+#if defined(_MSC_VER)
+  #define JSONSL_INLINE __inline
+  #elif defined(__GNUC__)
+  #define JSONSL_INLINE __inline__
+  #else
+  #define JSONSL_INLINE inline
+  #endif /* _MSC_VER or __GNUC__ */
+#endif /* JSONSL_INLINE */
+
+#define JSONSL_MAX_LEVELS 512
+
+struct jsonsl_st;
+typedef struct jsonsl_st *jsonsl_t;
+
+typedef struct jsonsl_jpr_st* jsonsl_jpr_t;
+
+/**
+ * This flag is true when AND'd against a type whose value
+ * must be in "quoutes" i.e. T_HKEY and T_STRING
+ */
+#define JSONSL_Tf_STRINGY 0xffff00
+
+/**
+ * Constant representing the special JSON types.
+ * The values are special and aid in speed (the OBJECT and LIST
+ * values are the char literals of their openings).
+ *
+ * Their actual value is a character which attempts to resemble
+ * some mnemonic reference to the actual type.
+ *
+ * If new types are added, they must fit into the ASCII printable
+ * range (so they should be AND'd with 0x7f and yield something
+ * meaningful)
+ */
+#define JSONSL_XTYPE \
+    X(STRING,   '"'|JSONSL_Tf_STRINGY) \
+    X(HKEY,     '#'|JSONSL_Tf_STRINGY) \
+    X(OBJECT,   '{') \
+    X(LIST,     '[') \
+    X(SPECIAL,  '^') \
+    X(UESCAPE,  'u')
+typedef enum {
+#define X(o, c) \
+    JSONSL_T_##o = c,
+    JSONSL_XTYPE
+    JSONSL_T_UNKNOWN = '?',
+    /* Abstract 'root' object */
+    JSONSL_T_ROOT = 0
+#undef X
+} jsonsl_type_t;
+
+/**
+ * Subtypes for T_SPECIAL. We define them as flags
+ * because more than one type can be applied to a
+ * given object.
+ */
+
+#define JSONSL_XSPECIAL \
+    X(NONE, 0) \
+    X(SIGNED,       1<<0) \
+    X(UNSIGNED,     1<<1) \
+    X(TRUE,         1<<2) \
+    X(FALSE,        1<<3) \
+    X(NULL,         1<<4) \
+    X(FLOAT,        1<<5) \
+    X(EXPONENT,     1<<6) \
+    X(NONASCII,     1<<7) \
+    X(NAN,          1<<8) \
+    X(INF,          1<<9)
+typedef enum {
+#define X(o,b) \
+    JSONSL_SPECIALf_##o = b,
+    JSONSL_XSPECIAL
+#undef X
+    /* Handy flags for checking */
+
+    JSONSL_SPECIALf_UNKNOWN = 1 << 8,
+
+    /** @private Private */
+    JSONSL_SPECIALf_ZERO    = 1 << 9 | JSONSL_SPECIALf_UNSIGNED,
+    /** @private */
+    JSONSL_SPECIALf_DASH    = 1 << 10,
+    /** @private */
+    JSONSL_SPECIALf_POS_INF = (JSONSL_SPECIALf_INF),
+    JSONSL_SPECIALf_NEG_INF = (JSONSL_SPECIALf_INF|JSONSL_SPECIALf_SIGNED),
+
+    /** Type is numeric */
+    JSONSL_SPECIALf_NUMERIC = (JSONSL_SPECIALf_SIGNED| JSONSL_SPECIALf_UNSIGNED),
+
+    /** Type is a boolean */
+    JSONSL_SPECIALf_BOOLEAN = (JSONSL_SPECIALf_TRUE|JSONSL_SPECIALf_FALSE),
+
+    /** Type is an "extended", not integral type (but numeric) */
+   JSONSL_SPECIALf_NUMNOINT =
+       (JSONSL_SPECIALf_FLOAT|JSONSL_SPECIALf_EXPONENT|JSONSL_SPECIALf_NAN
+        |JSONSL_SPECIALf_INF)
+} jsonsl_special_t;
+
+
+/**
+ * These are the various types of stack (or other) events
+ * which will trigger a callback.
+ * Like the type constants, this are also mnemonic
+ */
+#define JSONSL_XACTION \
+    X(PUSH, '+') \
+    X(POP, '-') \
+    X(UESCAPE, 'U') \
+    X(ERROR, '!')
+typedef enum {
+#define X(a,c) \
+    JSONSL_ACTION_##a = c,
+    JSONSL_XACTION
+    JSONSL_ACTION_UNKNOWN = '?'
+#undef X
+} jsonsl_action_t;
+
+
+/**
+ * Various errors which may be thrown while parsing JSON
+ */
+#define JSONSL_XERR \
+/* Trailing garbage characters */ \
+    X(GARBAGE_TRAILING) \
+/* We were expecting a 'special' (numeric, true, false, null) */ \
+    X(SPECIAL_EXPECTED) \
+/* The 'special' value was incomplete */ \
+    X(SPECIAL_INCOMPLETE) \
+/* Found a stray token */ \
+    X(STRAY_TOKEN) \
+/* We were expecting a token before this one */ \
+    X(MISSING_TOKEN) \
+/* Cannot insert because the container is not ready */ \
+    X(CANT_INSERT) \
+/* Found a '\' outside a string */ \
+    X(ESCAPE_OUTSIDE_STRING) \
+/* Found a ':' outside of a hash */ \
+    X(KEY_OUTSIDE_OBJECT) \
+/* found a string outside of a container */ \
+    X(STRING_OUTSIDE_CONTAINER) \
+/* Found a null byte in middle of string */ \
+    X(FOUND_NULL_BYTE) \
+/* Current level exceeds limit specified in constructor */ \
+    X(LEVELS_EXCEEDED) \
+/* Got a } as a result of an opening [ or vice versa */ \
+    X(BRACKET_MISMATCH) \
+/* We expected a key, but got something else instead */ \
+    X(HKEY_EXPECTED) \
+/* We got an illegal control character (bad whitespace or something) */ \
+    X(WEIRD_WHITESPACE) \
+/* Found a \u-escape, but there were less than 4 following hex digits */ \
+    X(UESCAPE_TOOSHORT) \
+/* Invalid two-character escape */ \
+    X(ESCAPE_INVALID) \
+/* Trailing comma */ \
+    X(TRAILING_COMMA) \
+/* An invalid number was passed in a numeric field */ \
+    X(INVALID_NUMBER) \
+/* Value is missing for object */ \
+    X(VALUE_EXPECTED) \
+/* The following are for JPR Stuff */ \
+    \
+/* Found a literal '%' but it was only followed by a single valid hex digit */ \
+    X(PERCENT_BADHEX) \
+/* jsonpointer URI is malformed '/' */ \
+    X(JPR_BADPATH) \
+/* Duplicate slash */ \
+    X(JPR_DUPSLASH) \
+/* No leading root */ \
+    X(JPR_NOROOT) \
+/* Allocation failure */ \
+    X(ENOMEM) \
+/* Invalid unicode codepoint detected (in case of escapes) */ \
+    X(INVALID_CODEPOINT)
+
+typedef enum {
+    JSONSL_ERROR_SUCCESS = 0,
+#define X(e) \
+    JSONSL_ERROR_##e,
+    JSONSL_XERR
+#undef X
+    JSONSL_ERROR_GENERIC
+} jsonsl_error_t;
+
+
+/**
+ * A state is a single level of the stack.
+ * Non-private data (i.e. the 'data' field, see the STATE_GENERIC section)
+ * will remain in tact until the item is popped.
+ *
+ * As a result, it means a parent state object may be accessed from a child
+ * object, (the parents fields will all be valid). This allows a user to create
+ * an ad-hoc hierarchy on top of the JSON one.
+ *
+ */
+struct jsonsl_state_st {
+    /**
+     * The JSON object type
+     */
+    unsigned type;
+
+    /** If this element is special, then its extended type is here */
+    unsigned special_flags;
+
+    /**
+     * The position (in terms of number of bytes since the first call to
+     * jsonsl_feed()) at which the state was first pushed. This includes
+     * opening tokens, if applicable.
+     *
+     * @note For strings (i.e. type & JSONSL_Tf_STRINGY is nonzero) this will
+     * be the position of the first quote.
+     *
+     * @see jsonsl_st::pos which contains the _current_ position and can be
+     * used during a POP callback to get the length of the element.
+     */
+    size_t pos_begin;
+
+    /**FIXME: This is redundant as the same information can be derived from
+     * jsonsl_st::pos at pop-time */
+    size_t pos_cur;
+
+    /**
+     * Level of recursion into nesting. This is mainly a convenience
+     * variable, as this can technically be deduced from the lexer's
+     * level parameter (though the logic is not that simple)
+     */
+    unsigned int level;
+
+
+    /**
+     * how many elements in the object/list.
+     * For objects (hashes), an element is either
+     * a key or a value. Thus for one complete pair,
+     * nelem will be 2.
+     *
+     * For special types, this will hold the sum of the digits.
+     * This only holds true for values which are simple signed/unsigned
+     * numbers. Otherwise a special flag is set, and extra handling is not
+     * performed.
+     */
+    uint64_t nelem;
+
+
+
+    /*TODO: merge this and special_flags into a union */
+
+
+    /**
+     * Useful for an opening nest, this will prevent a callback from being
+     * invoked on this item or any of its children
+     */
+    int ignore_callback;
+
+    /**
+     * Counter which is incremented each time an escape ('\') is encountered.
+     * This is used internally for non-string types and should only be
+     * inspected by the user if the state actually represents a string
+     * type.
+     */
+    unsigned int nescapes;
+
+    /**
+     * Put anything you want here. if JSONSL_STATE_USER_FIELDS is here, then
+     * the macro expansion happens here.
+     *
+     * You can use these fields to store hierarchical or 'tagging' information
+     * for specific objects.
+     *
+     * See the documentation above for the lifetime of the state object (i.e.
+     * if the private data points to allocated memory, it should be freed
+     * when the object is popped, as the state object will be re-used)
+     */
+#ifndef JSONSL_STATE_GENERIC
+    JSONSL_STATE_USER_FIELDS
+#else
+
+    /**
+     * Otherwise, this is a simple void * pointer for anything you want
+     */
+    void *data;
+#endif /* JSONSL_STATE_USER_FIELDS */
+};
+
+/**Gets the number of elements in the list.
+ * @param st The state. Must be of type JSONSL_T_LIST
+ * @return number of elements in the list
+ */
+#define JSONSL_LIST_SIZE(st) ((st)->nelem)
+
+/**Gets the number of key-value pairs in an object
+ * @param st The state. Must be of type JSONSL_T_OBJECT
+ * @return the number of key-value pairs in the object
+ */
+#define JSONSL_OBJECT_SIZE(st) ((st)->nelem / 2)
+
+/**Gets the numeric value.
+ * @param st The state. Must be of type JSONSL_T_SPECIAL and
+ *           special_flags must have the JSONSL_SPECIALf_NUMERIC flag
+ *           set.
+ * @return the numeric value of the state.
+ */
+#define JSONSL_NUMERIC_VALUE(st) ((st)->nelem)
+
+/*
+ * So now we need some special structure for keeping the
+ * JPR info in sync. Preferrably all in a single block
+ * of memory (there's no need for separate allocations.
+ * So we will define a 'table' with the following layout
+ *
+ * Level    nPosbl  JPR1_last   JPR2_last   JPR3_last
+ *
+ * 0        1       NOMATCH     POSSIBLE    POSSIBLE
+ * 1        0       NOMATCH     NOMATCH     COMPLETE
+ * [ table ends here because no further path is possible]
+ *
+ * Where the JPR..n corresponds to the number of JPRs
+ * requested, and nPosble is a quick flag to determine
+ *
+ * the number of possibilities. In the future this might
+ * be made into a proper 'jump' table,
+ *
+ * Since we always mark JPRs from the higher levels descending
+ * into the lower ones, a prospective child match would first
+ * look at the parent table to check the possibilities, and then
+ * see which ones were possible..
+ *
+ * Thus, the size of this blob would be (and these are all ints here)
+ * nLevels * nJPR * 2.
+ *
+ * the 'Width' of the table would be nJPR*2, and the 'height' would be
+ * nlevels
+ */
+
+/**
+ * This is called when a stack change ocurs.
+ *
+ * @param jsn The lexer
+ * @param action The type of action, this can be PUSH or POP
+ * @param state A pointer to the stack currently affected by the action
+ * @param at A pointer to the position of the input buffer which triggered
+ * this action.
+ */
+typedef void (*jsonsl_stack_callback)(
+        jsonsl_t jsn,
+        jsonsl_action_t action,
+        struct jsonsl_state_st* state,
+        const jsonsl_char_t *at);
+
+
+/**
+ * This is called when an error is encountered.
+ * Sometimes it's possible to 'erase' characters (by replacing them
+ * with whitespace). If you think you have corrected the error, you
+ * can return a true value, in which case the parser will backtrack
+ * and try again.
+ *
+ * @param jsn The lexer
+ * @param error The error which was thrown
+ * @param state the current state
+ * @param a pointer to the position of the input buffer which triggered
+ * the error. Note that this is not const, this is because you have the
+ * possibility of modifying the character in an attempt to correct the
+ * error
+ *
+ * @return zero to bail, nonzero to try again (this only makes sense if
+ * the input buffer has been modified by this callback)
+ */
+typedef int (*jsonsl_error_callback)(
+        jsonsl_t jsn,
+        jsonsl_error_t error,
+        struct jsonsl_state_st* state,
+        jsonsl_char_t *at);
+
+struct jsonsl_st {
+    /** Public, read-only */
+
+    /** This is the current level of the stack */
+    unsigned int level;
+
+    /** Flag set to indicate we should stop processing */
+    unsigned int stopfl;
+
+    /**
+     * This is the current position, relative to the beginning
+     * of the stream.
+     */
+    size_t pos;
+
+    /** This is the 'bytes' variable passed to feed() */
+    const jsonsl_char_t *base;
+
+    /** Callback invoked for PUSH actions */
+    jsonsl_stack_callback action_callback_PUSH;
+
+    /** Callback invoked for POP actions */
+    jsonsl_stack_callback action_callback_POP;
+
+    /** Default callback for any action, if neither PUSH or POP callbacks are defined */
+    jsonsl_stack_callback action_callback;
+
+    /**
+     * Do not invoke callbacks for objects deeper than this level.
+     * NOTE: This field establishes the lower bound for ignored callbacks,
+     * and is thus misnamed. `min_ignore_level` would actually make more
+     * sense, but we don't want to break API.
+     */
+    unsigned int max_callback_level;
+
+    /** The error callback. Invoked when an error happens. Should not be NULL */
+    jsonsl_error_callback error_callback;
+
+    /* these are boolean flags you can modify. You will be called
+     * about notification for each of these types if the corresponding
+     * variable is true.
+     */
+
+    /**
+     * @name Callback Booleans.
+     * These determine whether a callback is to be invoked for certain types of objects
+     * @{*/
+
+    /** Boolean flag to enable or disable the invokcation for events on this type*/
+    int call_SPECIAL;
+    int call_OBJECT;
+    int call_LIST;
+    int call_STRING;
+    int call_HKEY;
+    /*@}*/
+
+    /**
+     * @name u-Escape handling
+     * Special handling for the \\u-f00d type sequences. These are meant
+     * to be translated back into the corresponding octet(s).
+     * A special callback (if set) is invoked with *at=='u'. An application
+     * may wish to temporarily suspend parsing and handle the 'u-' sequence
+     * internally (or not).
+     */
+
+     /*@{*/
+
+    /** Callback to be invoked for a u-escape */
+    jsonsl_stack_callback action_callback_UESCAPE;
+
+    /** Boolean flag, whether to invoke the callback */
+    int call_UESCAPE;
+
+    /** Boolean flag, whether we should return after encountering a u-escape:
+     * the callback is invoked and then we return if this is true
+     */
+    int return_UESCAPE;
+    /*@}*/
+
+    struct {
+        int allow_trailing_comma;
+    } options;
+
+    /** Put anything here */
+    void *data;
+
+    /*@{*/
+    /** Private */
+    int in_escape;
+    char expecting;
+    char tok_last;
+    int can_insert;
+    unsigned int levels_max;
+
+#ifndef JSONSL_NO_JPR
+    size_t jpr_count;
+    jsonsl_jpr_t *jprs;
+
+    /* Root pointer for JPR matching information */
+    size_t *jpr_root;
+#endif /* JSONSL_NO_JPR */
+    /*@}*/
+
+    /**
+     * This is the stack. Its upper bound is levels_max, or the
+     * nlevels argument passed to jsonsl_new. If you modify this structure,
+     * make sure that this member is last.
+     */
+    struct jsonsl_state_st stack[1];
+};
+
+
+/**
+ * Creates a new lexer object, with capacity for recursion up to nlevels
+ *
+ * @param nlevels maximum recursion depth
+ */
+JSONSL_API
+jsonsl_t jsonsl_new(int nlevels);
+
+/**
+ * Feeds data into the lexer.
+ *
+ * @param jsn the lexer object
+ * @param bytes new data to be fed
+ * @param nbytes size of new data
+ */
+JSONSL_API
+void jsonsl_feed(jsonsl_t jsn, const jsonsl_char_t *bytes, size_t nbytes);
+
+/**
+ * Resets the internal parser state. This does not free the parser
+ * but does clean it internally, so that the next time feed() is called,
+ * it will be treated as a new stream
+ *
+ * @param jsn the lexer
+ */
+JSONSL_API
+void jsonsl_reset(jsonsl_t jsn);
+
+/**
+ * Frees the lexer, cleaning any allocated memory taken
+ *
+ * @param jsn the lexer
+ */
+JSONSL_API
+void jsonsl_destroy(jsonsl_t jsn);
+
+/**
+ * Gets the 'parent' element, given the current one
+ *
+ * @param jsn the lexer
+ * @param cur the current nest, which should be a struct jsonsl_nest_st
+ */
+static JSONSL_INLINE
+struct jsonsl_state_st *jsonsl_last_state(const jsonsl_t jsn,
+                                          const struct jsonsl_state_st *state)
+{
+    /* Don't complain about overriding array bounds */
+    if (state->level > 1) {
+        return jsn->stack + state->level - 1;
+    } else {
+        return NULL;
+    }
+}
+
+/**
+ * Gets the state of the last fully consumed child of this parent. This is
+ * only valid in the parent's POP callback.
+ *
+ * @param the lexer
+ * @return A pointer to the child.
+ */
+static JSONSL_INLINE
+struct jsonsl_state_st *jsonsl_last_child(const jsonsl_t jsn,
+                                          const struct jsonsl_state_st *parent)
+{
+    return jsn->stack + (parent->level + 1);
+}
+
+/**Call to instruct the parser to stop parsing and return. This is valid
+ * only from within a callback */
+static JSONSL_INLINE
+void jsonsl_stop(jsonsl_t jsn)
+{
+    jsn->stopfl = 1;
+}
+
+/**
+ * This enables receiving callbacks on all events. Doesn't do
+ * anything special but helps avoid some boilerplate.
+ * This does not touch the UESCAPE callbacks or flags.
+ */
+static JSONSL_INLINE
+void jsonsl_enable_all_callbacks(jsonsl_t jsn)
+{
+    jsn->call_HKEY = 1;
+    jsn->call_STRING = 1;
+    jsn->call_OBJECT = 1;
+    jsn->call_SPECIAL = 1;
+    jsn->call_LIST = 1;
+}
+
+/**
+ * A macro which returns true if the current state object can
+ * have children. This means a list type or an object type.
+ */
+#define JSONSL_STATE_IS_CONTAINER(state) \
+        (state->type == JSONSL_T_OBJECT || state->type == JSONSL_T_LIST)
+
+/**
+ * These two functions, dump a string representation
+ * of the error or type, respectively. They will never
+ * return NULL
+ */
+JSONSL_API
+const char* jsonsl_strerror(jsonsl_error_t err);
+JSONSL_API
+const char* jsonsl_strtype(jsonsl_type_t jt);
+
+/**
+ * Dumps global metrics to the screen. This is a noop unless
+ * jsonsl was compiled with JSONSL_USE_METRICS
+ */
+JSONSL_API
+void jsonsl_dump_global_metrics(void);
+
+/* This macro just here for editors to do code folding */
+#ifndef JSONSL_NO_JPR
+
+/**
+ * @name JSON Pointer API
+ *
+ * JSONPointer API. This isn't really related to the lexer (at least not yet)
+ * JSONPointer provides an extremely simple specification for providing
+ * locations within JSON objects. We will extend it a bit and allow for
+ * providing 'wildcard' characters by which to be able to 'query' the stream.
+ *
+ * See http://tools.ietf.org/html/draft-pbryan-zyp-json-pointer-00
+ *
+ * Currently I'm implementing the 'single query' API which can only use a single
+ * query component. In the future I will integrate my yet-to-be-published
+ * Boyer-Moore-esque prefix searching implementation, in order to allow
+ * multiple paths to be merged into one for quick and efficient searching.
+ *
+ *
+ * JPR (as we'll refer to it within the source) can be used by splitting
+ * the components into mutliple sections, and incrementally 'track' each
+ * component. When JSONSL delivers a 'pop' callback for a string, or a 'push'
+ * callback for an object, we will check to see whether the index matching
+ * the component corresponding to the current level contains a match
+ * for our path.
+ *
+ * In order to do this properly, a structure must be maintained within the
+ * parent indicating whether its children are possible matches. This flag
+ * will be 'inherited' by call children which may conform to the match
+ * specification, and discarded by all which do not (thereby eliminating
+ * their children from inheriting it).
+ *
+ * A successful match is a complete one. One can provide multiple paths with
+ * multiple levels of matches e.g.
+ *  /foo/bar/baz/^/blah
+ *
+ *  @{
+ */
+
+/** The wildcard character */
+#ifndef JSONSL_PATH_WILDCARD_CHAR
+#define JSONSL_PATH_WILDCARD_CHAR '^'
+#endif /* WILDCARD_CHAR */
+
+#define JSONSL_XMATCH \
+    X(COMPLETE,1) \
+    X(POSSIBLE,0) \
+    X(NOMATCH,-1) \
+    X(TYPE_MISMATCH, -2)
+
+typedef enum {
+
+#define X(T,v) \
+    JSONSL_MATCH_##T = v,
+    JSONSL_XMATCH
+
+#undef X
+    JSONSL_MATCH_UNKNOWN
+} jsonsl_jpr_match_t;
+
+typedef enum {
+    JSONSL_PATH_STRING = 1,
+    JSONSL_PATH_WILDCARD,
+    JSONSL_PATH_NUMERIC,
+    JSONSL_PATH_ROOT,
+
+    /* Special */
+    JSONSL_PATH_INVALID = -1,
+    JSONSL_PATH_NONE = 0
+} jsonsl_jpr_type_t;
+
+struct jsonsl_jpr_component_st {
+    /** The string the component points to */
+    char *pstr;
+    /** if this is a numeric type, the number is 'cached' here */
+    unsigned long idx;
+    /** The length of the string */
+    size_t len;
+    /** The type of component (NUMERIC or STRING) */
+    jsonsl_jpr_type_t ptype;
+
+    /** Set this to true to enforce type checking between dict keys and array
+     * indices. jsonsl_jpr_match() will return TYPE_MISMATCH if it detects
+     * that an array index is actually a child of a dictionary. */
+    short is_arridx;
+
+    /* Extra fields (for more advanced searches. Default is empty) */
+    JSONSL_JPR_COMPONENT_USER_FIELDS
+};
+
+struct jsonsl_jpr_st {
+    /** Path components */
+    struct jsonsl_jpr_component_st *components;
+    size_t ncomponents;
+
+    /**Type of the match to be expected. If nonzero, will be compared against
+     * the actual type */
+    unsigned match_type;
+
+    /** Base of allocated string for components */
+    char *basestr;
+
+    /** The original match string. Useful for returning to the user */
+    char *orig;
+    size_t norig;
+};
+
+/**
+ * Create a new JPR object.
+ *
+ * @param path the JSONPointer path specification.
+ * @param errp a pointer to a jsonsl_error_t. If this function returns NULL,
+ * then more details will be in this variable.
+ *
+ * @return a new jsonsl_jpr_t object, or NULL on error.
+ */
+JSONSL_API
+jsonsl_jpr_t jsonsl_jpr_new(const char *path, jsonsl_error_t *errp);
+
+/**
+ * Destroy a JPR object
+ */
+JSONSL_API
+void jsonsl_jpr_destroy(jsonsl_jpr_t jpr);
+
+/**
+ * Match a JSON object against a type and specific level
+ *
+ * @param jpr the JPR object
+ * @param parent_type the type of the parent (should be T_LIST or T_OBJECT)
+ * @param parent_level the level of the parent
+ * @param key the 'key' of the child. If the parent is an array, this should be
+ * empty.
+ * @param nkey - the length of the key. If the parent is an array (T_LIST), then
+ * this should be the current index.
+ *
+ * NOTE: The key of the child means any kind of associative data related to the
+ * element. Thus: <<< { "foo" : [ >>,
+ * the opening array's key is "foo".
+ *
+ * @return a status constant. This indicates whether a match was excluded, possible,
+ * or successful.
+ */
+JSONSL_API
+jsonsl_jpr_match_t jsonsl_jpr_match(jsonsl_jpr_t jpr,
+                                    unsigned int parent_type,
+                                    unsigned int parent_level,
+                                    const char *key, size_t nkey);
+
+/**
+ * Alternate matching algorithm. This matching algorithm does not use
+ * JSONPointer but relies on a more structured searching mechanism. It
+ * assumes that there is a clear distinction between array indices and
+ * object keys. In this case, the jsonsl_path_component_st::ptype should
+ * be set to @ref JSONSL_PATH_NUMERIC for an array index (the
+ * jsonsl_path_comonent_st::is_arridx field will be removed in a future
+ * version).
+ *
+ * @param jpr The path
+ * @param parent The parent structure. Can be NULL if this is the root object
+ * @param child The child structure. Should not be NULL
+ * @param key Object key, if an object
+ * @param nkey Length of object key
+ * @return Status constant if successful
+ *
+ * @note
+ * For successful matching, both the key and the path itself should be normalized
+ * to contain 'proper' utf8 sequences rather than utf16 '\uXXXX' escapes. This
+ * should currently be done in the application. Another version of this function
+ * may use a temporary buffer in such circumstances (allocated by the application).
+ *
+ * Since this function also checks the state of the child, it should only
+ * be called on PUSH callbacks, and not POP callbacks
+ */
+JSONSL_API
+jsonsl_jpr_match_t
+jsonsl_path_match(jsonsl_jpr_t jpr,
+                  const struct jsonsl_state_st *parent,
+                  const struct jsonsl_state_st *child,
+                  const char *key, size_t nkey);
+
+
+/**
+ * Associate a set of JPR objects with a lexer instance.
+ * This should be called before the lexer has been fed any data (and
+ * behavior is undefined if you don't adhere to this).
+ *
+ * After using this function, you may subsequently call match_state() on
+ * given states (presumably from within the callbacks).
+ *
+ * Note that currently the first JPR is the quickest and comes
+ * pre-allocated with the state structure. Further JPR objects
+ * are chained.
+ *
+ * @param jsn The lexer
+ * @param jprs An array of jsonsl_jpr_t objects
+ * @param njprs How many elements in the jprs array.
+ */
+JSONSL_API
+void jsonsl_jpr_match_state_init(jsonsl_t jsn,
+                                 jsonsl_jpr_t *jprs,
+                                 size_t njprs);
+
+/**
+ * This follows the same semantics as the normal match,
+ * except we infer parent and type information from the relevant state objects.
+ * The match status (for all possible JPR objects) is set in the *out parameter.
+ *
+ * If a match has succeeded, then its JPR object will be returned. In all other
+ * instances, NULL is returned;
+ *
+ * @param jpr The jsonsl_jpr_t handle
+ * @param state The jsonsl_state_st which is a candidate
+ * @param key The hash key (if applicable, can be NULL if parent is list)
+ * @param nkey Length of hash key (if applicable, can be zero if parent is list)
+ * @param out A pointer to a jsonsl_jpr_match_t. This will be populated with
+ * the match result
+ *
+ * @return If a match was completed in full, then the JPR object containing
+ * the matching path will be returned. Otherwise, the return is NULL (note, this
+ * does not mean matching has failed, it can still be part of the match: check
+ * the out parameter).
+ */
+JSONSL_API
+jsonsl_jpr_t jsonsl_jpr_match_state(jsonsl_t jsn,
+                                    struct jsonsl_state_st *state,
+                                    const char *key,
+                                    size_t nkey,
+                                    jsonsl_jpr_match_t *out);
+
+
+/**
+ * Cleanup any memory allocated and any states set by
+ * match_state_init() and match_state()
+ * @param jsn The lexer
+ */
+JSONSL_API
+void jsonsl_jpr_match_state_cleanup(jsonsl_t jsn);
+
+/**
+ * Return a string representation of the match result returned by match()
+ */
+JSONSL_API
+const char *jsonsl_strmatchtype(jsonsl_jpr_match_t match);
+
+/* @}*/
+
+/**
+ * Utility function to convert escape sequences into their original form.
+ *
+ * The decoders I've sampled do not seem to specify a standard behavior of what
+ * to escape/unescape.
+ *
+ * RFC 4627 Mandates only that the quoute, backslash, and ASCII control
+ * characters (0x00-0x1f) be escaped. It is often common for applications
+ * to escape a '/' - however this may also be desired behavior. the JSON
+ * spec is not clear on this, and therefore jsonsl leaves it up to you.
+ *
+ * Additionally, sometimes you may wish to _normalize_ JSON. This is specifically
+ * true when dealing with 'u-escapes' which can be expressed perfectly fine
+ * as utf8. One use case for normalization is JPR string comparison, in which
+ * case two effectively equivalent strings may not match because one is using
+ * u-escapes and the other proper utf8. To normalize u-escapes only, pass in
+ * an empty `toEscape` table, enabling only the `u` index.
+ *
+ * @param in The input string.
+ * @param out An allocated output (should be the same size as in)
+ * @param len the size of the buffer
+ * @param toEscape - A sparse array of characters to unescape. Characters
+ * which are not present in this array, e.g. toEscape['c'] == 0 will be
+ * ignored and passed to the output in their original form.
+ * @param oflags If not null, and a \uXXXX escape expands to a non-ascii byte,
+ * then this variable will have the SPECIALf_NONASCII flag on.
+ *
+ * @param err A pointer to an error variable. If an error ocurrs, it will be
+ * set in this variable
+ * @param errat If not null and an error occurs, this will be set to point
+ * to the position within the string at which the offending character was
+ * encountered.
+ *
+ * @return The effective size of the output buffer.
+ *
+ * @note
+ * This function now encodes the UTF8 equivalents of utf16 escapes (i.e.
+ * 'u-escapes'). Previously this would encode the escapes as utf16 literals,
+ * which while still correct in some sense was confusing for many (especially
+ * considering that the inputs were variations of char).
+ *
+ * @note
+ * The output buffer will never be larger than the input buffer, since
+ * standard escape sequences (i.e. '\t') occupy two bytes in the source
+ * but only one byte (when unescaped) in the output. Likewise u-escapes
+ * (i.e. \uXXXX) will occupy six bytes in the source, but at the most
+ * two bytes when escaped.
+ */
+JSONSL_API
+size_t jsonsl_util_unescape_ex(const char *in,
+                               char *out,
+                               size_t len,
+                               const int toEscape[128],
+                               unsigned *oflags,
+                               jsonsl_error_t *err,
+                               const char **errat);
+
+/**
+ * Convenience macro to avoid passing too many parameters
+ */
+#define jsonsl_util_unescape(in, out, len, toEscape, err) \
+    jsonsl_util_unescape_ex(in, out, len, toEscape, NULL, err, NULL)
+
+#endif /* JSONSL_NO_JPR */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* JSONSL_H_ */
diff --git a/chaos_micro_unit_toolkit/external_lib/json.h b/chaos_micro_unit_toolkit/external_lib/json.h
deleted file mode 100644
index 0738fd39065be0677e9012a3102161bdf37dc654..0000000000000000000000000000000000000000
--- a/chaos_micro_unit_toolkit/external_lib/json.h
+++ /dev/null
@@ -1,2176 +0,0 @@
-/// Json-cpp amalgated header (http://jsoncpp.sourceforge.net/).
-/// It is intended to be used with #include "json/json.h"
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: LICENSE
-// //////////////////////////////////////////////////////////////////////
-
-/*
-The JsonCpp library's source code, including accompanying documentation, 
-tests and demonstration applications, are licensed under the following
-conditions...
-
-Baptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all 
-jurisdictions which recognize such a disclaimer. In such jurisdictions, 
-this software is released into the Public Domain.
-
-In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
-2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur and
-The JsonCpp Authors, and is released under the terms of the MIT License (see below).
-
-In jurisdictions which recognize Public Domain property, the user of this 
-software may choose to accept it either as 1) Public Domain, 2) under the 
-conditions of the MIT License (see below), or 3) under the terms of dual 
-Public Domain/MIT License conditions described here, as they choose.
-
-The MIT License is about as close to Public Domain as a license can get, and is
-described in clear, concise terms at:
-
-   http://en.wikipedia.org/wiki/MIT_License
-   
-The full text of the MIT License follows:
-
-========================================================================
-Copyright (c) 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use, copy,
-modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-========================================================================
-(END LICENSE TEXT)
-
-The MIT license is compatible with both the GPL and commercial
-software, affording one all of the rights of Public Domain with the
-minor nuisance of being required to keep the above copyright notice
-and license text in the source code. Note also that by accepting the
-Public Domain "license" you can re-license your copy using whatever
-license you like.
-
-*/
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: LICENSE
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-#ifndef JSON_AMALGATED_H_INCLUDED
-# define JSON_AMALGATED_H_INCLUDED
-/// If defined, indicates that the source file is amalgated
-/// to prevent private header inclusion.
-#define JSON_IS_AMALGAMATION
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: include/json/version.h
-// //////////////////////////////////////////////////////////////////////
-
-// DO NOT EDIT. This file (and "version") is generated by CMake.
-// Run CMake configure step to update it.
-#ifndef JSON_VERSION_H_INCLUDED
-# define JSON_VERSION_H_INCLUDED
-
-# define JSONCPP_VERSION_STRING "1.8.1"
-# define JSONCPP_VERSION_MAJOR 1
-# define JSONCPP_VERSION_MINOR 8
-# define JSONCPP_VERSION_PATCH 1
-# define JSONCPP_VERSION_QUALIFIER
-# define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8))
-
-#ifdef JSONCPP_USING_SECURE_MEMORY
-#undef JSONCPP_USING_SECURE_MEMORY
-#endif
-#define JSONCPP_USING_SECURE_MEMORY 0
-// If non-zero, the library zeroes any memory that it has allocated before
-// it frees its memory.
-
-#endif // JSON_VERSION_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: include/json/version.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: include/json/config.h
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#ifndef JSON_CONFIG_H_INCLUDED
-#define JSON_CONFIG_H_INCLUDED
-#include <stddef.h>
-#include <string> //typedef String
-#include <stdint.h> //typedef int64_t, uint64_t
-
-/// If defined, indicates that json library is embedded in CppTL library.
-//# define JSON_IN_CPPTL 1
-
-/// If defined, indicates that json may leverage CppTL library
-//#  define JSON_USE_CPPTL 1
-/// If defined, indicates that cpptl vector based map should be used instead of
-/// std::map
-/// as Value container.
-//#  define JSON_USE_CPPTL_SMALLMAP 1
-
-// If non-zero, the library uses exceptions to report bad input instead of C
-// assertion macros. The default is to use exceptions.
-#ifndef JSON_USE_EXCEPTION
-#define JSON_USE_EXCEPTION 1
-#endif
-
-/// If defined, indicates that the source file is amalgated
-/// to prevent private header inclusion.
-/// Remarks: it is automatically defined in the generated amalgated header.
-// #define JSON_IS_AMALGAMATION
-
-#ifdef JSON_IN_CPPTL
-#include <cpptl/config.h>
-#ifndef JSON_USE_CPPTL
-#define JSON_USE_CPPTL 1
-#endif
-#endif
-
-#ifdef JSON_IN_CPPTL
-#define JSON_API CPPTL_API
-#elif defined(JSON_DLL_BUILD)
-#if defined(_MSC_VER) || defined(__MINGW32__)
-#define JSON_API __declspec(dllexport)
-#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
-#endif // if defined(_MSC_VER)
-#elif defined(JSON_DLL)
-#if defined(_MSC_VER) || defined(__MINGW32__)
-#define JSON_API __declspec(dllimport)
-#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
-#endif // if defined(_MSC_VER)
-#endif // ifdef JSON_IN_CPPTL
-#if !defined(JSON_API)
-#define JSON_API
-#endif
-
-// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for
-// integer
-// Storages, and 64 bits integer support is disabled.
-// #define JSON_NO_INT64 1
-
-#if defined(_MSC_VER) // MSVC
-#  if _MSC_VER <= 1200 // MSVC 6
-    // Microsoft Visual Studio 6 only support conversion from __int64 to double
-    // (no conversion from unsigned __int64).
-#    define JSON_USE_INT64_DOUBLE_CONVERSION 1
-    // Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255'
-    // characters in the debug information)
-    // All projects I've ever seen with VS6 were using this globally (not bothering
-    // with pragma push/pop).
-#    pragma warning(disable : 4786)
-#  endif // MSVC 6
-
-#  if _MSC_VER >= 1500 // MSVC 2008
-    /// Indicates that the following function is deprecated.
-#    define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
-#  endif
-
-#endif // defined(_MSC_VER)
-
-// In c++11 the override keyword allows you to explicity define that a function
-// is intended to override the base-class version.  This makes the code more
-// managable and fixes a set of common hard-to-find bugs.
-#if __cplusplus >= 201103L
-# define JSONCPP_OVERRIDE override
-# define JSONCPP_NOEXCEPT noexcept
-#elif defined(_MSC_VER) && _MSC_VER > 1600 && _MSC_VER < 1900
-# define JSONCPP_OVERRIDE override
-# define JSONCPP_NOEXCEPT throw()
-#elif defined(_MSC_VER) && _MSC_VER >= 1900
-# define JSONCPP_OVERRIDE override
-# define JSONCPP_NOEXCEPT noexcept
-#else
-# define JSONCPP_OVERRIDE
-# define JSONCPP_NOEXCEPT throw()
-#endif
-
-#ifndef JSON_HAS_RVALUE_REFERENCES
-
-#if defined(_MSC_VER) && _MSC_VER >= 1600 // MSVC >= 2010
-#define JSON_HAS_RVALUE_REFERENCES 1
-#endif // MSVC >= 2010
-
-#ifdef __clang__
-#if __has_feature(cxx_rvalue_references)
-#define JSON_HAS_RVALUE_REFERENCES 1
-#endif  // has_feature
-
-#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
-#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)
-#define JSON_HAS_RVALUE_REFERENCES 1
-#endif  // GXX_EXPERIMENTAL
-
-#endif // __clang__ || __GNUC__
-
-#endif // not defined JSON_HAS_RVALUE_REFERENCES
-
-#ifndef JSON_HAS_RVALUE_REFERENCES
-#define JSON_HAS_RVALUE_REFERENCES 0
-#endif
-
-#ifdef __clang__
-#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
-#  if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
-#    define JSONCPP_DEPRECATED(message)  __attribute__ ((deprecated(message)))
-#  elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
-#    define JSONCPP_DEPRECATED(message)  __attribute__((__deprecated__))
-#  endif  // GNUC version
-#endif // __clang__ || __GNUC__
-
-#if !defined(JSONCPP_DEPRECATED)
-#define JSONCPP_DEPRECATED(message)
-#endif // if !defined(JSONCPP_DEPRECATED)
-
-#if __GNUC__ >= 6
-#  define JSON_USE_INT64_DOUBLE_CONVERSION 1
-#endif
-
-#if !defined(JSON_IS_AMALGAMATION)
-
-# include "version.h"
-
-# if JSONCPP_USING_SECURE_MEMORY
-#  include "allocator.h" //typedef Allocator
-# endif
-
-#endif // if !defined(JSON_IS_AMALGAMATION)
-
-namespace Json {
-typedef int Int;
-typedef unsigned int UInt;
-#if defined(JSON_NO_INT64)
-typedef int LargestInt;
-typedef unsigned int LargestUInt;
-#undef JSON_HAS_INT64
-#else                 // if defined(JSON_NO_INT64)
-// For Microsoft Visual use specific types as long long is not supported
-#if defined(_MSC_VER) // Microsoft Visual Studio
-typedef __int64 Int64;
-typedef unsigned __int64 UInt64;
-#else                 // if defined(_MSC_VER) // Other platforms, use long long
-typedef int64_t Int64;
-typedef uint64_t UInt64;
-#endif // if defined(_MSC_VER)
-typedef Int64 LargestInt;
-typedef UInt64 LargestUInt;
-#define JSON_HAS_INT64
-#endif // if defined(JSON_NO_INT64)
-#if JSONCPP_USING_SECURE_MEMORY
-#define JSONCPP_STRING        std::basic_string<char, std::char_traits<char>, Json::SecureAllocator<char> >
-#define JSONCPP_OSTRINGSTREAM std::basic_ostringstream<char, std::char_traits<char>, Json::SecureAllocator<char> >
-#define JSONCPP_OSTREAM       std::basic_ostream<char, std::char_traits<char>>
-#define JSONCPP_ISTRINGSTREAM std::basic_istringstream<char, std::char_traits<char>, Json::SecureAllocator<char> >
-#define JSONCPP_ISTREAM       std::istream
-#else
-#define JSONCPP_STRING        std::string
-#define JSONCPP_OSTRINGSTREAM std::ostringstream
-#define JSONCPP_OSTREAM       std::ostream
-#define JSONCPP_ISTRINGSTREAM std::istringstream
-#define JSONCPP_ISTREAM       std::istream
-#endif // if JSONCPP_USING_SECURE_MEMORY
-} // end namespace Json
-
-#endif // JSON_CONFIG_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: include/json/config.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: include/json/forwards.h
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#ifndef JSON_FORWARDS_H_INCLUDED
-#define JSON_FORWARDS_H_INCLUDED
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include "config.h"
-#endif // if !defined(JSON_IS_AMALGAMATION)
-
-namespace Json {
-
-// writer.h
-class FastWriter;
-class StyledWriter;
-
-// reader.h
-class Reader;
-
-// features.h
-class Features;
-
-// value.h
-typedef unsigned int ArrayIndex;
-class StaticString;
-class Path;
-class PathArgument;
-class Value;
-class ValueIteratorBase;
-class ValueIterator;
-class ValueConstIterator;
-
-} // namespace Json
-
-#endif // JSON_FORWARDS_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: include/json/forwards.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: include/json/features.h
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#ifndef CPPTL_JSON_FEATURES_H_INCLUDED
-#define CPPTL_JSON_FEATURES_H_INCLUDED
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include "forwards.h"
-#endif // if !defined(JSON_IS_AMALGAMATION)
-
-#pragma pack(push, 8)
-
-namespace Json {
-
-/** \brief Configuration passed to reader and writer.
- * This configuration object can be used to force the Reader or Writer
- * to behave in a standard conforming way.
- */
-class JSON_API Features {
-public:
-  /** \brief A configuration that allows all features and assumes all strings
-   * are UTF-8.
-   * - C & C++ comments are allowed
-   * - Root object can be any JSON value
-   * - Assumes Value strings are encoded in UTF-8
-   */
-  static Features all();
-
-  /** \brief A configuration that is strictly compatible with the JSON
-   * specification.
-   * - Comments are forbidden.
-   * - Root object must be either an array or an object value.
-   * - Assumes Value strings are encoded in UTF-8
-   */
-  static Features strictMode();
-
-  /** \brief Initialize the configuration like JsonConfig::allFeatures;
-   */
-  Features();
-
-  /// \c true if comments are allowed. Default: \c true.
-  bool allowComments_;
-
-  /// \c true if root must be either an array or an object value. Default: \c
-  /// false.
-  bool strictRoot_;
-
-  /// \c true if dropped null placeholders are allowed. Default: \c false.
-  bool allowDroppedNullPlaceholders_;
-
-  /// \c true if numeric object key are allowed. Default: \c false.
-  bool allowNumericKeys_;
-};
-
-} // namespace Json
-
-#pragma pack(pop)
-
-#endif // CPPTL_JSON_FEATURES_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: include/json/features.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: include/json/value.h
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#ifndef CPPTL_JSON_H_INCLUDED
-#define CPPTL_JSON_H_INCLUDED
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include "forwards.h"
-#endif // if !defined(JSON_IS_AMALGAMATION)
-#include <string>
-#include <vector>
-#include <exception>
-
-#ifndef JSON_USE_CPPTL_SMALLMAP
-#include <map>
-#else
-#include <cpptl/smallmap.h>
-#endif
-#ifdef JSON_USE_CPPTL
-#include <cpptl/forwards.h>
-#endif
-
-//Conditional NORETURN attribute on the throw functions would:
-// a) suppress false positives from static code analysis
-// b) possibly improve optimization opportunities.
-#if !defined(JSONCPP_NORETURN)
-#  if defined(_MSC_VER)
-#    define JSONCPP_NORETURN __declspec(noreturn)
-#  elif defined(__GNUC__)
-#    define JSONCPP_NORETURN __attribute__ ((__noreturn__))
-#  else
-#    define JSONCPP_NORETURN
-#  endif
-#endif
-
-// Disable warning C4251: <data member>: <type> needs to have dll-interface to
-// be used by...
-#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-#pragma warning(push)
-#pragma warning(disable : 4251)
-#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-
-#pragma pack(push, 8)
-
-/** \brief JSON (JavaScript Object Notation).
- */
-namespace Json {
-
-/** Base class for all exceptions we throw.
- *
- * We use nothing but these internally. Of course, STL can throw others.
- */
-class JSON_API Exception : public std::exception {
-public:
-  Exception(JSONCPP_STRING const& msg);
-  ~Exception() JSONCPP_NOEXCEPT JSONCPP_OVERRIDE;
-  char const* what() const JSONCPP_NOEXCEPT JSONCPP_OVERRIDE;
-protected:
-  JSONCPP_STRING msg_;
-};
-
-/** Exceptions which the user cannot easily avoid.
- *
- * E.g. out-of-memory (when we use malloc), stack-overflow, malicious input
- *
- * \remark derived from Json::Exception
- */
-class JSON_API RuntimeError : public Exception {
-public:
-  RuntimeError(JSONCPP_STRING const& msg);
-};
-
-/** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros.
- *
- * These are precondition-violations (user bugs) and internal errors (our bugs).
- *
- * \remark derived from Json::Exception
- */
-class JSON_API LogicError : public Exception {
-public:
-  LogicError(JSONCPP_STRING const& msg);
-};
-
-/// used internally
-JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg);
-/// used internally
-JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg);
-
-/** \brief Type of the value held by a Value object.
- */
-enum ValueType {
-  nullValue = 0, ///< 'null' value
-  intValue,      ///< signed integer value
-  uintValue,     ///< unsigned integer value
-  realValue,     ///< double value
-  stringValue,   ///< UTF-8 string value
-  booleanValue,  ///< bool value
-  arrayValue,    ///< array value (ordered list)
-  objectValue    ///< object value (collection of name/value pairs).
-};
-
-enum CommentPlacement {
-  commentBefore = 0,      ///< a comment placed on the line before a value
-  commentAfterOnSameLine, ///< a comment just after a value on the same line
-  commentAfter, ///< a comment on the line after a value (only make sense for
-  /// root value)
-  numberOfCommentPlacement
-};
-
-//# ifdef JSON_USE_CPPTL
-//   typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;
-//   typedef CppTL::AnyEnumerator<const Value &> EnumValues;
-//# endif
-
-/** \brief Lightweight wrapper to tag static string.
- *
- * Value constructor and objectValue member assignement takes advantage of the
- * StaticString and avoid the cost of string duplication when storing the
- * string or the member name.
- *
- * Example of usage:
- * \code
- * Json::Value aValue( StaticString("some text") );
- * Json::Value object;
- * static const StaticString code("code");
- * object[code] = 1234;
- * \endcode
- */
-class JSON_API StaticString {
-public:
-  explicit StaticString(const char* czstring) : c_str_(czstring) {}
-
-  operator const char*() const { return c_str_; }
-
-  const char* c_str() const { return c_str_; }
-
-private:
-  const char* c_str_;
-};
-
-/** \brief Represents a <a HREF="http://www.json.org">JSON</a> value.
- *
- * This class is a discriminated union wrapper that can represents a:
- * - signed integer [range: Value::minInt - Value::maxInt]
- * - unsigned integer (range: 0 - Value::maxUInt)
- * - double
- * - UTF-8 string
- * - boolean
- * - 'null'
- * - an ordered list of Value
- * - collection of name/value pairs (javascript object)
- *
- * The type of the held value is represented by a #ValueType and
- * can be obtained using type().
- *
- * Values of an #objectValue or #arrayValue can be accessed using operator[]()
- * methods.
- * Non-const methods will automatically create the a #nullValue element
- * if it does not exist.
- * The sequence of an #arrayValue will be automatically resized and initialized
- * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue.
- *
- * The get() methods can be used to obtain default value in the case the
- * required element does not exist.
- *
- * It is possible to iterate over the list of a #objectValue values using
- * the getMemberNames() method.
- *
- * \note #Value string-length fit in size_t, but keys must be < 2^30.
- * (The reason is an implementation detail.) A #CharReader will raise an
- * exception if a bound is exceeded to avoid security holes in your app,
- * but the Value API does *not* check bounds. That is the responsibility
- * of the caller.
- */
-class JSON_API Value {
-  friend class ValueIteratorBase;
-public:
-  typedef std::vector<JSONCPP_STRING> Members;
-  typedef ValueIterator iterator;
-  typedef ValueConstIterator const_iterator;
-  typedef Json::UInt UInt;
-  typedef Json::Int Int;
-#if defined(JSON_HAS_INT64)
-  typedef Json::UInt64 UInt64;
-  typedef Json::Int64 Int64;
-#endif // defined(JSON_HAS_INT64)
-  typedef Json::LargestInt LargestInt;
-  typedef Json::LargestUInt LargestUInt;
-  typedef Json::ArrayIndex ArrayIndex;
-
-  static const Value& null;  ///< We regret this reference to a global instance; prefer the simpler Value().
-  static const Value& nullRef;  ///< just a kludge for binary-compatibility; same as null
-  static Value const& nullSingleton(); ///< Prefer this to null or nullRef.
-
-  /// Minimum signed integer value that can be stored in a Json::Value.
-  static const LargestInt minLargestInt;
-  /// Maximum signed integer value that can be stored in a Json::Value.
-  static const LargestInt maxLargestInt;
-  /// Maximum unsigned integer value that can be stored in a Json::Value.
-  static const LargestUInt maxLargestUInt;
-
-  /// Minimum signed int value that can be stored in a Json::Value.
-  static const Int minInt;
-  /// Maximum signed int value that can be stored in a Json::Value.
-  static const Int maxInt;
-  /// Maximum unsigned int value that can be stored in a Json::Value.
-  static const UInt maxUInt;
-
-#if defined(JSON_HAS_INT64)
-  /// Minimum signed 64 bits int value that can be stored in a Json::Value.
-  static const Int64 minInt64;
-  /// Maximum signed 64 bits int value that can be stored in a Json::Value.
-  static const Int64 maxInt64;
-  /// Maximum unsigned 64 bits int value that can be stored in a Json::Value.
-  static const UInt64 maxUInt64;
-#endif // defined(JSON_HAS_INT64)
-
-private:
-#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
-  class CZString {
-  public:
-    enum DuplicationPolicy {
-      noDuplication = 0,
-      duplicate,
-      duplicateOnCopy
-    };
-    CZString(ArrayIndex index);
-    CZString(char const* str, unsigned length, DuplicationPolicy allocate);
-    CZString(CZString const& other);
-#if JSON_HAS_RVALUE_REFERENCES
-    CZString(CZString&& other);
-#endif
-    ~CZString();
-    CZString& operator=(const CZString& other);
-
-#if JSON_HAS_RVALUE_REFERENCES
-    CZString& operator=(CZString&& other);
-#endif
-
-    bool operator<(CZString const& other) const;
-    bool operator==(CZString const& other) const;
-    ArrayIndex index() const;
-    //const char* c_str() const; ///< \deprecated
-    char const* data() const;
-    unsigned length() const;
-    bool isStaticString() const;
-
-  private:
-    void swap(CZString& other);
-
-    struct StringStorage {
-      unsigned policy_: 2;
-      unsigned length_: 30; // 1GB max
-    };
-
-    char const* cstr_;  // actually, a prefixed string, unless policy is noDup
-    union {
-      ArrayIndex index_;
-      StringStorage storage_;
-    };
-  };
-
-public:
-#ifndef JSON_USE_CPPTL_SMALLMAP
-  typedef std::map<CZString, Value> ObjectValues;
-#else
-  typedef CppTL::SmallMap<CZString, Value> ObjectValues;
-#endif // ifndef JSON_USE_CPPTL_SMALLMAP
-#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
-
-public:
-  /** \brief Create a default Value of the given type.
-
-    This is a very useful constructor.
-    To create an empty array, pass arrayValue.
-    To create an empty object, pass objectValue.
-    Another Value can then be set to this one by assignment.
-This is useful since clear() and resize() will not alter types.
-
-    Examples:
-\code
-Json::Value null_value; // null
-Json::Value arr_value(Json::arrayValue); // []
-Json::Value obj_value(Json::objectValue); // {}
-\endcode
-  */
-  Value(ValueType type = nullValue);
-  Value(Int value);
-  Value(UInt value);
-#if defined(JSON_HAS_INT64)
-  Value(Int64 value);
-  Value(UInt64 value);
-#endif // if defined(JSON_HAS_INT64)
-  Value(double value);
-  Value(const char* value); ///< Copy til first 0. (NULL causes to seg-fault.)
-  Value(const char* begin, const char* end); ///< Copy all, incl zeroes.
-  /** \brief Constructs a value from a static string.
-
-   * Like other value string constructor but do not duplicate the string for
-   * internal storage. The given string must remain alive after the call to this
-   * constructor.
-   * \note This works only for null-terminated strings. (We cannot change the
-   *   size of this class, so we have nowhere to store the length,
-   *   which might be computed later for various operations.)
-   *
-   * Example of usage:
-   * \code
-   * static StaticString foo("some text");
-   * Json::Value aValue(foo);
-   * \endcode
-   */
-  Value(const StaticString& value);
-  Value(const JSONCPP_STRING& value); ///< Copy data() til size(). Embedded zeroes too.
-#ifdef JSON_USE_CPPTL
-  Value(const CppTL::ConstString& value);
-#endif
-  Value(bool value);
-  /// Deep copy.
-  Value(const Value& other);
-#if JSON_HAS_RVALUE_REFERENCES
-  /// Move constructor
-  Value(Value&& other);
-#endif
-  ~Value();
-
-  /// Deep copy, then swap(other).
-  /// \note Over-write existing comments. To preserve comments, use #swapPayload().
-  Value& operator=(Value other);
-
-  /// Swap everything.
-  void swap(Value& other);
-  /// Swap values but leave comments and source offsets in place.
-  void swapPayload(Value& other);
-
-  /// copy everything.
-  void copy(const Value& other);
-  /// copy values but leave comments and source offsets in place.
-  void copyPayload(const Value& other);
-
-  ValueType type() const;
-
-  /// Compare payload only, not comments etc.
-  bool operator<(const Value& other) const;
-  bool operator<=(const Value& other) const;
-  bool operator>=(const Value& other) const;
-  bool operator>(const Value& other) const;
-  bool operator==(const Value& other) const;
-  bool operator!=(const Value& other) const;
-  int compare(const Value& other) const;
-
-  const char* asCString() const; ///< Embedded zeroes could cause you trouble!
-#if JSONCPP_USING_SECURE_MEMORY
-  unsigned getCStringLength() const; //Allows you to understand the length of the CString
-#endif
-  JSONCPP_STRING asString() const; ///< Embedded zeroes are possible.
-  /** Get raw char* of string-value.
-   *  \return false if !string. (Seg-fault if str or end are NULL.)
-   */
-  bool getString(
-      char const** begin, char const** end) const;
-#ifdef JSON_USE_CPPTL
-  CppTL::ConstString asConstString() const;
-#endif
-  Int asInt() const;
-  UInt asUInt() const;
-#if defined(JSON_HAS_INT64)
-  Int64 asInt64() const;
-  UInt64 asUInt64() const;
-#endif // if defined(JSON_HAS_INT64)
-  LargestInt asLargestInt() const;
-  LargestUInt asLargestUInt() const;
-  float asFloat() const;
-  double asDouble() const;
-  bool asBool() const;
-
-  bool isNull() const;
-  bool isBool() const;
-  bool isInt() const;
-  bool isInt64() const;
-  bool isUInt() const;
-  bool isUInt64() const;
-  bool isIntegral() const;
-  bool isDouble() const;
-  bool isNumeric() const;
-  bool isString() const;
-  bool isArray() const;
-  bool isObject() const;
-
-  bool isConvertibleTo(ValueType other) const;
-
-  /// Number of values in array or object
-  ArrayIndex size() const;
-
-  /// \brief Return true if empty array, empty object, or null;
-  /// otherwise, false.
-  bool empty() const;
-
-  /// Return isNull()
-  bool operator!() const;
-
-  /// Remove all object members and array elements.
-  /// \pre type() is arrayValue, objectValue, or nullValue
-  /// \post type() is unchanged
-  void clear();
-
-  /// Resize the array to size elements.
-  /// New elements are initialized to null.
-  /// May only be called on nullValue or arrayValue.
-  /// \pre type() is arrayValue or nullValue
-  /// \post type() is arrayValue
-  void resize(ArrayIndex size);
-
-  /// Access an array element (zero based index ).
-  /// If the array contains less than index element, then null value are
-  /// inserted
-  /// in the array so that its size is index+1.
-  /// (You may need to say 'value[0u]' to get your compiler to distinguish
-  ///  this from the operator[] which takes a string.)
-  Value& operator[](ArrayIndex index);
-
-  /// Access an array element (zero based index ).
-  /// If the array contains less than index element, then null value are
-  /// inserted
-  /// in the array so that its size is index+1.
-  /// (You may need to say 'value[0u]' to get your compiler to distinguish
-  ///  this from the operator[] which takes a string.)
-  Value& operator[](int index);
-
-  /// Access an array element (zero based index )
-  /// (You may need to say 'value[0u]' to get your compiler to distinguish
-  ///  this from the operator[] which takes a string.)
-  const Value& operator[](ArrayIndex index) const;
-
-  /// Access an array element (zero based index )
-  /// (You may need to say 'value[0u]' to get your compiler to distinguish
-  ///  this from the operator[] which takes a string.)
-  const Value& operator[](int index) const;
-
-  /// If the array contains at least index+1 elements, returns the element
-  /// value,
-  /// otherwise returns defaultValue.
-  Value get(ArrayIndex index, const Value& defaultValue) const;
-  /// Return true if index < size().
-  bool isValidIndex(ArrayIndex index) const;
-  /// \brief Append value to array at the end.
-  ///
-  /// Equivalent to jsonvalue[jsonvalue.size()] = value;
-  Value& append(const Value& value);
-
-#if JSON_HAS_RVALUE_REFERENCES
-  Value& append(Value&& value);
-#endif
-
-  /// Access an object value by name, create a null member if it does not exist.
-  /// \note Because of our implementation, keys are limited to 2^30 -1 chars.
-  ///  Exceeding that will cause an exception.
-  Value& operator[](const char* key);
-  /// Access an object value by name, returns null if there is no member with
-  /// that name.
-  const Value& operator[](const char* key) const;
-  /// Access an object value by name, create a null member if it does not exist.
-  /// \param key may contain embedded nulls.
-  Value& operator[](const JSONCPP_STRING& key);
-  /// Access an object value by name, returns null if there is no member with
-  /// that name.
-  /// \param key may contain embedded nulls.
-  const Value& operator[](const JSONCPP_STRING& key) const;
-  /** \brief Access an object value by name, create a null member if it does not
-   exist.
-
-   * If the object has no entry for that name, then the member name used to store
-   * the new entry is not duplicated.
-   * Example of use:
-   * \code
-   * Json::Value object;
-   * static const StaticString code("code");
-   * object[code] = 1234;
-   * \endcode
-   */
-  Value& operator[](const StaticString& key);
-#ifdef JSON_USE_CPPTL
-  /// Access an object value by name, create a null member if it does not exist.
-  Value& operator[](const CppTL::ConstString& key);
-  /// Access an object value by name, returns null if there is no member with
-  /// that name.
-  const Value& operator[](const CppTL::ConstString& key) const;
-#endif
-  /// Return the member named key if it exist, defaultValue otherwise.
-  /// \note deep copy
-  Value get(const char* key, const Value& defaultValue) const;
-  /// Return the member named key if it exist, defaultValue otherwise.
-  /// \note deep copy
-  /// \note key may contain embedded nulls.
-  Value get(const char* begin, const char* end, const Value& defaultValue) const;
-  /// Return the member named key if it exist, defaultValue otherwise.
-  /// \note deep copy
-  /// \param key may contain embedded nulls.
-  Value get(const JSONCPP_STRING& key, const Value& defaultValue) const;
-#ifdef JSON_USE_CPPTL
-  /// Return the member named key if it exist, defaultValue otherwise.
-  /// \note deep copy
-  Value get(const CppTL::ConstString& key, const Value& defaultValue) const;
-#endif
-  /// Most general and efficient version of isMember()const, get()const,
-  /// and operator[]const
-  /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30
-  Value const* find(char const* begin, char const* end) const;
-  /// Most general and efficient version of object-mutators.
-  /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30
-  /// \return non-zero, but JSON_ASSERT if this is neither object nor nullValue.
-  Value const* demand(char const* begin, char const* end);
-  /// \brief Remove and return the named member.
-  ///
-  /// Do nothing if it did not exist.
-  /// \return the removed Value, or null.
-  /// \pre type() is objectValue or nullValue
-  /// \post type() is unchanged
-  /// \deprecated
-  Value removeMember(const char* key);
-  /// Same as removeMember(const char*)
-  /// \param key may contain embedded nulls.
-  /// \deprecated
-  Value removeMember(const JSONCPP_STRING& key);
-  /// Same as removeMember(const char* begin, const char* end, Value* removed),
-  /// but 'key' is null-terminated.
-  bool removeMember(const char* key, Value* removed);
-  /** \brief Remove the named map member.
-
-      Update 'removed' iff removed.
-      \param key may contain embedded nulls.
-      \return true iff removed (no exceptions)
-  */
-  bool removeMember(JSONCPP_STRING const& key, Value* removed);
-  /// Same as removeMember(JSONCPP_STRING const& key, Value* removed)
-  bool removeMember(const char* begin, const char* end, Value* removed);
-  /** \brief Remove the indexed array element.
-
-      O(n) expensive operations.
-      Update 'removed' iff removed.
-      \return true iff removed (no exceptions)
-  */
-  bool removeIndex(ArrayIndex i, Value* removed);
-
-  /// Return true if the object has a member named key.
-  /// \note 'key' must be null-terminated.
-  bool isMember(const char* key) const;
-  /// Return true if the object has a member named key.
-  /// \param key may contain embedded nulls.
-  bool isMember(const JSONCPP_STRING& key) const;
-  /// Same as isMember(JSONCPP_STRING const& key)const
-  bool isMember(const char* begin, const char* end) const;
-#ifdef JSON_USE_CPPTL
-  /// Return true if the object has a member named key.
-  bool isMember(const CppTL::ConstString& key) const;
-#endif
-
-  /// \brief Return a list of the member names.
-  ///
-  /// If null, return an empty list.
-  /// \pre type() is objectValue or nullValue
-  /// \post if type() was nullValue, it remains nullValue
-  Members getMemberNames() const;
-
-  //# ifdef JSON_USE_CPPTL
-  //      EnumMemberNames enumMemberNames() const;
-  //      EnumValues enumValues() const;
-  //# endif
-
-  /// \deprecated Always pass len.
-  JSONCPP_DEPRECATED("Use setComment(JSONCPP_STRING const&) instead.")
-  void setComment(const char* comment, CommentPlacement placement);
-  /// Comments must be //... or /* ... */
-  void setComment(const char* comment, size_t len, CommentPlacement placement);
-  /// Comments must be //... or /* ... */
-  void setComment(const JSONCPP_STRING& comment, CommentPlacement placement);
-  bool hasComment(CommentPlacement placement) const;
-  /// Include delimiters and embedded newlines.
-  JSONCPP_STRING getComment(CommentPlacement placement) const;
-
-  JSONCPP_STRING toStyledString() const;
-
-  const_iterator begin() const;
-  const_iterator end() const;
-
-  iterator begin();
-  iterator end();
-
-  // Accessors for the [start, limit) range of bytes within the JSON text from
-  // which this value was parsed, if any.
-  void setOffsetStart(ptrdiff_t start);
-  void setOffsetLimit(ptrdiff_t limit);
-  ptrdiff_t getOffsetStart() const;
-  ptrdiff_t getOffsetLimit() const;
-
-private:
-  void initBasic(ValueType type, bool allocated = false);
-
-  Value& resolveReference(const char* key);
-  Value& resolveReference(const char* key, const char* end);
-
-  struct CommentInfo {
-    CommentInfo();
-    ~CommentInfo();
-
-    void setComment(const char* text, size_t len);
-
-    char* comment_;
-  };
-
-  // struct MemberNamesTransform
-  //{
-  //   typedef const char *result_type;
-  //   const char *operator()( const CZString &name ) const
-  //   {
-  //      return name.c_str();
-  //   }
-  //};
-
-  union ValueHolder {
-    LargestInt int_;
-    LargestUInt uint_;
-    double real_;
-    bool bool_;
-    char* string_;  // actually ptr to unsigned, followed by str, unless !allocated_
-    ObjectValues* map_;
-  } value_;
-  ValueType type_ : 8;
-  unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
-                               // If not allocated_, string_ must be null-terminated.
-  CommentInfo* comments_;
-
-  // [start, limit) byte offsets in the source JSON text from which this Value
-  // was extracted.
-  ptrdiff_t start_;
-  ptrdiff_t limit_;
-};
-
-/** \brief Experimental and untested: represents an element of the "path" to
- * access a node.
- */
-class JSON_API PathArgument {
-public:
-  friend class Path;
-
-  PathArgument();
-  PathArgument(ArrayIndex index);
-  PathArgument(const char* key);
-  PathArgument(const JSONCPP_STRING& key);
-
-private:
-  enum Kind {
-    kindNone = 0,
-    kindIndex,
-    kindKey
-  };
-  JSONCPP_STRING key_;
-  ArrayIndex index_;
-  Kind kind_;
-};
-
-/** \brief Experimental and untested: represents a "path" to access a node.
- *
- * Syntax:
- * - "." => root node
- * - ".[n]" => elements at index 'n' of root node (an array value)
- * - ".name" => member named 'name' of root node (an object value)
- * - ".name1.name2.name3"
- * - ".[0][1][2].name1[3]"
- * - ".%" => member name is provided as parameter
- * - ".[%]" => index is provied as parameter
- */
-class JSON_API Path {
-public:
-  Path(const JSONCPP_STRING& path,
-       const PathArgument& a1 = PathArgument(),
-       const PathArgument& a2 = PathArgument(),
-       const PathArgument& a3 = PathArgument(),
-       const PathArgument& a4 = PathArgument(),
-       const PathArgument& a5 = PathArgument());
-
-  const Value& resolve(const Value& root) const;
-  Value resolve(const Value& root, const Value& defaultValue) const;
-  /// Creates the "path" to access the specified node and returns a reference on
-  /// the node.
-  Value& make(Value& root) const;
-
-private:
-  typedef std::vector<const PathArgument*> InArgs;
-  typedef std::vector<PathArgument> Args;
-
-  void makePath(const JSONCPP_STRING& path, const InArgs& in);
-  void addPathInArg(const JSONCPP_STRING& path,
-                    const InArgs& in,
-                    InArgs::const_iterator& itInArg,
-                    PathArgument::Kind kind);
-  void invalidPath(const JSONCPP_STRING& path, int location);
-
-  Args args_;
-};
-
-/** \brief base class for Value iterators.
- *
- */
-class JSON_API ValueIteratorBase {
-public:
-  typedef std::bidirectional_iterator_tag iterator_category;
-  typedef unsigned int size_t;
-  typedef int difference_type;
-  typedef ValueIteratorBase SelfType;
-
-  bool operator==(const SelfType& other) const { return isEqual(other); }
-
-  bool operator!=(const SelfType& other) const { return !isEqual(other); }
-
-  difference_type operator-(const SelfType& other) const {
-    return other.computeDistance(*this);
-  }
-
-  /// Return either the index or the member name of the referenced value as a
-  /// Value.
-  Value key() const;
-
-  /// Return the index of the referenced Value, or -1 if it is not an arrayValue.
-  UInt index() const;
-
-  /// Return the member name of the referenced Value, or "" if it is not an
-  /// objectValue.
-  /// \note Avoid `c_str()` on result, as embedded zeroes are possible.
-  JSONCPP_STRING name() const;
-
-  /// Return the member name of the referenced Value. "" if it is not an
-  /// objectValue.
-  /// \deprecated This cannot be used for UTF-8 strings, since there can be embedded nulls.
-  JSONCPP_DEPRECATED("Use `key = name();` instead.")
-  char const* memberName() const;
-  /// Return the member name of the referenced Value, or NULL if it is not an
-  /// objectValue.
-  /// \note Better version than memberName(). Allows embedded nulls.
-  char const* memberName(char const** end) const;
-
-protected:
-  Value& deref() const;
-
-  void increment();
-
-  void decrement();
-
-  difference_type computeDistance(const SelfType& other) const;
-
-  bool isEqual(const SelfType& other) const;
-
-  void copy(const SelfType& other);
-
-private:
-  Value::ObjectValues::iterator current_;
-  // Indicates that iterator is for a null value.
-  bool isNull_;
-
-public:
-  // For some reason, BORLAND needs these at the end, rather
-  // than earlier. No idea why.
-  ValueIteratorBase();
-  explicit ValueIteratorBase(const Value::ObjectValues::iterator& current);
-};
-
-/** \brief const iterator for object and array value.
- *
- */
-class JSON_API ValueConstIterator : public ValueIteratorBase {
-  friend class Value;
-
-public:
-  typedef const Value value_type;
-  //typedef unsigned int size_t;
-  //typedef int difference_type;
-  typedef const Value& reference;
-  typedef const Value* pointer;
-  typedef ValueConstIterator SelfType;
-
-  ValueConstIterator();
-  ValueConstIterator(ValueIterator const& other);
-
-private:
-/*! \internal Use by Value to create an iterator.
- */
-  explicit ValueConstIterator(const Value::ObjectValues::iterator& current);
-public:
-  SelfType& operator=(const ValueIteratorBase& other);
-
-  SelfType operator++(int) {
-    SelfType temp(*this);
-    ++*this;
-    return temp;
-  }
-
-  SelfType operator--(int) {
-    SelfType temp(*this);
-    --*this;
-    return temp;
-  }
-
-  SelfType& operator--() {
-    decrement();
-    return *this;
-  }
-
-  SelfType& operator++() {
-    increment();
-    return *this;
-  }
-
-  reference operator*() const { return deref(); }
-
-  pointer operator->() const { return &deref(); }
-};
-
-/** \brief Iterator for object and array value.
- */
-class JSON_API ValueIterator : public ValueIteratorBase {
-  friend class Value;
-
-public:
-  typedef Value value_type;
-  typedef unsigned int size_t;
-  typedef int difference_type;
-  typedef Value& reference;
-  typedef Value* pointer;
-  typedef ValueIterator SelfType;
-
-  ValueIterator();
-  explicit ValueIterator(const ValueConstIterator& other);
-  ValueIterator(const ValueIterator& other);
-
-private:
-/*! \internal Use by Value to create an iterator.
- */
-  explicit ValueIterator(const Value::ObjectValues::iterator& current);
-public:
-  SelfType& operator=(const SelfType& other);
-
-  SelfType operator++(int) {
-    SelfType temp(*this);
-    ++*this;
-    return temp;
-  }
-
-  SelfType operator--(int) {
-    SelfType temp(*this);
-    --*this;
-    return temp;
-  }
-
-  SelfType& operator--() {
-    decrement();
-    return *this;
-  }
-
-  SelfType& operator++() {
-    increment();
-    return *this;
-  }
-
-  reference operator*() const { return deref(); }
-
-  pointer operator->() const { return &deref(); }
-};
-
-} // namespace Json
-
-
-namespace std {
-/// Specialize std::swap() for Json::Value.
-template<>
-inline void swap(Json::Value& a, Json::Value& b) { a.swap(b); }
-}
-
-#pragma pack(pop)
-
-#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-#pragma warning(pop)
-#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-
-#endif // CPPTL_JSON_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: include/json/value.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: include/json/reader.h
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#ifndef CPPTL_JSON_READER_H_INCLUDED
-#define CPPTL_JSON_READER_H_INCLUDED
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include "features.h"
-#include "value.h"
-#endif // if !defined(JSON_IS_AMALGAMATION)
-#include <deque>
-#include <iosfwd>
-#include <stack>
-#include <string>
-#include <istream>
-
-// Disable warning C4251: <data member>: <type> needs to have dll-interface to
-// be used by...
-#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-#pragma warning(push)
-#pragma warning(disable : 4251)
-#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-
-#pragma pack(push, 8)
-
-namespace Json {
-
-/** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a
- *Value.
- *
- * \deprecated Use CharReader and CharReaderBuilder.
- */
-class JSON_API Reader {
-public:
-  typedef char Char;
-  typedef const Char* Location;
-
-  /** \brief An error tagged with where in the JSON text it was encountered.
-   *
-   * The offsets give the [start, limit) range of bytes within the text. Note
-   * that this is bytes, not codepoints.
-   *
-   */
-  struct StructuredError {
-    ptrdiff_t offset_start;
-    ptrdiff_t offset_limit;
-    JSONCPP_STRING message;
-  };
-
-  /** \brief Constructs a Reader allowing all features
-   * for parsing.
-   */
-  Reader();
-
-  /** \brief Constructs a Reader allowing the specified feature set
-   * for parsing.
-   */
-  Reader(const Features& features);
-
-  /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
-   * document.
-   * \param document UTF-8 encoded string containing the document to read.
-   * \param root [out] Contains the root value of the document if it was
-   *             successfully parsed.
-   * \param collectComments \c true to collect comment and allow writing them
-   * back during
-   *                        serialization, \c false to discard comments.
-   *                        This parameter is ignored if
-   * Features::allowComments_
-   *                        is \c false.
-   * \return \c true if the document was successfully parsed, \c false if an
-   * error occurred.
-   */
-  bool
-  parse(const std::string& document, Value& root, bool collectComments = true);
-
-  /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
-   document.
-   * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the
-   document to read.
-   * \param endDoc Pointer on the end of the UTF-8 encoded string of the
-   document to read.
-   *               Must be >= beginDoc.
-   * \param root [out] Contains the root value of the document if it was
-   *             successfully parsed.
-   * \param collectComments \c true to collect comment and allow writing them
-   back during
-   *                        serialization, \c false to discard comments.
-   *                        This parameter is ignored if
-   Features::allowComments_
-   *                        is \c false.
-   * \return \c true if the document was successfully parsed, \c false if an
-   error occurred.
-   */
-  bool parse(const char* beginDoc,
-             const char* endDoc,
-             Value& root,
-             bool collectComments = true);
-
-  /// \brief Parse from input stream.
-  /// \see Json::operator>>(std::istream&, Json::Value&).
-  bool parse(JSONCPP_ISTREAM& is, Value& root, bool collectComments = true);
-
-  /** \brief Returns a user friendly string that list errors in the parsed
-   * document.
-   * \return Formatted error message with the list of errors with their location
-   * in
-   *         the parsed document. An empty string is returned if no error
-   * occurred
-   *         during parsing.
-   * \deprecated Use getFormattedErrorMessages() instead (typo fix).
-   */
-  JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.")
-  JSONCPP_STRING getFormatedErrorMessages() const;
-
-  /** \brief Returns a user friendly string that list errors in the parsed
-   * document.
-   * \return Formatted error message with the list of errors with their location
-   * in
-   *         the parsed document. An empty string is returned if no error
-   * occurred
-   *         during parsing.
-   */
-  JSONCPP_STRING getFormattedErrorMessages() const;
-
-  /** \brief Returns a vector of structured erros encounted while parsing.
-   * \return A (possibly empty) vector of StructuredError objects. Currently
-   *         only one error can be returned, but the caller should tolerate
-   * multiple
-   *         errors.  This can occur if the parser recovers from a non-fatal
-   *         parse error and then encounters additional errors.
-   */
-  std::vector<StructuredError> getStructuredErrors() const;
-
-  /** \brief Add a semantic error message.
-   * \param value JSON Value location associated with the error
-   * \param message The error message.
-   * \return \c true if the error was successfully added, \c false if the
-   * Value offset exceeds the document size.
-   */
-  bool pushError(const Value& value, const JSONCPP_STRING& message);
-
-  /** \brief Add a semantic error message with extra context.
-   * \param value JSON Value location associated with the error
-   * \param message The error message.
-   * \param extra Additional JSON Value location to contextualize the error
-   * \return \c true if the error was successfully added, \c false if either
-   * Value offset exceeds the document size.
-   */
-  bool pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra);
-
-  /** \brief Return whether there are any errors.
-   * \return \c true if there are no errors to report \c false if
-   * errors have occurred.
-   */
-  bool good() const;
-
-private:
-  enum TokenType {
-    tokenEndOfStream = 0,
-    tokenObjectBegin,
-    tokenObjectEnd,
-    tokenArrayBegin,
-    tokenArrayEnd,
-    tokenString,
-    tokenNumber,
-    tokenTrue,
-    tokenFalse,
-    tokenNull,
-    tokenArraySeparator,
-    tokenMemberSeparator,
-    tokenComment,
-    tokenError
-  };
-
-  class Token {
-  public:
-    TokenType type_;
-    Location start_;
-    Location end_;
-  };
-
-  class ErrorInfo {
-  public:
-    Token token_;
-    JSONCPP_STRING message_;
-    Location extra_;
-  };
-
-  typedef std::deque<ErrorInfo> Errors;
-
-  bool readToken(Token& token);
-  void skipSpaces();
-  bool match(Location pattern, int patternLength);
-  bool readComment();
-  bool readCStyleComment();
-  bool readCppStyleComment();
-  bool readString();
-  void readNumber();
-  bool readValue();
-  bool readObject(Token& token);
-  bool readArray(Token& token);
-  bool decodeNumber(Token& token);
-  bool decodeNumber(Token& token, Value& decoded);
-  bool decodeString(Token& token);
-  bool decodeString(Token& token, JSONCPP_STRING& decoded);
-  bool decodeDouble(Token& token);
-  bool decodeDouble(Token& token, Value& decoded);
-  bool decodeUnicodeCodePoint(Token& token,
-                              Location& current,
-                              Location end,
-                              unsigned int& unicode);
-  bool decodeUnicodeEscapeSequence(Token& token,
-                                   Location& current,
-                                   Location end,
-                                   unsigned int& unicode);
-  bool addError(const JSONCPP_STRING& message, Token& token, Location extra = 0);
-  bool recoverFromError(TokenType skipUntilToken);
-  bool addErrorAndRecover(const JSONCPP_STRING& message,
-                          Token& token,
-                          TokenType skipUntilToken);
-  void skipUntilSpace();
-  Value& currentValue();
-  Char getNextChar();
-  void
-  getLocationLineAndColumn(Location location, int& line, int& column) const;
-  JSONCPP_STRING getLocationLineAndColumn(Location location) const;
-  void addComment(Location begin, Location end, CommentPlacement placement);
-  void skipCommentTokens(Token& token);
-
-  typedef std::stack<Value*> Nodes;
-  Nodes nodes_;
-  Errors errors_;
-  JSONCPP_STRING document_;
-  Location begin_;
-  Location end_;
-  Location current_;
-  Location lastValueEnd_;
-  Value* lastValue_;
-  JSONCPP_STRING commentsBefore_;
-  Features features_;
-  bool collectComments_;
-};  // Reader
-
-/** Interface for reading JSON from a char array.
- */
-class JSON_API CharReader {
-public:
-  virtual ~CharReader() {}
-  /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
-   document.
-   * The document must be a UTF-8 encoded string containing the document to read.
-   *
-   * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the
-   document to read.
-   * \param endDoc Pointer on the end of the UTF-8 encoded string of the
-   document to read.
-   *        Must be >= beginDoc.
-   * \param root [out] Contains the root value of the document if it was
-   *             successfully parsed.
-   * \param errs [out] Formatted error messages (if not NULL)
-   *        a user friendly string that lists errors in the parsed
-   * document.
-   * \return \c true if the document was successfully parsed, \c false if an
-   error occurred.
-   */
-  virtual bool parse(
-      char const* beginDoc, char const* endDoc,
-      Value* root, JSONCPP_STRING* errs) = 0;
-
-  class JSON_API Factory {
-  public:
-    virtual ~Factory() {}
-    /** \brief Allocate a CharReader via operator new().
-     * \throw std::exception if something goes wrong (e.g. invalid settings)
-     */
-    virtual CharReader* newCharReader() const = 0;
-  };  // Factory
-};  // CharReader
-
-/** \brief Build a CharReader implementation.
-
-Usage:
-\code
-  using namespace Json;
-  CharReaderBuilder builder;
-  builder["collectComments"] = false;
-  Value value;
-  JSONCPP_STRING errs;
-  bool ok = parseFromStream(builder, std::cin, &value, &errs);
-\endcode
-*/
-class JSON_API CharReaderBuilder : public CharReader::Factory {
-public:
-  // Note: We use a Json::Value so that we can add data-members to this class
-  // without a major version bump.
-  /** Configuration of this builder.
-    These are case-sensitive.
-    Available settings (case-sensitive):
-    - `"collectComments": false or true`
-      - true to collect comment and allow writing them
-        back during serialization, false to discard comments.
-        This parameter is ignored if allowComments is false.
-    - `"allowComments": false or true`
-      - true if comments are allowed.
-    - `"strictRoot": false or true`
-      - true if root must be either an array or an object value
-    - `"allowDroppedNullPlaceholders": false or true`
-      - true if dropped null placeholders are allowed. (See StreamWriterBuilder.)
-    - `"allowNumericKeys": false or true`
-      - true if numeric object keys are allowed.
-    - `"allowSingleQuotes": false or true`
-      - true if '' are allowed for strings (both keys and values)
-    - `"stackLimit": integer`
-      - Exceeding stackLimit (recursive depth of `readValue()`) will
-        cause an exception.
-      - This is a security issue (seg-faults caused by deeply nested JSON),
-        so the default is low.
-    - `"failIfExtra": false or true`
-      - If true, `parse()` returns false when extra non-whitespace trails
-        the JSON value in the input string.
-    - `"rejectDupKeys": false or true`
-      - If true, `parse()` returns false when a key is duplicated within an object.
-    - `"allowSpecialFloats": false or true`
-      - If true, special float values (NaNs and infinities) are allowed 
-        and their values are lossfree restorable.
-
-    You can examine 'settings_` yourself
-    to see the defaults. You can also write and read them just like any
-    JSON Value.
-    \sa setDefaults()
-    */
-  Json::Value settings_;
-
-  CharReaderBuilder();
-  ~CharReaderBuilder() JSONCPP_OVERRIDE;
-
-  CharReader* newCharReader() const JSONCPP_OVERRIDE;
-
-  /** \return true if 'settings' are legal and consistent;
-   *   otherwise, indicate bad settings via 'invalid'.
-   */
-  bool validate(Json::Value* invalid) const;
-
-  /** A simple way to update a specific setting.
-   */
-  Value& operator[](JSONCPP_STRING key);
-
-  /** Called by ctor, but you can use this to reset settings_.
-   * \pre 'settings' != NULL (but Json::null is fine)
-   * \remark Defaults:
-   * \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults
-   */
-  static void setDefaults(Json::Value* settings);
-  /** Same as old Features::strictMode().
-   * \pre 'settings' != NULL (but Json::null is fine)
-   * \remark Defaults:
-   * \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode
-   */
-  static void strictMode(Json::Value* settings);
-};
-
-/** Consume entire stream and use its begin/end.
-  * Someday we might have a real StreamReader, but for now this
-  * is convenient.
-  */
-bool JSON_API parseFromStream(
-    CharReader::Factory const&,
-    JSONCPP_ISTREAM&,
-    Value* root, std::string* errs);
-
-/** \brief Read from 'sin' into 'root'.
-
- Always keep comments from the input JSON.
-
- This can be used to read a file into a particular sub-object.
- For example:
- \code
- Json::Value root;
- cin >> root["dir"]["file"];
- cout << root;
- \endcode
- Result:
- \verbatim
- {
- "dir": {
-     "file": {
-     // The input stream JSON would be nested here.
-     }
- }
- }
- \endverbatim
- \throw std::exception on parse error.
- \see Json::operator<<()
-*/
-JSON_API JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM&, Value&);
-
-} // namespace Json
-
-#pragma pack(pop)
-
-#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-#pragma warning(pop)
-#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-
-#endif // CPPTL_JSON_READER_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: include/json/reader.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: include/json/writer.h
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#ifndef JSON_WRITER_H_INCLUDED
-#define JSON_WRITER_H_INCLUDED
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include "value.h"
-#endif // if !defined(JSON_IS_AMALGAMATION)
-#include <vector>
-#include <string>
-#include <ostream>
-
-// Disable warning C4251: <data member>: <type> needs to have dll-interface to
-// be used by...
-#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-#pragma warning(push)
-#pragma warning(disable : 4251)
-#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-
-#pragma pack(push, 8)
-
-namespace Json {
-
-class Value;
-
-/**
-
-Usage:
-\code
-  using namespace Json;
-  void writeToStdout(StreamWriter::Factory const& factory, Value const& value) {
-    std::unique_ptr<StreamWriter> const writer(
-      factory.newStreamWriter());
-    writer->write(value, &std::cout);
-    std::cout << std::endl;  // add lf and flush
-  }
-\endcode
-*/
-class JSON_API StreamWriter {
-protected:
-  JSONCPP_OSTREAM* sout_;  // not owned; will not delete
-public:
-  StreamWriter();
-  virtual ~StreamWriter();
-  /** Write Value into document as configured in sub-class.
-      Do not take ownership of sout, but maintain a reference during function.
-      \pre sout != NULL
-      \return zero on success (For now, we always return zero, so check the stream instead.)
-      \throw std::exception possibly, depending on configuration
-   */
-  virtual int write(Value const& root, JSONCPP_OSTREAM* sout) = 0;
-
-  /** \brief A simple abstract factory.
-   */
-  class JSON_API Factory {
-  public:
-    virtual ~Factory();
-    /** \brief Allocate a CharReader via operator new().
-     * \throw std::exception if something goes wrong (e.g. invalid settings)
-     */
-    virtual StreamWriter* newStreamWriter() const = 0;
-  };  // Factory
-};  // StreamWriter
-
-/** \brief Write into stringstream, then return string, for convenience.
- * A StreamWriter will be created from the factory, used, and then deleted.
- */
-JSONCPP_STRING JSON_API writeString(StreamWriter::Factory const& factory, Value const& root);
-
-
-/** \brief Build a StreamWriter implementation.
-
-Usage:
-\code
-  using namespace Json;
-  Value value = ...;
-  StreamWriterBuilder builder;
-  builder["commentStyle"] = "None";
-  builder["indentation"] = "   ";  // or whatever you like
-  std::unique_ptr<Json::StreamWriter> writer(
-      builder.newStreamWriter());
-  writer->write(value, &std::cout);
-  std::cout << std::endl;  // add lf and flush
-\endcode
-*/
-class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
-public:
-  // Note: We use a Json::Value so that we can add data-members to this class
-  // without a major version bump.
-  /** Configuration of this builder.
-    Available settings (case-sensitive):
-    - "commentStyle": "None" or "All"
-    - "indentation":  "<anything>"
-    - "enableYAMLCompatibility": false or true
-      - slightly change the whitespace around colons
-    - "dropNullPlaceholders": false or true
-      - Drop the "null" string from the writer's output for nullValues.
-        Strictly speaking, this is not valid JSON. But when the output is being
-        fed to a browser's Javascript, it makes for smaller output and the
-        browser can handle the output just fine.
-    - "useSpecialFloats": false or true
-      - If true, outputs non-finite floating point values in the following way:
-        NaN values as "NaN", positive infinity as "Infinity", and negative infinity
-        as "-Infinity".
-
-    You can examine 'settings_` yourself
-    to see the defaults. You can also write and read them just like any
-    JSON Value.
-    \sa setDefaults()
-    */
-  Json::Value settings_;
-
-  StreamWriterBuilder();
-  ~StreamWriterBuilder() JSONCPP_OVERRIDE;
-
-  /**
-   * \throw std::exception if something goes wrong (e.g. invalid settings)
-   */
-  StreamWriter* newStreamWriter() const JSONCPP_OVERRIDE;
-
-  /** \return true if 'settings' are legal and consistent;
-   *   otherwise, indicate bad settings via 'invalid'.
-   */
-  bool validate(Json::Value* invalid) const;
-  /** A simple way to update a specific setting.
-   */
-  Value& operator[](JSONCPP_STRING key);
-
-  /** Called by ctor, but you can use this to reset settings_.
-   * \pre 'settings' != NULL (but Json::null is fine)
-   * \remark Defaults:
-   * \snippet src/lib_json/json_writer.cpp StreamWriterBuilderDefaults
-   */
-  static void setDefaults(Json::Value* settings);
-};
-
-/** \brief Abstract class for writers.
- * \deprecated Use StreamWriter. (And really, this is an implementation detail.)
- */
-class JSON_API Writer {
-public:
-  virtual ~Writer();
-
-  virtual JSONCPP_STRING write(const Value& root) = 0;
-};
-
-/** \brief Outputs a Value in <a HREF="http://www.json.org">JSON</a> format
- *without formatting (not human friendly).
- *
- * The JSON document is written in a single line. It is not intended for 'human'
- *consumption,
- * but may be usefull to support feature such as RPC where bandwith is limited.
- * \sa Reader, Value
- * \deprecated Use StreamWriterBuilder.
- */
-class JSON_API FastWriter : public Writer {
-
-public:
-  FastWriter();
-  ~FastWriter() JSONCPP_OVERRIDE {}
-
-  void enableYAMLCompatibility();
-
-  /** \brief Drop the "null" string from the writer's output for nullValues.
-   * Strictly speaking, this is not valid JSON. But when the output is being
-   * fed to a browser's Javascript, it makes for smaller output and the
-   * browser can handle the output just fine.
-   */
-  void dropNullPlaceholders();
-
-  void omitEndingLineFeed();
-
-public: // overridden from Writer
-  JSONCPP_STRING write(const Value& root) JSONCPP_OVERRIDE;
-
-private:
-  void writeValue(const Value& value);
-
-  JSONCPP_STRING document_;
-  bool yamlCompatiblityEnabled_;
-  bool dropNullPlaceholders_;
-  bool omitEndingLineFeed_;
-};
-
-/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
- *human friendly way.
- *
- * The rules for line break and indent are as follow:
- * - Object value:
- *     - if empty then print {} without indent and line break
- *     - if not empty the print '{', line break & indent, print one value per
- *line
- *       and then unindent and line break and print '}'.
- * - Array value:
- *     - if empty then print [] without indent and line break
- *     - if the array contains no object value, empty array or some other value
- *types,
- *       and all the values fit on one lines, then print the array on a single
- *line.
- *     - otherwise, it the values do not fit on one line, or the array contains
- *       object or non empty array, then print one value per line.
- *
- * If the Value have comments then they are outputed according to their
- *#CommentPlacement.
- *
- * \sa Reader, Value, Value::setComment()
- * \deprecated Use StreamWriterBuilder.
- */
-class JSON_API StyledWriter : public Writer {
-public:
-  StyledWriter();
-  ~StyledWriter() JSONCPP_OVERRIDE {}
-
-public: // overridden from Writer
-  /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
-   * \param root Value to serialize.
-   * \return String containing the JSON document that represents the root value.
-   */
-  JSONCPP_STRING write(const Value& root) JSONCPP_OVERRIDE;
-
-private:
-  void writeValue(const Value& value);
-  void writeArrayValue(const Value& value);
-  bool isMultineArray(const Value& value);
-  void pushValue(const JSONCPP_STRING& value);
-  void writeIndent();
-  void writeWithIndent(const JSONCPP_STRING& value);
-  void indent();
-  void unindent();
-  void writeCommentBeforeValue(const Value& root);
-  void writeCommentAfterValueOnSameLine(const Value& root);
-  bool hasCommentForValue(const Value& value);
-  static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text);
-
-  typedef std::vector<JSONCPP_STRING> ChildValues;
-
-  ChildValues childValues_;
-  JSONCPP_STRING document_;
-  JSONCPP_STRING indentString_;
-  unsigned int rightMargin_;
-  unsigned int indentSize_;
-  bool addChildValues_;
-};
-
-/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
- human friendly way,
-     to a stream rather than to a string.
- *
- * The rules for line break and indent are as follow:
- * - Object value:
- *     - if empty then print {} without indent and line break
- *     - if not empty the print '{', line break & indent, print one value per
- line
- *       and then unindent and line break and print '}'.
- * - Array value:
- *     - if empty then print [] without indent and line break
- *     - if the array contains no object value, empty array or some other value
- types,
- *       and all the values fit on one lines, then print the array on a single
- line.
- *     - otherwise, it the values do not fit on one line, or the array contains
- *       object or non empty array, then print one value per line.
- *
- * If the Value have comments then they are outputed according to their
- #CommentPlacement.
- *
- * \param indentation Each level will be indented by this amount extra.
- * \sa Reader, Value, Value::setComment()
- * \deprecated Use StreamWriterBuilder.
- */
-class JSON_API StyledStreamWriter {
-public:
-  StyledStreamWriter(JSONCPP_STRING indentation = "\t");
-  ~StyledStreamWriter() {}
-
-public:
-  /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
-   * \param out Stream to write to. (Can be ostringstream, e.g.)
-   * \param root Value to serialize.
-   * \note There is no point in deriving from Writer, since write() should not
-   * return a value.
-   */
-  void write(JSONCPP_OSTREAM& out, const Value& root);
-
-private:
-  void writeValue(const Value& value);
-  void writeArrayValue(const Value& value);
-  bool isMultineArray(const Value& value);
-  void pushValue(const JSONCPP_STRING& value);
-  void writeIndent();
-  void writeWithIndent(const JSONCPP_STRING& value);
-  void indent();
-  void unindent();
-  void writeCommentBeforeValue(const Value& root);
-  void writeCommentAfterValueOnSameLine(const Value& root);
-  bool hasCommentForValue(const Value& value);
-  static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text);
-
-  typedef std::vector<JSONCPP_STRING> ChildValues;
-
-  ChildValues childValues_;
-  JSONCPP_OSTREAM* document_;
-  JSONCPP_STRING indentString_;
-  unsigned int rightMargin_;
-  JSONCPP_STRING indentation_;
-  bool addChildValues_ : 1;
-  bool indented_ : 1;
-};
-
-#if defined(JSON_HAS_INT64)
-JSONCPP_STRING JSON_API valueToString(Int value);
-JSONCPP_STRING JSON_API valueToString(UInt value);
-#endif // if defined(JSON_HAS_INT64)
-JSONCPP_STRING JSON_API valueToString(LargestInt value);
-JSONCPP_STRING JSON_API valueToString(LargestUInt value);
-JSONCPP_STRING JSON_API valueToString(double value);
-JSONCPP_STRING JSON_API valueToString(bool value);
-JSONCPP_STRING JSON_API valueToQuotedString(const char* value);
-
-/// \brief Output using the StyledStreamWriter.
-/// \see Json::operator>>()
-JSON_API JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM&, const Value& root);
-
-} // namespace Json
-
-#pragma pack(pop)
-
-#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-#pragma warning(pop)
-#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-
-#endif // JSON_WRITER_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: include/json/writer.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: include/json/assertions.h
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#ifndef CPPTL_JSON_ASSERTIONS_H_INCLUDED
-#define CPPTL_JSON_ASSERTIONS_H_INCLUDED
-
-#include <stdlib.h>
-#include <sstream>
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include "config.h"
-#endif // if !defined(JSON_IS_AMALGAMATION)
-
-/** It should not be possible for a maliciously designed file to
- *  cause an abort() or seg-fault, so these macros are used only
- *  for pre-condition violations and internal logic errors.
- */
-#if JSON_USE_EXCEPTION
-
-// @todo <= add detail about condition in exception
-# define JSON_ASSERT(condition)                                                \
-  {if (!(condition)) {Json::throwLogicError( "assert json failed" );}}
-
-# define JSON_FAIL_MESSAGE(message)                                            \
-  {                                                                            \
-    JSONCPP_OSTRINGSTREAM oss; oss << message;                                    \
-    Json::throwLogicError(oss.str());                                          \
-    abort();                                                                   \
-  }
-
-#else // JSON_USE_EXCEPTION
-
-# define JSON_ASSERT(condition) assert(condition)
-
-// The call to assert() will show the failure message in debug builds. In
-// release builds we abort, for a core-dump or debugger.
-# define JSON_FAIL_MESSAGE(message)                                            \
-  {                                                                            \
-    JSONCPP_OSTRINGSTREAM oss; oss << message;                                    \
-    assert(false && oss.str().c_str());                                        \
-    abort();                                                                   \
-  }
-
-
-#endif
-
-#define JSON_ASSERT_MESSAGE(condition, message)                                \
-  if (!(condition)) {                                                          \
-    JSON_FAIL_MESSAGE(message);                                                \
-  }
-
-#endif // CPPTL_JSON_ASSERTIONS_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: include/json/assertions.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-#endif //ifndef JSON_AMALGATED_H_INCLUDED
diff --git a/chaos_micro_unit_toolkit/external_lib/jsoncpp.cpp b/chaos_micro_unit_toolkit/external_lib/jsoncpp.cpp
deleted file mode 100644
index 79e18b0f71797881aee3889d0bcc636251c0e31f..0000000000000000000000000000000000000000
--- a/chaos_micro_unit_toolkit/external_lib/jsoncpp.cpp
+++ /dev/null
@@ -1,5348 +0,0 @@
-/// Json-cpp amalgated source (http://jsoncpp.sourceforge.net/).
-/// It is intended to be used with #include "json/json.h"
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: LICENSE
-// //////////////////////////////////////////////////////////////////////
-
-/*
-The JsonCpp library's source code, including accompanying documentation, 
-tests and demonstration applications, are licensed under the following
-conditions...
-
-Baptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all 
-jurisdictions which recognize such a disclaimer. In such jurisdictions, 
-this software is released into the Public Domain.
-
-In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
-2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur and
-The JsonCpp Authors, and is released under the terms of the MIT License (see below).
-
-In jurisdictions which recognize Public Domain property, the user of this 
-software may choose to accept it either as 1) Public Domain, 2) under the 
-conditions of the MIT License (see below), or 3) under the terms of dual 
-Public Domain/MIT License conditions described here, as they choose.
-
-The MIT License is about as close to Public Domain as a license can get, and is
-described in clear, concise terms at:
-
-   http://en.wikipedia.org/wiki/MIT_License
-   
-The full text of the MIT License follows:
-
-========================================================================
-Copyright (c) 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use, copy,
-modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-========================================================================
-(END LICENSE TEXT)
-
-The MIT license is compatible with both the GPL and commercial
-software, affording one all of the rights of Public Domain with the
-minor nuisance of being required to keep the above copyright notice
-and license text in the source code. Note also that by accepting the
-Public Domain "license" you can re-license your copy using whatever
-license you like.
-
-*/
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: LICENSE
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-#include <chaos_micro_unit_toolkit/external_lib/json.h>
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: src/lib_json/json_tool.h
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#ifndef LIB_JSONCPP_JSON_TOOL_H_INCLUDED
-#define LIB_JSONCPP_JSON_TOOL_H_INCLUDED
-
-
-// Also support old flag NO_LOCALE_SUPPORT
-#ifdef NO_LOCALE_SUPPORT
-#define JSONCPP_NO_LOCALE_SUPPORT
-#endif
-
-#ifndef JSONCPP_NO_LOCALE_SUPPORT
-#include <clocale>
-#endif
-
-/* This header provides common string manipulation support, such as UTF-8,
- * portable conversion from/to string...
- *
- * It is an internal header that must not be exposed.
- */
-
-namespace Json {
-static char getDecimalPoint() {
-#ifdef JSONCPP_NO_LOCALE_SUPPORT
-  return '\0';
-#else
-  struct lconv* lc = localeconv();
-  return lc ? *(lc->decimal_point) : '\0';
-#endif
-}
-
-/// Converts a unicode code-point to UTF-8.
-static inline JSONCPP_STRING codePointToUTF8(unsigned int cp) {
-  JSONCPP_STRING result;
-
-  // based on description from http://en.wikipedia.org/wiki/UTF-8
-
-  if (cp <= 0x7f) {
-    result.resize(1);
-    result[0] = static_cast<char>(cp);
-  } else if (cp <= 0x7FF) {
-    result.resize(2);
-    result[1] = static_cast<char>(0x80 | (0x3f & cp));
-    result[0] = static_cast<char>(0xC0 | (0x1f & (cp >> 6)));
-  } else if (cp <= 0xFFFF) {
-    result.resize(3);
-    result[2] = static_cast<char>(0x80 | (0x3f & cp));
-    result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 6)));
-    result[0] = static_cast<char>(0xE0 | (0xf & (cp >> 12)));
-  } else if (cp <= 0x10FFFF) {
-    result.resize(4);
-    result[3] = static_cast<char>(0x80 | (0x3f & cp));
-    result[2] = static_cast<char>(0x80 | (0x3f & (cp >> 6)));
-    result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 12)));
-    result[0] = static_cast<char>(0xF0 | (0x7 & (cp >> 18)));
-  }
-
-  return result;
-}
-
-/// Returns true if ch is a control character (in range [1,31]).
-static inline bool isControlCharacter(char ch) { return ch > 0 && ch <= 0x1F; }
-
-enum {
-  /// Constant that specify the size of the buffer that must be passed to
-  /// uintToString.
-  uintToStringBufferSize = 3 * sizeof(LargestUInt) + 1
-};
-
-// Defines a char buffer for use with uintToString().
-typedef char UIntToStringBuffer[uintToStringBufferSize];
-
-/** Converts an unsigned integer to string.
- * @param value Unsigned interger to convert to string
- * @param current Input/Output string buffer.
- *        Must have at least uintToStringBufferSize chars free.
- */
-static inline void uintToString(LargestUInt value, char*& current) {
-  *--current = 0;
-  do {
-    *--current = static_cast<char>(value % 10U + static_cast<unsigned>('0'));
-    value /= 10;
-  } while (value != 0);
-}
-
-/** Change ',' to '.' everywhere in buffer.
- *
- * We had a sophisticated way, but it did not work in WinCE.
- * @see https://github.com/open-source-parsers/jsoncpp/pull/9
- */
-static inline void fixNumericLocale(char* begin, char* end) {
-  while (begin < end) {
-    if (*begin == ',') {
-      *begin = '.';
-    }
-    ++begin;
-  }
-}
-
-static inline void fixNumericLocaleInput(char* begin, char* end) {
-  char decimalPoint = getDecimalPoint();
-  if (decimalPoint != '\0' && decimalPoint != '.') {
-    while (begin < end) {
-      if (*begin == '.') {
-        *begin = decimalPoint;
-      }
-      ++begin;
-    }
-  }
-}
-
-} // namespace Json {
-
-#endif // LIB_JSONCPP_JSON_TOOL_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: src/lib_json/json_tool.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: src/lib_json/json_reader.cpp
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2011 Baptiste Lepilleur and The JsonCpp Authors
-// Copyright (C) 2016 InfoTeCS JSC. All rights reserved.
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include <json/assertions.h>
-#include <json/reader.h>
-#include <json/value.h>
-#include "json_tool.h"
-#endif // if !defined(JSON_IS_AMALGAMATION)
-#include <utility>
-#include <cstdio>
-#include <cassert>
-#include <cstring>
-#include <istream>
-#include <sstream>
-#include <memory>
-#include <set>
-#include <limits>
-
-#if defined(_MSC_VER)
-#if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && _MSC_VER >= 1500 // VC++ 9.0 and above 
-#define snprintf sprintf_s
-#elif _MSC_VER >= 1900 // VC++ 14.0 and above
-#define snprintf std::snprintf
-#else
-#define snprintf _snprintf
-#endif
-#elif defined(__ANDROID__) || defined(__QNXNTO__)
-#define snprintf snprintf
-#elif __cplusplus >= 201103L
-#if !defined(__MINGW32__) && !defined(__CYGWIN__)
-#define snprintf std::snprintf
-#endif
-#endif
-
-#if defined(__QNXNTO__)
-#define sscanf std::sscanf
-#endif
-
-#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0
-// Disable warning about strdup being deprecated.
-#pragma warning(disable : 4996)
-#endif
-
-// Define JSONCPP_DEPRECATED_STACK_LIMIT as an appropriate integer at compile time to change the stack limit
-#if !defined(JSONCPP_DEPRECATED_STACK_LIMIT)
-#define JSONCPP_DEPRECATED_STACK_LIMIT 1000
-#endif
-
-static size_t const stackLimit_g = JSONCPP_DEPRECATED_STACK_LIMIT; // see readValue()
-
-namespace Json {
-
-#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520)
-typedef std::unique_ptr<CharReader> CharReaderPtr;
-#else
-typedef std::auto_ptr<CharReader>   CharReaderPtr;
-#endif
-
-// Implementation of class Features
-// ////////////////////////////////
-
-Features::Features()
-    : allowComments_(true), strictRoot_(false),
-      allowDroppedNullPlaceholders_(false), allowNumericKeys_(false) {}
-
-Features Features::all() { return Features(); }
-
-Features Features::strictMode() {
-  Features features;
-  features.allowComments_ = false;
-  features.strictRoot_ = true;
-  features.allowDroppedNullPlaceholders_ = false;
-  features.allowNumericKeys_ = false;
-  return features;
-}
-
-// Implementation of class Reader
-// ////////////////////////////////
-
-static bool containsNewLine(Reader::Location begin, Reader::Location end) {
-  for (; begin < end; ++begin)
-    if (*begin == '\n' || *begin == '\r')
-      return true;
-  return false;
-}
-
-// Class Reader
-// //////////////////////////////////////////////////////////////////
-
-Reader::Reader()
-    : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
-      lastValue_(), commentsBefore_(), features_(Features::all()),
-      collectComments_() {}
-
-Reader::Reader(const Features& features)
-    : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
-      lastValue_(), commentsBefore_(), features_(features), collectComments_() {
-}
-
-bool
-Reader::parse(const std::string& document, Value& root, bool collectComments) {
-  JSONCPP_STRING documentCopy(document.data(), document.data() + document.capacity());
-  std::swap(documentCopy, document_);
-  const char* begin = document_.c_str();
-  const char* end = begin + document_.length();
-  return parse(begin, end, root, collectComments);
-}
-
-bool Reader::parse(std::istream& sin, Value& root, bool collectComments) {
-  // std::istream_iterator<char> begin(sin);
-  // std::istream_iterator<char> end;
-  // Those would allow streamed input from a file, if parse() were a
-  // template function.
-
-  // Since JSONCPP_STRING is reference-counted, this at least does not
-  // create an extra copy.
-  JSONCPP_STRING doc;
-  std::getline(sin, doc, (char)EOF);
-  return parse(doc.data(), doc.data() + doc.size(), root, collectComments);
-}
-
-bool Reader::parse(const char* beginDoc,
-                   const char* endDoc,
-                   Value& root,
-                   bool collectComments) {
-  if (!features_.allowComments_) {
-    collectComments = false;
-  }
-
-  begin_ = beginDoc;
-  end_ = endDoc;
-  collectComments_ = collectComments;
-  current_ = begin_;
-  lastValueEnd_ = 0;
-  lastValue_ = 0;
-  commentsBefore_.clear();
-  errors_.clear();
-  while (!nodes_.empty())
-    nodes_.pop();
-  nodes_.push(&root);
-
-  bool successful = readValue();
-  Token token;
-  skipCommentTokens(token);
-  if (collectComments_ && !commentsBefore_.empty())
-    root.setComment(commentsBefore_, commentAfter);
-  if (features_.strictRoot_) {
-    if (!root.isArray() && !root.isObject()) {
-      // Set error location to start of doc, ideally should be first token found
-      // in doc
-      token.type_ = tokenError;
-      token.start_ = beginDoc;
-      token.end_ = endDoc;
-      addError(
-          "A valid JSON document must be either an array or an object value.",
-          token);
-      return false;
-    }
-  }
-  return successful;
-}
-
-bool Reader::readValue() {
-  // readValue() may call itself only if it calls readObject() or ReadArray().
-  // These methods execute nodes_.push() just before and nodes_.pop)() just after calling readValue(). 
-  // parse() executes one nodes_.push(), so > instead of >=.
-  if (nodes_.size() > stackLimit_g) throwRuntimeError("Exceeded stackLimit in readValue().");
-
-  Token token;
-  skipCommentTokens(token);
-  bool successful = true;
-
-  if (collectComments_ && !commentsBefore_.empty()) {
-    currentValue().setComment(commentsBefore_, commentBefore);
-    commentsBefore_.clear();
-  }
-
-  switch (token.type_) {
-  case tokenObjectBegin:
-    successful = readObject(token);
-    currentValue().setOffsetLimit(current_ - begin_);
-    break;
-  case tokenArrayBegin:
-    successful = readArray(token);
-    currentValue().setOffsetLimit(current_ - begin_);
-    break;
-  case tokenNumber:
-    successful = decodeNumber(token);
-    break;
-  case tokenString:
-    successful = decodeString(token);
-    break;
-  case tokenTrue:
-    {
-    Value v(true);
-    currentValue().swapPayload(v);
-    currentValue().setOffsetStart(token.start_ - begin_);
-    currentValue().setOffsetLimit(token.end_ - begin_);
-    }
-    break;
-  case tokenFalse:
-    {
-    Value v(false);
-    currentValue().swapPayload(v);
-    currentValue().setOffsetStart(token.start_ - begin_);
-    currentValue().setOffsetLimit(token.end_ - begin_);
-    }
-    break;
-  case tokenNull:
-    {
-    Value v;
-    currentValue().swapPayload(v);
-    currentValue().setOffsetStart(token.start_ - begin_);
-    currentValue().setOffsetLimit(token.end_ - begin_);
-    }
-    break;
-  case tokenArraySeparator:
-  case tokenObjectEnd:
-  case tokenArrayEnd:
-    if (features_.allowDroppedNullPlaceholders_) {
-      // "Un-read" the current token and mark the current value as a null
-      // token.
-      current_--;
-      Value v;
-      currentValue().swapPayload(v);
-      currentValue().setOffsetStart(current_ - begin_ - 1);
-      currentValue().setOffsetLimit(current_ - begin_);
-      break;
-    } // Else, fall through...
-  default:
-    currentValue().setOffsetStart(token.start_ - begin_);
-    currentValue().setOffsetLimit(token.end_ - begin_);
-    return addError("Syntax error: value, object or array expected.", token);
-  }
-
-  if (collectComments_) {
-    lastValueEnd_ = current_;
-    lastValue_ = &currentValue();
-  }
-
-  return successful;
-}
-
-void Reader::skipCommentTokens(Token& token) {
-  if (features_.allowComments_) {
-    do {
-      readToken(token);
-    } while (token.type_ == tokenComment);
-  } else {
-    readToken(token);
-  }
-}
-
-bool Reader::readToken(Token& token) {
-  skipSpaces();
-  token.start_ = current_;
-  Char c = getNextChar();
-  bool ok = true;
-  switch (c) {
-  case '{':
-    token.type_ = tokenObjectBegin;
-    break;
-  case '}':
-    token.type_ = tokenObjectEnd;
-    break;
-  case '[':
-    token.type_ = tokenArrayBegin;
-    break;
-  case ']':
-    token.type_ = tokenArrayEnd;
-    break;
-  case '"':
-    token.type_ = tokenString;
-    ok = readString();
-    break;
-  case '/':
-    token.type_ = tokenComment;
-    ok = readComment();
-    break;
-  case '0':
-  case '1':
-  case '2':
-  case '3':
-  case '4':
-  case '5':
-  case '6':
-  case '7':
-  case '8':
-  case '9':
-  case '-':
-    token.type_ = tokenNumber;
-    readNumber();
-    break;
-  case 't':
-    token.type_ = tokenTrue;
-    ok = match("rue", 3);
-    break;
-  case 'f':
-    token.type_ = tokenFalse;
-    ok = match("alse", 4);
-    break;
-  case 'n':
-    token.type_ = tokenNull;
-    ok = match("ull", 3);
-    break;
-  case ',':
-    token.type_ = tokenArraySeparator;
-    break;
-  case ':':
-    token.type_ = tokenMemberSeparator;
-    break;
-  case 0:
-    token.type_ = tokenEndOfStream;
-    break;
-  default:
-    ok = false;
-    break;
-  }
-  if (!ok)
-    token.type_ = tokenError;
-  token.end_ = current_;
-  return true;
-}
-
-void Reader::skipSpaces() {
-  while (current_ != end_) {
-    Char c = *current_;
-    if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
-      ++current_;
-    else
-      break;
-  }
-}
-
-bool Reader::match(Location pattern, int patternLength) {
-  if (end_ - current_ < patternLength)
-    return false;
-  int index = patternLength;
-  while (index--)
-    if (current_[index] != pattern[index])
-      return false;
-  current_ += patternLength;
-  return true;
-}
-
-bool Reader::readComment() {
-  Location commentBegin = current_ - 1;
-  Char c = getNextChar();
-  bool successful = false;
-  if (c == '*')
-    successful = readCStyleComment();
-  else if (c == '/')
-    successful = readCppStyleComment();
-  if (!successful)
-    return false;
-
-  if (collectComments_) {
-    CommentPlacement placement = commentBefore;
-    if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) {
-      if (c != '*' || !containsNewLine(commentBegin, current_))
-        placement = commentAfterOnSameLine;
-    }
-
-    addComment(commentBegin, current_, placement);
-  }
-  return true;
-}
-
-static JSONCPP_STRING normalizeEOL(Reader::Location begin, Reader::Location end) {
-  JSONCPP_STRING normalized;
-  normalized.reserve(static_cast<size_t>(end - begin));
-  Reader::Location current = begin;
-  while (current != end) {
-    char c = *current++;
-    if (c == '\r') {
-      if (current != end && *current == '\n')
-         // convert dos EOL
-         ++current;
-      // convert Mac EOL
-      normalized += '\n';
-    } else {
-      normalized += c;
-    }
-  }
-  return normalized;
-}
-
-void
-Reader::addComment(Location begin, Location end, CommentPlacement placement) {
-  assert(collectComments_);
-  const JSONCPP_STRING& normalized = normalizeEOL(begin, end);
-  if (placement == commentAfterOnSameLine) {
-    assert(lastValue_ != 0);
-    lastValue_->setComment(normalized, placement);
-  } else {
-    commentsBefore_ += normalized;
-  }
-}
-
-bool Reader::readCStyleComment() {
-  while ((current_ + 1) < end_) {
-    Char c = getNextChar();
-    if (c == '*' && *current_ == '/')
-      break;
-  }
-  return getNextChar() == '/';
-}
-
-bool Reader::readCppStyleComment() {
-  while (current_ != end_) {
-    Char c = getNextChar();
-    if (c == '\n')
-      break;
-    if (c == '\r') {
-      // Consume DOS EOL. It will be normalized in addComment.
-      if (current_ != end_ && *current_ == '\n')
-        getNextChar();
-      // Break on Moc OS 9 EOL.
-      break;
-    }
-  }
-  return true;
-}
-
-void Reader::readNumber() {
-  const char *p = current_;
-  char c = '0'; // stopgap for already consumed character
-  // integral part
-  while (c >= '0' && c <= '9')
-    c = (current_ = p) < end_ ? *p++ : '\0';
-  // fractional part
-  if (c == '.') {
-    c = (current_ = p) < end_ ? *p++ : '\0';
-    while (c >= '0' && c <= '9')
-      c = (current_ = p) < end_ ? *p++ : '\0';
-  }
-  // exponential part
-  if (c == 'e' || c == 'E') {
-    c = (current_ = p) < end_ ? *p++ : '\0';
-    if (c == '+' || c == '-')
-      c = (current_ = p) < end_ ? *p++ : '\0';
-    while (c >= '0' && c <= '9')
-      c = (current_ = p) < end_ ? *p++ : '\0';
-  }
-}
-
-bool Reader::readString() {
-  Char c = '\0';
-  while (current_ != end_) {
-    c = getNextChar();
-    if (c == '\\')
-      getNextChar();
-    else if (c == '"')
-      break;
-  }
-  return c == '"';
-}
-
-bool Reader::readObject(Token& tokenStart) {
-  Token tokenName;
-  JSONCPP_STRING name;
-  Value init(objectValue);
-  currentValue().swapPayload(init);
-  currentValue().setOffsetStart(tokenStart.start_ - begin_);
-  while (readToken(tokenName)) {
-    bool initialTokenOk = true;
-    while (tokenName.type_ == tokenComment && initialTokenOk)
-      initialTokenOk = readToken(tokenName);
-    if (!initialTokenOk)
-      break;
-    if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object
-      return true;
-    name.clear();
-    if (tokenName.type_ == tokenString) {
-      if (!decodeString(tokenName, name))
-        return recoverFromError(tokenObjectEnd);
-    } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) {
-      Value numberName;
-      if (!decodeNumber(tokenName, numberName))
-        return recoverFromError(tokenObjectEnd);
-      name = JSONCPP_STRING(numberName.asCString());
-    } else {
-      break;
-    }
-
-    Token colon;
-    if (!readToken(colon) || colon.type_ != tokenMemberSeparator) {
-      return addErrorAndRecover(
-          "Missing ':' after object member name", colon, tokenObjectEnd);
-    }
-    Value& value = currentValue()[name];
-    nodes_.push(&value);
-    bool ok = readValue();
-    nodes_.pop();
-    if (!ok) // error already set
-      return recoverFromError(tokenObjectEnd);
-
-    Token comma;
-    if (!readToken(comma) ||
-        (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&
-         comma.type_ != tokenComment)) {
-      return addErrorAndRecover(
-          "Missing ',' or '}' in object declaration", comma, tokenObjectEnd);
-    }
-    bool finalizeTokenOk = true;
-    while (comma.type_ == tokenComment && finalizeTokenOk)
-      finalizeTokenOk = readToken(comma);
-    if (comma.type_ == tokenObjectEnd)
-      return true;
-  }
-  return addErrorAndRecover(
-      "Missing '}' or object member name", tokenName, tokenObjectEnd);
-}
-
-bool Reader::readArray(Token& tokenStart) {
-  Value init(arrayValue);
-  currentValue().swapPayload(init);
-  currentValue().setOffsetStart(tokenStart.start_ - begin_);
-  skipSpaces();
-  if (current_ != end_ && *current_ == ']') // empty array
-  {
-    Token endArray;
-    readToken(endArray);
-    return true;
-  }
-  int index = 0;
-  for (;;) {
-    Value& value = currentValue()[index++];
-    nodes_.push(&value);
-    bool ok = readValue();
-    nodes_.pop();
-    if (!ok) // error already set
-      return recoverFromError(tokenArrayEnd);
-
-    Token token;
-    // Accept Comment after last item in the array.
-    ok = readToken(token);
-    while (token.type_ == tokenComment && ok) {
-      ok = readToken(token);
-    }
-    bool badTokenType =
-        (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd);
-    if (!ok || badTokenType) {
-      return addErrorAndRecover(
-          "Missing ',' or ']' in array declaration", token, tokenArrayEnd);
-    }
-    if (token.type_ == tokenArrayEnd)
-      break;
-  }
-  return true;
-}
-
-bool Reader::decodeNumber(Token& token) {
-  Value decoded;
-  if (!decodeNumber(token, decoded))
-    return false;
-  currentValue().swapPayload(decoded);
-  currentValue().setOffsetStart(token.start_ - begin_);
-  currentValue().setOffsetLimit(token.end_ - begin_);
-  return true;
-}
-
-bool Reader::decodeNumber(Token& token, Value& decoded) {
-  // Attempts to parse the number as an integer. If the number is
-  // larger than the maximum supported value of an integer then
-  // we decode the number as a double.
-  Location current = token.start_;
-  bool isNegative = *current == '-';
-  if (isNegative)
-    ++current;
-  // TODO: Help the compiler do the div and mod at compile time or get rid of them.
-  Value::LargestUInt maxIntegerValue =
-      isNegative ? Value::LargestUInt(Value::maxLargestInt) + 1
-                 : Value::maxLargestUInt;
-  Value::LargestUInt threshold = maxIntegerValue / 10;
-  Value::LargestUInt value = 0;
-  while (current < token.end_) {
-    Char c = *current++;
-    if (c < '0' || c > '9')
-      return decodeDouble(token, decoded);
-    Value::UInt digit(static_cast<Value::UInt>(c - '0'));
-    if (value >= threshold) {
-      // We've hit or exceeded the max value divided by 10 (rounded down). If
-      // a) we've only just touched the limit, b) this is the last digit, and
-      // c) it's small enough to fit in that rounding delta, we're okay.
-      // Otherwise treat this number as a double to avoid overflow.
-      if (value > threshold || current != token.end_ ||
-          digit > maxIntegerValue % 10) {
-        return decodeDouble(token, decoded);
-      }
-    }
-    value = value * 10 + digit;
-  }
-  if (isNegative && value == maxIntegerValue)
-    decoded = Value::minLargestInt;
-  else if (isNegative)
-    decoded = -Value::LargestInt(value);
-  else if (value <= Value::LargestUInt(Value::maxInt))
-    decoded = Value::LargestInt(value);
-  else
-    decoded = value;
-  return true;
-}
-
-bool Reader::decodeDouble(Token& token) {
-  Value decoded;
-  if (!decodeDouble(token, decoded))
-    return false;
-  currentValue().swapPayload(decoded);
-  currentValue().setOffsetStart(token.start_ - begin_);
-  currentValue().setOffsetLimit(token.end_ - begin_);
-  return true;
-}
-
-bool Reader::decodeDouble(Token& token, Value& decoded) {
-  double value = 0;
-  JSONCPP_STRING buffer(token.start_, token.end_);
-  JSONCPP_ISTRINGSTREAM is(buffer);
-  if (!(is >> value))
-    return addError("'" + JSONCPP_STRING(token.start_, token.end_) +
-                        "' is not a number.",
-                    token);
-  decoded = value;
-  return true;
-}
-
-bool Reader::decodeString(Token& token) {
-  JSONCPP_STRING decoded_string;
-  if (!decodeString(token, decoded_string))
-    return false;
-  Value decoded(decoded_string);
-  currentValue().swapPayload(decoded);
-  currentValue().setOffsetStart(token.start_ - begin_);
-  currentValue().setOffsetLimit(token.end_ - begin_);
-  return true;
-}
-
-bool Reader::decodeString(Token& token, JSONCPP_STRING& decoded) {
-  decoded.reserve(static_cast<size_t>(token.end_ - token.start_ - 2));
-  Location current = token.start_ + 1; // skip '"'
-  Location end = token.end_ - 1;       // do not include '"'
-  while (current != end) {
-    Char c = *current++;
-    if (c == '"')
-      break;
-    else if (c == '\\') {
-      if (current == end)
-        return addError("Empty escape sequence in string", token, current);
-      Char escape = *current++;
-      switch (escape) {
-      case '"':
-        decoded += '"';
-        break;
-      case '/':
-        decoded += '/';
-        break;
-      case '\\':
-        decoded += '\\';
-        break;
-      case 'b':
-        decoded += '\b';
-        break;
-      case 'f':
-        decoded += '\f';
-        break;
-      case 'n':
-        decoded += '\n';
-        break;
-      case 'r':
-        decoded += '\r';
-        break;
-      case 't':
-        decoded += '\t';
-        break;
-      case 'u': {
-        unsigned int unicode;
-        if (!decodeUnicodeCodePoint(token, current, end, unicode))
-          return false;
-        decoded += codePointToUTF8(unicode);
-      } break;
-      default:
-        return addError("Bad escape sequence in string", token, current);
-      }
-    } else {
-      decoded += c;
-    }
-  }
-  return true;
-}
-
-bool Reader::decodeUnicodeCodePoint(Token& token,
-                                    Location& current,
-                                    Location end,
-                                    unsigned int& unicode) {
-
-  if (!decodeUnicodeEscapeSequence(token, current, end, unicode))
-    return false;
-  if (unicode >= 0xD800 && unicode <= 0xDBFF) {
-    // surrogate pairs
-    if (end - current < 6)
-      return addError(
-          "additional six characters expected to parse unicode surrogate pair.",
-          token,
-          current);
-    unsigned int surrogatePair;
-    if (*(current++) == '\\' && *(current++) == 'u') {
-      if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) {
-        unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF);
-      } else
-        return false;
-    } else
-      return addError("expecting another \\u token to begin the second half of "
-                      "a unicode surrogate pair",
-                      token,
-                      current);
-  }
-  return true;
-}
-
-bool Reader::decodeUnicodeEscapeSequence(Token& token,
-                                         Location& current,
-                                         Location end,
-                                         unsigned int& ret_unicode) {
-  if (end - current < 4)
-    return addError(
-        "Bad unicode escape sequence in string: four digits expected.",
-        token,
-        current);
-  int unicode = 0;
-  for (int index = 0; index < 4; ++index) {
-    Char c = *current++;
-    unicode *= 16;
-    if (c >= '0' && c <= '9')
-      unicode += c - '0';
-    else if (c >= 'a' && c <= 'f')
-      unicode += c - 'a' + 10;
-    else if (c >= 'A' && c <= 'F')
-      unicode += c - 'A' + 10;
-    else
-      return addError(
-          "Bad unicode escape sequence in string: hexadecimal digit expected.",
-          token,
-          current);
-  }
-  ret_unicode = static_cast<unsigned int>(unicode);
-  return true;
-}
-
-bool
-Reader::addError(const JSONCPP_STRING& message, Token& token, Location extra) {
-  ErrorInfo info;
-  info.token_ = token;
-  info.message_ = message;
-  info.extra_ = extra;
-  errors_.push_back(info);
-  return false;
-}
-
-bool Reader::recoverFromError(TokenType skipUntilToken) {
-  size_t const errorCount = errors_.size();
-  Token skip;
-  for (;;) {
-    if (!readToken(skip))
-      errors_.resize(errorCount); // discard errors caused by recovery
-    if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream)
-      break;
-  }
-  errors_.resize(errorCount);
-  return false;
-}
-
-bool Reader::addErrorAndRecover(const JSONCPP_STRING& message,
-                                Token& token,
-                                TokenType skipUntilToken) {
-  addError(message, token);
-  return recoverFromError(skipUntilToken);
-}
-
-Value& Reader::currentValue() { return *(nodes_.top()); }
-
-Reader::Char Reader::getNextChar() {
-  if (current_ == end_)
-    return 0;
-  return *current_++;
-}
-
-void Reader::getLocationLineAndColumn(Location location,
-                                      int& line,
-                                      int& column) const {
-  Location current = begin_;
-  Location lastLineStart = current;
-  line = 0;
-  while (current < location && current != end_) {
-    Char c = *current++;
-    if (c == '\r') {
-      if (*current == '\n')
-        ++current;
-      lastLineStart = current;
-      ++line;
-    } else if (c == '\n') {
-      lastLineStart = current;
-      ++line;
-    }
-  }
-  // column & line start at 1
-  column = int(location - lastLineStart) + 1;
-  ++line;
-}
-
-JSONCPP_STRING Reader::getLocationLineAndColumn(Location location) const {
-  int line, column;
-  getLocationLineAndColumn(location, line, column);
-  char buffer[18 + 16 + 16 + 1];
-  snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column);
-  return buffer;
-}
-
-// Deprecated. Preserved for backward compatibility
-JSONCPP_STRING Reader::getFormatedErrorMessages() const {
-  return getFormattedErrorMessages();
-}
-
-JSONCPP_STRING Reader::getFormattedErrorMessages() const {
-  JSONCPP_STRING formattedMessage;
-  for (Errors::const_iterator itError = errors_.begin();
-       itError != errors_.end();
-       ++itError) {
-    const ErrorInfo& error = *itError;
-    formattedMessage +=
-        "* " + getLocationLineAndColumn(error.token_.start_) + "\n";
-    formattedMessage += "  " + error.message_ + "\n";
-    if (error.extra_)
-      formattedMessage +=
-          "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n";
-  }
-  return formattedMessage;
-}
-
-std::vector<Reader::StructuredError> Reader::getStructuredErrors() const {
-  std::vector<Reader::StructuredError> allErrors;
-  for (Errors::const_iterator itError = errors_.begin();
-       itError != errors_.end();
-       ++itError) {
-    const ErrorInfo& error = *itError;
-    Reader::StructuredError structured;
-    structured.offset_start = error.token_.start_ - begin_;
-    structured.offset_limit = error.token_.end_ - begin_;
-    structured.message = error.message_;
-    allErrors.push_back(structured);
-  }
-  return allErrors;
-}
-
-bool Reader::pushError(const Value& value, const JSONCPP_STRING& message) {
-  ptrdiff_t const length = end_ - begin_;
-  if(value.getOffsetStart() > length
-    || value.getOffsetLimit() > length)
-    return false;
-  Token token;
-  token.type_ = tokenError;
-  token.start_ = begin_ + value.getOffsetStart();
-  token.end_ = end_ + value.getOffsetLimit();
-  ErrorInfo info;
-  info.token_ = token;
-  info.message_ = message;
-  info.extra_ = 0;
-  errors_.push_back(info);
-  return true;
-}
-
-bool Reader::pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra) {
-  ptrdiff_t const length = end_ - begin_;
-  if(value.getOffsetStart() > length
-    || value.getOffsetLimit() > length
-    || extra.getOffsetLimit() > length)
-    return false;
-  Token token;
-  token.type_ = tokenError;
-  token.start_ = begin_ + value.getOffsetStart();
-  token.end_ = begin_ + value.getOffsetLimit();
-  ErrorInfo info;
-  info.token_ = token;
-  info.message_ = message;
-  info.extra_ = begin_ + extra.getOffsetStart();
-  errors_.push_back(info);
-  return true;
-}
-
-bool Reader::good() const {
-  return !errors_.size();
-}
-
-// exact copy of Features
-class OurFeatures {
-public:
-  static OurFeatures all();
-  bool allowComments_;
-  bool strictRoot_;
-  bool allowDroppedNullPlaceholders_;
-  bool allowNumericKeys_;
-  bool allowSingleQuotes_;
-  bool failIfExtra_;
-  bool rejectDupKeys_;
-  bool allowSpecialFloats_;
-  int stackLimit_;
-};  // OurFeatures
-
-// exact copy of Implementation of class Features
-// ////////////////////////////////
-
-OurFeatures OurFeatures::all() { return OurFeatures(); }
-
-// Implementation of class Reader
-// ////////////////////////////////
-
-// exact copy of Reader, renamed to OurReader
-class OurReader {
-public:
-  typedef char Char;
-  typedef const Char* Location;
-  struct StructuredError {
-    ptrdiff_t offset_start;
-    ptrdiff_t offset_limit;
-    JSONCPP_STRING message;
-  };
-
-  OurReader(OurFeatures const& features);
-  bool parse(const char* beginDoc,
-             const char* endDoc,
-             Value& root,
-             bool collectComments = true);
-  JSONCPP_STRING getFormattedErrorMessages() const;
-  std::vector<StructuredError> getStructuredErrors() const;
-  bool pushError(const Value& value, const JSONCPP_STRING& message);
-  bool pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra);
-  bool good() const;
-
-private:
-  OurReader(OurReader const&);  // no impl
-  void operator=(OurReader const&);  // no impl
-
-  enum TokenType {
-    tokenEndOfStream = 0,
-    tokenObjectBegin,
-    tokenObjectEnd,
-    tokenArrayBegin,
-    tokenArrayEnd,
-    tokenString,
-    tokenNumber,
-    tokenTrue,
-    tokenFalse,
-    tokenNull,
-    tokenNaN,
-    tokenPosInf,
-    tokenNegInf,
-    tokenArraySeparator,
-    tokenMemberSeparator,
-    tokenComment,
-    tokenError
-  };
-
-  class Token {
-  public:
-    TokenType type_;
-    Location start_;
-    Location end_;
-  };
-
-  class ErrorInfo {
-  public:
-    Token token_;
-    JSONCPP_STRING message_;
-    Location extra_;
-  };
-
-  typedef std::deque<ErrorInfo> Errors;
-
-  bool readToken(Token& token);
-  void skipSpaces();
-  bool match(Location pattern, int patternLength);
-  bool readComment();
-  bool readCStyleComment();
-  bool readCppStyleComment();
-  bool readString();
-  bool readStringSingleQuote();
-  bool readNumber(bool checkInf);
-  bool readValue();
-  bool readObject(Token& token);
-  bool readArray(Token& token);
-  bool decodeNumber(Token& token);
-  bool decodeNumber(Token& token, Value& decoded);
-  bool decodeString(Token& token);
-  bool decodeString(Token& token, JSONCPP_STRING& decoded);
-  bool decodeDouble(Token& token);
-  bool decodeDouble(Token& token, Value& decoded);
-  bool decodeUnicodeCodePoint(Token& token,
-                              Location& current,
-                              Location end,
-                              unsigned int& unicode);
-  bool decodeUnicodeEscapeSequence(Token& token,
-                                   Location& current,
-                                   Location end,
-                                   unsigned int& unicode);
-  bool addError(const JSONCPP_STRING& message, Token& token, Location extra = 0);
-  bool recoverFromError(TokenType skipUntilToken);
-  bool addErrorAndRecover(const JSONCPP_STRING& message,
-                          Token& token,
-                          TokenType skipUntilToken);
-  void skipUntilSpace();
-  Value& currentValue();
-  Char getNextChar();
-  void
-  getLocationLineAndColumn(Location location, int& line, int& column) const;
-  JSONCPP_STRING getLocationLineAndColumn(Location location) const;
-  void addComment(Location begin, Location end, CommentPlacement placement);
-  void skipCommentTokens(Token& token);
-
-  typedef std::stack<Value*> Nodes;
-  Nodes nodes_;
-  Errors errors_;
-  JSONCPP_STRING document_;
-  Location begin_;
-  Location end_;
-  Location current_;
-  Location lastValueEnd_;
-  Value* lastValue_;
-  JSONCPP_STRING commentsBefore_;
-
-  OurFeatures const features_;
-  bool collectComments_;
-};  // OurReader
-
-// complete copy of Read impl, for OurReader
-
-OurReader::OurReader(OurFeatures const& features)
-    : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
-      lastValue_(), commentsBefore_(),
-      features_(features), collectComments_() {
-}
-
-bool OurReader::parse(const char* beginDoc,
-                   const char* endDoc,
-                   Value& root,
-                   bool collectComments) {
-  if (!features_.allowComments_) {
-    collectComments = false;
-  }
-
-  begin_ = beginDoc;
-  end_ = endDoc;
-  collectComments_ = collectComments;
-  current_ = begin_;
-  lastValueEnd_ = 0;
-  lastValue_ = 0;
-  commentsBefore_.clear();
-  errors_.clear();
-  while (!nodes_.empty())
-    nodes_.pop();
-  nodes_.push(&root);
-
-  bool successful = readValue();
-  Token token;
-  skipCommentTokens(token);
-  if (features_.failIfExtra_) {
-    if ((features_.strictRoot_ || token.type_ != tokenError) && token.type_ != tokenEndOfStream) {
-      addError("Extra non-whitespace after JSON value.", token);
-      return false;
-    }
-  }
-  if (collectComments_ && !commentsBefore_.empty())
-    root.setComment(commentsBefore_, commentAfter);
-  if (features_.strictRoot_) {
-    if (!root.isArray() && !root.isObject()) {
-      // Set error location to start of doc, ideally should be first token found
-      // in doc
-      token.type_ = tokenError;
-      token.start_ = beginDoc;
-      token.end_ = endDoc;
-      addError(
-          "A valid JSON document must be either an array or an object value.",
-          token);
-      return false;
-    }
-  }
-  return successful;
-}
-
-bool OurReader::readValue() {
-  //  To preserve the old behaviour we cast size_t to int.
-  if (static_cast<int>(nodes_.size()) > features_.stackLimit_) throwRuntimeError("Exceeded stackLimit in readValue().");
-  Token token;
-  skipCommentTokens(token);
-  bool successful = true;
-
-  if (collectComments_ && !commentsBefore_.empty()) {
-    currentValue().setComment(commentsBefore_, commentBefore);
-    commentsBefore_.clear();
-  }
-
-  switch (token.type_) {
-  case tokenObjectBegin:
-    successful = readObject(token);
-    currentValue().setOffsetLimit(current_ - begin_);
-    break;
-  case tokenArrayBegin:
-    successful = readArray(token);
-    currentValue().setOffsetLimit(current_ - begin_);
-    break;
-  case tokenNumber:
-    successful = decodeNumber(token);
-    break;
-  case tokenString:
-    successful = decodeString(token);
-    break;
-  case tokenTrue:
-    {
-    Value v(true);
-    currentValue().swapPayload(v);
-    currentValue().setOffsetStart(token.start_ - begin_);
-    currentValue().setOffsetLimit(token.end_ - begin_);
-    }
-    break;
-  case tokenFalse:
-    {
-    Value v(false);
-    currentValue().swapPayload(v);
-    currentValue().setOffsetStart(token.start_ - begin_);
-    currentValue().setOffsetLimit(token.end_ - begin_);
-    }
-    break;
-  case tokenNull:
-    {
-    Value v;
-    currentValue().swapPayload(v);
-    currentValue().setOffsetStart(token.start_ - begin_);
-    currentValue().setOffsetLimit(token.end_ - begin_);
-    }
-    break;
-  case tokenNaN:
-    {
-    Value v(std::numeric_limits<double>::quiet_NaN());
-    currentValue().swapPayload(v);
-    currentValue().setOffsetStart(token.start_ - begin_);
-    currentValue().setOffsetLimit(token.end_ - begin_);
-    }
-    break;
-  case tokenPosInf:
-    {
-    Value v(std::numeric_limits<double>::infinity());
-    currentValue().swapPayload(v);
-    currentValue().setOffsetStart(token.start_ - begin_);
-    currentValue().setOffsetLimit(token.end_ - begin_);
-    }
-    break;
-  case tokenNegInf:
-    {
-    Value v(-std::numeric_limits<double>::infinity());
-    currentValue().swapPayload(v);
-    currentValue().setOffsetStart(token.start_ - begin_);
-    currentValue().setOffsetLimit(token.end_ - begin_);
-    }
-    break;
-  case tokenArraySeparator:
-  case tokenObjectEnd:
-  case tokenArrayEnd:
-    if (features_.allowDroppedNullPlaceholders_) {
-      // "Un-read" the current token and mark the current value as a null
-      // token.
-      current_--;
-      Value v;
-      currentValue().swapPayload(v);
-      currentValue().setOffsetStart(current_ - begin_ - 1);
-      currentValue().setOffsetLimit(current_ - begin_);
-      break;
-    } // else, fall through ...
-  default:
-    currentValue().setOffsetStart(token.start_ - begin_);
-    currentValue().setOffsetLimit(token.end_ - begin_);
-    return addError("Syntax error: value, object or array expected.", token);
-  }
-
-  if (collectComments_) {
-    lastValueEnd_ = current_;
-    lastValue_ = &currentValue();
-  }
-
-  return successful;
-}
-
-void OurReader::skipCommentTokens(Token& token) {
-  if (features_.allowComments_) {
-    do {
-      readToken(token);
-    } while (token.type_ == tokenComment);
-  } else {
-    readToken(token);
-  }
-}
-
-bool OurReader::readToken(Token& token) {
-  skipSpaces();
-  token.start_ = current_;
-  Char c = getNextChar();
-  bool ok = true;
-  switch (c) {
-  case '{':
-    token.type_ = tokenObjectBegin;
-    break;
-  case '}':
-    token.type_ = tokenObjectEnd;
-    break;
-  case '[':
-    token.type_ = tokenArrayBegin;
-    break;
-  case ']':
-    token.type_ = tokenArrayEnd;
-    break;
-  case '"':
-    token.type_ = tokenString;
-    ok = readString();
-    break;
-  case '\'':
-    if (features_.allowSingleQuotes_) {
-    token.type_ = tokenString;
-    ok = readStringSingleQuote();
-    break;
-    } // else continue
-  case '/':
-    token.type_ = tokenComment;
-    ok = readComment();
-    break;
-  case '0':
-  case '1':
-  case '2':
-  case '3':
-  case '4':
-  case '5':
-  case '6':
-  case '7':
-  case '8':
-  case '9':
-    token.type_ = tokenNumber;
-    readNumber(false);
-    break;
-  case '-':
-    if (readNumber(true)) {
-      token.type_ = tokenNumber;
-    } else {
-      token.type_ = tokenNegInf;
-      ok = features_.allowSpecialFloats_ && match("nfinity", 7);
-    }
-    break;
-  case 't':
-    token.type_ = tokenTrue;
-    ok = match("rue", 3);
-    break;
-  case 'f':
-    token.type_ = tokenFalse;
-    ok = match("alse", 4);
-    break;
-  case 'n':
-    token.type_ = tokenNull;
-    ok = match("ull", 3);
-    break;
-  case 'N':
-    if (features_.allowSpecialFloats_) {
-      token.type_ = tokenNaN;
-      ok = match("aN", 2);
-    } else {
-      ok = false;
-    }
-    break;
-  case 'I':
-    if (features_.allowSpecialFloats_) {
-      token.type_ = tokenPosInf;
-      ok = match("nfinity", 7);
-    } else {
-      ok = false;
-    }
-    break;
-  case ',':
-    token.type_ = tokenArraySeparator;
-    break;
-  case ':':
-    token.type_ = tokenMemberSeparator;
-    break;
-  case 0:
-    token.type_ = tokenEndOfStream;
-    break;
-  default:
-    ok = false;
-    break;
-  }
-  if (!ok)
-    token.type_ = tokenError;
-  token.end_ = current_;
-  return true;
-}
-
-void OurReader::skipSpaces() {
-  while (current_ != end_) {
-    Char c = *current_;
-    if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
-      ++current_;
-    else
-      break;
-  }
-}
-
-bool OurReader::match(Location pattern, int patternLength) {
-  if (end_ - current_ < patternLength)
-    return false;
-  int index = patternLength;
-  while (index--)
-    if (current_[index] != pattern[index])
-      return false;
-  current_ += patternLength;
-  return true;
-}
-
-bool OurReader::readComment() {
-  Location commentBegin = current_ - 1;
-  Char c = getNextChar();
-  bool successful = false;
-  if (c == '*')
-    successful = readCStyleComment();
-  else if (c == '/')
-    successful = readCppStyleComment();
-  if (!successful)
-    return false;
-
-  if (collectComments_) {
-    CommentPlacement placement = commentBefore;
-    if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) {
-      if (c != '*' || !containsNewLine(commentBegin, current_))
-        placement = commentAfterOnSameLine;
-    }
-
-    addComment(commentBegin, current_, placement);
-  }
-  return true;
-}
-
-void
-OurReader::addComment(Location begin, Location end, CommentPlacement placement) {
-  assert(collectComments_);
-  const JSONCPP_STRING& normalized = normalizeEOL(begin, end);
-  if (placement == commentAfterOnSameLine) {
-    assert(lastValue_ != 0);
-    lastValue_->setComment(normalized, placement);
-  } else {
-    commentsBefore_ += normalized;
-  }
-}
-
-bool OurReader::readCStyleComment() {
-  while ((current_ + 1) < end_) {
-    Char c = getNextChar();
-    if (c == '*' && *current_ == '/')
-      break;
-  }
-  return getNextChar() == '/';
-}
-
-bool OurReader::readCppStyleComment() {
-  while (current_ != end_) {
-    Char c = getNextChar();
-    if (c == '\n')
-      break;
-    if (c == '\r') {
-      // Consume DOS EOL. It will be normalized in addComment.
-      if (current_ != end_ && *current_ == '\n')
-        getNextChar();
-      // Break on Moc OS 9 EOL.
-      break;
-    }
-  }
-  return true;
-}
-
-bool OurReader::readNumber(bool checkInf) {
-  const char *p = current_;
-  if (checkInf && p != end_ && *p == 'I') {
-    current_ = ++p;
-    return false;
-  }
-  char c = '0'; // stopgap for already consumed character
-  // integral part
-  while (c >= '0' && c <= '9')
-    c = (current_ = p) < end_ ? *p++ : '\0';
-  // fractional part
-  if (c == '.') {
-    c = (current_ = p) < end_ ? *p++ : '\0';
-    while (c >= '0' && c <= '9')
-      c = (current_ = p) < end_ ? *p++ : '\0';
-  }
-  // exponential part
-  if (c == 'e' || c == 'E') {
-    c = (current_ = p) < end_ ? *p++ : '\0';
-    if (c == '+' || c == '-')
-      c = (current_ = p) < end_ ? *p++ : '\0';
-    while (c >= '0' && c <= '9')
-      c = (current_ = p) < end_ ? *p++ : '\0';
-  }
-  return true;
-}
-bool OurReader::readString() {
-  Char c = 0;
-  while (current_ != end_) {
-    c = getNextChar();
-    if (c == '\\')
-      getNextChar();
-    else if (c == '"')
-      break;
-  }
-  return c == '"';
-}
-
-
-bool OurReader::readStringSingleQuote() {
-  Char c = 0;
-  while (current_ != end_) {
-    c = getNextChar();
-    if (c == '\\')
-      getNextChar();
-    else if (c == '\'')
-      break;
-  }
-  return c == '\'';
-}
-
-bool OurReader::readObject(Token& tokenStart) {
-  Token tokenName;
-  JSONCPP_STRING name;
-  Value init(objectValue);
-  currentValue().swapPayload(init);
-  currentValue().setOffsetStart(tokenStart.start_ - begin_);
-  while (readToken(tokenName)) {
-    bool initialTokenOk = true;
-    while (tokenName.type_ == tokenComment && initialTokenOk)
-      initialTokenOk = readToken(tokenName);
-    if (!initialTokenOk)
-      break;
-    if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object
-      return true;
-    name.clear();
-    if (tokenName.type_ == tokenString) {
-      if (!decodeString(tokenName, name))
-        return recoverFromError(tokenObjectEnd);
-    } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) {
-      Value numberName;
-      if (!decodeNumber(tokenName, numberName))
-        return recoverFromError(tokenObjectEnd);
-      name = numberName.asString();
-    } else {
-      break;
-    }
-
-    Token colon;
-    if (!readToken(colon) || colon.type_ != tokenMemberSeparator) {
-      return addErrorAndRecover(
-          "Missing ':' after object member name", colon, tokenObjectEnd);
-    }
-    if (name.length() >= (1U<<30)) throwRuntimeError("keylength >= 2^30");
-    if (features_.rejectDupKeys_ && currentValue().isMember(name)) {
-      JSONCPP_STRING msg = "Duplicate key: '" + name + "'";
-      return addErrorAndRecover(
-          msg, tokenName, tokenObjectEnd);
-    }
-    Value& value = currentValue()[name];
-    nodes_.push(&value);
-    bool ok = readValue();
-    nodes_.pop();
-    if (!ok) // error already set
-      return recoverFromError(tokenObjectEnd);
-
-    Token comma;
-    if (!readToken(comma) ||
-        (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&
-         comma.type_ != tokenComment)) {
-      return addErrorAndRecover(
-          "Missing ',' or '}' in object declaration", comma, tokenObjectEnd);
-    }
-    bool finalizeTokenOk = true;
-    while (comma.type_ == tokenComment && finalizeTokenOk)
-      finalizeTokenOk = readToken(comma);
-    if (comma.type_ == tokenObjectEnd)
-      return true;
-  }
-  return addErrorAndRecover(
-      "Missing '}' or object member name", tokenName, tokenObjectEnd);
-}
-
-bool OurReader::readArray(Token& tokenStart) {
-  Value init(arrayValue);
-  currentValue().swapPayload(init);
-  currentValue().setOffsetStart(tokenStart.start_ - begin_);
-  skipSpaces();
-  if (current_ != end_ && *current_ == ']') // empty array
-  {
-    Token endArray;
-    readToken(endArray);
-    return true;
-  }
-  int index = 0;
-  for (;;) {
-    Value& value = currentValue()[index++];
-    nodes_.push(&value);
-    bool ok = readValue();
-    nodes_.pop();
-    if (!ok) // error already set
-      return recoverFromError(tokenArrayEnd);
-
-    Token token;
-    // Accept Comment after last item in the array.
-    ok = readToken(token);
-    while (token.type_ == tokenComment && ok) {
-      ok = readToken(token);
-    }
-    bool badTokenType =
-        (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd);
-    if (!ok || badTokenType) {
-      return addErrorAndRecover(
-          "Missing ',' or ']' in array declaration", token, tokenArrayEnd);
-    }
-    if (token.type_ == tokenArrayEnd)
-      break;
-  }
-  return true;
-}
-
-bool OurReader::decodeNumber(Token& token) {
-  Value decoded;
-  if (!decodeNumber(token, decoded))
-    return false;
-  currentValue().swapPayload(decoded);
-  currentValue().setOffsetStart(token.start_ - begin_);
-  currentValue().setOffsetLimit(token.end_ - begin_);
-  return true;
-}
-
-bool OurReader::decodeNumber(Token& token, Value& decoded) {
-  // Attempts to parse the number as an integer. If the number is
-  // larger than the maximum supported value of an integer then
-  // we decode the number as a double.
-  Location current = token.start_;
-  bool isNegative = *current == '-';
-  if (isNegative)
-    ++current;
-  // TODO: Help the compiler do the div and mod at compile time or get rid of them.
-  Value::LargestUInt maxIntegerValue =
-      isNegative ? Value::LargestUInt(-Value::minLargestInt)
-                 : Value::maxLargestUInt;
-  Value::LargestUInt threshold = maxIntegerValue / 10;
-  Value::LargestUInt value = 0;
-  while (current < token.end_) {
-    Char c = *current++;
-    if (c < '0' || c > '9')
-      return decodeDouble(token, decoded);
-    Value::UInt digit(static_cast<Value::UInt>(c - '0'));
-    if (value >= threshold) {
-      // We've hit or exceeded the max value divided by 10 (rounded down). If
-      // a) we've only just touched the limit, b) this is the last digit, and
-      // c) it's small enough to fit in that rounding delta, we're okay.
-      // Otherwise treat this number as a double to avoid overflow.
-      if (value > threshold || current != token.end_ ||
-          digit > maxIntegerValue % 10) {
-        return decodeDouble(token, decoded);
-      }
-    }
-    value = value * 10 + digit;
-  }
-  if (isNegative)
-    decoded = -Value::LargestInt(value);
-  else if (value <= Value::LargestUInt(Value::maxInt))
-    decoded = Value::LargestInt(value);
-  else
-    decoded = value;
-  return true;
-}
-
-bool OurReader::decodeDouble(Token& token) {
-  Value decoded;
-  if (!decodeDouble(token, decoded))
-    return false;
-  currentValue().swapPayload(decoded);
-  currentValue().setOffsetStart(token.start_ - begin_);
-  currentValue().setOffsetLimit(token.end_ - begin_);
-  return true;
-}
-
-bool OurReader::decodeDouble(Token& token, Value& decoded) {
-  double value = 0;
-  const int bufferSize = 32;
-  int count;
-  ptrdiff_t const length = token.end_ - token.start_;
-
-  // Sanity check to avoid buffer overflow exploits.
-  if (length < 0) {
-    return addError("Unable to parse token length", token);
-  }
-  size_t const ulength = static_cast<size_t>(length);
-
-  // Avoid using a string constant for the format control string given to
-  // sscanf, as this can cause hard to debug crashes on OS X. See here for more
-  // info:
-  //
-  //     http://developer.apple.com/library/mac/#DOCUMENTATION/DeveloperTools/gcc-4.0.1/gcc/Incompatibilities.html
-  char format[] = "%lf";
-
-  if (length <= bufferSize) {
-    Char buffer[bufferSize + 1];
-    memcpy(buffer, token.start_, ulength);
-    buffer[length] = 0;
-    fixNumericLocaleInput(buffer, buffer + length);
-    count = sscanf(buffer, format, &value);
-  } else {
-    JSONCPP_STRING buffer(token.start_, token.end_);
-    count = sscanf(buffer.c_str(), format, &value);
-  }
-
-  if (count != 1)
-    return addError("'" + JSONCPP_STRING(token.start_, token.end_) +
-                        "' is not a number.",
-                    token);
-  decoded = value;
-  return true;
-}
-
-bool OurReader::decodeString(Token& token) {
-  JSONCPP_STRING decoded_string;
-  if (!decodeString(token, decoded_string))
-    return false;
-  Value decoded(decoded_string);
-  currentValue().swapPayload(decoded);
-  currentValue().setOffsetStart(token.start_ - begin_);
-  currentValue().setOffsetLimit(token.end_ - begin_);
-  return true;
-}
-
-bool OurReader::decodeString(Token& token, JSONCPP_STRING& decoded) {
-  decoded.reserve(static_cast<size_t>(token.end_ - token.start_ - 2));
-  Location current = token.start_ + 1; // skip '"'
-  Location end = token.end_ - 1;       // do not include '"'
-  while (current != end) {
-    Char c = *current++;
-    if (c == '"')
-      break;
-    else if (c == '\\') {
-      if (current == end)
-        return addError("Empty escape sequence in string", token, current);
-      Char escape = *current++;
-      switch (escape) {
-      case '"':
-        decoded += '"';
-        break;
-      case '/':
-        decoded += '/';
-        break;
-      case '\\':
-        decoded += '\\';
-        break;
-      case 'b':
-        decoded += '\b';
-        break;
-      case 'f':
-        decoded += '\f';
-        break;
-      case 'n':
-        decoded += '\n';
-        break;
-      case 'r':
-        decoded += '\r';
-        break;
-      case 't':
-        decoded += '\t';
-        break;
-      case 'u': {
-        unsigned int unicode;
-        if (!decodeUnicodeCodePoint(token, current, end, unicode))
-          return false;
-        decoded += codePointToUTF8(unicode);
-      } break;
-      default:
-        return addError("Bad escape sequence in string", token, current);
-      }
-    } else {
-      decoded += c;
-    }
-  }
-  return true;
-}
-
-bool OurReader::decodeUnicodeCodePoint(Token& token,
-                                    Location& current,
-                                    Location end,
-                                    unsigned int& unicode) {
-
-  if (!decodeUnicodeEscapeSequence(token, current, end, unicode))
-    return false;
-  if (unicode >= 0xD800 && unicode <= 0xDBFF) {
-    // surrogate pairs
-    if (end - current < 6)
-      return addError(
-          "additional six characters expected to parse unicode surrogate pair.",
-          token,
-          current);
-    unsigned int surrogatePair;
-    if (*(current++) == '\\' && *(current++) == 'u') {
-      if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) {
-        unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF);
-      } else
-        return false;
-    } else
-      return addError("expecting another \\u token to begin the second half of "
-                      "a unicode surrogate pair",
-                      token,
-                      current);
-  }
-  return true;
-}
-
-bool OurReader::decodeUnicodeEscapeSequence(Token& token,
-                                         Location& current,
-                                         Location end,
-                                         unsigned int& ret_unicode) {
-  if (end - current < 4)
-    return addError(
-        "Bad unicode escape sequence in string: four digits expected.",
-        token,
-        current);
-  int unicode = 0;
-  for (int index = 0; index < 4; ++index) {
-    Char c = *current++;
-    unicode *= 16;
-    if (c >= '0' && c <= '9')
-      unicode += c - '0';
-    else if (c >= 'a' && c <= 'f')
-      unicode += c - 'a' + 10;
-    else if (c >= 'A' && c <= 'F')
-      unicode += c - 'A' + 10;
-    else
-      return addError(
-          "Bad unicode escape sequence in string: hexadecimal digit expected.",
-          token,
-          current);
-  }
-  ret_unicode = static_cast<unsigned int>(unicode);
-  return true;
-}
-
-bool
-OurReader::addError(const JSONCPP_STRING& message, Token& token, Location extra) {
-  ErrorInfo info;
-  info.token_ = token;
-  info.message_ = message;
-  info.extra_ = extra;
-  errors_.push_back(info);
-  return false;
-}
-
-bool OurReader::recoverFromError(TokenType skipUntilToken) {
-  size_t errorCount = errors_.size();
-  Token skip;
-  for (;;) {
-    if (!readToken(skip))
-      errors_.resize(errorCount); // discard errors caused by recovery
-    if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream)
-      break;
-  }
-  errors_.resize(errorCount);
-  return false;
-}
-
-bool OurReader::addErrorAndRecover(const JSONCPP_STRING& message,
-                                Token& token,
-                                TokenType skipUntilToken) {
-  addError(message, token);
-  return recoverFromError(skipUntilToken);
-}
-
-Value& OurReader::currentValue() { return *(nodes_.top()); }
-
-OurReader::Char OurReader::getNextChar() {
-  if (current_ == end_)
-    return 0;
-  return *current_++;
-}
-
-void OurReader::getLocationLineAndColumn(Location location,
-                                      int& line,
-                                      int& column) const {
-  Location current = begin_;
-  Location lastLineStart = current;
-  line = 0;
-  while (current < location && current != end_) {
-    Char c = *current++;
-    if (c == '\r') {
-      if (*current == '\n')
-        ++current;
-      lastLineStart = current;
-      ++line;
-    } else if (c == '\n') {
-      lastLineStart = current;
-      ++line;
-    }
-  }
-  // column & line start at 1
-  column = int(location - lastLineStart) + 1;
-  ++line;
-}
-
-JSONCPP_STRING OurReader::getLocationLineAndColumn(Location location) const {
-  int line, column;
-  getLocationLineAndColumn(location, line, column);
-  char buffer[18 + 16 + 16 + 1];
-  snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column);
-  return buffer;
-}
-
-JSONCPP_STRING OurReader::getFormattedErrorMessages() const {
-  JSONCPP_STRING formattedMessage;
-  for (Errors::const_iterator itError = errors_.begin();
-       itError != errors_.end();
-       ++itError) {
-    const ErrorInfo& error = *itError;
-    formattedMessage +=
-        "* " + getLocationLineAndColumn(error.token_.start_) + "\n";
-    formattedMessage += "  " + error.message_ + "\n";
-    if (error.extra_)
-      formattedMessage +=
-          "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n";
-  }
-  return formattedMessage;
-}
-
-std::vector<OurReader::StructuredError> OurReader::getStructuredErrors() const {
-  std::vector<OurReader::StructuredError> allErrors;
-  for (Errors::const_iterator itError = errors_.begin();
-       itError != errors_.end();
-       ++itError) {
-    const ErrorInfo& error = *itError;
-    OurReader::StructuredError structured;
-    structured.offset_start = error.token_.start_ - begin_;
-    structured.offset_limit = error.token_.end_ - begin_;
-    structured.message = error.message_;
-    allErrors.push_back(structured);
-  }
-  return allErrors;
-}
-
-bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message) {
-  ptrdiff_t length = end_ - begin_;
-  if(value.getOffsetStart() > length
-    || value.getOffsetLimit() > length)
-    return false;
-  Token token;
-  token.type_ = tokenError;
-  token.start_ = begin_ + value.getOffsetStart();
-  token.end_ = end_ + value.getOffsetLimit();
-  ErrorInfo info;
-  info.token_ = token;
-  info.message_ = message;
-  info.extra_ = 0;
-  errors_.push_back(info);
-  return true;
-}
-
-bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra) {
-  ptrdiff_t length = end_ - begin_;
-  if(value.getOffsetStart() > length
-    || value.getOffsetLimit() > length
-    || extra.getOffsetLimit() > length)
-    return false;
-  Token token;
-  token.type_ = tokenError;
-  token.start_ = begin_ + value.getOffsetStart();
-  token.end_ = begin_ + value.getOffsetLimit();
-  ErrorInfo info;
-  info.token_ = token;
-  info.message_ = message;
-  info.extra_ = begin_ + extra.getOffsetStart();
-  errors_.push_back(info);
-  return true;
-}
-
-bool OurReader::good() const {
-  return !errors_.size();
-}
-
-
-class OurCharReader : public CharReader {
-  bool const collectComments_;
-  OurReader reader_;
-public:
-  OurCharReader(
-    bool collectComments,
-    OurFeatures const& features)
-  : collectComments_(collectComments)
-  , reader_(features)
-  {}
-  bool parse(
-      char const* beginDoc, char const* endDoc,
-      Value* root, JSONCPP_STRING* errs) JSONCPP_OVERRIDE {
-    bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_);
-    if (errs) {
-      *errs = reader_.getFormattedErrorMessages();
-    }
-    return ok;
-  }
-};
-
-CharReaderBuilder::CharReaderBuilder()
-{
-  setDefaults(&settings_);
-}
-CharReaderBuilder::~CharReaderBuilder()
-{}
-CharReader* CharReaderBuilder::newCharReader() const
-{
-  bool collectComments = settings_["collectComments"].asBool();
-  OurFeatures features = OurFeatures::all();
-  features.allowComments_ = settings_["allowComments"].asBool();
-  features.strictRoot_ = settings_["strictRoot"].asBool();
-  features.allowDroppedNullPlaceholders_ = settings_["allowDroppedNullPlaceholders"].asBool();
-  features.allowNumericKeys_ = settings_["allowNumericKeys"].asBool();
-  features.allowSingleQuotes_ = settings_["allowSingleQuotes"].asBool();
-  features.stackLimit_ = settings_["stackLimit"].asInt();
-  features.failIfExtra_ = settings_["failIfExtra"].asBool();
-  features.rejectDupKeys_ = settings_["rejectDupKeys"].asBool();
-  features.allowSpecialFloats_ = settings_["allowSpecialFloats"].asBool();
-  return new OurCharReader(collectComments, features);
-}
-static void getValidReaderKeys(std::set<JSONCPP_STRING>* valid_keys)
-{
-  valid_keys->clear();
-  valid_keys->insert("collectComments");
-  valid_keys->insert("allowComments");
-  valid_keys->insert("strictRoot");
-  valid_keys->insert("allowDroppedNullPlaceholders");
-  valid_keys->insert("allowNumericKeys");
-  valid_keys->insert("allowSingleQuotes");
-  valid_keys->insert("stackLimit");
-  valid_keys->insert("failIfExtra");
-  valid_keys->insert("rejectDupKeys");
-  valid_keys->insert("allowSpecialFloats");
-}
-bool CharReaderBuilder::validate(Json::Value* invalid) const
-{
-  Json::Value my_invalid;
-  if (!invalid) invalid = &my_invalid;  // so we do not need to test for NULL
-  Json::Value& inv = *invalid;
-  std::set<JSONCPP_STRING> valid_keys;
-  getValidReaderKeys(&valid_keys);
-  Value::Members keys = settings_.getMemberNames();
-  size_t n = keys.size();
-  for (size_t i = 0; i < n; ++i) {
-    JSONCPP_STRING const& key = keys[i];
-    if (valid_keys.find(key) == valid_keys.end()) {
-      inv[key] = settings_[key];
-    }
-  }
-  return 0u == inv.size();
-}
-Value& CharReaderBuilder::operator[](JSONCPP_STRING key)
-{
-  return settings_[key];
-}
-// static
-void CharReaderBuilder::strictMode(Json::Value* settings)
-{
-//! [CharReaderBuilderStrictMode]
-  (*settings)["allowComments"] = false;
-  (*settings)["strictRoot"] = true;
-  (*settings)["allowDroppedNullPlaceholders"] = false;
-  (*settings)["allowNumericKeys"] = false;
-  (*settings)["allowSingleQuotes"] = false;
-  (*settings)["stackLimit"] = 1000;
-  (*settings)["failIfExtra"] = true;
-  (*settings)["rejectDupKeys"] = true;
-  (*settings)["allowSpecialFloats"] = false;
-//! [CharReaderBuilderStrictMode]
-}
-// static
-void CharReaderBuilder::setDefaults(Json::Value* settings)
-{
-//! [CharReaderBuilderDefaults]
-  (*settings)["collectComments"] = true;
-  (*settings)["allowComments"] = true;
-  (*settings)["strictRoot"] = false;
-  (*settings)["allowDroppedNullPlaceholders"] = false;
-  (*settings)["allowNumericKeys"] = false;
-  (*settings)["allowSingleQuotes"] = false;
-  (*settings)["stackLimit"] = 1000;
-  (*settings)["failIfExtra"] = false;
-  (*settings)["rejectDupKeys"] = false;
-  (*settings)["allowSpecialFloats"] = false;
-//! [CharReaderBuilderDefaults]
-}
-
-//////////////////////////////////
-// global functions
-
-bool parseFromStream(
-    CharReader::Factory const& fact, JSONCPP_ISTREAM& sin,
-    Value* root, JSONCPP_STRING* errs)
-{
-  JSONCPP_OSTRINGSTREAM ssin;
-  ssin << sin.rdbuf();
-  JSONCPP_STRING doc = ssin.str();
-  char const* begin = doc.data();
-  char const* end = begin + doc.size();
-  // Note that we do not actually need a null-terminator.
-  CharReaderPtr const reader(fact.newCharReader());
-  return reader->parse(begin, end, root, errs);
-}
-
-JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM& sin, Value& root) {
-  CharReaderBuilder b;
-  JSONCPP_STRING errs;
-  bool ok = parseFromStream(b, sin, &root, &errs);
-  if (!ok) {
-    fprintf(stderr,
-            "Error from reader: %s",
-            errs.c_str());
-
-    throwRuntimeError(errs);
-  }
-  return sin;
-}
-
-} // namespace Json
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: src/lib_json/json_reader.cpp
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: src/lib_json/json_valueiterator.inl
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-// included by json_value.cpp
-
-namespace Json {
-
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// class ValueIteratorBase
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-
-ValueIteratorBase::ValueIteratorBase()
-    : current_(), isNull_(true) {
-}
-
-ValueIteratorBase::ValueIteratorBase(
-    const Value::ObjectValues::iterator& current)
-    : current_(current), isNull_(false) {}
-
-Value& ValueIteratorBase::deref() const {
-  return current_->second;
-}
-
-void ValueIteratorBase::increment() {
-  ++current_;
-}
-
-void ValueIteratorBase::decrement() {
-  --current_;
-}
-
-ValueIteratorBase::difference_type
-ValueIteratorBase::computeDistance(const SelfType& other) const {
-#ifdef JSON_USE_CPPTL_SMALLMAP
-  return other.current_ - current_;
-#else
-  // Iterator for null value are initialized using the default
-  // constructor, which initialize current_ to the default
-  // std::map::iterator. As begin() and end() are two instance
-  // of the default std::map::iterator, they can not be compared.
-  // To allow this, we handle this comparison specifically.
-  if (isNull_ && other.isNull_) {
-    return 0;
-  }
-
-  // Usage of std::distance is not portable (does not compile with Sun Studio 12
-  // RogueWave STL,
-  // which is the one used by default).
-  // Using a portable hand-made version for non random iterator instead:
-  //   return difference_type( std::distance( current_, other.current_ ) );
-  difference_type myDistance = 0;
-  for (Value::ObjectValues::iterator it = current_; it != other.current_;
-       ++it) {
-    ++myDistance;
-  }
-  return myDistance;
-#endif
-}
-
-bool ValueIteratorBase::isEqual(const SelfType& other) const {
-  if (isNull_) {
-    return other.isNull_;
-  }
-  return current_ == other.current_;
-}
-
-void ValueIteratorBase::copy(const SelfType& other) {
-  current_ = other.current_;
-  isNull_ = other.isNull_;
-}
-
-Value ValueIteratorBase::key() const {
-  const Value::CZString czstring = (*current_).first;
-  if (czstring.data()) {
-    if (czstring.isStaticString())
-      return Value(StaticString(czstring.data()));
-    return Value(czstring.data(), czstring.data() + czstring.length());
-  }
-  return Value(czstring.index());
-}
-
-UInt ValueIteratorBase::index() const {
-  const Value::CZString czstring = (*current_).first;
-  if (!czstring.data())
-    return czstring.index();
-  return Value::UInt(-1);
-}
-
-JSONCPP_STRING ValueIteratorBase::name() const {
-  char const* keey;
-  char const* end;
-  keey = memberName(&end);
-  if (!keey) return JSONCPP_STRING();
-  return JSONCPP_STRING(keey, end);
-}
-
-char const* ValueIteratorBase::memberName() const {
-  const char* cname = (*current_).first.data();
-  return cname ? cname : "";
-}
-
-char const* ValueIteratorBase::memberName(char const** end) const {
-  const char* cname = (*current_).first.data();
-  if (!cname) {
-    *end = NULL;
-    return NULL;
-  }
-  *end = cname + (*current_).first.length();
-  return cname;
-}
-
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// class ValueConstIterator
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-
-ValueConstIterator::ValueConstIterator() {}
-
-ValueConstIterator::ValueConstIterator(
-    const Value::ObjectValues::iterator& current)
-    : ValueIteratorBase(current) {}
-
-ValueConstIterator::ValueConstIterator(ValueIterator const& other)
-    : ValueIteratorBase(other) {}
-
-ValueConstIterator& ValueConstIterator::
-operator=(const ValueIteratorBase& other) {
-  copy(other);
-  return *this;
-}
-
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// class ValueIterator
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-
-ValueIterator::ValueIterator() {}
-
-ValueIterator::ValueIterator(const Value::ObjectValues::iterator& current)
-    : ValueIteratorBase(current) {}
-
-ValueIterator::ValueIterator(const ValueConstIterator& other)
-    : ValueIteratorBase(other) {
-  throwRuntimeError("ConstIterator to Iterator should never be allowed.");
-}
-
-ValueIterator::ValueIterator(const ValueIterator& other)
-    : ValueIteratorBase(other) {}
-
-ValueIterator& ValueIterator::operator=(const SelfType& other) {
-  copy(other);
-  return *this;
-}
-
-} // namespace Json
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: src/lib_json/json_valueiterator.inl
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: src/lib_json/json_value.cpp
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2011 Baptiste Lepilleur and The JsonCpp Authors
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include <json/assertions.h>
-#include <json/value.h>
-#include <json/writer.h>
-#endif // if !defined(JSON_IS_AMALGAMATION)
-#include <math.h>
-#include <sstream>
-#include <utility>
-#include <cstring>
-#include <cassert>
-#ifdef JSON_USE_CPPTL
-#include <cpptl/conststring.h>
-#endif
-#include <cstddef> // size_t
-#include <algorithm> // min()
-
-#define JSON_ASSERT_UNREACHABLE assert(false)
-
-namespace Json {
-
-// This is a walkaround to avoid the static initialization of Value::null.
-// kNull must be word-aligned to avoid crashing on ARM.  We use an alignment of
-// 8 (instead of 4) as a bit of future-proofing.
-#if defined(__ARMEL__)
-#define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
-#else
-#define ALIGNAS(byte_alignment)
-#endif
-//static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 };
-//const unsigned char& kNullRef = kNull[0];
-//const Value& Value::null = reinterpret_cast<const Value&>(kNullRef);
-//const Value& Value::nullRef = null;
-
-// static
-Value const& Value::nullSingleton()
-{
- static Value const nullStatic;
- return nullStatic;
-}
-
-// for backwards compatibility, we'll leave these global references around, but DO NOT
-// use them in JSONCPP library code any more!
-Value const& Value::null = Value::nullSingleton();
-Value const& Value::nullRef = Value::nullSingleton();
-
-const Int Value::minInt = Int(~(UInt(-1) / 2));
-const Int Value::maxInt = Int(UInt(-1) / 2);
-const UInt Value::maxUInt = UInt(-1);
-#if defined(JSON_HAS_INT64)
-const Int64 Value::minInt64 = Int64(~(UInt64(-1) / 2));
-const Int64 Value::maxInt64 = Int64(UInt64(-1) / 2);
-const UInt64 Value::maxUInt64 = UInt64(-1);
-// The constant is hard-coded because some compiler have trouble
-// converting Value::maxUInt64 to a double correctly (AIX/xlC).
-// Assumes that UInt64 is a 64 bits integer.
-static const double maxUInt64AsDouble = 18446744073709551615.0;
-#endif // defined(JSON_HAS_INT64)
-const LargestInt Value::minLargestInt = LargestInt(~(LargestUInt(-1) / 2));
-const LargestInt Value::maxLargestInt = LargestInt(LargestUInt(-1) / 2);
-const LargestUInt Value::maxLargestUInt = LargestUInt(-1);
-
-#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
-template <typename T, typename U>
-static inline bool InRange(double d, T min, U max) {
-  // The casts can lose precision, but we are looking only for
-  // an approximate range. Might fail on edge cases though. ~cdunn
-  //return d >= static_cast<double>(min) && d <= static_cast<double>(max);
-  return d >= min && d <= max;
-}
-#else  // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
-static inline double integerToDouble(Json::UInt64 value) {
-  return static_cast<double>(Int64(value / 2)) * 2.0 + static_cast<double>(Int64(value & 1));
-}
-
-template <typename T> static inline double integerToDouble(T value) {
-  return static_cast<double>(value);
-}
-
-template <typename T, typename U>
-static inline bool InRange(double d, T min, U max) {
-  return d >= integerToDouble(min) && d <= integerToDouble(max);
-}
-#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
-
-/** Duplicates the specified string value.
- * @param value Pointer to the string to duplicate. Must be zero-terminated if
- *              length is "unknown".
- * @param length Length of the value. if equals to unknown, then it will be
- *               computed using strlen(value).
- * @return Pointer on the duplicate instance of string.
- */
-static inline char* duplicateStringValue(const char* value,
-                                         size_t length)
-{
-  // Avoid an integer overflow in the call to malloc below by limiting length
-  // to a sane value.
-  if (length >= static_cast<size_t>(Value::maxInt))
-    length = Value::maxInt - 1;
-
-  char* newString = static_cast<char*>(malloc(length + 1));
-  if (newString == NULL) {
-    throwRuntimeError(
-        "in Json::Value::duplicateStringValue(): "
-        "Failed to allocate string value buffer");
-  }
-  memcpy(newString, value, length);
-  newString[length] = 0;
-  return newString;
-}
-
-/* Record the length as a prefix.
- */
-static inline char* duplicateAndPrefixStringValue(
-    const char* value,
-    unsigned int length)
-{
-  // Avoid an integer overflow in the call to malloc below by limiting length
-  // to a sane value.
-  JSON_ASSERT_MESSAGE(length <= static_cast<unsigned>(Value::maxInt) - sizeof(unsigned) - 1U,
-                      "in Json::Value::duplicateAndPrefixStringValue(): "
-                      "length too big for prefixing");
-  unsigned actualLength = length + static_cast<unsigned>(sizeof(unsigned)) + 1U;
-  char* newString = static_cast<char*>(malloc(actualLength));
-  if (newString == 0) {
-    throwRuntimeError(
-        "in Json::Value::duplicateAndPrefixStringValue(): "
-        "Failed to allocate string value buffer");
-  }
-  *reinterpret_cast<unsigned*>(newString) = length;
-  memcpy(newString + sizeof(unsigned), value, length);
-  newString[actualLength - 1U] = 0; // to avoid buffer over-run accidents by users later
-  return newString;
-}
-inline static void decodePrefixedString(
-    bool isPrefixed, char const* prefixed,
-    unsigned* length, char const** value)
-{
-  if (!isPrefixed) {
-    *length = static_cast<unsigned>(strlen(prefixed));
-    *value = prefixed;
-  } else {
-    *length = *reinterpret_cast<unsigned const*>(prefixed);
-    *value = prefixed + sizeof(unsigned);
-  }
-}
-/** Free the string duplicated by duplicateStringValue()/duplicateAndPrefixStringValue().
- */
-#if JSONCPP_USING_SECURE_MEMORY
-static inline void releasePrefixedStringValue(char* value) {
-  unsigned length = 0;
-  char const* valueDecoded;
-  decodePrefixedString(true, value, &length, &valueDecoded);
-  size_t const size = sizeof(unsigned) + length + 1U;
-  memset(value, 0, size);
-  free(value);
-}
-static inline void releaseStringValue(char* value, unsigned length) {
-  // length==0 => we allocated the strings memory
-  size_t size = (length==0) ? strlen(value) : length;
-  memset(value, 0, size);
-  free(value);
-}
-#else // !JSONCPP_USING_SECURE_MEMORY
-static inline void releasePrefixedStringValue(char* value) {
-  free(value);
-}
-static inline void releaseStringValue(char* value, unsigned) {
-  free(value);
-}
-#endif // JSONCPP_USING_SECURE_MEMORY
-
-} // namespace Json
-
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// ValueInternals...
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-#if !defined(JSON_IS_AMALGAMATION)
-
-#include "json_valueiterator.inl"
-#endif // if !defined(JSON_IS_AMALGAMATION)
-
-namespace Json {
-
-Exception::Exception(JSONCPP_STRING const& msg)
-  : msg_(msg)
-{}
-Exception::~Exception() JSONCPP_NOEXCEPT
-{}
-char const* Exception::what() const JSONCPP_NOEXCEPT
-{
-  return msg_.c_str();
-}
-RuntimeError::RuntimeError(JSONCPP_STRING const& msg)
-  : Exception(msg)
-{}
-LogicError::LogicError(JSONCPP_STRING const& msg)
-  : Exception(msg)
-{}
-JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg)
-{
-  throw RuntimeError(msg);
-}
-JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg)
-{
-  throw LogicError(msg);
-}
-
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// class Value::CommentInfo
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-
-Value::CommentInfo::CommentInfo() : comment_(0)
-{}
-
-Value::CommentInfo::~CommentInfo() {
-  if (comment_)
-    releaseStringValue(comment_, 0u);
-}
-
-void Value::CommentInfo::setComment(const char* text, size_t len) {
-  if (comment_) {
-    releaseStringValue(comment_, 0u);
-    comment_ = 0;
-  }
-  JSON_ASSERT(text != 0);
-  JSON_ASSERT_MESSAGE(
-      text[0] == '\0' || text[0] == '/',
-      "in Json::Value::setComment(): Comments must start with /");
-  // It seems that /**/ style comments are acceptable as well.
-  comment_ = duplicateStringValue(text, len);
-}
-
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// class Value::CZString
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-
-// Notes: policy_ indicates if the string was allocated when
-// a string is stored.
-
-Value::CZString::CZString(ArrayIndex aindex) : cstr_(0), index_(aindex) {}
-
-Value::CZString::CZString(char const* str, unsigned ulength, DuplicationPolicy allocate)
-    : cstr_(str) {
-  // allocate != duplicate
-  storage_.policy_ = allocate & 0x3;
-  storage_.length_ = ulength & 0x3FFFFFFF;
-}
-
-Value::CZString::CZString(const CZString& other) {
-  cstr_ = (other.storage_.policy_ != noDuplication && other.cstr_ != 0
-				 ? duplicateStringValue(other.cstr_, other.storage_.length_)
-				 : other.cstr_);
-  storage_.policy_ = static_cast<unsigned>(other.cstr_
-                 ? (static_cast<DuplicationPolicy>(other.storage_.policy_) == noDuplication
-                     ? noDuplication : duplicate)
-                 : static_cast<DuplicationPolicy>(other.storage_.policy_)) & 3U;
-  storage_.length_ = other.storage_.length_;
-}
-
-#if JSON_HAS_RVALUE_REFERENCES
-Value::CZString::CZString(CZString&& other)
-  : cstr_(other.cstr_), index_(other.index_) {
-  other.cstr_ = nullptr;
-}
-#endif
-
-Value::CZString::~CZString() {
-  if (cstr_ && storage_.policy_ == duplicate) {
-	  releaseStringValue(const_cast<char*>(cstr_), storage_.length_ + 1u); //+1 for null terminating character for sake of completeness but not actually necessary
-  }
-}
-
-void Value::CZString::swap(CZString& other) {
-  std::swap(cstr_, other.cstr_);
-  std::swap(index_, other.index_);
-}
-
-Value::CZString& Value::CZString::operator=(const CZString& other) {
-  cstr_ = other.cstr_;
-  index_ = other.index_;
-  return *this;
-}
-
-#if JSON_HAS_RVALUE_REFERENCES
-Value::CZString& Value::CZString::operator=(CZString&& other) {
-  cstr_ = other.cstr_;
-  index_ = other.index_;
-  other.cstr_ = nullptr;
-  return *this;
-}
-#endif
-
-bool Value::CZString::operator<(const CZString& other) const {
-  if (!cstr_) return index_ < other.index_;
-  //return strcmp(cstr_, other.cstr_) < 0;
-  // Assume both are strings.
-  unsigned this_len = this->storage_.length_;
-  unsigned other_len = other.storage_.length_;
-  unsigned min_len = std::min<unsigned>(this_len, other_len);
-  JSON_ASSERT(this->cstr_ && other.cstr_);
-  int comp = memcmp(this->cstr_, other.cstr_, min_len);
-  if (comp < 0) return true;
-  if (comp > 0) return false;
-  return (this_len < other_len);
-}
-
-bool Value::CZString::operator==(const CZString& other) const {
-  if (!cstr_) return index_ == other.index_;
-  //return strcmp(cstr_, other.cstr_) == 0;
-  // Assume both are strings.
-  unsigned this_len = this->storage_.length_;
-  unsigned other_len = other.storage_.length_;
-  if (this_len != other_len) return false;
-  JSON_ASSERT(this->cstr_ && other.cstr_);
-  int comp = memcmp(this->cstr_, other.cstr_, this_len);
-  return comp == 0;
-}
-
-ArrayIndex Value::CZString::index() const { return index_; }
-
-//const char* Value::CZString::c_str() const { return cstr_; }
-const char* Value::CZString::data() const { return cstr_; }
-unsigned Value::CZString::length() const { return storage_.length_; }
-bool Value::CZString::isStaticString() const { return storage_.policy_ == noDuplication; }
-
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// class Value::Value
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-
-/*! \internal Default constructor initialization must be equivalent to:
- * memset( this, 0, sizeof(Value) )
- * This optimization is used in ValueInternalMap fast allocator.
- */
-Value::Value(ValueType vtype) {
-  static char const emptyString[] = "";
-  initBasic(vtype);
-  switch (vtype) {
-  case nullValue:
-    break;
-  case intValue:
-  case uintValue:
-    value_.int_ = 0;
-    break;
-  case realValue:
-    value_.real_ = 0.0;
-    break;
-  case stringValue:
-    // allocated_ == false, so this is safe.
-    value_.string_ = const_cast<char*>(static_cast<char const*>(emptyString));
-    break;
-  case arrayValue:
-  case objectValue:
-    value_.map_ = new ObjectValues();
-    break;
-  case booleanValue:
-    value_.bool_ = false;
-    break;
-  default:
-    JSON_ASSERT_UNREACHABLE;
-  }
-}
-
-Value::Value(Int value) {
-  initBasic(intValue);
-  value_.int_ = value;
-}
-
-Value::Value(UInt value) {
-  initBasic(uintValue);
-  value_.uint_ = value;
-}
-#if defined(JSON_HAS_INT64)
-Value::Value(Int64 value) {
-  initBasic(intValue);
-  value_.int_ = value;
-}
-Value::Value(UInt64 value) {
-  initBasic(uintValue);
-  value_.uint_ = value;
-}
-#endif // defined(JSON_HAS_INT64)
-
-Value::Value(double value) {
-  initBasic(realValue);
-  value_.real_ = value;
-}
-
-Value::Value(const char* value) {
-  initBasic(stringValue, true);
-  JSON_ASSERT_MESSAGE(value != NULL, "Null Value Passed to Value Constructor");
-  value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(strlen(value)));
-}
-
-Value::Value(const char* beginValue, const char* endValue) {
-  initBasic(stringValue, true);
-  value_.string_ =
-      duplicateAndPrefixStringValue(beginValue, static_cast<unsigned>(endValue - beginValue));
-}
-
-Value::Value(const JSONCPP_STRING& value) {
-  initBasic(stringValue, true);
-  value_.string_ =
-      duplicateAndPrefixStringValue(value.data(), static_cast<unsigned>(value.length()));
-}
-
-Value::Value(const StaticString& value) {
-  initBasic(stringValue);
-  value_.string_ = const_cast<char*>(value.c_str());
-}
-
-#ifdef JSON_USE_CPPTL
-Value::Value(const CppTL::ConstString& value) {
-  initBasic(stringValue, true);
-  value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(value.length()));
-}
-#endif
-
-Value::Value(bool value) {
-  initBasic(booleanValue);
-  value_.bool_ = value;
-}
-
-Value::Value(Value const& other)
-    : type_(other.type_), allocated_(false)
-      ,
-      comments_(0), start_(other.start_), limit_(other.limit_)
-{
-  switch (type_) {
-  case nullValue:
-  case intValue:
-  case uintValue:
-  case realValue:
-  case booleanValue:
-    value_ = other.value_;
-    break;
-  case stringValue:
-    if (other.value_.string_ && other.allocated_) {
-      unsigned len;
-      char const* str;
-      decodePrefixedString(other.allocated_, other.value_.string_,
-          &len, &str);
-      value_.string_ = duplicateAndPrefixStringValue(str, len);
-      allocated_ = true;
-    } else {
-      value_.string_ = other.value_.string_;
-      allocated_ = false;
-    }
-    break;
-  case arrayValue:
-  case objectValue:
-    value_.map_ = new ObjectValues(*other.value_.map_);
-    break;
-  default:
-    JSON_ASSERT_UNREACHABLE;
-  }
-  if (other.comments_) {
-    comments_ = new CommentInfo[numberOfCommentPlacement];
-    for (int comment = 0; comment < numberOfCommentPlacement; ++comment) {
-      const CommentInfo& otherComment = other.comments_[comment];
-      if (otherComment.comment_)
-        comments_[comment].setComment(
-            otherComment.comment_, strlen(otherComment.comment_));
-    }
-  }
-}
-
-#if JSON_HAS_RVALUE_REFERENCES
-// Move constructor
-Value::Value(Value&& other) {
-  initBasic(nullValue);
-  swap(other);
-}
-#endif
-
-Value::~Value() {
-  switch (type_) {
-  case nullValue:
-  case intValue:
-  case uintValue:
-  case realValue:
-  case booleanValue:
-    break;
-  case stringValue:
-    if (allocated_)
-      releasePrefixedStringValue(value_.string_);
-    break;
-  case arrayValue:
-  case objectValue:
-    delete value_.map_;
-    break;
-  default:
-    JSON_ASSERT_UNREACHABLE;
-  }
-
-  delete[] comments_;
-
-  value_.uint_ = 0;
-}
-
-Value& Value::operator=(Value other) {
-  swap(other);
-  return *this;
-}
-
-void Value::swapPayload(Value& other) {
-  ValueType temp = type_;
-  type_ = other.type_;
-  other.type_ = temp;
-  std::swap(value_, other.value_);
-  int temp2 = allocated_;
-  allocated_ = other.allocated_;
-  other.allocated_ = temp2 & 0x1;
-}
-
-void Value::copyPayload(const Value& other) {
-  type_ = other.type_;
-  value_ = other.value_;
-  allocated_ = other.allocated_;
-}
-
-void Value::swap(Value& other) {
-  swapPayload(other);
-  std::swap(comments_, other.comments_);
-  std::swap(start_, other.start_);
-  std::swap(limit_, other.limit_);
-}
-
-void Value::copy(const Value& other) {
-  copyPayload(other);
-  comments_ = other.comments_;
-  start_ = other.start_;
-  limit_ = other.limit_;
-}
-
-ValueType Value::type() const { return type_; }
-
-int Value::compare(const Value& other) const {
-  if (*this < other)
-    return -1;
-  if (*this > other)
-    return 1;
-  return 0;
-}
-
-bool Value::operator<(const Value& other) const {
-  int typeDelta = type_ - other.type_;
-  if (typeDelta)
-    return typeDelta < 0 ? true : false;
-  switch (type_) {
-  case nullValue:
-    return false;
-  case intValue:
-    return value_.int_ < other.value_.int_;
-  case uintValue:
-    return value_.uint_ < other.value_.uint_;
-  case realValue:
-    return value_.real_ < other.value_.real_;
-  case booleanValue:
-    return value_.bool_ < other.value_.bool_;
-  case stringValue:
-  {
-    if ((value_.string_ == 0) || (other.value_.string_ == 0)) {
-      if (other.value_.string_) return true;
-      else return false;
-    }
-    unsigned this_len;
-    unsigned other_len;
-    char const* this_str;
-    char const* other_str;
-    decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
-    decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str);
-    unsigned min_len = std::min<unsigned>(this_len, other_len);
-    JSON_ASSERT(this_str && other_str);
-    int comp = memcmp(this_str, other_str, min_len);
-    if (comp < 0) return true;
-    if (comp > 0) return false;
-    return (this_len < other_len);
-  }
-  case arrayValue:
-  case objectValue: {
-    int delta = int(value_.map_->size() - other.value_.map_->size());
-    if (delta)
-      return delta < 0;
-    return (*value_.map_) < (*other.value_.map_);
-  }
-  default:
-    JSON_ASSERT_UNREACHABLE;
-  }
-  return false; // unreachable
-}
-
-bool Value::operator<=(const Value& other) const { return !(other < *this); }
-
-bool Value::operator>=(const Value& other) const { return !(*this < other); }
-
-bool Value::operator>(const Value& other) const { return other < *this; }
-
-bool Value::operator==(const Value& other) const {
-  // if ( type_ != other.type_ )
-  // GCC 2.95.3 says:
-  // attempt to take address of bit-field structure member `Json::Value::type_'
-  // Beats me, but a temp solves the problem.
-  int temp = other.type_;
-  if (type_ != temp)
-    return false;
-  switch (type_) {
-  case nullValue:
-    return true;
-  case intValue:
-    return value_.int_ == other.value_.int_;
-  case uintValue:
-    return value_.uint_ == other.value_.uint_;
-  case realValue:
-    return value_.real_ == other.value_.real_;
-  case booleanValue:
-    return value_.bool_ == other.value_.bool_;
-  case stringValue:
-  {
-    if ((value_.string_ == 0) || (other.value_.string_ == 0)) {
-      return (value_.string_ == other.value_.string_);
-    }
-    unsigned this_len;
-    unsigned other_len;
-    char const* this_str;
-    char const* other_str;
-    decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
-    decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str);
-    if (this_len != other_len) return false;
-    JSON_ASSERT(this_str && other_str);
-    int comp = memcmp(this_str, other_str, this_len);
-    return comp == 0;
-  }
-  case arrayValue:
-  case objectValue:
-    return value_.map_->size() == other.value_.map_->size() &&
-           (*value_.map_) == (*other.value_.map_);
-  default:
-    JSON_ASSERT_UNREACHABLE;
-  }
-  return false; // unreachable
-}
-
-bool Value::operator!=(const Value& other) const { return !(*this == other); }
-
-const char* Value::asCString() const {
-  JSON_ASSERT_MESSAGE(type_ == stringValue,
-                      "in Json::Value::asCString(): requires stringValue");
-  if (value_.string_ == 0) return 0;
-  unsigned this_len;
-  char const* this_str;
-  decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
-  return this_str;
-}
-
-#if JSONCPP_USING_SECURE_MEMORY
-unsigned Value::getCStringLength() const {
-  JSON_ASSERT_MESSAGE(type_ == stringValue,
-	                  "in Json::Value::asCString(): requires stringValue");
-  if (value_.string_ == 0) return 0;
-  unsigned this_len;
-  char const* this_str;
-  decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
-  return this_len;
-}
-#endif
-
-bool Value::getString(char const** str, char const** cend) const {
-  if (type_ != stringValue) return false;
-  if (value_.string_ == 0) return false;
-  unsigned length;
-  decodePrefixedString(this->allocated_, this->value_.string_, &length, str);
-  *cend = *str + length;
-  return true;
-}
-
-JSONCPP_STRING Value::asString() const {
-  switch (type_) {
-  case nullValue:
-    return "";
-  case stringValue:
-  {
-    if (value_.string_ == 0) return "";
-    unsigned this_len;
-    char const* this_str;
-    decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
-    return JSONCPP_STRING(this_str, this_len);
-  }
-  case booleanValue:
-    return value_.bool_ ? "true" : "false";
-  case intValue:
-    return valueToString(value_.int_);
-  case uintValue:
-    return valueToString(value_.uint_);
-  case realValue:
-    return valueToString(value_.real_);
-  default:
-    JSON_FAIL_MESSAGE("Type is not convertible to string");
-  }
-}
-
-#ifdef JSON_USE_CPPTL
-CppTL::ConstString Value::asConstString() const {
-  unsigned len;
-  char const* str;
-  decodePrefixedString(allocated_, value_.string_,
-      &len, &str);
-  return CppTL::ConstString(str, len);
-}
-#endif
-
-Value::Int Value::asInt() const {
-  switch (type_) {
-  case intValue:
-    JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range");
-    return Int(value_.int_);
-  case uintValue:
-    JSON_ASSERT_MESSAGE(isInt(), "LargestUInt out of Int range");
-    return Int(value_.uint_);
-  case realValue:
-    JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt),
-                        "double out of Int range");
-    return Int(value_.real_);
-  case nullValue:
-    return 0;
-  case booleanValue:
-    return value_.bool_ ? 1 : 0;
-  default:
-    break;
-  }
-  JSON_FAIL_MESSAGE("Value is not convertible to Int.");
-}
-
-Value::UInt Value::asUInt() const {
-  switch (type_) {
-  case intValue:
-    JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range");
-    return UInt(value_.int_);
-  case uintValue:
-    JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range");
-    return UInt(value_.uint_);
-  case realValue:
-    JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt),
-                        "double out of UInt range");
-    return UInt(value_.real_);
-  case nullValue:
-    return 0;
-  case booleanValue:
-    return value_.bool_ ? 1 : 0;
-  default:
-    break;
-  }
-  JSON_FAIL_MESSAGE("Value is not convertible to UInt.");
-}
-
-#if defined(JSON_HAS_INT64)
-
-Value::Int64 Value::asInt64() const {
-  switch (type_) {
-  case intValue:
-    return Int64(value_.int_);
-  case uintValue:
-    JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range");
-    return Int64(value_.uint_);
-  case realValue:
-    JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64),
-                        "double out of Int64 range");
-    return Int64(value_.real_);
-  case nullValue:
-    return 0;
-  case booleanValue:
-    return value_.bool_ ? 1 : 0;
-  default:
-    break;
-  }
-  JSON_FAIL_MESSAGE("Value is not convertible to Int64.");
-}
-
-Value::UInt64 Value::asUInt64() const {
-  switch (type_) {
-  case intValue:
-    JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range");
-    return UInt64(value_.int_);
-  case uintValue:
-    return UInt64(value_.uint_);
-  case realValue:
-    JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64),
-                        "double out of UInt64 range");
-    return UInt64(value_.real_);
-  case nullValue:
-    return 0;
-  case booleanValue:
-    return value_.bool_ ? 1 : 0;
-  default:
-    break;
-  }
-  JSON_FAIL_MESSAGE("Value is not convertible to UInt64.");
-}
-#endif // if defined(JSON_HAS_INT64)
-
-LargestInt Value::asLargestInt() const {
-#if defined(JSON_NO_INT64)
-  return asInt();
-#else
-  return asInt64();
-#endif
-}
-
-LargestUInt Value::asLargestUInt() const {
-#if defined(JSON_NO_INT64)
-  return asUInt();
-#else
-  return asUInt64();
-#endif
-}
-
-double Value::asDouble() const {
-  switch (type_) {
-  case intValue:
-    return static_cast<double>(value_.int_);
-  case uintValue:
-#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
-    return static_cast<double>(value_.uint_);
-#else  // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
-    return integerToDouble(value_.uint_);
-#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
-  case realValue:
-    return value_.real_;
-  case nullValue:
-    return 0.0;
-  case booleanValue:
-    return value_.bool_ ? 1.0 : 0.0;
-  default:
-    break;
-  }
-  JSON_FAIL_MESSAGE("Value is not convertible to double.");
-}
-
-float Value::asFloat() const {
-  switch (type_) {
-  case intValue:
-    return static_cast<float>(value_.int_);
-  case uintValue:
-#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
-    return static_cast<float>(value_.uint_);
-#else  // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
-    // This can fail (silently?) if the value is bigger than MAX_FLOAT.
-    return static_cast<float>(integerToDouble(value_.uint_));
-#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
-  case realValue:
-    return static_cast<float>(value_.real_);
-  case nullValue:
-    return 0.0;
-  case booleanValue:
-    return value_.bool_ ? 1.0f : 0.0f;
-  default:
-    break;
-  }
-  JSON_FAIL_MESSAGE("Value is not convertible to float.");
-}
-
-bool Value::asBool() const {
-  switch (type_) {
-  case booleanValue:
-    return value_.bool_;
-  case nullValue:
-    return false;
-  case intValue:
-    return value_.int_ ? true : false;
-  case uintValue:
-    return value_.uint_ ? true : false;
-  case realValue:
-    // This is kind of strange. Not recommended.
-    return (value_.real_ != 0.0) ? true : false;
-  default:
-    break;
-  }
-  JSON_FAIL_MESSAGE("Value is not convertible to bool.");
-}
-
-bool Value::isConvertibleTo(ValueType other) const {
-  switch (other) {
-  case nullValue:
-    return (isNumeric() && asDouble() == 0.0) ||
-           (type_ == booleanValue && value_.bool_ == false) ||
-           (type_ == stringValue && asString().empty()) ||
-           (type_ == arrayValue && value_.map_->size() == 0) ||
-           (type_ == objectValue && value_.map_->size() == 0) ||
-           type_ == nullValue;
-  case intValue:
-    return isInt() ||
-           (type_ == realValue && InRange(value_.real_, minInt, maxInt)) ||
-           type_ == booleanValue || type_ == nullValue;
-  case uintValue:
-    return isUInt() ||
-           (type_ == realValue && InRange(value_.real_, 0, maxUInt)) ||
-           type_ == booleanValue || type_ == nullValue;
-  case realValue:
-    return isNumeric() || type_ == booleanValue || type_ == nullValue;
-  case booleanValue:
-    return isNumeric() || type_ == booleanValue || type_ == nullValue;
-  case stringValue:
-    return isNumeric() || type_ == booleanValue || type_ == stringValue ||
-           type_ == nullValue;
-  case arrayValue:
-    return type_ == arrayValue || type_ == nullValue;
-  case objectValue:
-    return type_ == objectValue || type_ == nullValue;
-  }
-  JSON_ASSERT_UNREACHABLE;
-  return false;
-}
-
-/// Number of values in array or object
-ArrayIndex Value::size() const {
-  switch (type_) {
-  case nullValue:
-  case intValue:
-  case uintValue:
-  case realValue:
-  case booleanValue:
-  case stringValue:
-    return 0;
-  case arrayValue: // size of the array is highest index + 1
-    if (!value_.map_->empty()) {
-      ObjectValues::const_iterator itLast = value_.map_->end();
-      --itLast;
-      return (*itLast).first.index() + 1;
-    }
-    return 0;
-  case objectValue:
-    return ArrayIndex(value_.map_->size());
-  }
-  JSON_ASSERT_UNREACHABLE;
-  return 0; // unreachable;
-}
-
-bool Value::empty() const {
-  if (isNull() || isArray() || isObject())
-    return size() == 0u;
-  else
-    return false;
-}
-
-bool Value::operator!() const { return isNull(); }
-
-void Value::clear() {
-  JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue ||
-                          type_ == objectValue,
-                      "in Json::Value::clear(): requires complex value");
-  start_ = 0;
-  limit_ = 0;
-  switch (type_) {
-  case arrayValue:
-  case objectValue:
-    value_.map_->clear();
-    break;
-  default:
-    break;
-  }
-}
-
-void Value::resize(ArrayIndex newSize) {
-  JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue,
-                      "in Json::Value::resize(): requires arrayValue");
-  if (type_ == nullValue)
-    *this = Value(arrayValue);
-  ArrayIndex oldSize = size();
-  if (newSize == 0)
-    clear();
-  else if (newSize > oldSize)
-    (*this)[newSize - 1];
-  else {
-    for (ArrayIndex index = newSize; index < oldSize; ++index) {
-      value_.map_->erase(index);
-    }
-    JSON_ASSERT(size() == newSize);
-  }
-}
-
-Value& Value::operator[](ArrayIndex index) {
-  JSON_ASSERT_MESSAGE(
-      type_ == nullValue || type_ == arrayValue,
-      "in Json::Value::operator[](ArrayIndex): requires arrayValue");
-  if (type_ == nullValue)
-    *this = Value(arrayValue);
-  CZString key(index);
-  ObjectValues::iterator it = value_.map_->lower_bound(key);
-  if (it != value_.map_->end() && (*it).first == key)
-    return (*it).second;
-
-  ObjectValues::value_type defaultValue(key, nullSingleton());
-  it = value_.map_->insert(it, defaultValue);
-  return (*it).second;
-}
-
-Value& Value::operator[](int index) {
-  JSON_ASSERT_MESSAGE(
-      index >= 0,
-      "in Json::Value::operator[](int index): index cannot be negative");
-  return (*this)[ArrayIndex(index)];
-}
-
-const Value& Value::operator[](ArrayIndex index) const {
-  JSON_ASSERT_MESSAGE(
-      type_ == nullValue || type_ == arrayValue,
-      "in Json::Value::operator[](ArrayIndex)const: requires arrayValue");
-  if (type_ == nullValue)
-    return nullSingleton();
-  CZString key(index);
-  ObjectValues::const_iterator it = value_.map_->find(key);
-  if (it == value_.map_->end())
-    return nullSingleton();
-  return (*it).second;
-}
-
-const Value& Value::operator[](int index) const {
-  JSON_ASSERT_MESSAGE(
-      index >= 0,
-      "in Json::Value::operator[](int index) const: index cannot be negative");
-  return (*this)[ArrayIndex(index)];
-}
-
-void Value::initBasic(ValueType vtype, bool allocated) {
-  type_ = vtype;
-  allocated_ = allocated;
-  comments_ = 0;
-  start_ = 0;
-  limit_ = 0;
-}
-
-// Access an object value by name, create a null member if it does not exist.
-// @pre Type of '*this' is object or null.
-// @param key is null-terminated.
-Value& Value::resolveReference(const char* key) {
-  JSON_ASSERT_MESSAGE(
-      type_ == nullValue || type_ == objectValue,
-      "in Json::Value::resolveReference(): requires objectValue");
-  if (type_ == nullValue)
-    *this = Value(objectValue);
-  CZString actualKey(
-      key, static_cast<unsigned>(strlen(key)), CZString::noDuplication); // NOTE!
-  ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
-  if (it != value_.map_->end() && (*it).first == actualKey)
-    return (*it).second;
-
-  ObjectValues::value_type defaultValue(actualKey, nullSingleton());
-  it = value_.map_->insert(it, defaultValue);
-  Value& value = (*it).second;
-  return value;
-}
-
-// @param key is not null-terminated.
-Value& Value::resolveReference(char const* key, char const* cend)
-{
-  JSON_ASSERT_MESSAGE(
-      type_ == nullValue || type_ == objectValue,
-      "in Json::Value::resolveReference(key, end): requires objectValue");
-  if (type_ == nullValue)
-    *this = Value(objectValue);
-  CZString actualKey(
-      key, static_cast<unsigned>(cend-key), CZString::duplicateOnCopy);
-  ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
-  if (it != value_.map_->end() && (*it).first == actualKey)
-    return (*it).second;
-
-  ObjectValues::value_type defaultValue(actualKey, nullSingleton());
-  it = value_.map_->insert(it, defaultValue);
-  Value& value = (*it).second;
-  return value;
-}
-
-Value Value::get(ArrayIndex index, const Value& defaultValue) const {
-  const Value* value = &((*this)[index]);
-  return value == &nullSingleton() ? defaultValue : *value;
-}
-
-bool Value::isValidIndex(ArrayIndex index) const { return index < size(); }
-
-Value const* Value::find(char const* key, char const* cend) const
-{
-  JSON_ASSERT_MESSAGE(
-      type_ == nullValue || type_ == objectValue,
-      "in Json::Value::find(key, end, found): requires objectValue or nullValue");
-  if (type_ == nullValue) return NULL;
-  CZString actualKey(key, static_cast<unsigned>(cend-key), CZString::noDuplication);
-  ObjectValues::const_iterator it = value_.map_->find(actualKey);
-  if (it == value_.map_->end()) return NULL;
-  return &(*it).second;
-}
-const Value& Value::operator[](const char* key) const
-{
-  Value const* found = find(key, key + strlen(key));
-  if (!found) return nullSingleton();
-  return *found;
-}
-Value const& Value::operator[](JSONCPP_STRING const& key) const
-{
-  Value const* found = find(key.data(), key.data() + key.length());
-  if (!found) return nullSingleton();
-  return *found;
-}
-
-Value& Value::operator[](const char* key) {
-  return resolveReference(key, key + strlen(key));
-}
-
-Value& Value::operator[](const JSONCPP_STRING& key) {
-  return resolveReference(key.data(), key.data() + key.length());
-}
-
-Value& Value::operator[](const StaticString& key) {
-  return resolveReference(key.c_str());
-}
-
-#ifdef JSON_USE_CPPTL
-Value& Value::operator[](const CppTL::ConstString& key) {
-  return resolveReference(key.c_str(), key.end_c_str());
-}
-Value const& Value::operator[](CppTL::ConstString const& key) const
-{
-  Value const* found = find(key.c_str(), key.end_c_str());
-  if (!found) return nullSingleton();
-  return *found;
-}
-#endif
-
-Value& Value::append(const Value& value) { return (*this)[size()] = value; }
-
-#if JSON_HAS_RVALUE_REFERENCES
-  Value& Value::append(Value&& value) { return (*this)[size()] = value; }
-#endif
-
-Value Value::get(char const* key, char const* cend, Value const& defaultValue) const
-{
-  Value const* found = find(key, cend);
-  return !found ? defaultValue : *found;
-}
-Value Value::get(char const* key, Value const& defaultValue) const
-{
-  return get(key, key + strlen(key), defaultValue);
-}
-Value Value::get(JSONCPP_STRING const& key, Value const& defaultValue) const
-{
-  return get(key.data(), key.data() + key.length(), defaultValue);
-}
-
-
-bool Value::removeMember(const char* key, const char* cend, Value* removed)
-{
-  if (type_ != objectValue) {
-    return false;
-  }
-  CZString actualKey(key, static_cast<unsigned>(cend-key), CZString::noDuplication);
-  ObjectValues::iterator it = value_.map_->find(actualKey);
-  if (it == value_.map_->end())
-    return false;
-  *removed = it->second;
-  value_.map_->erase(it);
-  return true;
-}
-bool Value::removeMember(const char* key, Value* removed)
-{
-  return removeMember(key, key + strlen(key), removed);
-}
-bool Value::removeMember(JSONCPP_STRING const& key, Value* removed)
-{
-  return removeMember(key.data(), key.data() + key.length(), removed);
-}
-Value Value::removeMember(const char* key)
-{
-  JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue,
-                      "in Json::Value::removeMember(): requires objectValue");
-  if (type_ == nullValue)
-    return nullSingleton();
-
-  Value removed;  // null
-  removeMember(key, key + strlen(key), &removed);
-  return removed; // still null if removeMember() did nothing
-}
-Value Value::removeMember(const JSONCPP_STRING& key)
-{
-  return removeMember(key.c_str());
-}
-
-bool Value::removeIndex(ArrayIndex index, Value* removed) {
-  if (type_ != arrayValue) {
-    return false;
-  }
-  CZString key(index);
-  ObjectValues::iterator it = value_.map_->find(key);
-  if (it == value_.map_->end()) {
-    return false;
-  }
-  *removed = it->second;
-  ArrayIndex oldSize = size();
-  // shift left all items left, into the place of the "removed"
-  for (ArrayIndex i = index; i < (oldSize - 1); ++i){
-    CZString keey(i);
-    (*value_.map_)[keey] = (*this)[i + 1];
-  }
-  // erase the last one ("leftover")
-  CZString keyLast(oldSize - 1);
-  ObjectValues::iterator itLast = value_.map_->find(keyLast);
-  value_.map_->erase(itLast);
-  return true;
-}
-
-#ifdef JSON_USE_CPPTL
-Value Value::get(const CppTL::ConstString& key,
-                 const Value& defaultValue) const {
-  return get(key.c_str(), key.end_c_str(), defaultValue);
-}
-#endif
-
-bool Value::isMember(char const* key, char const* cend) const
-{
-  Value const* value = find(key, cend);
-  return NULL != value;
-}
-bool Value::isMember(char const* key) const
-{
-  return isMember(key, key + strlen(key));
-}
-bool Value::isMember(JSONCPP_STRING const& key) const
-{
-  return isMember(key.data(), key.data() + key.length());
-}
-
-#ifdef JSON_USE_CPPTL
-bool Value::isMember(const CppTL::ConstString& key) const {
-  return isMember(key.c_str(), key.end_c_str());
-}
-#endif
-
-Value::Members Value::getMemberNames() const {
-  JSON_ASSERT_MESSAGE(
-      type_ == nullValue || type_ == objectValue,
-      "in Json::Value::getMemberNames(), value must be objectValue");
-  if (type_ == nullValue)
-    return Value::Members();
-  Members members;
-  members.reserve(value_.map_->size());
-  ObjectValues::const_iterator it = value_.map_->begin();
-  ObjectValues::const_iterator itEnd = value_.map_->end();
-  for (; it != itEnd; ++it) {
-    members.push_back(JSONCPP_STRING((*it).first.data(),
-                                  (*it).first.length()));
-  }
-  return members;
-}
-//
-//# ifdef JSON_USE_CPPTL
-// EnumMemberNames
-// Value::enumMemberNames() const
-//{
-//   if ( type_ == objectValue )
-//   {
-//      return CppTL::Enum::any(  CppTL::Enum::transform(
-//         CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() ),
-//         MemberNamesTransform() ) );
-//   }
-//   return EnumMemberNames();
-//}
-//
-//
-// EnumValues
-// Value::enumValues() const
-//{
-//   if ( type_ == objectValue  ||  type_ == arrayValue )
-//      return CppTL::Enum::anyValues( *(value_.map_),
-//                                     CppTL::Type<const Value &>() );
-//   return EnumValues();
-//}
-//
-//# endif
-
-static bool IsIntegral(double d) {
-  double integral_part;
-  return modf(d, &integral_part) == 0.0;
-}
-
-bool Value::isNull() const { return type_ == nullValue; }
-
-bool Value::isBool() const { return type_ == booleanValue; }
-
-bool Value::isInt() const {
-  switch (type_) {
-  case intValue:
-#if defined(JSON_HAS_INT64)
-    return value_.int_ >= minInt && value_.int_ <= maxInt;
-#else
-    return true;
-#endif
-  case uintValue:
-    return value_.uint_ <= UInt(maxInt);
-  case realValue:
-    return value_.real_ >= minInt && value_.real_ <= maxInt &&
-           IsIntegral(value_.real_);
-  default:
-    break;
-  }
-  return false;
-}
-
-bool Value::isUInt() const {
-  switch (type_) {
-  case intValue:
-#if defined(JSON_HAS_INT64)
-    return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt);
-#else
-    return value_.int_ >= 0;
-#endif
-  case uintValue:
-#if defined(JSON_HAS_INT64)
-    return value_.uint_ <= maxUInt;
-#else
-    return true;
-#endif
-  case realValue:
-    return value_.real_ >= 0 && value_.real_ <= maxUInt &&
-           IsIntegral(value_.real_);
-  default:
-    break;
-  }
-  return false;
-}
-
-bool Value::isInt64() const {
-#if defined(JSON_HAS_INT64)
-  switch (type_) {
-  case intValue:
-    return true;
-  case uintValue:
-    return value_.uint_ <= UInt64(maxInt64);
-  case realValue:
-    // Note that maxInt64 (= 2^63 - 1) is not exactly representable as a
-    // double, so double(maxInt64) will be rounded up to 2^63. Therefore we
-    // require the value to be strictly less than the limit.
-    return value_.real_ >= double(minInt64) &&
-           value_.real_ < double(maxInt64) && IsIntegral(value_.real_);
-  default:
-    break;
-  }
-#endif // JSON_HAS_INT64
-  return false;
-}
-
-bool Value::isUInt64() const {
-#if defined(JSON_HAS_INT64)
-  switch (type_) {
-  case intValue:
-    return value_.int_ >= 0;
-  case uintValue:
-    return true;
-  case realValue:
-    // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a
-    // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we
-    // require the value to be strictly less than the limit.
-    return value_.real_ >= 0 && value_.real_ < maxUInt64AsDouble &&
-           IsIntegral(value_.real_);
-  default:
-    break;
-  }
-#endif // JSON_HAS_INT64
-  return false;
-}
-
-bool Value::isIntegral() const {
-  switch (type_) {
-    case intValue:
-    case uintValue:
-      return true;
-    case realValue:
-#if defined(JSON_HAS_INT64)
-      // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a
-      // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we
-      // require the value to be strictly less than the limit.
-      return value_.real_ >= double(minInt64) && value_.real_ < maxUInt64AsDouble && IsIntegral(value_.real_);
-#else
-      return value_.real_ >= minInt && value_.real_ <= maxUInt && IsIntegral(value_.real_);
-#endif // JSON_HAS_INT64
-    default:
-      break;
-  }
-  return false;
-}
-
-bool Value::isDouble() const { return type_ == intValue || type_ == uintValue || type_ == realValue; }
-
-bool Value::isNumeric() const { return isDouble(); }
-
-bool Value::isString() const { return type_ == stringValue; }
-
-bool Value::isArray() const { return type_ == arrayValue; }
-
-bool Value::isObject() const { return type_ == objectValue; }
-
-void Value::setComment(const char* comment, size_t len, CommentPlacement placement) {
-  if (!comments_)
-    comments_ = new CommentInfo[numberOfCommentPlacement];
-  if ((len > 0) && (comment[len-1] == '\n')) {
-    // Always discard trailing newline, to aid indentation.
-    len -= 1;
-  }
-  comments_[placement].setComment(comment, len);
-}
-
-void Value::setComment(const char* comment, CommentPlacement placement) {
-  setComment(comment, strlen(comment), placement);
-}
-
-void Value::setComment(const JSONCPP_STRING& comment, CommentPlacement placement) {
-  setComment(comment.c_str(), comment.length(), placement);
-}
-
-bool Value::hasComment(CommentPlacement placement) const {
-  return comments_ != 0 && comments_[placement].comment_ != 0;
-}
-
-JSONCPP_STRING Value::getComment(CommentPlacement placement) const {
-  if (hasComment(placement))
-    return comments_[placement].comment_;
-  return "";
-}
-
-void Value::setOffsetStart(ptrdiff_t start) { start_ = start; }
-
-void Value::setOffsetLimit(ptrdiff_t limit) { limit_ = limit; }
-
-ptrdiff_t Value::getOffsetStart() const { return start_; }
-
-ptrdiff_t Value::getOffsetLimit() const { return limit_; }
-
-JSONCPP_STRING Value::toStyledString() const {
-  StyledWriter writer;
-  return writer.write(*this);
-}
-
-Value::const_iterator Value::begin() const {
-  switch (type_) {
-  case arrayValue:
-  case objectValue:
-    if (value_.map_)
-      return const_iterator(value_.map_->begin());
-    break;
-  default:
-    break;
-  }
-  return const_iterator();
-}
-
-Value::const_iterator Value::end() const {
-  switch (type_) {
-  case arrayValue:
-  case objectValue:
-    if (value_.map_)
-      return const_iterator(value_.map_->end());
-    break;
-  default:
-    break;
-  }
-  return const_iterator();
-}
-
-Value::iterator Value::begin() {
-  switch (type_) {
-  case arrayValue:
-  case objectValue:
-    if (value_.map_)
-      return iterator(value_.map_->begin());
-    break;
-  default:
-    break;
-  }
-  return iterator();
-}
-
-Value::iterator Value::end() {
-  switch (type_) {
-  case arrayValue:
-  case objectValue:
-    if (value_.map_)
-      return iterator(value_.map_->end());
-    break;
-  default:
-    break;
-  }
-  return iterator();
-}
-
-// class PathArgument
-// //////////////////////////////////////////////////////////////////
-
-PathArgument::PathArgument() : key_(), index_(), kind_(kindNone) {}
-
-PathArgument::PathArgument(ArrayIndex index)
-    : key_(), index_(index), kind_(kindIndex) {}
-
-PathArgument::PathArgument(const char* key)
-    : key_(key), index_(), kind_(kindKey) {}
-
-PathArgument::PathArgument(const JSONCPP_STRING& key)
-    : key_(key.c_str()), index_(), kind_(kindKey) {}
-
-// class Path
-// //////////////////////////////////////////////////////////////////
-
-Path::Path(const JSONCPP_STRING& path,
-           const PathArgument& a1,
-           const PathArgument& a2,
-           const PathArgument& a3,
-           const PathArgument& a4,
-           const PathArgument& a5) {
-  InArgs in;
-  in.reserve(5);
-  in.push_back(&a1);
-  in.push_back(&a2);
-  in.push_back(&a3);
-  in.push_back(&a4);
-  in.push_back(&a5);
-  makePath(path, in);
-}
-
-void Path::makePath(const JSONCPP_STRING& path, const InArgs& in) {
-  const char* current = path.c_str();
-  const char* end = current + path.length();
-  InArgs::const_iterator itInArg = in.begin();
-  while (current != end) {
-    if (*current == '[') {
-      ++current;
-      if (*current == '%')
-        addPathInArg(path, in, itInArg, PathArgument::kindIndex);
-      else {
-        ArrayIndex index = 0;
-        for (; current != end && *current >= '0' && *current <= '9'; ++current)
-          index = index * 10 + ArrayIndex(*current - '0');
-        args_.push_back(index);
-      }
-      if (current == end || *++current != ']')
-        invalidPath(path, int(current - path.c_str()));
-    } else if (*current == '%') {
-      addPathInArg(path, in, itInArg, PathArgument::kindKey);
-      ++current;
-    } else if (*current == '.' || *current == ']') {
-      ++current;
-    } else {
-      const char* beginName = current;
-      while (current != end && !strchr("[.", *current))
-        ++current;
-      args_.push_back(JSONCPP_STRING(beginName, current));
-    }
-  }
-}
-
-void Path::addPathInArg(const JSONCPP_STRING& /*path*/,
-                        const InArgs& in,
-                        InArgs::const_iterator& itInArg,
-                        PathArgument::Kind kind) {
-  if (itInArg == in.end()) {
-    // Error: missing argument %d
-  } else if ((*itInArg)->kind_ != kind) {
-    // Error: bad argument type
-  } else {
-    args_.push_back(**itInArg++);
-  }
-}
-
-void Path::invalidPath(const JSONCPP_STRING& /*path*/, int /*location*/) {
-  // Error: invalid path.
-}
-
-const Value& Path::resolve(const Value& root) const {
-  const Value* node = &root;
-  for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
-    const PathArgument& arg = *it;
-    if (arg.kind_ == PathArgument::kindIndex) {
-      if (!node->isArray() || !node->isValidIndex(arg.index_)) {
-        // Error: unable to resolve path (array value expected at position...
-        return Value::null;
-      }
-      node = &((*node)[arg.index_]);
-    } else if (arg.kind_ == PathArgument::kindKey) {
-      if (!node->isObject()) {
-        // Error: unable to resolve path (object value expected at position...)
-        return Value::null;
-      }
-      node = &((*node)[arg.key_]);
-      if (node == &Value::nullSingleton()) {
-        // Error: unable to resolve path (object has no member named '' at
-        // position...)
-        return Value::null;
-      }
-    }
-  }
-  return *node;
-}
-
-Value Path::resolve(const Value& root, const Value& defaultValue) const {
-  const Value* node = &root;
-  for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
-    const PathArgument& arg = *it;
-    if (arg.kind_ == PathArgument::kindIndex) {
-      if (!node->isArray() || !node->isValidIndex(arg.index_))
-        return defaultValue;
-      node = &((*node)[arg.index_]);
-    } else if (arg.kind_ == PathArgument::kindKey) {
-      if (!node->isObject())
-        return defaultValue;
-      node = &((*node)[arg.key_]);
-      if (node == &Value::nullSingleton())
-        return defaultValue;
-    }
-  }
-  return *node;
-}
-
-Value& Path::make(Value& root) const {
-  Value* node = &root;
-  for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
-    const PathArgument& arg = *it;
-    if (arg.kind_ == PathArgument::kindIndex) {
-      if (!node->isArray()) {
-        // Error: node is not an array at position ...
-      }
-      node = &((*node)[arg.index_]);
-    } else if (arg.kind_ == PathArgument::kindKey) {
-      if (!node->isObject()) {
-        // Error: node is not an object at position...
-      }
-      node = &((*node)[arg.key_]);
-    }
-  }
-  return *node;
-}
-
-} // namespace Json
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: src/lib_json/json_value.cpp
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: src/lib_json/json_writer.cpp
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2011 Baptiste Lepilleur and The JsonCpp Authors
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include <json/writer.h>
-#include "json_tool.h"
-#endif // if !defined(JSON_IS_AMALGAMATION)
-#include <iomanip>
-#include <memory>
-#include <sstream>
-#include <utility>
-#include <set>
-#include <cassert>
-#include <cstring>
-#include <cstdio>
-
-#if defined(_MSC_VER) && _MSC_VER >= 1200 && _MSC_VER < 1800 // Between VC++ 6.0 and VC++ 11.0
-#include <float.h>
-#define isfinite _finite
-#elif defined(__sun) && defined(__SVR4) //Solaris
-#if !defined(isfinite)
-#include <ieeefp.h>
-#define isfinite finite
-#endif
-#elif defined(_AIX)
-#if !defined(isfinite)
-#include <math.h>
-#define isfinite finite
-#endif
-#elif defined(__hpux)
-#if !defined(isfinite)
-#if defined(__ia64) && !defined(finite)
-#define isfinite(x) ((sizeof(x) == sizeof(float) ? \
-                     _Isfinitef(x) : _IsFinite(x)))
-#else
-#include <math.h>
-#define isfinite finite
-#endif
-#endif
-#else
-#include <cmath>
-#if !(defined(__QNXNTO__)) // QNX already defines isfinite
-#define isfinite std::isfinite
-#endif
-#endif
-
-#if defined(_MSC_VER)
-#if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && _MSC_VER >= 1500 // VC++ 9.0 and above
-#define snprintf sprintf_s
-#elif _MSC_VER >= 1900 // VC++ 14.0 and above
-#define snprintf std::snprintf
-#else
-#define snprintf _snprintf
-#endif
-#elif defined(__ANDROID__) || defined(__QNXNTO__)
-#define snprintf snprintf
-#elif __cplusplus >= 201103L
-#if !defined(__MINGW32__) && !defined(__CYGWIN__)
-#define snprintf std::snprintf
-#endif
-#endif
-
-#if defined(__BORLANDC__)  
-#include <float.h>
-#define isfinite _finite
-#define snprintf _snprintf
-#endif
-
-#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0
-// Disable warning about strdup being deprecated.
-#pragma warning(disable : 4996)
-#endif
-
-namespace Json {
-
-#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520)
-typedef std::unique_ptr<StreamWriter> StreamWriterPtr;
-#else
-typedef std::auto_ptr<StreamWriter>   StreamWriterPtr;
-#endif
-
-static bool containsControlCharacter(const char* str) {
-  while (*str) {
-    if (isControlCharacter(*(str++)))
-      return true;
-  }
-  return false;
-}
-
-static bool containsControlCharacter0(const char* str, unsigned len) {
-  char const* end = str + len;
-  while (end != str) {
-    if (isControlCharacter(*str) || 0==*str)
-      return true;
-    ++str;
-  }
-  return false;
-}
-
-JSONCPP_STRING valueToString(LargestInt value) {
-  UIntToStringBuffer buffer;
-  char* current = buffer + sizeof(buffer);
-  if (value == Value::minLargestInt) {
-    uintToString(LargestUInt(Value::maxLargestInt) + 1, current);
-    *--current = '-';
-  } else if (value < 0) {
-    uintToString(LargestUInt(-value), current);
-    *--current = '-';
-  } else {
-    uintToString(LargestUInt(value), current);
-  }
-  assert(current >= buffer);
-  return current;
-}
-
-JSONCPP_STRING valueToString(LargestUInt value) {
-  UIntToStringBuffer buffer;
-  char* current = buffer + sizeof(buffer);
-  uintToString(value, current);
-  assert(current >= buffer);
-  return current;
-}
-
-#if defined(JSON_HAS_INT64)
-
-JSONCPP_STRING valueToString(Int value) {
-  return valueToString(LargestInt(value));
-}
-
-JSONCPP_STRING valueToString(UInt value) {
-  return valueToString(LargestUInt(value));
-}
-
-#endif // # if defined(JSON_HAS_INT64)
-
-namespace {
-JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int precision) {
-  // Allocate a buffer that is more than large enough to store the 16 digits of
-  // precision requested below.
-  char buffer[36];
-  int len = -1;
-
-  char formatString[15];
-  snprintf(formatString, sizeof(formatString), "%%.%dg", precision);
-
-  // Print into the buffer. We need not request the alternative representation
-  // that always has a decimal point because JSON doesn't distingish the
-  // concepts of reals and integers.
-  if (isfinite(value)) {
-    len = snprintf(buffer, sizeof(buffer), formatString, value);
-    fixNumericLocale(buffer, buffer + len);
-
-    // try to ensure we preserve the fact that this was given to us as a double on input
-    if (!strchr(buffer, '.') && !strchr(buffer, 'e')) {
-      strcat(buffer, ".0");
-    }
-
-  } else {
-    // IEEE standard states that NaN values will not compare to themselves
-    if (value != value) {
-      len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "NaN" : "null");
-    } else if (value < 0) {
-      len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "-Infinity" : "-1e+9999");
-    } else {
-      len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "Infinity" : "1e+9999");
-    }
-  }
-  assert(len >= 0);
-  return buffer;
-}
-}
-
-JSONCPP_STRING valueToString(double value) { return valueToString(value, false, 17); }
-
-JSONCPP_STRING valueToString(bool value) { return value ? "true" : "false"; }
-
-JSONCPP_STRING valueToQuotedString(const char* value) {
-  if (value == NULL)
-    return "";
-  // Not sure how to handle unicode...
-  if (strpbrk(value, "\"\\\b\f\n\r\t") == NULL &&
-      !containsControlCharacter(value))
-    return JSONCPP_STRING("\"") + value + "\"";
-  // We have to walk value and escape any special characters.
-  // Appending to JSONCPP_STRING is not efficient, but this should be rare.
-  // (Note: forward slashes are *not* rare, but I am not escaping them.)
-  JSONCPP_STRING::size_type maxsize =
-      strlen(value) * 2 + 3; // allescaped+quotes+NULL
-  JSONCPP_STRING result;
-  result.reserve(maxsize); // to avoid lots of mallocs
-  result += "\"";
-  for (const char* c = value; *c != 0; ++c) {
-    switch (*c) {
-    case '\"':
-      result += "\\\"";
-      break;
-    case '\\':
-      result += "\\\\";
-      break;
-    case '\b':
-      result += "\\b";
-      break;
-    case '\f':
-      result += "\\f";
-      break;
-    case '\n':
-      result += "\\n";
-      break;
-    case '\r':
-      result += "\\r";
-      break;
-    case '\t':
-      result += "\\t";
-      break;
-    // case '/':
-    // Even though \/ is considered a legal escape in JSON, a bare
-    // slash is also legal, so I see no reason to escape it.
-    // (I hope I am not misunderstanding something.
-    // blep notes: actually escaping \/ may be useful in javascript to avoid </
-    // sequence.
-    // Should add a flag to allow this compatibility mode and prevent this
-    // sequence from occurring.
-    default:
-      if (isControlCharacter(*c)) {
-        JSONCPP_OSTRINGSTREAM oss;
-        oss << "\\u" << std::hex << std::uppercase << std::setfill('0')
-            << std::setw(4) << static_cast<int>(*c);
-        result += oss.str();
-      } else {
-        result += *c;
-      }
-      break;
-    }
-  }
-  result += "\"";
-  return result;
-}
-
-// https://github.com/upcaste/upcaste/blob/master/src/upcore/src/cstring/strnpbrk.cpp
-static char const* strnpbrk(char const* s, char const* accept, size_t n) {
-  assert((s || !n) && accept);
-
-  char const* const end = s + n;
-  for (char const* cur = s; cur < end; ++cur) {
-    int const c = *cur;
-    for (char const* a = accept; *a; ++a) {
-      if (*a == c) {
-        return cur;
-      }
-    }
-  }
-  return NULL;
-}
-static JSONCPP_STRING valueToQuotedStringN(const char* value, unsigned length) {
-  if (value == NULL)
-    return "";
-  // Not sure how to handle unicode...
-  if (strnpbrk(value, "\"\\\b\f\n\r\t", length) == NULL &&
-      !containsControlCharacter0(value, length))
-    return JSONCPP_STRING("\"") + value + "\"";
-  // We have to walk value and escape any special characters.
-  // Appending to JSONCPP_STRING is not efficient, but this should be rare.
-  // (Note: forward slashes are *not* rare, but I am not escaping them.)
-  JSONCPP_STRING::size_type maxsize =
-      length * 2 + 3; // allescaped+quotes+NULL
-  JSONCPP_STRING result;
-  result.reserve(maxsize); // to avoid lots of mallocs
-  result += "\"";
-  char const* end = value + length;
-  for (const char* c = value; c != end; ++c) {
-    switch (*c) {
-    case '\"':
-      result += "\\\"";
-      break;
-    case '\\':
-      result += "\\\\";
-      break;
-    case '\b':
-      result += "\\b";
-      break;
-    case '\f':
-      result += "\\f";
-      break;
-    case '\n':
-      result += "\\n";
-      break;
-    case '\r':
-      result += "\\r";
-      break;
-    case '\t':
-      result += "\\t";
-      break;
-    // case '/':
-    // Even though \/ is considered a legal escape in JSON, a bare
-    // slash is also legal, so I see no reason to escape it.
-    // (I hope I am not misunderstanding something.)
-    // blep notes: actually escaping \/ may be useful in javascript to avoid </
-    // sequence.
-    // Should add a flag to allow this compatibility mode and prevent this
-    // sequence from occurring.
-    default:
-      if ((isControlCharacter(*c)) || (*c == 0)) {
-        JSONCPP_OSTRINGSTREAM oss;
-        oss << "\\u" << std::hex << std::uppercase << std::setfill('0')
-            << std::setw(4) << static_cast<int>(*c);
-        result += oss.str();
-      } else {
-        result += *c;
-      }
-      break;
-    }
-  }
-  result += "\"";
-  return result;
-}
-
-// Class Writer
-// //////////////////////////////////////////////////////////////////
-Writer::~Writer() {}
-
-// Class FastWriter
-// //////////////////////////////////////////////////////////////////
-
-FastWriter::FastWriter()
-    : yamlCompatiblityEnabled_(false), dropNullPlaceholders_(false),
-      omitEndingLineFeed_(false) {}
-
-void FastWriter::enableYAMLCompatibility() { yamlCompatiblityEnabled_ = true; }
-
-void FastWriter::dropNullPlaceholders() { dropNullPlaceholders_ = true; }
-
-void FastWriter::omitEndingLineFeed() { omitEndingLineFeed_ = true; }
-
-JSONCPP_STRING FastWriter::write(const Value& root) {
-  document_.clear();
-  writeValue(root);
-  if (!omitEndingLineFeed_)
-    document_ += "\n";
-  return document_;
-}
-
-void FastWriter::writeValue(const Value& value) {
-  switch (value.type()) {
-  case nullValue:
-    if (!dropNullPlaceholders_)
-      document_ += "null";
-    break;
-  case intValue:
-    document_ += valueToString(value.asLargestInt());
-    break;
-  case uintValue:
-    document_ += valueToString(value.asLargestUInt());
-    break;
-  case realValue:
-    document_ += valueToString(value.asDouble());
-    break;
-  case stringValue:
-  {
-    // Is NULL possible for value.string_? No.
-    char const* str;
-    char const* end;
-    bool ok = value.getString(&str, &end);
-    if (ok) document_ += valueToQuotedStringN(str, static_cast<unsigned>(end-str));
-    break;
-  }
-  case booleanValue:
-    document_ += valueToString(value.asBool());
-    break;
-  case arrayValue: {
-    document_ += '[';
-    ArrayIndex size = value.size();
-    for (ArrayIndex index = 0; index < size; ++index) {
-      if (index > 0)
-        document_ += ',';
-      writeValue(value[index]);
-    }
-    document_ += ']';
-  } break;
-  case objectValue: {
-    Value::Members members(value.getMemberNames());
-    document_ += '{';
-    for (Value::Members::iterator it = members.begin(); it != members.end();
-         ++it) {
-      const JSONCPP_STRING& name = *it;
-      if (it != members.begin())
-        document_ += ',';
-      document_ += valueToQuotedStringN(name.data(), static_cast<unsigned>(name.length()));
-      document_ += yamlCompatiblityEnabled_ ? ": " : ":";
-      writeValue(value[name]);
-    }
-    document_ += '}';
-  } break;
-  }
-}
-
-// Class StyledWriter
-// //////////////////////////////////////////////////////////////////
-
-StyledWriter::StyledWriter()
-    : rightMargin_(74), indentSize_(3), addChildValues_() {}
-
-JSONCPP_STRING StyledWriter::write(const Value& root) {
-  document_.clear();
-  addChildValues_ = false;
-  indentString_.clear();
-  writeCommentBeforeValue(root);
-  writeValue(root);
-  writeCommentAfterValueOnSameLine(root);
-  document_ += "\n";
-  return document_;
-}
-
-void StyledWriter::writeValue(const Value& value) {
-  switch (value.type()) {
-  case nullValue:
-    pushValue("null");
-    break;
-  case intValue:
-    pushValue(valueToString(value.asLargestInt()));
-    break;
-  case uintValue:
-    pushValue(valueToString(value.asLargestUInt()));
-    break;
-  case realValue:
-    pushValue(valueToString(value.asDouble()));
-    break;
-  case stringValue:
-  {
-    // Is NULL possible for value.string_? No.
-    char const* str;
-    char const* end;
-    bool ok = value.getString(&str, &end);
-    if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str)));
-    else pushValue("");
-    break;
-  }
-  case booleanValue:
-    pushValue(valueToString(value.asBool()));
-    break;
-  case arrayValue:
-    writeArrayValue(value);
-    break;
-  case objectValue: {
-    Value::Members members(value.getMemberNames());
-    if (members.empty())
-      pushValue("{}");
-    else {
-      writeWithIndent("{");
-      indent();
-      Value::Members::iterator it = members.begin();
-      for (;;) {
-        const JSONCPP_STRING& name = *it;
-        const Value& childValue = value[name];
-        writeCommentBeforeValue(childValue);
-        writeWithIndent(valueToQuotedString(name.c_str()));
-        document_ += " : ";
-        writeValue(childValue);
-        if (++it == members.end()) {
-          writeCommentAfterValueOnSameLine(childValue);
-          break;
-        }
-        document_ += ',';
-        writeCommentAfterValueOnSameLine(childValue);
-      }
-      unindent();
-      writeWithIndent("}");
-    }
-  } break;
-  }
-}
-
-void StyledWriter::writeArrayValue(const Value& value) {
-  unsigned size = value.size();
-  if (size == 0)
-    pushValue("[]");
-  else {
-    bool isArrayMultiLine = isMultineArray(value);
-    if (isArrayMultiLine) {
-      writeWithIndent("[");
-      indent();
-      bool hasChildValue = !childValues_.empty();
-      unsigned index = 0;
-      for (;;) {
-        const Value& childValue = value[index];
-        writeCommentBeforeValue(childValue);
-        if (hasChildValue)
-          writeWithIndent(childValues_[index]);
-        else {
-          writeIndent();
-          writeValue(childValue);
-        }
-        if (++index == size) {
-          writeCommentAfterValueOnSameLine(childValue);
-          break;
-        }
-        document_ += ',';
-        writeCommentAfterValueOnSameLine(childValue);
-      }
-      unindent();
-      writeWithIndent("]");
-    } else // output on a single line
-    {
-      assert(childValues_.size() == size);
-      document_ += "[ ";
-      for (unsigned index = 0; index < size; ++index) {
-        if (index > 0)
-          document_ += ", ";
-        document_ += childValues_[index];
-      }
-      document_ += " ]";
-    }
-  }
-}
-
-bool StyledWriter::isMultineArray(const Value& value) {
-  ArrayIndex const size = value.size();
-  bool isMultiLine = size * 3 >= rightMargin_;
-  childValues_.clear();
-  for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
-    const Value& childValue = value[index];
-    isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
-                        childValue.size() > 0);
-  }
-  if (!isMultiLine) // check if line length > max line length
-  {
-    childValues_.reserve(size);
-    addChildValues_ = true;
-    ArrayIndex lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
-    for (ArrayIndex index = 0; index < size; ++index) {
-      if (hasCommentForValue(value[index])) {
-        isMultiLine = true;
-      }
-      writeValue(value[index]);
-      lineLength += static_cast<ArrayIndex>(childValues_[index].length());
-    }
-    addChildValues_ = false;
-    isMultiLine = isMultiLine || lineLength >= rightMargin_;
-  }
-  return isMultiLine;
-}
-
-void StyledWriter::pushValue(const JSONCPP_STRING& value) {
-  if (addChildValues_)
-    childValues_.push_back(value);
-  else
-    document_ += value;
-}
-
-void StyledWriter::writeIndent() {
-  if (!document_.empty()) {
-    char last = document_[document_.length() - 1];
-    if (last == ' ') // already indented
-      return;
-    if (last != '\n') // Comments may add new-line
-      document_ += '\n';
-  }
-  document_ += indentString_;
-}
-
-void StyledWriter::writeWithIndent(const JSONCPP_STRING& value) {
-  writeIndent();
-  document_ += value;
-}
-
-void StyledWriter::indent() { indentString_ += JSONCPP_STRING(indentSize_, ' '); }
-
-void StyledWriter::unindent() {
-  assert(indentString_.size() >= indentSize_);
-  indentString_.resize(indentString_.size() - indentSize_);
-}
-
-void StyledWriter::writeCommentBeforeValue(const Value& root) {
-  if (!root.hasComment(commentBefore))
-    return;
-
-  document_ += "\n";
-  writeIndent();
-  const JSONCPP_STRING& comment = root.getComment(commentBefore);
-  JSONCPP_STRING::const_iterator iter = comment.begin();
-  while (iter != comment.end()) {
-    document_ += *iter;
-    if (*iter == '\n' &&
-       (iter != comment.end() && *(iter + 1) == '/'))
-      writeIndent();
-    ++iter;
-  }
-
-  // Comments are stripped of trailing newlines, so add one here
-  document_ += "\n";
-}
-
-void StyledWriter::writeCommentAfterValueOnSameLine(const Value& root) {
-  if (root.hasComment(commentAfterOnSameLine))
-    document_ += " " + root.getComment(commentAfterOnSameLine);
-
-  if (root.hasComment(commentAfter)) {
-    document_ += "\n";
-    document_ += root.getComment(commentAfter);
-    document_ += "\n";
-  }
-}
-
-bool StyledWriter::hasCommentForValue(const Value& value) {
-  return value.hasComment(commentBefore) ||
-         value.hasComment(commentAfterOnSameLine) ||
-         value.hasComment(commentAfter);
-}
-
-// Class StyledStreamWriter
-// //////////////////////////////////////////////////////////////////
-
-StyledStreamWriter::StyledStreamWriter(JSONCPP_STRING indentation)
-    : document_(NULL), rightMargin_(74), indentation_(indentation),
-      addChildValues_() {}
-
-void StyledStreamWriter::write(JSONCPP_OSTREAM& out, const Value& root) {
-  document_ = &out;
-  addChildValues_ = false;
-  indentString_.clear();
-  indented_ = true;
-  writeCommentBeforeValue(root);
-  if (!indented_) writeIndent();
-  indented_ = true;
-  writeValue(root);
-  writeCommentAfterValueOnSameLine(root);
-  *document_ << "\n";
-  document_ = NULL; // Forget the stream, for safety.
-}
-
-void StyledStreamWriter::writeValue(const Value& value) {
-  switch (value.type()) {
-  case nullValue:
-    pushValue("null");
-    break;
-  case intValue:
-    pushValue(valueToString(value.asLargestInt()));
-    break;
-  case uintValue:
-    pushValue(valueToString(value.asLargestUInt()));
-    break;
-  case realValue:
-    pushValue(valueToString(value.asDouble()));
-    break;
-  case stringValue:
-  {
-    // Is NULL possible for value.string_? No.
-    char const* str;
-    char const* end;
-    bool ok = value.getString(&str, &end);
-    if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str)));
-    else pushValue("");
-    break;
-  }
-  case booleanValue:
-    pushValue(valueToString(value.asBool()));
-    break;
-  case arrayValue:
-    writeArrayValue(value);
-    break;
-  case objectValue: {
-    Value::Members members(value.getMemberNames());
-    if (members.empty())
-      pushValue("{}");
-    else {
-      writeWithIndent("{");
-      indent();
-      Value::Members::iterator it = members.begin();
-      for (;;) {
-        const JSONCPP_STRING& name = *it;
-        const Value& childValue = value[name];
-        writeCommentBeforeValue(childValue);
-        writeWithIndent(valueToQuotedString(name.c_str()));
-        *document_ << " : ";
-        writeValue(childValue);
-        if (++it == members.end()) {
-          writeCommentAfterValueOnSameLine(childValue);
-          break;
-        }
-        *document_ << ",";
-        writeCommentAfterValueOnSameLine(childValue);
-      }
-      unindent();
-      writeWithIndent("}");
-    }
-  } break;
-  }
-}
-
-void StyledStreamWriter::writeArrayValue(const Value& value) {
-  unsigned size = value.size();
-  if (size == 0)
-    pushValue("[]");
-  else {
-    bool isArrayMultiLine = isMultineArray(value);
-    if (isArrayMultiLine) {
-      writeWithIndent("[");
-      indent();
-      bool hasChildValue = !childValues_.empty();
-      unsigned index = 0;
-      for (;;) {
-        const Value& childValue = value[index];
-        writeCommentBeforeValue(childValue);
-        if (hasChildValue)
-          writeWithIndent(childValues_[index]);
-        else {
-          if (!indented_) writeIndent();
-          indented_ = true;
-          writeValue(childValue);
-          indented_ = false;
-        }
-        if (++index == size) {
-          writeCommentAfterValueOnSameLine(childValue);
-          break;
-        }
-        *document_ << ",";
-        writeCommentAfterValueOnSameLine(childValue);
-      }
-      unindent();
-      writeWithIndent("]");
-    } else // output on a single line
-    {
-      assert(childValues_.size() == size);
-      *document_ << "[ ";
-      for (unsigned index = 0; index < size; ++index) {
-        if (index > 0)
-          *document_ << ", ";
-        *document_ << childValues_[index];
-      }
-      *document_ << " ]";
-    }
-  }
-}
-
-bool StyledStreamWriter::isMultineArray(const Value& value) {
-  ArrayIndex const size = value.size();
-  bool isMultiLine = size * 3 >= rightMargin_;
-  childValues_.clear();
-  for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
-    const Value& childValue = value[index];
-    isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
-                        childValue.size() > 0);
-  }
-  if (!isMultiLine) // check if line length > max line length
-  {
-    childValues_.reserve(size);
-    addChildValues_ = true;
-    ArrayIndex lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
-    for (ArrayIndex index = 0; index < size; ++index) {
-      if (hasCommentForValue(value[index])) {
-        isMultiLine = true;
-      }
-      writeValue(value[index]);
-      lineLength += static_cast<ArrayIndex>(childValues_[index].length());
-    }
-    addChildValues_ = false;
-    isMultiLine = isMultiLine || lineLength >= rightMargin_;
-  }
-  return isMultiLine;
-}
-
-void StyledStreamWriter::pushValue(const JSONCPP_STRING& value) {
-  if (addChildValues_)
-    childValues_.push_back(value);
-  else
-    *document_ << value;
-}
-
-void StyledStreamWriter::writeIndent() {
-  // blep intended this to look at the so-far-written string
-  // to determine whether we are already indented, but
-  // with a stream we cannot do that. So we rely on some saved state.
-  // The caller checks indented_.
-  *document_ << '\n' << indentString_;
-}
-
-void StyledStreamWriter::writeWithIndent(const JSONCPP_STRING& value) {
-  if (!indented_) writeIndent();
-  *document_ << value;
-  indented_ = false;
-}
-
-void StyledStreamWriter::indent() { indentString_ += indentation_; }
-
-void StyledStreamWriter::unindent() {
-  assert(indentString_.size() >= indentation_.size());
-  indentString_.resize(indentString_.size() - indentation_.size());
-}
-
-void StyledStreamWriter::writeCommentBeforeValue(const Value& root) {
-  if (!root.hasComment(commentBefore))
-    return;
-
-  if (!indented_) writeIndent();
-  const JSONCPP_STRING& comment = root.getComment(commentBefore);
-  JSONCPP_STRING::const_iterator iter = comment.begin();
-  while (iter != comment.end()) {
-    *document_ << *iter;
-    if (*iter == '\n' &&
-       (iter != comment.end() && *(iter + 1) == '/'))
-      // writeIndent();  // would include newline
-      *document_ << indentString_;
-    ++iter;
-  }
-  indented_ = false;
-}
-
-void StyledStreamWriter::writeCommentAfterValueOnSameLine(const Value& root) {
-  if (root.hasComment(commentAfterOnSameLine))
-    *document_ << ' ' << root.getComment(commentAfterOnSameLine);
-
-  if (root.hasComment(commentAfter)) {
-    writeIndent();
-    *document_ << root.getComment(commentAfter);
-  }
-  indented_ = false;
-}
-
-bool StyledStreamWriter::hasCommentForValue(const Value& value) {
-  return value.hasComment(commentBefore) ||
-         value.hasComment(commentAfterOnSameLine) ||
-         value.hasComment(commentAfter);
-}
-
-//////////////////////////
-// BuiltStyledStreamWriter
-
-/// Scoped enums are not available until C++11.
-struct CommentStyle {
-  /// Decide whether to write comments.
-  enum Enum {
-    None,  ///< Drop all comments.
-    Most,  ///< Recover odd behavior of previous versions (not implemented yet).
-    All  ///< Keep all comments.
-  };
-};
-
-struct BuiltStyledStreamWriter : public StreamWriter
-{
-  BuiltStyledStreamWriter(
-      JSONCPP_STRING const& indentation,
-      CommentStyle::Enum cs,
-      JSONCPP_STRING const& colonSymbol,
-      JSONCPP_STRING const& nullSymbol,
-      JSONCPP_STRING const& endingLineFeedSymbol,
-      bool useSpecialFloats,
-      unsigned int precision);
-  int write(Value const& root, JSONCPP_OSTREAM* sout) JSONCPP_OVERRIDE;
-private:
-  void writeValue(Value const& value);
-  void writeArrayValue(Value const& value);
-  bool isMultineArray(Value const& value);
-  void pushValue(JSONCPP_STRING const& value);
-  void writeIndent();
-  void writeWithIndent(JSONCPP_STRING const& value);
-  void indent();
-  void unindent();
-  void writeCommentBeforeValue(Value const& root);
-  void writeCommentAfterValueOnSameLine(Value const& root);
-  static bool hasCommentForValue(const Value& value);
-
-  typedef std::vector<JSONCPP_STRING> ChildValues;
-
-  ChildValues childValues_;
-  JSONCPP_STRING indentString_;
-  unsigned int rightMargin_;
-  JSONCPP_STRING indentation_;
-  CommentStyle::Enum cs_;
-  JSONCPP_STRING colonSymbol_;
-  JSONCPP_STRING nullSymbol_;
-  JSONCPP_STRING endingLineFeedSymbol_;
-  bool addChildValues_ : 1;
-  bool indented_ : 1;
-  bool useSpecialFloats_ : 1;
-  unsigned int precision_;
-};
-BuiltStyledStreamWriter::BuiltStyledStreamWriter(
-      JSONCPP_STRING const& indentation,
-      CommentStyle::Enum cs,
-      JSONCPP_STRING const& colonSymbol,
-      JSONCPP_STRING const& nullSymbol,
-      JSONCPP_STRING const& endingLineFeedSymbol,
-      bool useSpecialFloats,
-      unsigned int precision)
-  : rightMargin_(74)
-  , indentation_(indentation)
-  , cs_(cs)
-  , colonSymbol_(colonSymbol)
-  , nullSymbol_(nullSymbol)
-  , endingLineFeedSymbol_(endingLineFeedSymbol)
-  , addChildValues_(false)
-  , indented_(false)
-  , useSpecialFloats_(useSpecialFloats)
-  , precision_(precision)
-{
-}
-int BuiltStyledStreamWriter::write(Value const& root, JSONCPP_OSTREAM* sout)
-{
-  sout_ = sout;
-  addChildValues_ = false;
-  indented_ = true;
-  indentString_.clear();
-  writeCommentBeforeValue(root);
-  if (!indented_) writeIndent();
-  indented_ = true;
-  writeValue(root);
-  writeCommentAfterValueOnSameLine(root);
-  *sout_ << endingLineFeedSymbol_;
-  sout_ = NULL;
-  return 0;
-}
-void BuiltStyledStreamWriter::writeValue(Value const& value) {
-  switch (value.type()) {
-  case nullValue:
-    pushValue(nullSymbol_);
-    break;
-  case intValue:
-    pushValue(valueToString(value.asLargestInt()));
-    break;
-  case uintValue:
-    pushValue(valueToString(value.asLargestUInt()));
-    break;
-  case realValue:
-    pushValue(valueToString(value.asDouble(), useSpecialFloats_, precision_));
-    break;
-  case stringValue:
-  {
-    // Is NULL is possible for value.string_? No.
-    char const* str;
-    char const* end;
-    bool ok = value.getString(&str, &end);
-    if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str)));
-    else pushValue("");
-    break;
-  }
-  case booleanValue:
-    pushValue(valueToString(value.asBool()));
-    break;
-  case arrayValue:
-    writeArrayValue(value);
-    break;
-  case objectValue: {
-    Value::Members members(value.getMemberNames());
-    if (members.empty())
-      pushValue("{}");
-    else {
-      writeWithIndent("{");
-      indent();
-      Value::Members::iterator it = members.begin();
-      for (;;) {
-        JSONCPP_STRING const& name = *it;
-        Value const& childValue = value[name];
-        writeCommentBeforeValue(childValue);
-        writeWithIndent(valueToQuotedStringN(name.data(), static_cast<unsigned>(name.length())));
-        *sout_ << colonSymbol_;
-        writeValue(childValue);
-        if (++it == members.end()) {
-          writeCommentAfterValueOnSameLine(childValue);
-          break;
-        }
-        *sout_ << ",";
-        writeCommentAfterValueOnSameLine(childValue);
-      }
-      unindent();
-      writeWithIndent("}");
-    }
-  } break;
-  }
-}
-
-void BuiltStyledStreamWriter::writeArrayValue(Value const& value) {
-  unsigned size = value.size();
-  if (size == 0)
-    pushValue("[]");
-  else {
-    bool isMultiLine = (cs_ == CommentStyle::All) || isMultineArray(value);
-    if (isMultiLine) {
-      writeWithIndent("[");
-      indent();
-      bool hasChildValue = !childValues_.empty();
-      unsigned index = 0;
-      for (;;) {
-        Value const& childValue = value[index];
-        writeCommentBeforeValue(childValue);
-        if (hasChildValue)
-          writeWithIndent(childValues_[index]);
-        else {
-          if (!indented_) writeIndent();
-          indented_ = true;
-          writeValue(childValue);
-          indented_ = false;
-        }
-        if (++index == size) {
-          writeCommentAfterValueOnSameLine(childValue);
-          break;
-        }
-        *sout_ << ",";
-        writeCommentAfterValueOnSameLine(childValue);
-      }
-      unindent();
-      writeWithIndent("]");
-    } else // output on a single line
-    {
-      assert(childValues_.size() == size);
-      *sout_ << "[";
-      if (!indentation_.empty()) *sout_ << " ";
-      for (unsigned index = 0; index < size; ++index) {
-        if (index > 0)
-          *sout_ << ((!indentation_.empty()) ? ", " : ",");
-        *sout_ << childValues_[index];
-      }
-      if (!indentation_.empty()) *sout_ << " ";
-      *sout_ << "]";
-    }
-  }
-}
-
-bool BuiltStyledStreamWriter::isMultineArray(Value const& value) {
-  ArrayIndex const size = value.size();
-  bool isMultiLine = size * 3 >= rightMargin_;
-  childValues_.clear();
-  for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
-    Value const& childValue = value[index];
-    isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
-                        childValue.size() > 0);
-  }
-  if (!isMultiLine) // check if line length > max line length
-  {
-    childValues_.reserve(size);
-    addChildValues_ = true;
-    ArrayIndex lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
-    for (ArrayIndex index = 0; index < size; ++index) {
-      if (hasCommentForValue(value[index])) {
-        isMultiLine = true;
-      }
-      writeValue(value[index]);
-      lineLength += static_cast<ArrayIndex>(childValues_[index].length());
-    }
-    addChildValues_ = false;
-    isMultiLine = isMultiLine || lineLength >= rightMargin_;
-  }
-  return isMultiLine;
-}
-
-void BuiltStyledStreamWriter::pushValue(JSONCPP_STRING const& value) {
-  if (addChildValues_)
-    childValues_.push_back(value);
-  else
-    *sout_ << value;
-}
-
-void BuiltStyledStreamWriter::writeIndent() {
-  // blep intended this to look at the so-far-written string
-  // to determine whether we are already indented, but
-  // with a stream we cannot do that. So we rely on some saved state.
-  // The caller checks indented_.
-
-  if (!indentation_.empty()) {
-    // In this case, drop newlines too.
-    *sout_ << '\n' << indentString_;
-  }
-}
-
-void BuiltStyledStreamWriter::writeWithIndent(JSONCPP_STRING const& value) {
-  if (!indented_) writeIndent();
-  *sout_ << value;
-  indented_ = false;
-}
-
-void BuiltStyledStreamWriter::indent() { indentString_ += indentation_; }
-
-void BuiltStyledStreamWriter::unindent() {
-  assert(indentString_.size() >= indentation_.size());
-  indentString_.resize(indentString_.size() - indentation_.size());
-}
-
-void BuiltStyledStreamWriter::writeCommentBeforeValue(Value const& root) {
-  if (cs_ == CommentStyle::None) return;
-  if (!root.hasComment(commentBefore))
-    return;
-
-  if (!indented_) writeIndent();
-  const JSONCPP_STRING& comment = root.getComment(commentBefore);
-  JSONCPP_STRING::const_iterator iter = comment.begin();
-  while (iter != comment.end()) {
-    *sout_ << *iter;
-    if (*iter == '\n' &&
-       (iter != comment.end() && *(iter + 1) == '/'))
-      // writeIndent();  // would write extra newline
-      *sout_ << indentString_;
-    ++iter;
-  }
-  indented_ = false;
-}
-
-void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(Value const& root) {
-  if (cs_ == CommentStyle::None) return;
-  if (root.hasComment(commentAfterOnSameLine))
-    *sout_ << " " + root.getComment(commentAfterOnSameLine);
-
-  if (root.hasComment(commentAfter)) {
-    writeIndent();
-    *sout_ << root.getComment(commentAfter);
-  }
-}
-
-// static
-bool BuiltStyledStreamWriter::hasCommentForValue(const Value& value) {
-  return value.hasComment(commentBefore) ||
-         value.hasComment(commentAfterOnSameLine) ||
-         value.hasComment(commentAfter);
-}
-
-///////////////
-// StreamWriter
-
-StreamWriter::StreamWriter()
-    : sout_(NULL)
-{
-}
-StreamWriter::~StreamWriter()
-{
-}
-StreamWriter::Factory::~Factory()
-{}
-StreamWriterBuilder::StreamWriterBuilder()
-{
-  setDefaults(&settings_);
-}
-StreamWriterBuilder::~StreamWriterBuilder()
-{}
-StreamWriter* StreamWriterBuilder::newStreamWriter() const
-{
-  JSONCPP_STRING indentation = settings_["indentation"].asString();
-  JSONCPP_STRING cs_str = settings_["commentStyle"].asString();
-  bool eyc = settings_["enableYAMLCompatibility"].asBool();
-  bool dnp = settings_["dropNullPlaceholders"].asBool();
-  bool usf = settings_["useSpecialFloats"].asBool(); 
-  unsigned int pre = settings_["precision"].asUInt();
-  CommentStyle::Enum cs = CommentStyle::All;
-  if (cs_str == "All") {
-    cs = CommentStyle::All;
-  } else if (cs_str == "None") {
-    cs = CommentStyle::None;
-  } else {
-    throwRuntimeError("commentStyle must be 'All' or 'None'");
-  }
-  JSONCPP_STRING colonSymbol = " : ";
-  if (eyc) {
-    colonSymbol = ": ";
-  } else if (indentation.empty()) {
-    colonSymbol = ":";
-  }
-  JSONCPP_STRING nullSymbol = "null";
-  if (dnp) {
-    nullSymbol.clear();
-  }
-  if (pre > 17) pre = 17;
-  JSONCPP_STRING endingLineFeedSymbol;
-  return new BuiltStyledStreamWriter(
-      indentation, cs,
-      colonSymbol, nullSymbol, endingLineFeedSymbol, usf, pre);
-}
-static void getValidWriterKeys(std::set<JSONCPP_STRING>* valid_keys)
-{
-  valid_keys->clear();
-  valid_keys->insert("indentation");
-  valid_keys->insert("commentStyle");
-  valid_keys->insert("enableYAMLCompatibility");
-  valid_keys->insert("dropNullPlaceholders");
-  valid_keys->insert("useSpecialFloats");
-  valid_keys->insert("precision");
-}
-bool StreamWriterBuilder::validate(Json::Value* invalid) const
-{
-  Json::Value my_invalid;
-  if (!invalid) invalid = &my_invalid;  // so we do not need to test for NULL
-  Json::Value& inv = *invalid;
-  std::set<JSONCPP_STRING> valid_keys;
-  getValidWriterKeys(&valid_keys);
-  Value::Members keys = settings_.getMemberNames();
-  size_t n = keys.size();
-  for (size_t i = 0; i < n; ++i) {
-    JSONCPP_STRING const& key = keys[i];
-    if (valid_keys.find(key) == valid_keys.end()) {
-      inv[key] = settings_[key];
-    }
-  }
-  return 0u == inv.size();
-}
-Value& StreamWriterBuilder::operator[](JSONCPP_STRING key)
-{
-  return settings_[key];
-}
-// static
-void StreamWriterBuilder::setDefaults(Json::Value* settings)
-{
-  //! [StreamWriterBuilderDefaults]
-  (*settings)["commentStyle"] = "All";
-  (*settings)["indentation"] = "\t";
-  (*settings)["enableYAMLCompatibility"] = false;
-  (*settings)["dropNullPlaceholders"] = false;
-  (*settings)["useSpecialFloats"] = false;
-  (*settings)["precision"] = 17;
-  //! [StreamWriterBuilderDefaults]
-}
-
-JSONCPP_STRING writeString(StreamWriter::Factory const& builder, Value const& root) {
-  JSONCPP_OSTRINGSTREAM sout;
-  StreamWriterPtr const writer(builder.newStreamWriter());
-  writer->write(root, &sout);
-  return sout.str();
-}
-
-JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM& sout, Value const& root) {
-  StreamWriterBuilder builder;
-  StreamWriterPtr const writer(builder.newStreamWriter());
-  writer->write(root, &sout);
-  return sout;
-}
-
-} // namespace Json
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: src/lib_json/json_writer.cpp
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-