example is mostly working
diff --git a/example.c b/example.c
index b07a76c..ca30c28 100644
--- a/example.c
+++ b/example.c
@@ -21,9 +21,9 @@
 typedef struct
 {
     UsefulBufC Manufacturer;
-    uint64_t uNumCylinders;
-    uint64_t uDisplacement;
-    uint64_t uHorsePower;
+    int64_t uNumCylinders;
+    int64_t uDisplacement;
+    int64_t uHorsePower;
     double uDesignedCompresion;
     struct {
         double uMeasuredCompression;
@@ -51,23 +51,29 @@
 
 UsefulBufC EncodeEngine(const Engine *pEngine, UsefulBuf Buffer)
 {
+    /* Initialize th encoder with the buffer big enough to hold the expected output.
+     If it is too small, QCBOREncode_Finish() will return an error. */
     QCBOREncodeContext EncodeCtx;
-
     QCBOREncode_Init(&EncodeCtx, Buffer);
+
+    /* Proceed output all the items, letting the internal error
+     tracking do its work. */
     QCBOREncode_OpenMap(&EncodeCtx);
     QCBOREncode_AddTextToMap(&EncodeCtx, "Manufacturer", pEngine->Manufacturer);
-    QCBOREncode_AddUInt64ToMap(&EncodeCtx, "NumCylinders", pEngine->uNumCylinders);
-    QCBOREncode_AddUInt64ToMap(&EncodeCtx, "Displacement", pEngine->uDisplacement);
-    QCBOREncode_AddUInt64ToMap(&EncodeCtx, "HorsePower", pEngine->uHorsePower);
+    QCBOREncode_AddInt64ToMap(&EncodeCtx, "NumCylinders", pEngine->uNumCylinders);
+    QCBOREncode_AddInt64ToMap(&EncodeCtx, "Displacement", pEngine->uDisplacement);
+    QCBOREncode_AddInt64ToMap(&EncodeCtx, "Horsepower", pEngine->uHorsePower);
     QCBOREncode_AddDoubleToMap(&EncodeCtx, "DesignedCompression", pEngine->uDesignedCompresion);
     QCBOREncode_OpenArrayInMap(&EncodeCtx, "Cylinders");
-    for(uint64_t i = 0 ; i < pEngine->uNumCylinders; i++) {
+    for(int64_t i = 0 ; i < pEngine->uNumCylinders; i++) {
         QCBOREncode_AddDouble(&EncodeCtx, pEngine->cylinders[i].uMeasuredCompression);
     }
     QCBOREncode_CloseArray(&EncodeCtx);
     QCBOREncode_AddBoolToMap(&EncodeCtx, "turbo", pEngine->bTurboCharged);
     QCBOREncode_CloseMap(&EncodeCtx);
 
+    /* Get the pointer and length of the encoded output. If there was
+     anny error it will be returned here. */
     UsefulBufC EncodedCBOR;
     QCBORError uErr;
     uErr = QCBOREncode_Finish(&EncodeCtx, &EncodedCBOR);
@@ -86,12 +92,12 @@
     QCBOREncode_Init(&EncodeCtx, Buffer);
     QCBOREncode_OpenMapIndefiniteLength(&EncodeCtx);
     QCBOREncode_AddTextToMap(&EncodeCtx, "Manufacturer", pEngine->Manufacturer);
-    QCBOREncode_AddUInt64ToMap(&EncodeCtx, "Displacement", pEngine->uDisplacement);
-    QCBOREncode_AddUInt64ToMap(&EncodeCtx, "HorsePower", pEngine->uHorsePower);
+    QCBOREncode_AddInt64ToMap(&EncodeCtx, "Displacement", pEngine->uDisplacement);
+    QCBOREncode_AddInt64ToMap(&EncodeCtx, "Horsepower", pEngine->uHorsePower);
     QCBOREncode_AddDoubleToMap(&EncodeCtx, "DesignedCompression", pEngine->uDesignedCompresion);
-    QCBOREncode_AddUInt64ToMap(&EncodeCtx, "NumCylinders", pEngine->uNumCylinders);
+    QCBOREncode_AddInt64ToMap(&EncodeCtx, "NumCylinders", pEngine->uNumCylinders);
     QCBOREncode_OpenArrayIndefiniteLengthInMap(&EncodeCtx, "Cylinders");
-    for(uint64_t i = 0 ; i < pEngine->uNumCylinders; i++) {
+    for(int64_t i = 0 ; i < pEngine->uNumCylinders; i++) {
         QCBOREncode_AddDouble(&EncodeCtx, pEngine->cylinders[i].uMeasuredCompression);
     }
     QCBOREncode_CloseArrayIndefiniteLength(&EncodeCtx);
@@ -109,41 +115,72 @@
 }
 
 
-/*
-A -- require all fields ; easiest code
-B -- all are optional; messiest code; should this be accommodate better?
-C -- some are optional; not too hard
 
-It is a protocol error to have the wrong type for a label.
+typedef enum  {
+    EngineSuccess,
+    CBORNotWellFormed,
+    TooManyCylinders,
+    EngineProtocolerror,
+    WrongNumberOfCylinders
+} EngineDecodeErrors;
 
- */
 
-QCBORError DecodeEngine(UsefulBufC EncodedEngine, Engine *pE)
+EngineDecodeErrors ConvertError(QCBORError uErr)
 {
+    EngineDecodeErrors uReturn;
+
+    switch(uErr)
+    {
+        case QCBOR_SUCCESS:
+            uReturn = EngineSuccess;
+            break;
+
+        case QCBOR_ERR_HIT_END:
+            uReturn = CBORNotWellFormed;
+            break;
+
+        default:
+            uReturn = EngineProtocolerror;
+            break;
+    }
+
+    return uReturn;
+}
+
+
+/*
+ Decode using the advanced decode features. This pulls in more
+ code from the QCBOR library, but is much simpler and
+ roughly mirrors the encoding implementation.
+ */
+EngineDecodeErrors DecodeEngine(UsefulBufC EncodedEngine, Engine *pE)
+{
+    QCBORError uErr;
     QCBORDecodeContext DecodeCtx;
 
     QCBORDecode_Init(&DecodeCtx, EncodedEngine, QCBOR_DECODE_MODE_NORMAL);
     QCBORDecode_EnterMap(&DecodeCtx);
     QCBORDecode_GetTextInMapSZ(&DecodeCtx, "Manufacturer", &(pE->Manufacturer));
-    QCBORDecode_GetUInt64InMapSZ(&DecodeCtx, "Displacement", &(pE->uDisplacement));
-    QCBORDecode_GetUInt64InMapSZ(&DecodeCtx, "HorsePower", &(pE->uHorsePower));
+    QCBORDecode_GetInt64InMapSZ(&DecodeCtx, "Displacement", &(pE->uDisplacement));
+    QCBORDecode_GetInt64InMapSZ(&DecodeCtx, "Horsepower", &(pE->uHorsePower));
     QCBORDecode_GetDoubleInMapSZ(&DecodeCtx, "DesignedCompression", &(pE->uDesignedCompresion));
     QCBORDecode_GetBoolInMapSZ(&DecodeCtx, "turbo", &(pE->bTurboCharged));
 
-    QCBORDecode_GetUInt64InMapSZ(&DecodeCtx, "NumCylinders", &(pE->uNumCylinders));
+    QCBORDecode_GetInt64InMapSZ(&DecodeCtx, "NumCylinders", &(pE->uNumCylinders));
 
     /* Must check error before referencing pE->uNumCylinders to be sure it
      is valid. If any of the above errored, it won't be valid. */
-    if(QCBORDecode_GetError(&DecodeCtx)) {
-        return 100; // TODO: more error processing
+    uErr = QCBORDecode_GetError(&DecodeCtx);
+    if(uErr != QCBOR_SUCCESS) {
+        goto Done;
     }
 
     if(pE->uNumCylinders > MAX_CYLINDERS) {
-        return 900;
+        return TooManyCylinders;
     }
 
     QCBORDecode_EnterArrayFromMapSZ(&DecodeCtx, "Cylinders");
-    uint64_t i = 0;
+    int64_t i = 0;
     while(1) {
         QCBORDecode_GetDouble(&DecodeCtx, &(pE->cylinders[i].uMeasuredCompression));
         i++;
@@ -154,12 +191,24 @@
     QCBORDecode_ExitArray(&DecodeCtx);
     QCBORDecode_ExitMap(&DecodeCtx);
 
-    QCBORError uErr = QCBORDecode_Finish(&DecodeCtx);
+    /* Catch the remainder of errors here */
+    uErr = QCBORDecode_Finish(&DecodeCtx);
 
-    return uErr;
+Done:
+    return ConvertError(uErr);
 }
 
-#if 0
+
+
+
+/*
+
+ - Match
+ - Error
+ - No match
+
+ */
+
 QCBORError CheckLabelAndType(const char *szLabel, uint8_t uQCBORType, QCBORItem *pItem)
 {
     if(pItem->uLabelType != QCBOR_TYPE_TEXT_STRING) {
@@ -168,23 +217,54 @@
 
     UsefulBufC Label = UsefulBuf_FromSZ(szLabel);
 
-    if(UsefulBuf_Compare(Label, pItem->val.string)) {
+    if(UsefulBuf_Compare(Label, pItem->label.string)) {
         return QCBOR_ERR_NOT_FOUND;
     }
 
-    if(pItem->uDataType != uQCBORType) {
+    if(pItem->uDataType != uQCBORType && uQCBORType != QCBOR_TYPE_ANY) {
         return QCBOR_ERR_UNEXPECTED_TYPE;
     }
 
     return QCBOR_SUCCESS;
 }
 
-void DecodeCylinders(QCBORDecodeContext *pDctx, Engine *pE, const QCBORItem *pItem)
-{
 
+EngineDecodeErrors DecodeCylinders(QCBORDecodeContext *pDecodeCtx,
+                                   Engine *pE,
+                                   const QCBORItem *pItem)
+{
+    int i = 0;
+    QCBORItem Item;
+
+    /* Loop getting all the items in the array */
+    do {
+        QCBORError uErr;
+
+        uErr = QCBORDecode_GetNext(pDecodeCtx, &Item);
+        if(uErr != QCBOR_SUCCESS) {
+            return CBORNotWellFormed;
+        }
+        if(Item.uDataType != QCBOR_TYPE_DOUBLE) {
+            return CBORNotWellFormed;
+        }
+
+        if(i < MAX_CYLINDERS) {
+            pE->cylinders[i].uMeasuredCompression = Item.val.dfnum;
+            i++;
+        }
+
+    } while (Item.uNextNestLevel == pItem->uNextNestLevel);
+
+    if(i != pE->uNumCylinders) {
+        return WrongNumberOfCylinders;
+    } else {
+        return EngineSuccess;
+    }
 }
 
-QCBORError DecodeEngineBasic(UsefulBufC EncodedEngine, Engine *pE)
+
+
+EngineDecodeErrors DecodeEngineBasic(UsefulBufC EncodedEngine, Engine *pE)
 {
     QCBORDecodeContext DecodeCtx;
 
@@ -192,54 +272,112 @@
 
     QCBORItem Item;
     QCBORError uErr;
+    EngineDecodeErrors uReturn;
+
 
     uErr = QCBORDecode_GetNext(&DecodeCtx, &Item);
     if(uErr != QCBOR_SUCCESS) {
+        uReturn = CBORNotWellFormed;
         goto Done;
     }
     if(Item.uDataType != QCBOR_TYPE_MAP) {
-        uErr = 100;
+        uReturn = CBORNotWellFormed;
         goto Done;
     }
 
     while(1) {
         uErr = QCBORDecode_GetNext(&DecodeCtx, &Item);
         if(uErr != QCBOR_SUCCESS) {
-            goto Done;
-        }
-        if(Item.uDataType != QCBOR_TYPE_MAP) {
-            uErr = 100;
-            goto Done;
-        }
-
-        if(CheckLabelAndType("Manufacturer", QCBOR_TYPE_TEXT_STRING, &Item )) {
-            if(Item.uDataType != QCBOR_TYPE_TEXT_STRING) {
-                return 99; // TODO: what to do on wrong type?
+            if(uErr == QCBOR_ERR_NO_MORE_ITEMS) {
+                break; /* Non-error exit from the loop */
             } else {
-                // TODO: copy string or change data type
+                uReturn = CBORNotWellFormed;
+                goto Done;
             }
+        }
 
-        } else if(CheckLabel("NumCylinders", &Item)) {
-          if(Item.uDataType != QCBOR_TYPE_INT64) {
-              return 99; // TODO: what to do on wrong type?
-          } else {
-              // TODO: what about overflow
-              pE->uNumCylinders = (uint8_t)Item.val.int64;
-              // TODO: copy string or change data type
-          }
-        } else if(CheckLabel("Cylinders", &Item)) {
+        uErr = CheckLabelAndType("Manufacturer", QCBOR_TYPE_TEXT_STRING, &Item);
+        if(uErr == QCBOR_SUCCESS) {
+            pE->Manufacturer = Item.val.string;
+            continue;
+        } else if(uErr != QCBOR_ERR_NOT_FOUND){
+            /* Maunfacturer field missing or badly formed */
+            return EngineProtocolerror;
+        } /* continue on and try for another match */
+
+
+
+        uErr = CheckLabelAndType("NumCylinders", QCBOR_TYPE_INT64, &Item);
+        if(uErr == QCBOR_SUCCESS) {
+            if(Item.val.int64 > MAX_CYLINDERS) {
+                return TooManyCylinders;
+            } else {
+                pE->uNumCylinders = (uint8_t)Item.val.int64;
+                continue;
+            }
+        } else if(uErr != QCBOR_ERR_NOT_FOUND){
+            /* Maunfacturer field missing or badly formed */
+            return EngineProtocolerror;
+        }
+
+        uErr = CheckLabelAndType("Cylinders", QCBOR_TYPE_ARRAY, &Item);
+        if(uErr == QCBOR_SUCCESS) {
             DecodeCylinders(&DecodeCtx, pE, &Item);
-         }
+            continue;
+        } else if(uErr != QCBOR_ERR_NOT_FOUND){
+            return EngineProtocolerror;
+        }
 
+        uErr = CheckLabelAndType("Displacement", QCBOR_TYPE_INT64, &Item);
+        if(uErr == QCBOR_SUCCESS) {
+            pE->uDisplacement = Item.val.int64;
+            continue;
+        } else if(uErr != QCBOR_ERR_NOT_FOUND){
+            return EngineProtocolerror;
+        }
+
+        uErr = CheckLabelAndType("Horsepower", QCBOR_TYPE_INT64, &Item);
+        if(uErr == QCBOR_SUCCESS) {
+            pE->uHorsePower = Item.val.int64;
+            continue;
+        } else if(uErr != QCBOR_ERR_NOT_FOUND){
+            return EngineProtocolerror;
+        }
+
+        uErr = CheckLabelAndType("DesignedCompression", QCBOR_TYPE_DOUBLE, &Item);
+        if(uErr == QCBOR_SUCCESS) {
+            pE->uDisplacement = Item.val.int64;
+            continue;
+        } else if(uErr != QCBOR_ERR_NOT_FOUND){
+            return EngineProtocolerror;
+        }
+
+        uErr = CheckLabelAndType("turbo", QCBOR_TYPE_ANY, &Item);
+           if(uErr == QCBOR_SUCCESS) {
+               if(Item.uDataType == QCBOR_TYPE_TRUE) {
+                   pE->bTurboCharged = true;
+               } else if(Item.uDataType == QCBOR_TYPE_FALSE) {
+                   pE->bTurboCharged = false;
+               } else {
+                   return EngineProtocolerror;
+               }
+               continue;
+           } else if(uErr != QCBOR_ERR_NOT_FOUND){
+               return EngineProtocolerror;
+           }
+
+
+        /* Some label data item that is not known
+         (could just ignore extras data items) */
+        return EngineProtocolerror;
     }
+    uReturn = EngineSuccess;
 
 
 Done:
-    return uErr;
+    return uReturn;
 }
 
-#endif
-
 
 
 
@@ -259,11 +397,18 @@
 
     printf("Engine Encoded in %zu bytes\n", EncodedEngine.len);
 
-    DecodeEngine(EncodedEngine, &DecodedEngine);
+    int x = (int)DecodeEngine(EncodedEngine, &DecodedEngine);
+    printf("Engine Decode Result: %d\n", x);
 
 
     InDefEncodedEngine = EncodeEngineIndefinteLen(&E, InDefEngineBuffer);
 
     printf("Indef Engine Encoded in %zu bytes\n", InDefEncodedEngine.len);
 
+    x = (int)DecodeEngine(InDefEncodedEngine, &DecodedEngine);
+    printf("Indef Engine Decode Result: %d\n", x);
+
+
+    x = (int)DecodeEngineBasic(EncodedEngine, &DecodedEngine);
+    printf("Engine Basic Decode Result: %d\n", x);
 }