From 682f2e775effd7f5b294b9897ca4628fa28aa1dd Mon Sep 17 00:00:00 2001
From: Utz-Uwe Haus <uhaus@cray.com>
Date: Fri, 24 Apr 2020 17:38:00 +0200
Subject: [PATCH] Implement attribute default value handling

not fully working
---
 attributes/ecmwf-yaml.h        |  61 ++-
 attributes/ecmwf.yaml          |   4 +-
 attributes/maestro-core-yaml.h | 550 +++++++++++++-------------
 attributes/maestro-core.yaml   |  57 +--
 attributes/maestro-schema.c    | 703 ++++++++++++++++++++-------------
 attributes/symtab.c            |   2 +-
 6 files changed, 770 insertions(+), 607 deletions(-)

diff --git a/attributes/ecmwf-yaml.h b/attributes/ecmwf-yaml.h
index f8198d00..08c42fe0 100644
--- a/attributes/ecmwf-yaml.h
+++ b/attributes/ecmwf-yaml.h
@@ -124,36 +124,35 @@ unsigned char ecmwf_yaml[] = {
   0x3d, 0x31, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x3d, 0x35, 0x30, 0x29, 0x0a,
   0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64,
   0x3a, 0x20, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20,
-  0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x20, 0x46, 0x61, 0x6c,
-  0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d,
-  0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4e, 0x75,
-  0x6d, 0x62, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20,
-  0x65, 0x6e, 0x73, 0x65, 0x6d, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x74,
-  0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x6b, 0x65, 0x79, 0x3a, 0x20,
-  0x22, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x22, 0x0a, 0x20,
-  0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6e, 0x74,
-  0x28, 0x6d, 0x69, 0x6e, 0x3d, 0x31, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x3d,
-  0x31, 0x33, 0x37, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x71,
-  0x75, 0x69, 0x72, 0x65, 0x64, 0x3a, 0x20, 0x46, 0x61, 0x6c, 0x73, 0x65,
-  0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74,
-  0x3a, 0x20, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20,
-  0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f,
-  0x6e, 0x3a, 0x20, 0x56, 0x65, 0x72, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x20,
-  0x6c, 0x65, 0x76, 0x65, 0x6c, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65,
-  0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x61, 0x73,
-  0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74,
-  0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x20,
-  0x74, 0x79, 0x70, 0x65, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x6b,
-  0x65, 0x79, 0x3a, 0x20, 0x22, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x22, 0x0a,
-  0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6e,
-  0x74, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x71, 0x75,
-  0x69, 0x72, 0x65, 0x64, 0x3a, 0x20, 0x54, 0x72, 0x75, 0x65, 0x0a, 0x20,
+  0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x20, 0x30, 0x0a, 0x20,
   0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61,
-  0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x55, 0x6e, 0x69, 0x71, 0x65, 0x20,
-  0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x66,
-  0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64,
-  0x20, 0x61, 0x73, 0x20, 0x61, 0x20, 0x6d, 0x65, 0x74, 0x65, 0x6f, 0x72,
-  0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x71, 0x75, 0x61,
-  0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x0a
+  0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72,
+  0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x73, 0x65,
+  0x6d, 0x62, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x74, 0x2e, 0x0a, 0x0a, 0x20,
+  0x20, 0x2d, 0x20, 0x6b, 0x65, 0x79, 0x3a, 0x20, 0x22, 0x6c, 0x65, 0x76,
+  0x65, 0x6c, 0x69, 0x73, 0x74, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74,
+  0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x28, 0x6d, 0x69, 0x6e,
+  0x3d, 0x31, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x3d, 0x31, 0x33, 0x37, 0x29,
+  0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65,
+  0x64, 0x3a, 0x20, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20,
+  0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x20, 0x30, 0x0a,
+  0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74,
+  0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x56, 0x65, 0x72, 0x74, 0x69,
+  0x63, 0x61, 0x6c, 0x20, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x20, 0x69, 0x66,
+  0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x6f, 0x6e,
+  0x65, 0x20, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x65, 0x64,
+  0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x65,
+  0x76, 0x65, 0x6c, 0x20, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x0a, 0x0a, 0x20,
+  0x20, 0x2d, 0x20, 0x6b, 0x65, 0x79, 0x3a, 0x20, 0x22, 0x70, 0x61, 0x72,
+  0x61, 0x6d, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65,
+  0x3a, 0x20, 0x69, 0x6e, 0x74, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3a, 0x20, 0x54, 0x72,
+  0x75, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d,
+  0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x55, 0x6e,
+  0x69, 0x71, 0x65, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69,
+  0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66,
+  0x69, 0x65, 0x6c, 0x64, 0x20, 0x61, 0x73, 0x20, 0x61, 0x20, 0x6d, 0x65,
+  0x74, 0x65, 0x6f, 0x72, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c,
+  0x20, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x0a
 };
-const unsigned int ecmwf_yaml_len = 1867;
+const unsigned int ecmwf_yaml_len = 1859;
diff --git a/attributes/ecmwf.yaml b/attributes/ecmwf.yaml
index a3163b1a..36105026 100644
--- a/attributes/ecmwf.yaml
+++ b/attributes/ecmwf.yaml
@@ -62,13 +62,13 @@ maestro-attributes:
   - key: "number"
     type: int(min=1, max=50)
     required: False
-    default: False
+    default: 0
     documentation: Number in the ensemble set.
 
   - key: "levelist"
     type: int(min=1, max=137)
     required: False
-    default: False
+    default: 0
     documentation: Vertical level if there is one associated with the level type.
 
   - key: "param"
diff --git a/attributes/maestro-core-yaml.h b/attributes/maestro-core-yaml.h
index ad8278f6..487865da 100644
--- a/attributes/maestro-core-yaml.h
+++ b/attributes/maestro-core-yaml.h
@@ -23,297 +23,305 @@ unsigned char maestro_core_yaml[] = {
   0x0a, 0x23, 0x20, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x70, 0x65,
   0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x75,
   0x73, 0x65, 0x72, 0x2d, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20,
-  0x74, 0x79, 0x70, 0x65, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x0a, 0x73,
-  0x63, 0x68, 0x65, 0x6d, 0x61, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x2d, 0x76,
-  0x61, 0x6c, 0x75, 0x65, 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x23, 0x20, 0x76,
+  0x74, 0x79, 0x70, 0x65, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x0a, 0x23,
+  0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x2d,
+  0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x23, 0x20,
+  0x46, 0x49, 0x58, 0x4d, 0x45, 0x3a, 0x20, 0x75, 0x73, 0x65, 0x72, 0x2d,
+  0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65,
+  0x73, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x20,
+  0x62, 0x72, 0x6f, 0x6b, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x23, 0x20, 0x76,
   0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x69,
   0x6e, 0x67, 0x20, 0x69, 0x6e, 0x20, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69,
   0x6d, 0x65, 0x2d, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x6e, 0x65, 0x73,
-  0x73, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x26,
-  0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x2d, 0x73, 0x74, 0x72,
-  0x69, 0x63, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x2d, 0x76, 0x61, 0x6c, 0x75,
-  0x65, 0x73, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x28, 0x27, 0x6f, 0x70, 0x74,
-  0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x27, 0x2c, 0x20, 0x27, 0x72, 0x65, 0x71,
-  0x75, 0x69, 0x72, 0x65, 0x64, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x23, 0x20,
-  0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x6f, 0x63, 0x63, 0x75, 0x72,
-  0x69, 0x6e, 0x67, 0x20, 0x69, 0x6e, 0x20, 0x6c, 0x69, 0x66, 0x65, 0x74,
-  0x69, 0x6d, 0x65, 0x2d, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x6e, 0x65,
-  0x73, 0x73, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x0a, 0x20, 0x20, 0x2d, 0x20,
-  0x26, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x6d, 0x6f, 0x64, 0x65,
-  0x2d, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x65, 0x6e, 0x75, 0x6d,
-  0x28, 0x27, 0x72, 0x77, 0x27, 0x2c, 0x20, 0x27, 0x72, 0x27, 0x29, 0x0a,
-  0x0a, 0x23, 0x20, 0x75, 0x73, 0x65, 0x72, 0x2d, 0x64, 0x65, 0x66, 0x69,
-  0x6e, 0x65, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, 0x75, 0x73,
-  0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x73,
-  0x63, 0x68, 0x65, 0x6d, 0x61, 0x0a, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61,
-  0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x3a, 0x0a, 0x20, 0x20, 0x0a, 0x20,
-  0x20, 0x2d, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x6e, 0x61, 0x6d, 0x65,
-  0x3a, 0x20, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x2d, 0x69,
-  0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x70, 0x65, 0x63, 0x3a, 0x20, 0x6d,
-  0x61, 0x70, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f,
-  0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a,
-  0x20, 0x43, 0x44, 0x4f, 0x20, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d,
-  0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x20,
+  0x73, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x0a, 0x20, 0x20, 0x23, 0x20, 0x2d,
+  0x20, 0x26, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x2d, 0x73,
+  0x74, 0x72, 0x69, 0x63, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x2d, 0x76, 0x61,
+  0x6c, 0x75, 0x65, 0x73, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x28, 0x27, 0x6f,
+  0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x27, 0x2c, 0x20, 0x27, 0x72,
+  0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x27, 0x29, 0x0a, 0x20, 0x20,
+  0x23, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x6f, 0x63, 0x63,
+  0x75, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x6e, 0x20, 0x6c, 0x69, 0x66,
+  0x65, 0x74, 0x69, 0x6d, 0x65, 0x2d, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74,
+  0x6e, 0x65, 0x73, 0x73, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x0a, 0x20, 0x20,
+  0x23, 0x2d, 0x20, 0x26, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x6d,
+  0x6f, 0x64, 0x65, 0x2d, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x65,
+  0x6e, 0x75, 0x6d, 0x28, 0x27, 0x72, 0x77, 0x27, 0x2c, 0x20, 0x27, 0x72,
+  0x27, 0x29, 0x0a, 0x0a, 0x23, 0x20, 0x75, 0x73, 0x65, 0x72, 0x2d, 0x64,
+  0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73,
+  0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x69,
+  0x73, 0x20, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x0a, 0x23, 0x73, 0x63,
+  0x68, 0x65, 0x6d, 0x61, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x3a, 0x0a,
+  0x20, 0x20, 0x0a, 0x20, 0x20, 0x23, 0x20, 0x2d, 0x20, 0x20, 0x74, 0x79,
+  0x70, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x6c, 0x69, 0x66, 0x65,
+  0x74, 0x69, 0x6d, 0x65, 0x2d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61,
+  0x6c, 0x0a, 0x20, 0x20, 0x23, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70,
+  0x65, 0x73, 0x70, 0x65, 0x63, 0x3a, 0x20, 0x6d, 0x61, 0x70, 0x28, 0x29,
+  0x0a, 0x20, 0x20, 0x23, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75,
+  0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x43,
+  0x44, 0x4f, 0x20, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x20,
+  0x74, 0x79, 0x70, 0x65, 0x0a, 0x0a, 0x20, 0x20, 0x23, 0x20, 0x2d, 0x20,
   0x20, 0x74, 0x79, 0x70, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x6c,
   0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x2d, 0x73, 0x74, 0x72, 0x69,
-  0x63, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x74, 0x79, 0x70, 0x65, 0x73, 0x70, 0x65, 0x63, 0x3a, 0x20, 0x2a, 0x6c,
-  0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x2d, 0x73, 0x74, 0x72, 0x69,
-  0x63, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x2d, 0x76, 0x61, 0x6c, 0x75, 0x65,
-  0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d,
-  0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x43, 0x44,
-  0x4f, 0x20, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x73,
-  0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x74,
-  0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a,
-  0x0a, 0x20, 0x20, 0x2d, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x6e, 0x61,
-  0x6d, 0x65, 0x3a, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x6d,
-  0x6f, 0x64, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70,
-  0x65, 0x73, 0x70, 0x65, 0x63, 0x3a, 0x20, 0x2a, 0x61, 0x63, 0x63, 0x65,
-  0x73, 0x73, 0x2d, 0x6d, 0x6f, 0x64, 0x65, 0x2d, 0x76, 0x61, 0x6c, 0x75,
-  0x65, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75,
-  0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x43,
-  0x44, 0x4f, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x6d, 0x6f,
-  0x64, 0x65, 0x0a, 0x0a, 0x23, 0x20, 0x49, 0x6e, 0x64, 0x69, 0x76, 0x69,
-  0x64, 0x75, 0x61, 0x6c, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75,
-  0x74, 0x65, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
-  0x6f, 0x6e, 0x73, 0x0a, 0x6d, 0x61, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x2d,
-  0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x3a, 0x0a,
-  0x20, 0x20, 0x23, 0x23, 0x20, 0x54, 0x4f, 0x50, 0x4c, 0x45, 0x56, 0x45,
-  0x4c, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73,
-  0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x6b, 0x65, 0x79, 0x3a, 0x20, 0x22,
-  0x2e, 0x6d, 0x61, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x2e, 0x63, 0x6f, 0x72,
-  0x65, 0x2e, 0x63, 0x64, 0x6f, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x20,
-  0x23, 0x20, 0x6e, 0x6f, 0x74, 0x65, 0x3a, 0x20, 0x74, 0x68, 0x69, 0x73,
-  0x20, 0x69, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x62, 0x73, 0x6f, 0x6c,
-  0x75, 0x74, 0x65, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
-  0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74,
-  0x79, 0x70, 0x65, 0x3a, 0x20, 0x73, 0x74, 0x72, 0x28, 0x29, 0x0a, 0x20,
-  0x20, 0x20, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3a,
-  0x20, 0x54, 0x72, 0x75, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f,
-  0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a,
-  0x20, 0x54, 0x68, 0x65, 0x20, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x20,
-  0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20,
-  0x43, 0x44, 0x4f, 0x0a, 0x0a, 0x20, 0x20, 0x23, 0x20, 0x6e, 0x6f, 0x74,
-  0x65, 0x3a, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x44, 0x20, 0x69, 0x73,
-  0x20, 0x6e, 0x6f, 0x74, 0x20, 0x75, 0x73, 0x65, 0x72, 0x2d, 0x76, 0x69,
-  0x73, 0x69, 0x62, 0x6c, 0x65, 0x3b, 0x20, 0x69, 0x74, 0x27, 0x73, 0x20,
-  0x73, 0x79, 0x6e, 0x74, 0x68, 0x65, 0x74, 0x69, 0x7a, 0x65, 0x64, 0x20,
-  0x64, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x77, 0x6f, 0x72,
-  0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x6b,
-  0x65, 0x79, 0x3a, 0x20, 0x22, 0x63, 0x64, 0x6f, 0x2e, 0x61, 0x6c, 0x6c,
-  0x6f, 0x63, 0x61, 0x74, 0x65, 0x2d, 0x6e, 0x6f, 0x77, 0x22, 0x20, 0x23,
-  0x20, 0x6e, 0x6f, 0x74, 0x65, 0x3a, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20,
-  0x69, 0x73, 0x20, 0x61, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76,
+  0x63, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x0a, 0x20, 0x20, 0x23, 0x20, 0x20,
+  0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x70, 0x65, 0x63, 0x3a, 0x20,
+  0x2a, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x2d, 0x73, 0x74,
+  0x72, 0x69, 0x63, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x2d, 0x76, 0x61, 0x6c,
+  0x75, 0x65, 0x73, 0x0a, 0x20, 0x20, 0x23, 0x20, 0x20, 0x20, 0x20, 0x64,
+  0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+  0x3a, 0x20, 0x43, 0x44, 0x4f, 0x20, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69,
+  0x6d, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x72,
+  0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x61, 0x74,
+  0x69, 0x6f, 0x6e, 0x0a, 0x0a, 0x20, 0x20, 0x23, 0x20, 0x2d, 0x20, 0x20,
+  0x74, 0x79, 0x70, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x61, 0x63,
+  0x63, 0x65, 0x73, 0x73, 0x2d, 0x6d, 0x6f, 0x64, 0x65, 0x0a, 0x20, 0x20,
+  0x23, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x70, 0x65,
+  0x63, 0x3a, 0x20, 0x2a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x6d,
+  0x6f, 0x64, 0x65, 0x2d, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x0a, 0x20,
+  0x20, 0x23, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65,
+  0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x43, 0x44, 0x4f,
+  0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x6d, 0x6f, 0x64, 0x65,
+  0x0a, 0x0a, 0x23, 0x20, 0x49, 0x6e, 0x64, 0x69, 0x76, 0x69, 0x64, 0x75,
+  0x61, 0x6c, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
+  0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+  0x73, 0x0a, 0x6d, 0x61, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x2d, 0x61, 0x74,
+  0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x3a, 0x0a, 0x20, 0x20,
+  0x23, 0x23, 0x20, 0x54, 0x4f, 0x50, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x20,
+  0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x0a, 0x0a,
+  0x20, 0x20, 0x2d, 0x20, 0x6b, 0x65, 0x79, 0x3a, 0x20, 0x22, 0x2e, 0x6d,
+  0x61, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e,
+  0x63, 0x64, 0x6f, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x20, 0x23, 0x20,
+  0x6e, 0x6f, 0x74, 0x65, 0x3a, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69,
+  0x73, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x62, 0x73, 0x6f, 0x6c, 0x75, 0x74,
   0x65, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20,
   0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70,
-  0x65, 0x3a, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x28, 0x29, 0x0a, 0x20, 0x20,
-  0x20, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3a, 0x20,
-  0x46, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65,
-  0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x20, 0x46, 0x61, 0x6c, 0x73, 0x65,
-  0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e,
-  0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x50, 0x65, 0x72, 0x66,
-  0x6f, 0x72, 0x6d, 0x20, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74,
-  0x65, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-  0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x43, 0x44, 0x4f,
-  0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x6b, 0x65, 0x79, 0x3a, 0x20, 0x22,
-  0x63, 0x64, 0x6f, 0x2e, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x22,
-  0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x62,
-  0x6f, 0x6f, 0x6c, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65,
-  0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3a, 0x20, 0x46, 0x61, 0x6c, 0x73,
-  0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c,
-  0x74, 0x3a, 0x20, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20,
-  0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69,
-  0x6f, 0x6e, 0x3a, 0x20, 0x45, 0x6e, 0x73, 0x75, 0x72, 0x65, 0x20, 0x61,
-  0x20, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x20,
+  0x65, 0x3a, 0x20, 0x73, 0x74, 0x72, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20,
+  0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3a, 0x20, 0x54,
+  0x72, 0x75, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75,
+  0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x54,
+  0x68, 0x65, 0x20, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x20, 0x6e, 0x61,
+  0x6d, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x43, 0x44,
+  0x4f, 0x0a, 0x0a, 0x20, 0x20, 0x23, 0x20, 0x6e, 0x6f, 0x74, 0x65, 0x3a,
+  0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x44, 0x20, 0x69, 0x73, 0x20, 0x6e,
+  0x6f, 0x74, 0x20, 0x75, 0x73, 0x65, 0x72, 0x2d, 0x76, 0x69, 0x73, 0x69,
+  0x62, 0x6c, 0x65, 0x3b, 0x20, 0x69, 0x74, 0x27, 0x73, 0x20, 0x73, 0x79,
+  0x6e, 0x74, 0x68, 0x65, 0x74, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x64, 0x75,
+  0x72, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x77, 0x6f, 0x72, 0x6b, 0x66,
+  0x6c, 0x6f, 0x77, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x6b, 0x65, 0x79,
+  0x3a, 0x20, 0x22, 0x63, 0x64, 0x6f, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63,
+  0x61, 0x74, 0x65, 0x2d, 0x6e, 0x6f, 0x77, 0x22, 0x20, 0x23, 0x20, 0x6e,
+  0x6f, 0x74, 0x65, 0x3a, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73,
+  0x20, 0x61, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x20,
+  0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x6e, 0x61,
+  0x6d, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a,
+  0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3a, 0x20, 0x46, 0x61,
+  0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x66, 0x61,
+  0x75, 0x6c, 0x74, 0x3a, 0x20, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x20,
+  0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61,
+  0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72,
+  0x6d, 0x20, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x20,
+  0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66,
+  0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x43, 0x44, 0x4f, 0x0a, 0x0a,
+  0x20, 0x20, 0x2d, 0x20, 0x6b, 0x65, 0x79, 0x3a, 0x20, 0x22, 0x63, 0x64,
+  0x6f, 0x2e, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x22, 0x0a, 0x20,
+  0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x62, 0x6f, 0x6f,
+  0x6c, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x71, 0x75,
+  0x69, 0x72, 0x65, 0x64, 0x3a, 0x20, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x0a,
+  0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a,
+  0x20, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64,
+  0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+  0x3a, 0x20, 0x45, 0x6e, 0x73, 0x75, 0x72, 0x65, 0x20, 0x61, 0x20, 0x70,
+  0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x63, 0x6f,
+  0x70, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x43, 0x44,
+  0x4f, 0x20, 0x69, 0x73, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76,
+  0x65, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x68,
+  0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20,
   0x63, 0x6f, 0x70, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20,
-  0x43, 0x44, 0x4f, 0x20, 0x69, 0x73, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65,
-  0x72, 0x76, 0x65, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x77, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, 0x73,
-  0x74, 0x20, 0x63, 0x6f, 0x70, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68,
-  0x65, 0x20, 0x43, 0x44, 0x4f, 0x20, 0x69, 0x73, 0x20, 0x57, 0x49, 0x54,
-  0x48, 0x44, 0x52, 0x41, 0x57, 0x4e, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20,
-  0x74, 0x68, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70,
-  0x6f, 0x6f, 0x6c, 0x2e, 0x20, 0x28, 0x4e, 0x6f, 0x74, 0x65, 0x20, 0x74,
-  0x68, 0x65, 0x20, 0x6e, 0x6f, 0x6e, 0x2d, 0x74, 0x72, 0x69, 0x76, 0x69,
-  0x61, 0x6c, 0x20, 0x73, 0x65, 0x6d, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x20,
-  0x69, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20,
-  0x74, 0x68, 0x65, 0x20, 0x63, 0x64, 0x6f, 0x2e, 0x64, 0x65, 0x73, 0x69,
-  0x73, 0x74, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
-  0x2e, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x6b, 0x65, 0x79, 0x3a,
-  0x20, 0x22, 0x63, 0x64, 0x6f, 0x2e, 0x64, 0x65, 0x73, 0x69, 0x73, 0x74,
-  0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20,
-  0x62, 0x6f, 0x6f, 0x6c, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72,
-  0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3a, 0x20, 0x46, 0x61, 0x6c,
-  0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75,
-  0x6c, 0x74, 0x3a, 0x20, 0x54, 0x72, 0x75, 0x65, 0x0a, 0x20, 0x20, 0x20,
-  0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69,
-  0x6f, 0x6e, 0x3a, 0x20, 0x45, 0x6e, 0x73, 0x75, 0x72, 0x65, 0x20, 0x74,
-  0x68, 0x61, 0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x70, 0x65, 0x72, 0x73,
-  0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x63, 0x6f, 0x70, 0x69, 0x65,
-  0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x43, 0x44, 0x4f,
-  0x20, 0x61, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x43, 0x44, 0x4f, 0x20, 0x69, 0x73, 0x20, 0x57, 0x49, 0x54, 0x48, 0x44,
+  0x52, 0x41, 0x57, 0x4e, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68,
+  0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6f, 0x6f,
+  0x6c, 0x2e, 0x20, 0x28, 0x4e, 0x6f, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65,
+  0x20, 0x6e, 0x6f, 0x6e, 0x2d, 0x74, 0x72, 0x69, 0x76, 0x69, 0x61, 0x6c,
+  0x20, 0x73, 0x65, 0x6d, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x20, 0x69, 0x6e,
+  0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d,
-  0x20, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x20,
-  0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x20, 0x77, 0x68, 0x65, 0x6e,
-  0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x0a, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68,
+  0x65, 0x20, 0x63, 0x64, 0x6f, 0x2e, 0x64, 0x65, 0x73, 0x69, 0x73, 0x74,
+  0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x2e, 0x29,
+  0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x6b, 0x65, 0x79, 0x3a, 0x20, 0x22,
+  0x63, 0x64, 0x6f, 0x2e, 0x64, 0x65, 0x73, 0x69, 0x73, 0x74, 0x22, 0x0a,
+  0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x62, 0x6f,
+  0x6f, 0x6c, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x71,
+  0x75, 0x69, 0x72, 0x65, 0x64, 0x3a, 0x20, 0x46, 0x61, 0x6c, 0x73, 0x65,
+  0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74,
+  0x3a, 0x20, 0x54, 0x72, 0x75, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64,
+  0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+  0x3a, 0x20, 0x45, 0x6e, 0x73, 0x75, 0x72, 0x65, 0x20, 0x74, 0x68, 0x61,
+  0x74, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73,
+  0x74, 0x65, 0x6e, 0x74, 0x20, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x73, 0x20,
+  0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x43, 0x44, 0x4f, 0x20, 0x61,
+  0x72, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65,
+  0x6d, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x70,
+  0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x74,
+  0x6f, 0x72, 0x61, 0x67, 0x65, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x74,
+  0x68, 0x65, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e,
-  0x63, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x43, 0x44,
-  0x4f, 0x20, 0x69, 0x73, 0x20, 0x57, 0x49, 0x54, 0x48, 0x44, 0x52, 0x41,
-  0x57, 0x6e, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x0a,
+  0x20, 0x20, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65,
+  0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x43, 0x44, 0x4f, 0x20,
+  0x69, 0x73, 0x20, 0x57, 0x49, 0x54, 0x48, 0x44, 0x52, 0x41, 0x57, 0x6e,
+  0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x20, 0x20,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6f, 0x6f, 0x6c, 0x2e,
-  0x20, 0x28, 0x4e, 0x6f, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e,
-  0x6f, 0x6e, 0x2d, 0x74, 0x72, 0x69, 0x76, 0x69, 0x61, 0x6c, 0x20, 0x73,
-  0x65, 0x6d, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x20, 0x69, 0x6e, 0x74, 0x65,
-  0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6f, 0x6f, 0x6c, 0x2e, 0x20, 0x28,
+  0x4e, 0x6f, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x6f, 0x6e,
+  0x2d, 0x74, 0x72, 0x69, 0x76, 0x69, 0x61, 0x6c, 0x20, 0x73, 0x65, 0x6d,
+  0x61, 0x6e, 0x74, 0x69, 0x63, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x61,
+  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20,
-  0x63, 0x64, 0x6f, 0x2e, 0x64, 0x65, 0x73, 0x69, 0x73, 0x74, 0x20, 0x61,
-  0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x2e, 0x29, 0x0a, 0x0a,
-  0x20, 0x20, 0x2d, 0x20, 0x6b, 0x65, 0x79, 0x3a, 0x20, 0x22, 0x63, 0x64,
-  0x6f, 0x2e, 0x6d, 0x61, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x2d, 0x70, 0x72,
-  0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x2d, 0x73, 0x74, 0x6f, 0x72, 0x61,
-  0x67, 0x65, 0x22, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70,
-  0x65, 0x3a, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x28, 0x29, 0x0a, 0x20, 0x20,
-  0x20, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3a, 0x20,
-  0x46, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65,
-  0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x20, 0x46, 0x61, 0x6c, 0x73, 0x65,
-  0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e,
-  0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x52, 0x65, 0x71, 0x75,
-  0x65, 0x73, 0x74, 0x2f, 0x61, 0x64, 0x76, 0x69, 0x73, 0x65, 0x20, 0x6d,
-  0x61, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x61,
-  0x67, 0x65, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e,
-  0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x20, 0x20,
+  0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x64,
+  0x6f, 0x2e, 0x64, 0x65, 0x73, 0x69, 0x73, 0x74, 0x20, 0x61, 0x74, 0x74,
+  0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x2e, 0x29, 0x0a, 0x0a, 0x20, 0x20,
+  0x2d, 0x20, 0x6b, 0x65, 0x79, 0x3a, 0x20, 0x22, 0x63, 0x64, 0x6f, 0x2e,
+  0x6d, 0x61, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x2d, 0x70, 0x72, 0x6f, 0x76,
+  0x69, 0x64, 0x65, 0x64, 0x2d, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65,
+  0x22, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a,
+  0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3a, 0x20, 0x46, 0x61,
+  0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x66, 0x61,
+  0x75, 0x6c, 0x74, 0x3a, 0x20, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x20,
+  0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61,
+  0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+  0x74, 0x2f, 0x61, 0x64, 0x76, 0x69, 0x73, 0x65, 0x20, 0x6d, 0x61, 0x65,
+  0x73, 0x74, 0x72, 0x6f, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65,
+  0x20, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20,
+  0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x44, 0x4f, 0x20, 0x28, 0x6e, 0x6f,
-  0x20, 0x52, 0x41, 0x57, 0x2d, 0x50, 0x54, 0x52, 0x20, 0x77, 0x69, 0x6c,
-  0x6c, 0x20, 0x62, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65,
-  0x64, 0x20, 0x6f, 0x72, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20,
-  0x6f, 0x62, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x29, 0x0a, 0x0a, 0x20,
+  0x20, 0x20, 0x20, 0x43, 0x44, 0x4f, 0x20, 0x28, 0x6e, 0x6f, 0x20, 0x52,
+  0x41, 0x57, 0x2d, 0x50, 0x54, 0x52, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20,
+  0x62, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20,
+  0x6f, 0x72, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x6f, 0x62,
+  0x74, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x23,
   0x20, 0x2d, 0x20, 0x6b, 0x65, 0x79, 0x3a, 0x20, 0x22, 0x63, 0x64, 0x6f,
   0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x6d, 0x6f, 0x64, 0x65,
-  0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20,
-  0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x6d, 0x6f, 0x64, 0x65, 0x0a,
-  0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64,
-  0x3a, 0x20, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20,
-  0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x20, 0x2a, 0x61, 0x63,
-  0x63, 0x65, 0x73, 0x73, 0x2d, 0x6d, 0x6f, 0x64, 0x65, 0x2d, 0x76, 0x61,
-  0x6c, 0x75, 0x65, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x63,
-  0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20,
-  0x49, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x20, 0x68, 0x6f,
-  0x77, 0x20, 0x74, 0x68, 0x65, 0x20, 0x43, 0x44, 0x4f, 0x20, 0x77, 0x69,
-  0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73,
-  0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73,
-  0x65, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x72,
-  0x65, 0x61, 0x64, 0x2d, 0x77, 0x72, 0x69, 0x74, 0x65, 0x2c, 0x20, 0x72,
-  0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x2c, 0x20, 0x65, 0x74,
-  0x63, 0x2e, 0x29, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x6b, 0x65,
-  0x79, 0x3a, 0x20, 0x22, 0x63, 0x64, 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x6e,
-  0x73, 0x66, 0x65, 0x72, 0x2d, 0x61, 0x73, 0x61, 0x70, 0x22, 0x0a, 0x20,
-  0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x62, 0x6f, 0x6f,
-  0x6c, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x71, 0x75,
+  0x22, 0x0a, 0x20, 0x20, 0x23, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65,
+  0x3a, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x6d, 0x6f, 0x64,
+  0x65, 0x0a, 0x20, 0x20, 0x23, 0x20, 0x20, 0x20, 0x72, 0x65, 0x71, 0x75,
   0x69, 0x72, 0x65, 0x64, 0x3a, 0x20, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x0a,
-  0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a,
-  0x20, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64,
-  0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-  0x3a, 0x20, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x20,
-  0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x43, 0x44, 0x4f,
-  0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x74, 0x72, 0x61,
-  0x6e, 0x73, 0x66, 0x65, 0x72, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x73,
-  0x6f, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61,
-  0x73, 0x20, 0x70, 0x6f, 0x73, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2e, 0x0a,
-  0x0a, 0x20, 0x20, 0x2d, 0x20, 0x6b, 0x65, 0x79, 0x3a, 0x20, 0x22, 0x63,
-  0x64, 0x6f, 0x2e, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x2d, 0x70, 0x6f, 0x6f,
-  0x6c, 0x65, 0x64, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70,
-  0x65, 0x3a, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x28, 0x29, 0x0a, 0x20, 0x20,
-  0x20, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3a, 0x20,
-  0x46, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65,
-  0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x20, 0x46, 0x61, 0x6c, 0x73, 0x65,
-  0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e,
+  0x20, 0x20, 0x23, 0x20, 0x20, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c,
+  0x74, 0x3a, 0x20, 0x2a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x6d,
+  0x6f, 0x64, 0x65, 0x2d, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x0a, 0x20,
+  0x20, 0x23, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e,
   0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x49, 0x6e, 0x64, 0x69,
-  0x63, 0x61, 0x74, 0x65, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74,
-  0x68, 0x65, 0x20, 0x43, 0x44, 0x4f, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20,
-  0x62, 0x65, 0x20, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x20, 0x62, 0x65, 0x20,
-  0x75, 0x73, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x63, 0x61, 0x74, 0x65, 0x73, 0x20, 0x68, 0x6f, 0x77, 0x20, 0x74, 0x68,
+  0x65, 0x20, 0x43, 0x44, 0x4f, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62,
+  0x65, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x62,
+  0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x0a, 0x20,
+  0x20, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x72, 0x65, 0x61,
+  0x64, 0x2d, 0x77, 0x72, 0x69, 0x74, 0x65, 0x2c, 0x20, 0x72, 0x65, 0x61,
+  0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x2c, 0x20, 0x65, 0x74, 0x63, 0x2e,
+  0x29, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x6b, 0x65, 0x79, 0x3a,
+  0x20, 0x22, 0x63, 0x64, 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66,
+  0x65, 0x72, 0x2d, 0x61, 0x73, 0x61, 0x70, 0x22, 0x0a, 0x20, 0x20, 0x20,
+  0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x28,
+  0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72,
+  0x65, 0x64, 0x3a, 0x20, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20,
+  0x20, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x20, 0x46,
+  0x61, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x63,
+  0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20,
+  0x49, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x20, 0x74, 0x68,
+  0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x43, 0x44, 0x4f, 0x20, 0x6d,
+  0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73,
+  0x66, 0x65, 0x72, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x73, 0x6f, 0x6f,
+  0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x73, 0x20,
+  0x70, 0x6f, 0x73, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2e, 0x0a, 0x0a, 0x20,
+  0x20, 0x2d, 0x20, 0x6b, 0x65, 0x79, 0x3a, 0x20, 0x22, 0x63, 0x64, 0x6f,
+  0x2e, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x2d, 0x70, 0x6f, 0x6f, 0x6c, 0x65,
+  0x64, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a,
+  0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3a, 0x20, 0x46, 0x61,
+  0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x66, 0x61,
+  0x75, 0x6c, 0x74, 0x3a, 0x20, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x20,
+  0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61,
+  0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x61,
+  0x74, 0x65, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65,
+  0x20, 0x43, 0x44, 0x4f, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65,
+  0x20, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73,
+  0x65, 0x64, 0x20, 0x69, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x4f, 0x46, 0x46, 0x45, 0x52, 0x2f, 0x44, 0x45, 0x4d,
-  0x41, 0x4e, 0x44, 0x2c, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x70,
-  0x6f, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x70,
-  0x65, 0x72, 0x6d, 0x69, 0x74, 0x73, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61,
-  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x65, 0x72, 0x66,
-  0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x70, 0x74, 0x69,
-  0x6d, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x0a, 0x0a,
-  0x20, 0x20, 0x23, 0x23, 0x20, 0x4c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d,
-  0x65, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x0a, 0x20, 0x20,
+  0x20, 0x4f, 0x46, 0x46, 0x45, 0x52, 0x2f, 0x44, 0x45, 0x4d, 0x41, 0x4e,
+  0x44, 0x2c, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x70, 0x6f, 0x74,
+  0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x70, 0x65, 0x72,
+  0x6d, 0x69, 0x74, 0x73, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0x0a, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72,
+  0x6d, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69,
+  0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x0a, 0x0a, 0x20, 0x20,
+  0x23, 0x23, 0x20, 0x4c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x20,
+  0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x0a, 0x20, 0x20, 0x23, 0x20,
   0x2d, 0x20, 0x6b, 0x65, 0x79, 0x3a, 0x20, 0x22, 0x63, 0x64, 0x6f, 0x2e,
   0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x0a, 0x20, 0x20,
-  0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x6c, 0x69, 0x66, 0x65,
-  0x74, 0x69, 0x6d, 0x65, 0x2d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61,
-  0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72,
+  0x23, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x6c, 0x69,
+  0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x2d, 0x69, 0x6e, 0x74, 0x65, 0x72,
+  0x76, 0x61, 0x6c, 0x0a, 0x20, 0x20, 0x23, 0x20, 0x20, 0x20, 0x72, 0x65,
+  0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3a, 0x20, 0x46, 0x61, 0x6c, 0x73,
+  0x65, 0x0a, 0x20, 0x20, 0x23, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75,
+  0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x43,
+  0x44, 0x4f, 0x20, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x20,
+  0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+  0x6e, 0x2e, 0x0a, 0x20, 0x20, 0x23, 0x20, 0x2d, 0x20, 0x6b, 0x65, 0x79,
+  0x3a, 0x20, 0x22, 0x63, 0x64, 0x6f, 0x2e, 0x6c, 0x69, 0x66, 0x65, 0x74,
+  0x69, 0x6d, 0x65, 0x2d, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x6e, 0x65,
+  0x73, 0x73, 0x22, 0x0a, 0x20, 0x20, 0x23, 0x20, 0x20, 0x20, 0x74, 0x79,
+  0x70, 0x65, 0x3a, 0x20, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65,
+  0x2d, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x0a,
+  0x20, 0x20, 0x23, 0x20, 0x20, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72,
   0x65, 0x64, 0x3a, 0x20, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20,
+  0x23, 0x20, 0x20, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a,
+  0x20, 0x2a, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x2d, 0x73,
+  0x74, 0x72, 0x69, 0x63, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x2d, 0x76, 0x61,
+  0x6c, 0x75, 0x65, 0x73, 0x0a, 0x20, 0x20, 0x23, 0x20, 0x20, 0x20, 0x64,
+  0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+  0x3a, 0x20, 0x43, 0x44, 0x4f, 0x20, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69,
+  0x6d, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61,
+  0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x0a,
+  0x20, 0x20, 0x23, 0x23, 0x20, 0x53, 0x43, 0x4f, 0x50, 0x45, 0x20, 0x72,
+  0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x6b,
+  0x65, 0x79, 0x3a, 0x20, 0x22, 0x63, 0x64, 0x6f, 0x2e, 0x73, 0x63, 0x6f,
+  0x70, 0x65, 0x2e, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x0a, 0x20, 0x20, 0x20,
+  0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x28, 0x6d,
+  0x69, 0x6e, 0x3d, 0x2d, 0x31, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72,
+  0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3a, 0x20, 0x46, 0x61, 0x6c,
+  0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75,
+  0x6c, 0x74, 0x3a, 0x20, 0x2d, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64,
+  0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+  0x3a, 0x20, 0x54, 0x68, 0x65, 0x20, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x20,
+  0x73, 0x69, 0x7a, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20,
+  0x43, 0x44, 0x4f, 0x2e, 0x20, 0x2d, 0x31, 0x20, 0x69, 0x6e, 0x64, 0x69,
+  0x63, 0x61, 0x74, 0x65, 0x73, 0x20, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77,
+  0x6e, 0x2f, 0x55, 0x6e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65,
+  0x64, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x6b, 0x65, 0x79, 0x3a,
+  0x20, 0x22, 0x63, 0x64, 0x6f, 0x2e, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x2e,
+  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x0a,
+  0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6e,
+  0x74, 0x28, 0x6d, 0x69, 0x6e, 0x3d, 0x2d, 0x31, 0x29, 0x0a, 0x20, 0x20,
+  0x20, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3a, 0x20,
+  0x46, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65,
+  0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x20, 0x2d, 0x31, 0x0a, 0x20, 0x20,
   0x20, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74,
-  0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x43, 0x44, 0x4f, 0x20, 0x6c, 0x69, 0x66,
-  0x65, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66,
-  0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x20, 0x20, 0x2d,
-  0x20, 0x6b, 0x65, 0x79, 0x3a, 0x20, 0x22, 0x63, 0x64, 0x6f, 0x2e, 0x6c,
-  0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x2d, 0x73, 0x74, 0x72, 0x69,
-  0x63, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20,
-  0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69,
-  0x6d, 0x65, 0x2d, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x6e, 0x65, 0x73,
-  0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72,
-  0x65, 0x64, 0x3a, 0x20, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20,
-  0x20, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x20, 0x2a,
-  0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x2d, 0x73, 0x74, 0x72,
-  0x69, 0x63, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x2d, 0x76, 0x61, 0x6c, 0x75,
-  0x65, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d,
-  0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x43, 0x44,
-  0x4f, 0x20, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x73,
-  0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-  0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x23, 0x23,
-  0x20, 0x53, 0x43, 0x4f, 0x50, 0x45, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74,
-  0x65, 0x64, 0x0a, 0x20, 0x20, 0x2d, 0x20, 0x6b, 0x65, 0x79, 0x3a, 0x20,
-  0x22, 0x63, 0x64, 0x6f, 0x2e, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x2e, 0x73,
-  0x69, 0x7a, 0x65, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70,
-  0x65, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x28, 0x6d, 0x69, 0x6e, 0x3d, 0x2d,
-  0x31, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69,
-  0x72, 0x65, 0x64, 0x3a, 0x20, 0x46, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x20,
-  0x20, 0x20, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x20,
-  0x2d, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d,
-  0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x54, 0x68,
-  0x65, 0x20, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x20, 0x73, 0x69, 0x7a, 0x65,
-  0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x43, 0x44, 0x4f, 0x2e,
-  0x20, 0x2d, 0x31, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65,
-  0x73, 0x20, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x2f, 0x55, 0x6e,
-  0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x64, 0x2e, 0x0a, 0x0a,
-  0x20, 0x20, 0x2d, 0x20, 0x6b, 0x65, 0x79, 0x3a, 0x20, 0x22, 0x63, 0x64,
-  0x6f, 0x2e, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x2e, 0x6c, 0x6f, 0x63, 0x61,
-  0x6c, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20,
-  0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x28, 0x6d, 0x69,
-  0x6e, 0x3d, 0x2d, 0x31, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65,
-  0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3a, 0x20, 0x46, 0x61, 0x6c, 0x73,
-  0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c,
-  0x74, 0x3a, 0x20, 0x2d, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f,
-  0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a,
-  0x20, 0x54, 0x68, 0x65, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73,
-  0x69, 0x7a, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x43,
-  0x44, 0x4f, 0x2e, 0x20, 0x2d, 0x31, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63,
-  0x61, 0x74, 0x65, 0x73, 0x20, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e,
-  0x2f, 0x55, 0x6e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x64,
-  0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x23, 0x20, 0x4c, 0x61, 0x79, 0x6f, 0x75,
-  0x74, 0x73, 0x0a, 0x20, 0x20, 0x23, 0x20, 0x44, 0x69, 0x73, 0x74, 0x72,
-  0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x0a, 0x0a, 0x23,
-  0x20, 0x28, 0x65, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x6d, 0x61, 0x65,
-  0x73, 0x74, 0x72, 0x6f, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x79, 0x61,
-  0x6d, 0x6c, 0x29, 0x0a, 0x0a
+  0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6c, 0x6f, 0x63,
+  0x61, 0x6c, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74,
+  0x68, 0x65, 0x20, 0x43, 0x44, 0x4f, 0x2e, 0x20, 0x2d, 0x31, 0x20, 0x69,
+  0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x20, 0x55, 0x6e, 0x6b,
+  0x6e, 0x6f, 0x77, 0x6e, 0x2f, 0x55, 0x6e, 0x61, 0x6c, 0x6c, 0x6f, 0x63,
+  0x61, 0x74, 0x65, 0x64, 0x2e, 0x0a, 0x0a, 0x20, 0x20, 0x23, 0x20, 0x4c,
+  0x61, 0x79, 0x6f, 0x75, 0x74, 0x73, 0x0a, 0x20, 0x20, 0x23, 0x20, 0x44,
+  0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+  0x0a, 0x0a, 0x0a, 0x23, 0x20, 0x28, 0x65, 0x6e, 0x64, 0x20, 0x6f, 0x66,
+  0x20, 0x6d, 0x61, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x2d, 0x63, 0x6f, 0x72,
+  0x65, 0x2e, 0x79, 0x61, 0x6d, 0x6c, 0x29, 0x0a, 0x0a
 };
-const unsigned int maestro_core_yaml_len = 3785;
+const unsigned int maestro_core_yaml_len = 3885;
diff --git a/attributes/maestro-core.yaml b/attributes/maestro-core.yaml
index c497681a..7a23acc3 100644
--- a/attributes/maestro-core.yaml
+++ b/attributes/maestro-core.yaml
@@ -7,26 +7,27 @@ schema-version: 0
 schema-namespace: ".maestro.core."
 
 # Values permitted in user-defined types used
-schema-type-values:
+#schema-type-values:
+  # FIXME: user-defined types currently broken
   # values occuring in lifetime-strictness flag
-  - &lifetime-strictness-values enum('optional', 'required')
+  # - &lifetime-strictness-values enum('optional', 'required')
   # values occuring in lifetime-strictness flag
-  - &access-mode-values enum('rw', 'r')
+  #- &access-mode-values enum('rw', 'r')
 
 # user-defined types used in this schema
-schema-types:
+#schema-types:
   
-  -  typename: lifetime-interval
-     typespec: map()
-     documentation: CDO lifetime type
+  # -  typename: lifetime-interval
+  #    typespec: map()
+  #    documentation: CDO lifetime type
 
-  -  typename: lifetime-strictness
-     typespec: *lifetime-strictness-values
-     documentation: CDO lifetime specifier interpretation
+  # -  typename: lifetime-strictness
+  #    typespec: *lifetime-strictness-values
+  #    documentation: CDO lifetime specifier interpretation
 
-  -  typename: access-mode
-     typespec: *access-mode-values
-     documentation: CDO access mode
+  # -  typename: access-mode
+  #    typespec: *access-mode-values
+  #    documentation: CDO access mode
 
 # Individual attribute descriptions
 maestro-attributes:
@@ -71,12 +72,12 @@ maestro-attributes:
     documentation: Request/advise maestro storage management for the
                    CDO (no RAW-PTR will be provided or can be obtained)
 
-  - key: "cdo.access-mode"
-    type: access-mode
-    required: False
-    default: *access-mode-values
-    documentation: Indicates how the CDO will be accessed by the user
-                   (read-write, read-only, etc.).
+  # - key: "cdo.access-mode"
+  #   type: access-mode
+  #   required: False
+  #   default: *access-mode-values
+  #   documentation: Indicates how the CDO will be accessed by the user
+  #                  (read-write, read-only, etc.).
 
   - key: "cdo.transfer-asap"
     type: bool()
@@ -94,15 +95,15 @@ maestro-attributes:
                    performance optimizations.
 
   ## Lifetime related
-  - key: "cdo.lifetime"
-    type: lifetime-interval
-    required: False
-    documentation: CDO lifetime specification.
-  - key: "cdo.lifetime-strictness"
-    type: lifetime-strictness
-    required: False
-    default: *lifetime-strictness-values
-    documentation: CDO lifetime specification.
+  # - key: "cdo.lifetime"
+  #   type: lifetime-interval
+  #   required: False
+  #   documentation: CDO lifetime specification.
+  # - key: "cdo.lifetime-strictness"
+  #   type: lifetime-strictness
+  #   required: False
+  #   default: *lifetime-strictness-values
+  #   documentation: CDO lifetime specification.
 
     
   ## SCOPE related
diff --git a/attributes/maestro-schema.c b/attributes/maestro-schema.c
index b9d6138d..11f50beb 100644
--- a/attributes/maestro-schema.c
+++ b/attributes/maestro-schema.c
@@ -102,9 +102,6 @@ struct mstro_schema_type_ {
   char *documentation;       /**< "documentation: str()" */
 
   struct mstro_stp_val *parsed_type; /**< parsed type handle */
-  /* A closure each for parser, serializer, deserializer. May be
-   * NULL. Main use: instantiated regex parser automaton for string-ish types */
-  void *parser_closure;
 
 };
 
@@ -131,9 +128,19 @@ csv_schema_type_entry = {
                       csf_schema_type_mapping),                      
 };
 
+struct mstro_schema_attribute_type_parse_closure {
+  struct mstro_stp_val *info;
+};
+
 /** attribute entry data structure */
 struct mstro_schema_attribute_ {
+  /* not set by CYAML parse: */
   UT_hash_handle hh; /**< hashable by key_symbol */
+  void *defaultval; /**< parsed defaultval_string */
+  size_t defaultval_size; /**< size of defaultval */
+  mstro_symbol key_symbol; /**< symbol for key; key in the hash table */
+  struct mstro_schema_attribute_type_parse_closure type_parse_closure; /**< information for parsing values of this type */
+  /* these slots get filled by CYAML parse */
   char *key; /**<   key: regex('(^(\.[^\s\.]+)+$)|(^[^\s\.]+(\.[^\s\.]+)*$)',
                 required=False,
                 none=False, multiline=False,
@@ -141,16 +148,13 @@ struct mstro_schema_attribute_ {
 #define ATTRIBUTE_KEY_PATTERN "(^(\\.[^[:space:].]+)+$)|(^[^[:space:].]+(\\.[^[:space:].]+)*$)"
 #define ATTRIBUTE_KEY_PATTERN_CFLAGS (REG_EXTENDED|REG_ICASE)
 #define ATTRIBUTE_KEY_PATTERN_EFLAGS 0
-
-  mstro_symbol key_symbol; /**< symbol for key; key in the hash table */
   char *typespec;   /**< type: include('maestro-user-typespec') */
-  
   bool required; /**<  required: bool() */
   
-  struct mstro_schema_type_val *defaultval; /**< Any(include('maestro-builtin-typeval'),
-                                               include('maestro-user-typeval'),
-                                               required=False, none=False) */
-  
+  /* struct mstro_schema_type_val *defaultval; /\**< Any(include('maestro-builtin-typeval'), */
+  /*                                              include('maestro-user-typeval'), */
+  /*                                              required=False, none=False) *\/ */
+  char * defaultval_string; /**< string form of default value */
   char *documentation; /**<  documentation: str(multiline=True) */
 };
 
@@ -165,9 +169,11 @@ csf_schema_attribute_mapping[] = {
   CYAML_FIELD_BOOL("required",
                    CYAML_FLAG_DEFAULT,
                    struct mstro_schema_attribute_, required),
+  /* because we're lazy we store it as a string currently and parse it at instantiation time
+     It's actually easier that way, since complicated user-defined types' values can't be parsed by cyaml */
   CYAML_FIELD_STRING_PTR("default",
                          CYAML_FLAG_DEFAULT|CYAML_FLAG_OPTIONAL,
-                         struct mstro_schema_attribute_, defaultval, 0, CYAML_UNLIMITED),
+                         struct mstro_schema_attribute_, defaultval_string, 0, CYAML_UNLIMITED),
   CYAML_FIELD_STRING_PTR("documentation",
                          CYAML_FLAG_DEFAULT,
                          struct mstro_schema_attribute_, documentation, 0, CYAML_UNLIMITED),
@@ -266,13 +272,8 @@ mstro_schema_name(mstro_schema sch)
 {
   if(sch==NULL)
     return "(null)";
-  else {
-    if(sch->next!=NULL) {
-      /* FIXME: */
-      WARN("schema has merged content, name not reflecting this\n");
-    }
+  else 
     return sch->schema_name;
-  }
 }
 
 /** Return the version of a schema. */
@@ -399,7 +400,7 @@ mstro_schema__validate_namespace(const char *string)
         s, mstro_status_description(s));
     return s;
   }
-  bool namespace_ok;
+  //bool namespace_ok;
   s = mstro_schema__check_regex(string,
                                 namespace_regex,
                                 NAMESPACE_PATTERN_EFLAGS);
@@ -470,7 +471,7 @@ mstro_schema__validate_attribute_key(const char *string)
         s, mstro_status_description(s));
     return s;
   }
-  bool attribute_key_ok;
+  //bool attribute_key_ok;
   s = mstro_schema__check_regex(string,
                                 attribute_key_regex,
                                 ATTRIBUTE_KEY_PATTERN_EFLAGS);
@@ -501,6 +502,317 @@ mstro_cyaml_config = {
 
 
 
+/* look at the typespec string and parse it; fill in information that
+ * helps us parse values of this type whenever needed later */
+static inline
+mstro_status
+mstro_schema_attribute__install_type_parser(struct mstro_schema_attribute_ *attr)
+{
+  mstro_status s = mstro_schema_type_parse(attr->typespec, &attr->type_parse_closure.info);
+  if(s!=MSTRO_OK) {
+    if(attr->type_parse_closure.info && attr->type_parse_closure.info->kind == MSTRO_STP_ERROR) {
+      ERR("Error parsing type |%s|, error message %s\n",
+          attr->typespec, attr->type_parse_closure.info->errmsg);
+    } else {
+      ERR("error parsing built-in type: %d (no parser error message available)\n",
+          s);
+    }
+  }
+  return s;
+}
+
+/* compute the space needed to store the value of STP_VAL arising from
+* parsing STRING or inspecting VAL.  Only one of the two may ne
+* non-NULL. */
+static inline
+mstro_status
+mstro_attribute_val__compute_size(enum mstro_stp_val_kind kind,
+                                  const char *string,
+                                  void *val,
+                                  size_t *val_size)
+{
+  if(kind==MSTRO_STP_ERROR) {
+    ERR("Invalid stp val\n");
+    return MSTRO_INVARG;
+  }
+  if(string==NULL && val==NULL) {
+    ERR("not both src args may be NULL\n");
+    return MSTRO_INVARG;
+  }
+  if(string!=NULL && val!=NULL) {
+    ERR("not both src args may be non-NULL\n");
+    return MSTRO_INVARG;
+  }
+  if(val_size==NULL) {
+    ERR("Invalid output destination\n");
+    return MSTRO_INVOUT;
+  }
+
+  mstro_status status = MSTRO_OK;
+  
+  switch(kind) {
+    case MSTRO_STP_BOOL: 
+      *val_size = sizeof(bool); break;
+    case MSTRO_STP_UINT: 
+      *val_size = sizeof(uint64_t); break;
+    case MSTRO_STP_INT: 
+      *val_size = sizeof(int64_t); break;
+    case MSTRO_STP_FLOAT:
+      *val_size = sizeof(float); break;
+    case MSTRO_STP_DOUBLE: 
+      *val_size = sizeof(double); break;
+    case MSTRO_STP_STR:
+    case MSTRO_STP_REGEX: 
+      if(string)
+        *val_size = strlen(string)+1;
+      else
+        *val_size = strlen((char*)val)+1;
+      break;
+    case MSTRO_STP_TIMESTAMP:
+      *val_size = sizeof(mstro_timestamp);
+      break;
+    case MSTRO_STP_BLOB:
+      if(string!=NULL) {
+        /* FIXME: could be base64 encoded */
+        ERR("Cannot parse external-representation of BLOB (FIXME)\n");
+        status=MSTRO_UNIMPL;
+      } else  {
+        *val_size = ((mstro_blob*)val)->len;
+      }
+      break;
+    default:
+      ERR("Unexpected parsed type %d\n", kind);
+      status=MSTRO_UNIMPL;
+  }
+  return status;
+}
+
+/* parse a string according to type specification of the attribute.
+ * Store freshly-allocated value in **val_p, and the size in *val_size.
+ */
+static inline
+mstro_status
+mstro_attribute_val_parse(const struct mstro_stp_val *parsed_type, const char *string,
+                          void **val_p, size_t *val_size)
+{
+  if(parsed_type==NULL ||string==NULL) {
+    ERR("Invalid input args\n");
+    return MSTRO_INVARG;
+  }
+  if(val_p==NULL||val_size==NULL) {
+    ERR("Invalid output args\n");
+    return MSTRO_INVOUT;
+  }
+
+  mstro_status s=MSTRO_OK;
+
+
+  s =mstro_attribute_val__compute_size(parsed_type->kind, string, NULL, val_size);
+  if(s!=MSTRO_OK) {
+    ERR("Failed to compute value size\n");
+    return s;
+  }
+
+  /* all built-ins recognized by built-in regexps for now */
+  size_t num_re;
+  if(parsed_type->kind == MSTRO_STP_REGEX) {
+    num_re = parsed_type->regex_numpatterns;
+  } else {
+    num_re = 1;
+  }
+  regex_t regex[num_re];
+  int err=0;
+  bool need_regmatch = true; /* except for BLOB we need it */
+  size_t val_len = strlen(string);
+  size_t minlen =0, maxlen=val_len; /* might be changed for strings */
+
+  switch(parsed_type->kind) {
+    case MSTRO_STP_BOOL: {
+      err = regcomp(&(regex[0]), "1|0|On|Off|True|False",REG_ICASE|REG_NOSUB|REG_EXTENDED);
+      break;
+    }
+    case MSTRO_STP_UINT: {
+      err = regcomp(&(regex[0]), "[+]?[[:blank:]]*[0-9]+",REG_EXTENDED|REG_NOSUB);
+      WARN("Not checking numeric bounds on types\n");
+      break;
+    }      
+    case MSTRO_STP_INT: {
+      err = regcomp(&(regex[0]), "[-+]?[[:blank:]]*[0-9]+",REG_EXTENDED|REG_NOSUB);
+      WARN("Not checking numeric bounds on types\n");
+      break;
+    }
+    case MSTRO_STP_FLOAT: {
+      err = regcomp(&(regex[0]), "[-+]?[[:blank:]]*[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?",REG_EXTENDED);
+      WARN("Not checking numeric bounds on types\n");
+      break;
+    }
+    case MSTRO_STP_DOUBLE: {
+      err = regcomp(&(regex[0]), "[-+]?[[:blank:]]*[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?",REG_EXTENDED);
+      WARN("Not checking numeric bounds on types\n");
+      break;
+    }
+    case MSTRO_STP_STR: {
+      minlen = parsed_type->str_minlen;
+      maxlen = parsed_type->str_maxlen;
+      char *re;
+      if(parsed_type->str_excludedchars) {
+        size_t l = strlen(parsed_type->str_excludedchars)+strlen("[^]*") + 1;
+        re=malloc(sizeof(char)*l);
+        if(re) {
+          re[0]='['; re[1]='^';
+          strcpy(re+2,parsed_type->str_excludedchars);
+          re[l-3] = ']'; re[l-2]='*'; re[l-1] = '\0';
+        }
+      } else {
+        re = strdup(".*");
+      }
+      if(re==NULL) {
+        ERR("Failed to allocate string regex\n");
+        s=MSTRO_NOMEM;
+        goto BAILOUT;
+      }
+      err = regcomp(&(regex[0]), re, REG_NOSUB);
+      free(re);
+      break;
+    }
+    case MSTRO_STP_REGEX:
+      for(size_t i=0; i<num_re; i++) {
+        err |= regcomp(&(regex[i]), parsed_type->regex_patterns[i],
+                       REG_EXTENDED|REG_NOSUB| (parsed_type->regex_ignorecase ? REG_ICASE : 0));
+      }
+      break;          
+    case MSTRO_STP_BLOB:
+      need_regmatch = false;
+      minlen = parsed_type->blob_minlen;
+      maxlen = parsed_type->blob_maxlen;
+      break;
+    case MSTRO_STP_TIMESTAMP:
+      err = regcomp(&(regex[0]), RFC3339_PATTERN, REG_EXTENDED);
+      break;
+
+    default:
+      ERR("Unexpected parsed type %d\n", parsed_type->kind);
+      s=MSTRO_UNIMPL;
+  }
+  if(err) {
+    ERR("Failed to construct regex\n");
+    // regerror ...
+    goto BAILOUT;
+  }
+  
+  if(! (minlen<=val_len  && val_len <=maxlen)) {
+    ERR("Argument |%s| (strlen %zu) not within length bounds for type: min=%zu, max=%zu\n",
+        string, val_len, minlen, maxlen);
+    s=MSTRO_FAIL;
+    goto BAILOUT;
+  }
+
+  s=MSTRO_OK;
+  if(need_regmatch) {
+    s=MSTRO_NOMATCH;
+    for(size_t i=0; i<num_re; i++) {
+      s = mstro_schema__check_regex(string, &(regex[i]), 0);
+      /* DEBUG("Checked regex against |%s|, result %d (%s)\n", val, s, mstro_status_description(s)); */
+      if(s==MSTRO_OK)
+        break;
+      /* NOMATCH: try further */
+      if(s==MSTRO_NOMATCH) {
+        continue;
+      } else {
+        break;
+      }
+    }
+    for(size_t i=0; i<num_re; i++) {
+      regfree(&regex[i]);
+    }
+  }
+
+  *val_p = malloc(*val_size);
+  if(*val_p==NULL) {
+    ERR("Failed to allocate for attribute value\n");
+    s=MSTRO_NOMEM;
+    goto BAILOUT;
+  }
+
+  /* numeric bound checking should happen in this switch. All the info is in the stp_val */
+  if(s==MSTRO_OK) {
+    switch(parsed_type->kind) {
+      case MSTRO_STP_BOOL: {
+        /* we are alredy checked by regex above */
+        switch(tolower(string[0])) {
+          case 't': // TRUE
+          case '1': // 1
+          case 'o': // ON
+          case 'y': // YES
+            **((bool**)(val_p)) = true;
+            break;
+          default:
+            *((bool**)(val_p)) = false;
+            break;
+        }
+        break;
+      }
+      case MSTRO_STP_UINT: 
+        **((uint64_t**)(val_p)) = strtoumax((const char*)string, NULL, 10);
+        break;
+
+      case MSTRO_STP_INT: 
+        **((int64_t**)(val_p))  = strtoimax(string, NULL, 10);
+        break;
+
+      case MSTRO_STP_FLOAT: 
+        *((float*)(val_p)) = strtof(string, NULL);
+        break;
+
+      case MSTRO_STP_DOUBLE: 
+        **((double**)(val_p)) = strtod(string, NULL);
+        break;
+
+      case MSTRO_STP_STR:
+      case MSTRO_STP_REGEX: 
+        strcpy(*(char**)val_p, string);
+        (*(char**)(val_p))[(*val_size)-1] = '\0';
+        break;
+        
+      case MSTRO_STP_BLOB:
+        memcpy(*(char**)val_p, string, *val_size);
+        break;
+
+      case MSTRO_STP_TIMESTAMP: {
+        s=mstro_timestamp_parse(string, *val_size, *((mstro_timestamp**)val_p));
+        if(s!=MSTRO_OK) {
+          ERR("Failed to parse timestamp value |%s| as rfc3339-timestamp\n");
+        }
+        break;
+      }
+
+      default:
+        ERR("Unexpected parsed type %d\n", parsed_type->kind);
+        s=MSTRO_UNIMPL;
+    }
+  }
+
+BAILOUT:
+  return s;
+}
+
+
+/* parse the defaultval_string and store it (in a fresh allocation) in the default slot */
+static inline
+mstro_status
+mstro_schema_attribute__parse_defaultval(struct mstro_schema_attribute_ *attr)
+{
+  assert(attr->type_parse_closure.info!=NULL);
+  if(attr->defaultval_string)
+    return mstro_attribute_val_parse(attr->type_parse_closure.info, attr->defaultval_string,
+                                     &attr->defaultval, &attr->defaultval_size);
+  else {
+    attr->defaultval = NULL;
+    attr->defaultval_size = 0;
+    return MSTRO_OK;
+  }
+}
+
 
 /** update ACC to VAL if that is greater */
 #define SAVE_MAX(acc,val) (acc) = ((acc)<(val)? (val) : (acc));
@@ -625,14 +937,42 @@ mstro_schema_validate_and_instantiate(mstro_schema schema)
       ERR("Failed to intern attribute name |%s|\n", fqstr);
       goto BAILOUT;
     }
+
+    s=mstro_schema_attribute__install_type_parser(current);
+    if(s!=MSTRO_OK) {
+      ERR("Failed to install type parser for %s (type %s)\n",
+          mstro_symbol_name(current->key_symbol),
+          current->typespec);
+      goto BAILOUT;
+    }
+    
     HASH_ADD(hh, schema->attribute_table, key_symbol, sizeof(mstro_symbol), current);
 
+    /* parse default value */
+    if(!current->required)
+      if(current->defaultval_string==NULL) {
+        ERR("Attribute |%s| is optional, but schema provides no default value\n",
+            fqstr);
+        s=MSTRO_FAIL;
+        goto BAILOUT;
+      }
+
+    DEBUG("Adding default value for %s\n", fqstr);
+    s = mstro_schema_attribute__parse_defaultval(current);
+    if(s!=MSTRO_OK) {
+      ERR("Failed to parse default value |%s| for attribute |%s|\n",
+          current->defaultval_string, fqstr);
+      goto BAILOUT;
+    }
+        
     /* check that attribute has value type */
-    DEBUG("Attribute |%s| type |%s|, required %s, default %s\n",
+    DEBUG("Attribute |%s| type |%s|, required %s, default %s, doc: %s\n",
           mstro_symbol_name(current->key_symbol),
           current->typespec,
           current->required ? "YES" : "NO",
-          "?"//current->defaultval ? current->defaultval->val : "(none)"
+          //"?"//
+          current->defaultval_string ? current->defaultval_string : "(none)",
+          current->documentation ? current->documentation : "(none)"
           );
   }
 
@@ -751,6 +1091,18 @@ mstro_schema_merge(mstro_schema main,
   if(main==NULL || consumed==NULL) {
     return MSTRO_INVARG;
   }
+  char *tmpname = malloc(strlen(main->schema_name)+strlen(" + ")+strlen(consumed->schema_name)+1);
+  if(tmpname==NULL) {
+    ERR("Cannot allocate merged schema name\n");
+    return MSTRO_NOMEM;
+  }
+  strcpy(tmpname,main->schema_name);
+  strcat(tmpname," + ");
+  strcat(tmpname,consumed->schema_name);
+
+  free(main->schema_name);
+  
+  main->schema_name=tmpname;
 
   LL_APPEND(main,consumed);
   /* FIXME: we could copy entries from consumed into main, but until
@@ -877,7 +1229,7 @@ mstro_schema_lookup_type__builtins(
       if(*result) {
         (*result)->typename = strdup(typename);
         (*result)->type_symbol = sym;
-        (*result)->unparsed_typespec = strdup("?");
+        (*result)->unparsed_typespec = strdup(typename);
         (*result)->documentation = strdup("builtin type");
         (*result)->parsed_type = parsed_type;
         HASH_ADD(hh, schema->type_table, type_symbol, sizeof(mstro_symbol), *result);
@@ -942,7 +1294,7 @@ mstro_schema_lookup_symbol(mstro_schema schema, const char *fqkey, mstro_symbol
   for(mstro_schema schem = schema;
       schem!=NULL;
       schem=schem->next) {
-    DEBUG("Trying schema %s\n", mstro_schema_name(schem));
+    //DEBUG("Trying schema %s\n", mstro_schema_name(schem));
     status = mstro_symtab_lookup(schem->symtab, fqkey, sym);
     if(status!=MSTRO_OK) {
       return status;
@@ -1037,251 +1389,10 @@ mstro_status
 mstro_attribute_entry__set_size(struct mstro_attribute_entry_ *entry,
                                 enum mstro_stp_val_kind kind)
 {
-  mstro_status status=MSTRO_OK;
-  switch(kind) {
-    case MSTRO_STP_BOOL: 
-      entry->valsize = sizeof(bool); break;
-    case MSTRO_STP_UINT: 
-      entry->valsize = sizeof(uint64_t); break;
-    case MSTRO_STP_INT: 
-      entry->valsize = sizeof(int64_t); break;
-    case MSTRO_STP_FLOAT:
-      entry->valsize = sizeof(float); break;
-    case MSTRO_STP_DOUBLE: 
-      entry->valsize = sizeof(double); break;
-    case MSTRO_STP_STR:
-    case MSTRO_STP_REGEX:
-      entry->valsize = strlen(entry->val)+1;
-      break;
-    case MSTRO_STP_BLOB:
-      entry->valsize = 0; /* FIXME: query a previously set key like 'strcat(fqkey,"_len")' ? */
-      break;
-    case MSTRO_STP_TIMESTAMP:
-      entry->valsize = sizeof(mstro_timestamp); break;
-      
-    default:
-      ERR("Unexpected parsed type %d\n", kind);
-      status=MSTRO_UNIMPL;
-  }
-  return status;
+  return mstro_attribute_val__compute_size(kind, NULL, entry->val, &entry->valsize);
 }
 
-/* parse VAL and fill in *entry */
-static inline
-mstro_status
-mstro_attributes_parse_val(mstro_schema schema,
-                           struct mstro_schema_attribute_ *decl,
-                           const unsigned char *val, size_t val_len,
-                           struct mstro_attribute_entry_ *entry)
-{
-  const char *aname = mstro_symbol_name(decl->key_symbol);
-  const char *tname = decl->typespec;
-  DEBUG("Attribute |%s|, declared type |%s|\n", aname, tname);
-  /* fetch type declaration */
-
-  mstro_schema_type tdecl;
-  mstro_status s = mstro_schema_lookup_type(schema, tname, &tdecl);
-
-  if(s!=MSTRO_OK) {
-    ERR("Failed to find type declaration for type |%s| (attribute |%s|)\n",
-        tname, aname);
-    return MSTRO_INVARG;
-  } else {
-    DEBUG("Found type declaration for type |%s| (attribute |%s|)\n", tname, aname);
-  }
-  /* FIXME: this could be handled better by pre-allocated parsers
-   * (needs to be reentrant!) built with a schema-typeval.peg */
-  if(!tdecl->parsed_type) {
-    ERR("Parsed type not available\n");
-    return MSTRO_UNIMPL;
-  }
-
-  /* all built-ins recognized by built-in regexps for now */
-  size_t num_re;
-  if(tdecl->parsed_type->kind == MSTRO_STP_REGEX) {
-    num_re = tdecl->parsed_type->regex_numpatterns;
-  } else {
-    num_re = 1;
-  }
-  regex_t regex[num_re];
-  int err=0;
-  bool need_regmatch = true; /* except for BLOB we need it */
-  size_t minlen =0, maxlen=val_len; /* might be changed for strings */
-
-  entry->kind = tdecl->parsed_type->kind;
-  s = mstro_attribute_entry__set_size(entry, entry->kind);
-  if(s!=MSTRO_OK) {
-    ERR("Failed to set entry value size\n");
-    goto BAILOUT;
-  }
-
-  switch(entry->kind) {
-    case MSTRO_STP_BOOL: {
-      err = regcomp(&(regex[0]), "1|0|On|Off|True|False",REG_ICASE|REG_NOSUB|REG_EXTENDED);
-      break;
-    }
-    case MSTRO_STP_UINT: {
-      err = regcomp(&(regex[0]), "[+]?[[:blank:]]*[0-9]+",REG_EXTENDED|REG_NOSUB);
-      WARN("Not checking numeric bounds on types\n");
-      break;
-    }      
-    case MSTRO_STP_INT: {
-      err = regcomp(&(regex[0]), "[-+]?[[:blank:]]*[0-9]+",REG_EXTENDED|REG_NOSUB);
-      WARN("Not checking numeric bounds on types\n");
-      break;
-    }
-    case MSTRO_STP_FLOAT: {
-      err = regcomp(&(regex[0]), "[-+]?[[:blank:]]*[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?",REG_EXTENDED);
-      WARN("Not checking numeric bounds on types\n");
-      break;
-    }
-    case MSTRO_STP_DOUBLE: {
-      err = regcomp(&(regex[0]), "[-+]?[[:blank:]]*[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?",REG_EXTENDED);
-      WARN("Not checking numeric bounds on types\n");
-      break;
-    }
-    case MSTRO_STP_STR: {
-      minlen = tdecl->parsed_type->str_minlen;
-      maxlen = tdecl->parsed_type->str_maxlen;
-      char *re;
-      if(tdecl->parsed_type->str_excludedchars) {
-        size_t l = strlen(tdecl->parsed_type->str_excludedchars)+strlen("[^]*") + 1;
-        re=malloc(sizeof(char)*l);
-        if(re) {
-          re[0]='['; re[1]='^';
-          strcpy(re+2,tdecl->parsed_type->str_excludedchars);
-          re[l-3] = ']'; re[l-2]='*'; re[l-1] = '\0';
-        }
-      } else {
-        re = strdup(".*");
-      }
-      if(re==NULL) {
-        ERR("Failed to allocate string regex\n");
-        s=MSTRO_NOMEM;
-        goto BAILOUT;
-      }
-      err = regcomp(&(regex[0]), re, REG_NOSUB);
-      free(re);
-      break;
-    }
-    case MSTRO_STP_REGEX:
-      for(size_t i=0; i<num_re; i++) {
-        err |= regcomp(&(regex[i]), tdecl->parsed_type->regex_patterns[i],
-                       REG_EXTENDED|REG_NOSUB| (tdecl->parsed_type->regex_ignorecase ? REG_ICASE : 0));
-      }
-      break;          
-    case MSTRO_STP_BLOB:
-      need_regmatch = false;
-      minlen = tdecl->parsed_type->blob_minlen;
-      maxlen = tdecl->parsed_type->blob_maxlen;
-      break;
-    case MSTRO_STP_TIMESTAMP:
-      err = regcomp(&(regex[0]), RFC3339_PATTERN, REG_EXTENDED);
-      break;
-
-    default:
-      ERR("Unexpected parsed type %d\n", tdecl->parsed_type->kind);
-      s=MSTRO_UNIMPL;
-  }
-  if(err) {
-    ERR("Failed to construct regex\n");
-    // regerror ...
-    goto BAILOUT;
-  }
-  if(! (minlen<=val_len  && val_len <=maxlen)) {
-    ERR("Argument |%s| (len %zu, strlen %zu) not within length bounds for type: min=%zu, max=%zu\n",
-        val, val_len, strlen((const char*)val), minlen, maxlen);
-    s=MSTRO_FAIL;
-    goto BAILOUT;
-  }
-
-  s=MSTRO_OK;
-  if(need_regmatch) {
-    s=MSTRO_NOMATCH;
-    for(size_t i=0; i<num_re; i++) {
-      s = mstro_schema__check_regex((const char*)val, &(regex[i]), 0);
-      /* DEBUG("Checked regex against |%s|, result %d (%s)\n", val, s, mstro_status_description(s)); */
-      if(s==MSTRO_OK)
-        break;
-      /* NOMATCH: try further */
-      if(s==MSTRO_NOMATCH) {
-        continue;
-      } else {
-        break;
-      }
-    }
-    for(size_t i=0; i<num_re; i++) {
-      regfree(&regex[i]);
-    }
-  }
-
-  entry->val = malloc(entry->valsize);
-  if(entry->val==NULL) {
-    ERR("Failed to allocate for attribute value\n");
-    s=MSTRO_NOMEM;
-    goto BAILOUT;
-  }
-
-  if(s==MSTRO_OK) {
-    switch(entry->kind) {
-      case MSTRO_STP_BOOL: {
-        /* we are alredy checked by regex above */
-        switch(tolower(val[0])) {
-          case 't': // TRUE
-          case '1': // 1
-          case 'o': // ON
-          case 'y': // YES
-            *((bool*)(entry->val)) = true;
-            break;
-          default:
-            *((bool*)(entry->val)) = false;
-            break;
-        }
-        break;
-      }
-      case MSTRO_STP_UINT: 
-        *((uint64_t*)(entry->val)) = strtoumax((const char*)val, NULL, 10);
-        break;
-
-      case MSTRO_STP_INT: 
-        *((int64_t*)(entry->val))  = strtoimax((const char*)val, NULL, 10);
-        break;
-
-      case MSTRO_STP_FLOAT: 
-        *((float*)(entry->val)) = strtof((const char*)val, NULL);
-        break;
-
-      case MSTRO_STP_DOUBLE: 
-        *((double*)(entry->val)) = strtod((const char*)val, NULL);
-        break;
 
-      case MSTRO_STP_STR:
-      case MSTRO_STP_REGEX: 
-        strcpy((char*)entry->val, (const char*)val);
-        ((char*)(entry->val))[entry->valsize-1] = '\0';
-        break;
-        
-      case MSTRO_STP_BLOB:
-        memcpy((char*)entry->val, val, val_len);
-        break;
-
-      case MSTRO_STP_TIMESTAMP: {
-        s=mstro_timestamp_parse((const char*)val, val_len, ((mstro_timestamp*)entry->val));
-        if(s!=MSTRO_OK) {
-          ERR("Failed to parse timestamp value |%s| as rfc3339-timestamp\n");
-        }
-        break;
-      }
-
-      default:
-        ERR("Unexpected parsed type %d\n", tdecl->parsed_type->kind);
-        s=MSTRO_UNIMPL;
-    }
-  }
-
-BAILOUT:
-  return s;
-}
 
 
 static inline
@@ -1525,7 +1636,9 @@ mstro_attributes__parse_helper(yaml_parser_t parser,
               goto BAILOUT;
           }
 
-          status = mstro_attributes_parse_val(schema, decl, val, val_len, entry);
+          status = mstro_attribute_val_parse(decl->type_parse_closure.info,
+                                             (char*)val,
+                                             &entry->val, &entry->valsize);
           if(status!=MSTRO_OK) {
             ERR("Failed to parse |%s| as value for attribute |%s|\n",
                 val, mstro_symbol_name(decl->key_symbol));
@@ -1537,6 +1650,10 @@ mstro_attributes__parse_helper(yaml_parser_t parser,
                   val, mstro_symbol_name(decl->key_symbol));
             /* FIXME: describe_entry function call here */
           }
+          entry->kind = decl->type_parse_closure.info->kind;
+          
+          assert(entry->kind!=MSTRO_STP_ERROR);
+
           if(new_entry)
             HASH_ADD(hh, (*result)->dict, key, sizeof(mstro_symbol), entry);
           
@@ -1790,12 +1907,21 @@ mstro_attribute_dict__insert_default(mstro_attribute_dict dict,
   bool must_insert=false;
   mstro_status status = MSTRO_OK;
 
+  DEBUG("schema dict insert default for key %s\n", mstro_symbol_name(key));
   mstro_schema_attribute attr=NULL;
   status = mstro_schema_lookup_attribute(dict->schema, mstro_symbol_name(key), &attr);
   if(status!=MSTRO_OK) {
     ERR("Cannot find attribute in schema !? (should not happen here)\n");
     goto BAILOUT;
   }
+  if(!attr->defaultval) {
+    /* schema instantiation should have parsed the defaultval_string for us */
+    DEBUG("No default for |%s| in schema\n", mstro_symbol_name(key));
+    return MSTRO_NOENT;
+  }
+
+  assert(attr->defaultval!=NULL);
+
   mstro_schema_type tdecl;
   status = mstro_schema_lookup_type(dict->schema, attr->typespec, &tdecl);
   if(status!=MSTRO_OK) {
@@ -1809,8 +1935,8 @@ mstro_attribute_dict__insert_default(mstro_attribute_dict dict,
       ERR("Cannot allocate default entry\n");
       goto BAILOUT;
     }
+
     entry->kind=tdecl->parsed_type->kind;
-    
     status = mstro_attribute_entry__set_size(entry, entry->kind);
     if(status!=MSTRO_OK) {
       ERR("Cannot set entry size\n");
@@ -1853,7 +1979,7 @@ mstro_attribute_dict__insert_default(mstro_attribute_dict dict,
       status=MSTRO_UNIMPL;
       goto BAILOUT;
   }
-
+  
   if(must_insert) {
     HASH_ADD(hh, dict->dict, key, sizeof(mstro_symbol), entry);
   }
@@ -1918,6 +2044,10 @@ mstro_attribute_dict_get(mstro_attribute_dict dict,
     DEBUG("Key |%s| found, but no value in attribute dictionary at %p, fetching default\n", fqkey, dict);
 
     status = mstro_attribute_dict__insert_default(dict, sym);
+    if(status==MSTRO_NOENT) {
+      DEBUG("Key |%s| has no default value in schema\n", fqkey);
+      goto BAILOUT;
+    }
     if(status!=MSTRO_OK) {
       ERR("Failed to insert default value for attribute %s\n", fqkey);
       goto BAILOUT;
@@ -1999,6 +2129,8 @@ mstro_attribute_dict_set(mstro_attribute_dict dict, const char *key,
   }
   fqkey = key;
 
+  DEBUG("Setting value for |%s|\n", fqkey);
+  
   status = mstro_schema_lookup_symbol(dict->schema, fqkey, &sym);
   if(sym==NULL) {
     DEBUG("Key |%s| not found in schema %s (V%zu)\n",
@@ -2016,7 +2148,6 @@ mstro_attribute_dict_set(mstro_attribute_dict dict, const char *key,
     DEBUG("Key |%s| found, but no value in attribute dictionary at %p, adding it\n", fqkey, dict);
     /* lookup key in schema */
 
-    /* FIXME: this should move to a 'ensure_default_entry' function that is shared */
     struct mstro_schema_attribute_ *decl;
     status = mstro_schema_lookup_attribute(dict->schema, fqkey, &decl);
     if(status!=MSTRO_OK) {
@@ -2043,21 +2174,24 @@ mstro_attribute_dict_set(mstro_attribute_dict dict, const char *key,
      * (needs to be reentrant!) built with a schema-typeval.peg */
     if(!tdecl->parsed_type) {
       ERR("Parsed type not available\n");
-    return MSTRO_UNIMPL;
+      return MSTRO_UNIMPL;
     }
 
     /* create fresh entry */
     status = mstro_attribute_entry_create(decl->key_symbol, &entry);
-    if(status!=MSTRO_OK)
+    if(status!=MSTRO_OK) {
+      ERR("Failed to create new entry for |%s|\n", fqkey);
       goto BAILOUT;
+    }
 
     entry->kind = tdecl->parsed_type->kind;
-    status = mstro_attribute_entry__set_size(entry, entry->kind);
-    if(status!=MSTRO_OK)
-      goto BAILOUT;
     
     HASH_ADD(hh, dict->dict, key, sizeof(mstro_symbol), entry);
+    DEBUG("Added fresh entry for |%s|\n", fqkey);
+  } else {
+    DEBUG("Found existing entry for |%s|, updating\n", fqkey);
   }
+            
 
   /* some lax type checking */
   if(valtype) {
@@ -2113,6 +2247,27 @@ mstro_attribute_dict_set(mstro_attribute_dict dict, const char *key,
   entry->val = val;
   entry->user_owned_val = true;
   
+  status = mstro_attribute_entry__set_size(entry, entry->kind);
+  if(status!=MSTRO_OK) {
+    ERR("Failed to set entry size for |%s|\n", fqkey);
+    goto BAILOUT;
+  }
+
+  DEBUG("Set value on entry |%s|\n", fqkey);
+
+  switch(entry->kind) {
+    case MSTRO_STP_STR:
+    case MSTRO_STP_REGEX:
+      /* adjust value size */
+      entry->valsize = strlen(entry->val);
+      break;
+    case MSTRO_STP_BLOB:
+      entry->valsize = ((mstro_blob*)entry->val)->len;
+      break;
+    default:
+      break;
+  }
+  
   status=MSTRO_OK;
   
 BAILOUT:
diff --git a/attributes/symtab.c b/attributes/symtab.c
index 265e873d..d2686731 100644
--- a/attributes/symtab.c
+++ b/attributes/symtab.c
@@ -32,7 +32,7 @@ struct mstro_symtab_entry_key {
   const void *permanent_address;  /**< set to the address of constants
                                    * that get interned. NULL for 'not
                                    * permanent' */
-  char fullname[0];               /**< the fully-qualified name;
+  char fullname[];                /**< the fully-qualified name;
                                    * auto-extended at mstro_intern
                                    * time */
 };
-- 
GitLab