Add tests from CAF exactly as they came from CAF. They are not yet being called and run
diff --git a/test/qcbor_decode_tests.c b/test/qcbor_decode_tests.c
new file mode 100644
index 0000000..2328912
--- /dev/null
+++ b/test/qcbor_decode_tests.c
@@ -0,0 +1,1534 @@
+/*==============================================================================
+Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of The Linux Foundation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+==============================================================================*/
+
+#include "qcbor.h"
+#include "qcbor_decode_tests.h"
+#include <stdio.h>
+#include <strings.h>
+#include <float.h>
+#include <math.h>
+#include <stdlib.h>
+
+
+// TODO: test other than the normal decoder mode
+
+static void printencoded(const char *szLabel, const uint8_t *pEncoded, size_t nLen)
+{
+   if(szLabel) {
+      printf("%s ", szLabel);
+   }
+   
+   int i;
+   for(i = 0; i < nLen; i++) {
+      uint8_t Z = pEncoded[i];
+      printf("%02x ", Z);
+   }
+   printf("\n");
+
+   fflush(stdout);
+}
+
+
+// TODO: -- add a test for counting the top level items and adding it back in with AddRaw()
+
+
+static const uint8_t pExpectedEncodedInts[] = {
+   0x98, 0x2f, 0x3b, 0x7f, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff, 0xff, 0x3b, 0x00, 0x00, 0x00, 0x01,
+   0x00, 0x00, 0x00, 0x00, 0x3a, 0xff, 0xff, 0xff,
+   0xff, 0x3a, 0xff, 0xff, 0xff, 0xfe, 0x3a, 0xff,
+   0xff, 0xff, 0xfd, 0x3a, 0x7f, 0xff, 0xff, 0xff,
+   0x3a, 0x7f, 0xff, 0xff, 0xfe, 0x3a, 0x00, 0x01,
+   0x00, 0x01, 0x3a, 0x00, 0x01, 0x00, 0x00, 0x39,
+   0xff, 0xff, 0x39, 0xff, 0xfe, 0x39, 0xff, 0xfd,
+   0x39, 0x01, 0x00, 0x38, 0xff, 0x38, 0xfe, 0x38,
+   0xfd, 0x38, 0x18, 0x37, 0x36, 0x20, 0x00, 0x00,
+   0x01, 0x16, 0x17, 0x18, 0x18, 0x18, 0x19, 0x18,
+   0x1a, 0x18, 0xfe, 0x18, 0xff, 0x19, 0x01, 0x00,
+   0x19, 0x01, 0x01, 0x19, 0xff, 0xfe, 0x19, 0xff,
+   0xff, 0x1a, 0x00, 0x01, 0x00, 0x00, 0x1a, 0x00,
+   0x01, 0x00, 0x01, 0x1a, 0x00, 0x01, 0x00, 0x02,
+   0x1a, 0x7f, 0xff, 0xff, 0xff, 0x1a, 0x7f, 0xff,
+   0xff, 0xff, 0x1a, 0x80, 0x00, 0x00, 0x00, 0x1a,
+   0x80, 0x00, 0x00, 0x01, 0x1a, 0xff, 0xff, 0xff,
+   0xfe, 0x1a, 0xff, 0xff, 0xff, 0xff, 0x1b, 0x00,
+   0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1b,
+   0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+   0x1b, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+   0xff, 0xff};
+
+
+
+
+
+
+
+
+
+// return CBOR error or -1 if type of value doesn't match
+
+static int IntegerValuesParseTestInternal(QCBORDecodeContext *pDCtx)
+{
+   QCBORItem          Item;
+   int nCBORError;
+   
+   if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_ARRAY)
+      return -1;
+
+   if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 || // Todo; fix this for 32-bit machines
+      Item.val.uint64 != -9223372036854775807LL - 1)
+      return -1;
+
+   if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.uint64 != -4294967297)
+      return -1;
+   
+   if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.uint64 != -4294967296)
+      return -1;
+   
+   if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.uint64 != -4294967295)
+      return -1;
+   
+   if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.uint64 != -4294967294)
+      return -1;
+   
+   
+   if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != -2147483648)
+      return -1;
+  
+   if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != -2147483647)
+      return -1;
+   
+   if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != -65538)
+      return  -1;
+   
+   if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != -65537)
+      return  -1;
+   
+   if((nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != -65536)
+      return  -1;
+
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != -65535)
+      return  -1;
+
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != -65534)
+      return  -1;
+
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != -257)
+      return  -1;
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != -256)
+      return  -1;
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != -255)
+      return  -1;
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != -254)
+      return  -1;
+   
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != -25)
+      return  -1;
+
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != -24)
+      return  -1;
+
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != -23)
+      return  -1;
+
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != -1)
+      return  -1;
+
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 0)
+      return  -1;
+
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 0)
+      return  -1;
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 1)
+      return  -1;
+
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 22)
+      return  -1;
+
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 23)
+      return  -1;
+
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 24)
+      return  -1;
+
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 25)
+      return  -1;
+
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 26)
+      return  -1;
+
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 254)
+      return  -1;
+   
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 255)
+      return  -1;
+   
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 256)
+      return  -1;
+
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 257)
+      return  -1;
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 65534)
+      return  -1;
+
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 65535)
+      return  -1;
+
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 65536)
+      return  -1;
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 65537)
+      return  -1;
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 65538)
+      return  -1;
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 2147483647)
+      return  -1;
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 2147483647)
+      return  -1;
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 2147483648)
+      return  -1;
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 2147483649)
+      return  -1;
+  
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 4294967294)
+      return  -1;
+   
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 4294967295)
+      return  -1;
+   
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 4294967296)
+      return  -1;
+   
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 4294967297)
+      return  -1;
+
+   
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 9223372036854775807LL)
+      return  -1;
+   
+   
+   if((   nCBORError = QCBORDecode_GetNext(pDCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_UINT64 ||
+      Item.val.uint64 != 18446744073709551615ULL)
+      return  -1;
+   
+   
+   if(QCBORDecode_Finish(pDCtx) != QCBOR_SUCCESS) {
+      return -1;
+   }
+   
+   return 0;
+}
+
+
+/* 
+   Tests the decoding of lots of different integers sizes 
+   and values.  
+ 
+   Todo: test values 254, 255 and 256
+ 
+ */
+
+int IntegerValuesParseTest()
+{
+   int n;
+   QCBORDecodeContext DCtx;
+   
+   QCBORDecode_Init(&DCtx, (UsefulBufC){pExpectedEncodedInts, sizeof(pExpectedEncodedInts)}, QCBOR_DECODE_MODE_NORMAL);
+   
+   n = IntegerValuesParseTestInternal(&DCtx);
+   
+   return(n);
+}
+
+
+/*
+   Creates a simple CBOR array and returns it in *pEncoded. The array is malloced
+   and needs to be freed. This is used by several tests. 
+ 
+   Two of the inputs can be set. Two other items in the array are fixed.
+ 
+ */
+
+static int CreateSimpleArray(int nInt1, int nInt2, uint8_t **pEncoded, size_t *pEncodedLen)
+{
+   QCBOREncodeContext ECtx;
+   int nReturn = -1;
+   
+   *pEncoded = NULL;
+   *pEncodedLen = INT32_MAX;
+   
+   // loop runs CBOR encoding twice. First with no buffer to
+   // calucate the length so buffer can be allocated correctly,
+   // and last with the buffer to do the actual encoding
+   do {
+      QCBOREncode_Init(&ECtx, *pEncoded, *pEncodedLen);
+      QCBOREncode_OpenArray(&ECtx);
+      QCBOREncode_AddInt64(&ECtx, nInt1);
+      QCBOREncode_AddInt64(&ECtx, nInt2);
+      QCBOREncode_AddBytes(&ECtx, ((UsefulBufC) {"galactic", 8}));
+      QCBOREncode_AddBytes(&ECtx, ((UsefulBufC) {"haven token", 11}));
+      QCBOREncode_CloseArray(&ECtx);
+      
+      if(QCBOREncode_Finish(&ECtx, pEncodedLen))
+         goto Done;
+
+      if(*pEncoded != NULL) {
+         nReturn = 0;
+         goto Done;
+      }
+      *pEncoded = malloc(*pEncodedLen);
+      if(*pEncoded == NULL) {
+         nReturn = -1;
+         goto Done;
+      }
+      
+   } while(1);
+Done:
+   return (nReturn);
+   
+}
+
+
+
+/*
+ {"first integer": 42,
+  "an array of two strings": ["string1", "string2"], 
+  "map in a map": {
+      "bytes 1": h'78787878',
+      "bytes 2": h'79797979',
+      "another int": 98, "text 2": 
+      "lies, damn lies and statistics"}
+  }
+ */
+
+static uint8_t pValidMapEncoded[] = {
+   0xa3, 0x6d, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x18, 0x2a,
+   0x77, 0x61, 0x6e, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x77, 0x6f, 0x20,
+   0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x82, 0x67, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x67,
+   0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32, 0x6c, 0x6d, 0x61, 0x70, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20,
+   0x6d, 0x61, 0x70, 0xa4, 0x67, 0x62, 0x79, 0x74, 0x65, 0x73, 0x20, 0x31, 0x44, 0x78, 0x78, 0x78, 0x78,
+   0x67, 0x62, 0x79, 0x74, 0x65, 0x73, 0x20, 0x32, 0x44, 0x79, 0x79, 0x79, 0x79, 0x6b, 0x61, 0x6e, 0x6f,
+   0x74, 0x68, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x74, 0x18, 0x62, 0x66, 0x74, 0x65, 0x78, 0x74, 0x20, 0x32,
+   0x78, 0x1e, 0x6c, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x64, 0x61, 0x6d, 0x6e, 0x20, 0x6c, 0x69, 0x65, 0x73,
+   0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73 } ;
+
+
+
+
+
+
+
+static int ParseOrderedArray(const uint8_t *pEncoded, size_t nLen, int64_t *pInt1, int64_t *pInt2,  const uint8_t **pBuf3, size_t *pBuf3Len,  const uint8_t **pBuf4, size_t *pBuf4Len)
+{
+   QCBORDecodeContext DCtx;
+   QCBORItem          Item;
+   int                nReturn = -1; // assume error until success
+   
+   QCBORDecode_Init(&DCtx, (UsefulBufC){pEncoded, nLen}, QCBOR_DECODE_MODE_NORMAL);
+   
+   // Make sure the first thing is a map
+   if(QCBORDecode_GetNext(&DCtx, &Item) != 0 || Item.uDataType != QCBOR_TYPE_ARRAY)
+      goto Done;
+   
+   // First integer
+   if(QCBORDecode_GetNext(&DCtx, &Item) != 0 | Item.uDataType != QCBOR_TYPE_INT64)
+      goto Done;
+   *pInt1 = Item.val.int64;
+   
+   // Second integer
+   if(QCBORDecode_GetNext(&DCtx, &Item) != 0 || Item.uDataType != QCBOR_TYPE_INT64)
+      goto Done;
+   *pInt2 = Item.val.int64;
+   
+   // First string
+   if(QCBORDecode_GetNext(&DCtx, &Item) != 0 || Item.uDataType != QCBOR_TYPE_BYTE_STRING)
+      goto Done;
+   *pBuf3 = Item.val.string.ptr;
+   *pBuf3Len = Item.val.string.len;
+   
+   // Second string
+   if(QCBORDecode_GetNext(&DCtx, &Item) != 0 || Item.uDataType != QCBOR_TYPE_BYTE_STRING)
+      goto Done;
+   *pBuf4 = Item.val.string.ptr;
+   *pBuf4Len = Item.val.string.len;
+   
+   nReturn = 0;
+   
+Done:
+   return(nReturn);
+}
+
+
+
+int SimpleArrayTest()
+{
+   uint8_t *pEncoded;
+   size_t  nEncodedLen;
+   
+   int64_t i1, i2;
+   size_t i3, i4;
+   const uint8_t *s3, *s4;
+   
+   
+   if(CreateSimpleArray(23, 6000, &pEncoded, &nEncodedLen) < 0) {
+      return(-1);
+   }
+   
+   ParseOrderedArray(pEncoded, nEncodedLen, &i1, &i2, &s3, &i3, &s4, &i4);
+   
+   if(i1 != 23 ||
+      i2 != 6000 ||
+      i3 != 8 ||
+      i4 != 11 ||
+      bcmp("galactic", s3, 8) !=0 ||
+      bcmp("haven token", s4, 11) !=0) {
+      printf("SimpleArraryTest Failed\n");
+      return(-1);
+   }
+   
+   return(0);
+}
+
+
+static uint8_t s_pDeepArrays[] = {0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80};
+
+int ParseDeepArrayTest()
+{
+   QCBORDecodeContext DCtx;
+   int nReturn = 0;
+   int i;
+   
+   QCBORDecode_Init(&DCtx, (UsefulBufC){s_pDeepArrays, sizeof(s_pDeepArrays)}, QCBOR_DECODE_MODE_NORMAL);
+   
+   for(i = 0; i < 10; i++) {
+      QCBORItem Item;
+      
+      if(QCBORDecode_GetNext(&DCtx, &Item) != 0 ||
+         Item.uDataType != QCBOR_TYPE_ARRAY ||
+         Item.uNestingLevel != i) {
+         nReturn = -1;
+         break;
+      }
+   }
+   
+   return(nReturn);
+}
+
+
+
+static uint8_t s_pTooDeepArrays[] = {0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80};
+
+int ParseTooDeepArrayTest()
+{
+   QCBORDecodeContext DCtx;
+   int nReturn = 0;
+   int i;
+   QCBORItem Item;
+   
+   
+   QCBORDecode_Init(&DCtx, (UsefulBufC){s_pTooDeepArrays, sizeof(s_pTooDeepArrays)}, QCBOR_DECODE_MODE_NORMAL);
+   
+   for(i = 0; i < 10; i++) {
+      
+      if(QCBORDecode_GetNext(&DCtx, &Item) != 0 ||
+         Item.uDataType != QCBOR_TYPE_ARRAY ||
+         Item.uNestingLevel != i) {
+         nReturn = -1;
+         break;
+      }
+   }
+   
+   if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_ARRAY_NESTING_TOO_DEEP)
+      nReturn = -1;
+   
+   return(nReturn);
+}
+
+
+
+
+static uint8_t s_indefiniteLenString[] = { 0x7f, 0x65, 0x73, 0x74, 0x72, 0x65, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x67, 0xff};
+
+
+int UnsupportedCBORDecodeTest()
+{
+   QCBORDecodeContext DCtx;
+   QCBORItem Item;
+   
+   QCBORDecode_Init(&DCtx, (UsefulBufC){s_indefiniteLenString, sizeof(s_indefiniteLenString)}, QCBOR_DECODE_MODE_NORMAL);
+   if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_UNSUPPORTED)
+      return -1;
+   
+   return 0;
+}
+
+
+
+int ShortBufferParseTest()
+{
+   int nResult  = 0;
+   QCBORDecodeContext DCtx;
+   int num;
+   
+   for(num = sizeof(pExpectedEncodedInts)-1; num; num--) {
+      int n;
+      
+      QCBORDecode_Init(&DCtx, (UsefulBufC){pExpectedEncodedInts, num}, QCBOR_DECODE_MODE_NORMAL);
+      
+      n = IntegerValuesParseTestInternal(&DCtx);
+      
+      //printf("Len %d, result: %d\n", num, n);
+      
+      if(n != QCBOR_ERR_HIT_END) {
+         nResult = -1;
+         goto Done;
+      }
+   }
+Done:
+   return nResult;
+}
+
+
+int ShortBufferParseTest2()
+{
+   uint8_t *pEncoded;
+   int      nReturn;
+   size_t   nEncodedLen;
+   
+   int64_t i1, i2;
+   size_t i3, i4;
+   const uint8_t *s3, *s4;
+   
+   nReturn = 0;
+   
+   if(CreateSimpleArray(23, 6000, &pEncoded, &nEncodedLen) < 0) {
+      return(-1);
+   }
+   
+   //printencoded(pEncoded,  nEncodedLen);
+   
+   for(nEncodedLen--; nEncodedLen; nEncodedLen--) {
+      int nResult = ParseOrderedArray(pEncoded, (uint32_t)nEncodedLen, &i1, &i2, &s3, &i3, &s4, &i4);
+      if(nResult == 0) {
+         nReturn = -1;
+      }
+   }
+   
+   return(nReturn);
+}
+
+
+
+static int ParseMapTest1()
+{
+   QCBORDecodeContext DCtx;
+   QCBORItem Item;
+   int nCBORError;
+   
+   
+   QCBORDecode_Init(&DCtx, (UsefulBufC){pValidMapEncoded, sizeof(pValidMapEncoded)}, QCBOR_DECODE_MODE_NORMAL);
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_MAP ||
+      Item.val.uCount != 3)
+      return -1;
+   
+   
+ 
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
+      Item.label.string.len != 13 ||
+      Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 42 ||
+      memcmp(Item.label.string.ptr, "first integer", 13))
+      return -1;
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
+      Item.label.string.len != 23 ||
+      memcmp(Item.label.string.ptr, "an array of two strings", 23) ||
+      Item.uDataType != QCBOR_TYPE_ARRAY ||
+      Item.val.uCount != 2)
+      return -1;
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
+      Item.val.string.len != 7 ||
+      memcmp(Item.val.string.ptr, "string1", 7))
+      return -1;
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
+      Item.val.string.len != 7 ||
+      memcmp(Item.val.string.ptr, "string2", 7))
+      return -1;
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
+      Item.label.string.len != 12 ||
+      memcmp(Item.label.string.ptr, "map in a map", 12) ||
+      Item.uDataType != QCBOR_TYPE_MAP ||
+      Item.val.uCount != 4)
+      return -1;
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
+      Item.label.string.len != 7 ||
+      memcmp(Item.label.string.ptr, "bytes 1", 7)||
+      Item.uDataType != QCBOR_TYPE_BYTE_STRING ||
+      Item.val.string.len != 4 ||
+      memcmp(Item.val.string.ptr, "xxxx", 4))
+      return -1;
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
+      Item.label.string.len != 7 ||
+      memcmp(Item.label.string.ptr, "bytes 2", 7) ||
+      Item.uDataType != QCBOR_TYPE_BYTE_STRING ||
+      Item.val.string.len != 4 ||
+      memcmp(Item.val.string.ptr, "yyyy", 4))
+      return -1;
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
+      Item.label.string.len != 11 ||
+      memcmp(Item.label.string.ptr, "another int", 11) ||
+      Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 98)
+      return -1;
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
+      Item.label.string.len != 6 ||
+      memcmp(Item.label.string.ptr, "text 2", 6)||
+      Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
+      Item.val.string.len != 30 ||
+      memcmp(Item.val.string.ptr, "lies, damn lies and statistics", 30))
+      return -1;
+   
+   return 0;
+}
+
+
+
+/*
+ This test parses pValidMapEncoded and checks for extra bytes along the way
+ */
+static int ExtraBytesTest()
+{
+   QCBORDecodeContext DCtx;
+   QCBORItem Item;
+   int nCBORError;
+   
+   
+   QCBORDecode_Init(&DCtx, (UsefulBufC){pValidMapEncoded, sizeof(pValidMapEncoded)}, QCBOR_DECODE_MODE_NORMAL);
+   
+   if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_EXTRA_BYTES) {
+      return -1;
+   }
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_MAP ||
+      Item.val.uCount != 3)
+      return -1;
+
+   if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_EXTRA_BYTES) {
+      return -1;
+   }
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
+      Item.label.string.len != 13 ||
+      Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.uCount != 42 ||
+      memcmp(Item.label.string.ptr, "first integer", 13))
+      return -1;
+   
+   if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_EXTRA_BYTES) {
+      return -1;
+   }
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
+      Item.label.string.len != 23 ||
+      memcmp(Item.label.string.ptr, "an array of two strings", 23) ||
+      Item.uDataType != QCBOR_TYPE_ARRAY ||
+      Item.val.uCount != 2)
+      return -1;
+   
+   if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_EXTRA_BYTES) {
+      return -1;
+   }
+   
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
+      Item.val.string.len != 7 ||
+      memcmp(Item.val.string.ptr, "string1", 7))
+      return -1;
+   
+   if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_EXTRA_BYTES) {
+      return -1;
+   }
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
+      Item.val.string.len != 7 ||
+      memcmp(Item.val.string.ptr, "string2", 7))
+      return -1;
+ 
+   if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_EXTRA_BYTES) {
+      return -1;
+   }
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
+      Item.label.string.len != 12 ||
+      memcmp(Item.label.string.ptr, "map in a map", 12) ||
+      Item.uDataType != QCBOR_TYPE_MAP ||
+      Item.val.uCount != 4)
+      return -1;
+   
+   if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_EXTRA_BYTES) {
+      return -1;
+   }
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
+      Item.label.string.len != 7 ||
+      memcmp(Item.label.string.ptr, "bytes 1", 7)||
+      Item.uDataType != QCBOR_TYPE_BYTE_STRING ||
+      Item.val.string.len != 4 ||
+      memcmp(Item.val.string.ptr, "xxxx", 4))
+      return -1;
+   
+   if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_EXTRA_BYTES) {
+      return -1;
+   }
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
+      Item.label.string.len != 7 ||
+      memcmp(Item.label.string.ptr, "bytes 2", 7) ||
+      Item.uDataType != QCBOR_TYPE_BYTE_STRING ||
+      Item.val.string.len != 4 ||
+      memcmp(Item.val.string.ptr, "yyyy", 4))
+      return -1;
+   
+   if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_EXTRA_BYTES) {
+      return -1;
+   }
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
+      Item.label.string.len != 11 ||
+      memcmp(Item.label.string.ptr, "another int", 11) ||
+      Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.val.int64 != 98)
+      return -1;
+   
+   if(QCBORDecode_Finish(&DCtx) != QCBOR_ERR_EXTRA_BYTES) {
+      return -1;
+   }
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
+      Item.label.string.len != 6 ||
+      memcmp(Item.label.string.ptr, "text 2", 6)||
+      Item.uDataType != QCBOR_TYPE_TEXT_STRING ||
+      Item.val.string.len != 30 ||
+      memcmp(Item.val.string.ptr, "lies, damn lies and statistics", 30))
+      return -1;
+   
+   if(QCBORDecode_Finish(&DCtx) == QCBOR_ERR_EXTRA_BYTES) {
+      return -1;
+   }
+   
+   return 0;
+}
+
+
+
+
+int ParseMapTest()
+{
+   int n = ParseMapTest1();
+   
+   if(!n) {
+      n = ExtraBytesTest();
+   }
+   
+   return(n);
+}
+
+
+static uint8_t s_pSimpleValues[] = {0x8a, 0xf4, 0xf5, 0xf6, 0xf7, 0xff, 0xe0, 0xf3, 0xf8, 0x00, 0xf8, 0x13, 0xf8, 0x1f, 0xf8, 0x20, 0xf8, 0xff};
+
+int ParseSimpleTest()
+{
+   QCBORDecodeContext DCtx;
+   QCBORItem Item;
+   int nCBORError;
+   
+   
+   QCBORDecode_Init(&DCtx, ByteArrayLiteralToUsefulBufC(s_pSimpleValues), QCBOR_DECODE_MODE_NORMAL);
+   
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_ARRAY ||
+      Item.val.uCount != 10)
+      return -1;
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_FALSE)
+      return -1;
+
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_TRUE)
+      return -1;
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_NULL)
+      return -1;
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_UNDEF)
+      return -1;
+
+   // A break
+   if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_UNSUPPORTED)
+      return -1;
+
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_UKNOWN_SIMPLE || Item.val.uSimple != 0)
+      return -1;
+
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_UKNOWN_SIMPLE || Item.val.uSimple != 19)
+      return -1;
+
+   if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_INVALID_CBOR)
+      return -1;
+   
+   if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_INVALID_CBOR)
+      return -1;
+
+   if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_INVALID_CBOR)
+      return -1;
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_UKNOWN_SIMPLE || Item.val.uSimple != 32)
+      return -1;
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return nCBORError;
+   if(Item.uDataType != QCBOR_TYPE_UKNOWN_SIMPLE || Item.val.uSimple != 255)
+      return -1;
+   
+   return 0;
+   
+}
+
+
+struct FailInput {
+   UsefulBufC Input;
+   int nError;
+};
+
+
+struct FailInput  Failures[] = {
+   { {(uint8_t[]){0x18}, 1}, QCBOR_ERR_HIT_END },     // 1 byte integer missing the byte
+   { {(uint8_t[]){0x1c}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 28
+   { {(uint8_t[]){0x1d}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 29
+   { {(uint8_t[]){0x1e}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 30
+   { {(uint8_t[]){0x1f}, 1}, QCBOR_ERR_UNSUPPORTED }, // Indefinite length integer
+   { {(uint8_t[]){0x3c}, 1}, QCBOR_ERR_UNSUPPORTED }, // 1 byte integer missing the byte
+   { {(uint8_t[]){0x3d}, 1}, QCBOR_ERR_UNSUPPORTED }, // 1 byte integer missing the byte
+   { {(uint8_t[]){0x3e}, 1}, QCBOR_ERR_UNSUPPORTED }, // 1 byte integer missing the byte
+   { {(uint8_t[]){0x3f}, 1}, QCBOR_ERR_UNSUPPORTED }, // Indefinite length negative integer
+   { {(uint8_t[]){0x41}, 1}, QCBOR_ERR_HIT_END },     // Short byte string
+   { {(uint8_t[]){0x5c}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 28
+   { {(uint8_t[]){0x5f}, 1}, QCBOR_ERR_UNSUPPORTED }, // Indefinite length byte string
+   { {(uint8_t[]){0x61}, 1}, QCBOR_ERR_HIT_END },     // Short UTF-8 string
+   { {(uint8_t[]){0x7c}, 1}, QCBOR_ERR_UNSUPPORTED }, // Reserved additional info = 28
+   { {(uint8_t[]){0x7f}, 1}, QCBOR_ERR_UNSUPPORTED }, // Indefinite length UTF-8 string
+   { {(uint8_t[]){0xff}, 1}, QCBOR_ERR_UNSUPPORTED } , // break
+   { {(uint8_t[]){0xf8, 0x00}, 2}, QCBOR_ERR_INVALID_CBOR }, // An invalid encoding of a simple type
+   { {(uint8_t[]){0xf8, 0x1f}, 2}, QCBOR_ERR_INVALID_CBOR },  // An invalid encoding of a simple type
+   { {(uint8_t[]){0xc0, 0x00}, 2}, QCBOR_ERR_BAD_OPT_TAG },  // Text-based date, with an integer
+   { {(uint8_t[]){0xc1, 0x41, 0x33}, 3}, QCBOR_ERR_BAD_OPT_TAG },   // Epoch date, with an byte string
+   { {(uint8_t[]){0xc1, 0xc0, 0x00}, 3}, QCBOR_ERR_BAD_OPT_TAG },   // tagged as both epoch and string dates
+   { {(uint8_t[]){0xc2, 0x00}, 2}, QCBOR_ERR_BAD_OPT_TAG }  // big num tagged an int, not a byte string
+
+};
+
+
+void Dump(UsefulBufC Input, int x)
+{
+   char label[10];
+   
+   sprintf(label, "%d", x);
+   
+   printencoded(label, Input.ptr, Input.len);
+}
+
+
+int FailureTests()
+{
+   int nResult = 0;
+   
+   struct FailInput *pFEnd = &Failures[0] + sizeof(Failures)/sizeof(struct FailInput);
+   
+   for(struct FailInput *pF = &Failures[0]; pF < pFEnd ;pF++) {
+      QCBORDecodeContext DCtx;
+      QCBORItem Item;
+      int nCBORError;
+      
+      QCBORDecode_Init(&DCtx, pF->Input, QCBOR_DECODE_MODE_NORMAL);
+      
+      while(1) {
+         nCBORError = QCBORDecode_GetNext(&DCtx, &Item);
+         if(QCBOR_ERR_HIT_END == nCBORError) {
+            break;
+         }
+         if(nCBORError != pF->nError) {
+            nResult = 1;
+            // Dump(pF->Input, nCBORError);
+            break;
+         }
+      }
+   }
+   
+   {
+      QCBORDecodeContext DCtx;
+      QCBORItem Item;
+      int nCBORError;
+      
+      QCBORDecode_Init(&DCtx, ByteArrayLiteralToUsefulBufC(s_pSimpleValues), QCBOR_DECODE_MODE_NORMAL);
+
+      if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+         return nCBORError;
+      if(Item.uDataType != QCBOR_TYPE_ARRAY ||
+         Item.val.uCount != 10)
+         return -1;
+      
+      DCtx.InBuf.magic = 0; // Corrupt the UsefulInputBuf
+      
+      nCBORError = QCBORDecode_GetNext(&DCtx, &Item);
+      if(nCBORError != QCBOR_ERR_HIT_END)
+         return -1;
+   }
+   
+   
+   return nResult;
+}
+
+
+
+
+static void Recurser(uint8_t *pBuf, int nLen, int nLenMax)
+{
+   
+   if(nLen >= nLenMax) {
+      return;
+   }
+
+   //printf("__%d__%d__\n", nLen, nLenMax);
+   
+   for(int i = 0; i < 256; i++) {
+      pBuf[nLen] = i;
+      
+      QCBORDecodeContext DCtx;
+      QCBORItem Item;
+      int nCBORError;
+      
+      UsefulBufC Input = {pBuf, nLen+1};
+      
+      QCBORDecode_Init(&DCtx, Input, QCBOR_DECODE_MODE_NORMAL);
+      
+      while(1) {
+         nCBORError =  QCBORDecode_GetNext(&DCtx, &Item);
+         if(QCBOR_ERR_HIT_END == nCBORError) {
+            break;
+         }
+         if(nCBORError != QCBOR_SUCCESS) {
+            if(nCBORError != QCBOR_ERR_UNSUPPORTED && nCBORError != QCBOR_ERR_HIT_END && nCBORError != QCBOR_ERR_INVALID_CBOR) {
+               //Dump(Input, nCBORError);
+            }
+            break;
+         }
+      }
+      //Dump(Input, -1);
+
+   
+      Recurser(pBuf, nLen+1, nLenMax);
+   }
+}
+
+
+/*
+ Runs all possible input strings of a given length. This is set to 3 to make the test 
+ run in reasonable time.
+ Main point of this test is to not crash.
+ */
+
+int ComprehensiveInputTest()
+{
+   uint8_t pBuf[3]; // 3 keeps it running in reasonable time. 4 takes tens of minutes.
+   
+   Recurser(pBuf, 0, sizeof(pBuf));
+   
+   return 0;
+}
+
+
+static uint8_t s_DateTestInput[] = {
+   0xc0, // tag for string date
+   0x6a, '1','9','8','5','-','0','4','-','1','2', // Date string
+   
+   0xc1, // tag for epoch date
+   0x1a, 0x53, 0x72, 0x4E, 0x00, // Epoch date 1400000000; Tue, 13 May 2014 16:53:20 GMT
+
+   0xc1, 0xcf, 0xd8, 0xee, // Epoch date with extra tags
+   0x1a, 0x53, 0x72, 0x4E, 0x01,
+
+   0xc1, // tag for epoch date
+   0x1b, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // Too large integer
+   
+   0xc1, // tag for epoch date
+   0xfa, 0x3f, 0x8c, 0xcc, 0xcd, // double with value 1.1
+   
+   0xc1, // tag for epoch date
+   0xfa, 0x7f, 0x7f, 0xff, 0xff // 3.4028234663852886e+38 too large
+
+};
+
+
+// have to check float expected only to within an epsilon
+int CHECK_EXPECTED_DOUBLE(double val, double expected) {
+   
+   double diff = val - expected;
+   
+   diff = fabs(diff);
+   
+   return diff > 0.0000001;
+}
+
+
+int DateParseTest()
+{
+   QCBORDecodeContext DCtx;
+   QCBORItem Item;
+   int nCBORError;
+   
+   QCBORDecode_Init(&DCtx, ByteArrayLiteralToUsefulBufC(s_DateTestInput), QCBOR_DECODE_MODE_NORMAL);
+   
+   // String date
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return -1;
+   if(Item.uDataType != QCBOR_TYPE_DATE_STRING ||
+      UsefulBuf_Compare(Item.val.dateString, SZLiteralToUsefulBufC("1985-04-12"))){
+      return -1;
+   }
+
+   // Epoch date
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return -1;
+   if(Item.uDataType != QCBOR_TYPE_DATE_EPOCH ||
+      Item.val.epochDate.nSeconds != 1400000000 ||
+      Item.val.epochDate.fSecondsFraction != 0 ) {
+      return -1;
+   }
+   
+   // Epoch date with extra tags
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return -1;
+   if(Item.uDataType != QCBOR_TYPE_DATE_EPOCH ||
+      Item.val.epochDate.nSeconds != 1400000001 ||
+      Item.val.epochDate.fSecondsFraction != 0 ||
+      Item.uTagBits != (0x02 | (0x01 << 0x0f)) ||
+      Item.uTag != 0xee) {
+      return -1;
+   }
+   
+   // Epoch date that is too large for our representation
+   if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_DATE_OVERFLOW) {
+      return -1;
+   }
+   
+   // Epoch date in float format with fractional seconds
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return -1;
+   if(Item.uDataType != QCBOR_TYPE_DATE_EPOCH ||
+      Item.val.epochDate.nSeconds != 1 ||
+      CHECK_EXPECTED_DOUBLE(Item.val.epochDate.fSecondsFraction, 0.1 )) {
+      return -1;
+   }
+   
+   // Epoch date float that is too large for our representation
+   if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_DATE_OVERFLOW) {
+      return -1;
+   }
+   
+   // TODO: could use a few more tests with float, double, and half precsion and negative (but coverage is still pretty good)
+
+   return 0;
+}
+
+
+static uint8_t s_OptTestInput[] = {
+   0xd9, 0xd9, 0xf7, // CBOR magic number
+   0x81,
+   0xd8, 62, // 62 is decimal intentionally
+   0x00};
+
+int OptTagParseTest()
+{
+   QCBORDecodeContext DCtx;
+   QCBORItem Item;
+   int nCBORError;
+   
+   
+   QCBORDecode_Init(&DCtx, ByteArrayLiteralToUsefulBufC(s_OptTestInput), QCBOR_DECODE_MODE_NORMAL);
+   
+   //
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return -1;
+   if(Item.uDataType != QCBOR_TYPE_ARRAY ||
+      Item.uTagBits != QCBOR_TAGFLAG_CBOR_MAGIC) {
+      return -1;
+   }
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return -1;
+   if(Item.uDataType != QCBOR_TYPE_INT64 ||
+      Item.uTagBits != (0x01LL << 62) ||
+      Item.val.int64 != 0)
+      return -1;
+   
+   return 0;
+}
+
+
+
+   
+static uint8_t s_BigNumInput[] = {
+ 0x83,
+   0xC2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xC3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xA4,
+     0x63, 0x42, 0x4E, 0x2B,
+       0xC2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x18, 0x40,
+       0xC2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x63, 0x42, 0x4E, 0x2D,
+       0xC3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x38, 0x3F,
+       0xC3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+
+static uint8_t sBigNum[] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+
+int BignumParseTest()
+{
+   QCBORDecodeContext DCtx;
+   QCBORItem Item;
+   int nCBORError;
+   
+   QCBORDecode_Init(&DCtx, ByteArrayLiteralToUsefulBufC(s_BigNumInput), QCBOR_DECODE_MODE_NORMAL);
+   
+   
+   //
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return -1;
+   if(Item.uDataType != QCBOR_TYPE_ARRAY) {
+      return -1;
+   }
+   
+   // 
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return -1;
+   if(Item.uDataType != QCBOR_TYPE_POSBIGNUM ||
+      UsefulBuf_Compare(Item.val.bigNum, ByteArrayLiteralToUsefulBufC(sBigNum))){
+      return -1;
+   }
+
+   //
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return -1;
+   if(Item.uDataType != QCBOR_TYPE_NEGBIGNUM ||
+      UsefulBuf_Compare(Item.val.bigNum, ByteArrayLiteralToUsefulBufC(sBigNum))){
+      return -1;
+   }
+   
+   //
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return -1;
+   if(Item.uDataType != QCBOR_TYPE_MAP) {
+      return -1;
+   }
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return -1;
+   if(Item.uDataType != QCBOR_TYPE_POSBIGNUM ||
+      Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
+      UsefulBuf_Compare(Item.val.bigNum, ByteArrayLiteralToUsefulBufC(sBigNum))){
+      return -1;
+   }
+
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return -1;
+   if(Item.uDataType != QCBOR_TYPE_POSBIGNUM ||
+      Item.uLabelType != QCBOR_TYPE_INT64 ||
+      Item.label.int64 != 64 ||
+      UsefulBuf_Compare(Item.val.bigNum, ByteArrayLiteralToUsefulBufC(sBigNum))){
+      return -1;
+   }
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return -1;
+   if(Item.uDataType != QCBOR_TYPE_NEGBIGNUM ||
+      Item.uLabelType != QCBOR_TYPE_TEXT_STRING ||
+      UsefulBuf_Compare(Item.val.bigNum, ByteArrayLiteralToUsefulBufC(sBigNum))){
+      return -1;
+   }
+   
+   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+      return -1;
+   if(Item.uDataType != QCBOR_TYPE_NEGBIGNUM ||
+      Item.uLabelType != QCBOR_TYPE_INT64 ||
+      Item.label.int64 != -64 ||
+      UsefulBuf_Compare(Item.val.bigNum, ByteArrayLiteralToUsefulBufC(sBigNum))){
+      return -1;
+   }
+   
+   return 0;
+}
+
+
+
+static int CheckItemWithIntLabel(QCBORDecodeContext *pCtx, uint8_t uDataType, uint8_t uNestingLevel, int64_t nLabel, QCBORItem *pItem)
+{
+   QCBORItem Item;
+   int nCBORError;
+   
+   if((nCBORError = QCBORDecode_GetNext(pCtx, &Item))) return -1;
+   if(Item.uDataType != uDataType) return -1;
+   if(uNestingLevel > 0) {
+      if(Item.uLabelType != QCBOR_TYPE_INT64 &&  Item.uLabelType != QCBOR_TYPE_UINT64) return -1;
+      if(Item.uLabelType == QCBOR_TYPE_INT64) {
+         if(Item.label.int64 != nLabel) return -1;
+      } else  {
+         if(Item.label.uint64 != nLabel) return -1;
+      }
+   }
+   if(Item.uNestingLevel != uNestingLevel) return -1;
+   
+   if(pItem) {
+      *pItem = Item;
+   }
+   return 0;
+}
+
+
+/*
+// cbor.me decoded output
+{
+    -23: {
+        -20: {
+            -18: "Organization",
+            -17: "SSG",
+            -15: "Confusion",
+            -16: "San Diego",
+            -14: "US"
+        },
+        -19: {
+            -11: {
+                -9: -7
+            },
+            -10: '\u0001\u0002\u0003\u0004\u0005\u0006\a\b\t\n'
+        }
+    },
+    -22: {
+        -5: -3
+    }
+}
+ */
+
+static uint8_t s_CSRInput[] = {
+   0xa2, 0x36, 0xa2, 0x33, 0xa5, 0x31, 0x6c, 0x4f,
+   0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74,
+   0x69, 0x6f, 0x6e, 0x30, 0x63, 0x53, 0x53, 0x47,
+   0x2e, 0x69, 0x43, 0x6f, 0x6e, 0x66, 0x75, 0x73,
+   0x69, 0x6f, 0x6e, 0x2f, 0x69, 0x53, 0x61, 0x6e,
+   0x20, 0x44, 0x69, 0x65, 0x67, 0x6f, 0x2d, 0x62,
+   0x55, 0x53, 0x32, 0xa2, 0x2a, 0xa1, 0x28, 0x26,
+   0x29, 0x4a, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+   0x07, 0x08, 0x09, 0x0a, 0x35, 0xa1, 0x24, 0x22};
+
+int NestedMapTest()
+{
+   QCBORDecodeContext DCtx;
+   
+   QCBORDecode_Init(&DCtx, ByteArrayLiteralToUsefulBufC(s_CSRInput), QCBOR_DECODE_MODE_NORMAL);
+   
+   if(CheckItemWithIntLabel(&DCtx, QCBOR_TYPE_MAP, 0, 0, NULL)) return -1;
+
+   if(CheckItemWithIntLabel(&DCtx, QCBOR_TYPE_MAP, 1, -23, NULL)) return -1;
+
+   if(CheckItemWithIntLabel(&DCtx, QCBOR_TYPE_MAP, 2, -20, NULL)) return -1;
+
+   if(CheckItemWithIntLabel(&DCtx, QCBOR_TYPE_TEXT_STRING, 3, -18, NULL)) return -1;
+   if(CheckItemWithIntLabel(&DCtx, QCBOR_TYPE_TEXT_STRING, 3, -17, NULL)) return -1;
+   if(CheckItemWithIntLabel(&DCtx, QCBOR_TYPE_TEXT_STRING, 3, -15, NULL)) return -1;
+   if(CheckItemWithIntLabel(&DCtx, QCBOR_TYPE_TEXT_STRING, 3, -16, NULL)) return -1;
+   if(CheckItemWithIntLabel(&DCtx, QCBOR_TYPE_TEXT_STRING, 3, -14, NULL)) return -1;
+
+   if(CheckItemWithIntLabel(&DCtx, QCBOR_TYPE_MAP, 2, -19, NULL)) return -1;
+   if(CheckItemWithIntLabel(&DCtx, QCBOR_TYPE_MAP, 3, -11, NULL)) return -1;
+   
+   if(CheckItemWithIntLabel(&DCtx, QCBOR_TYPE_INT64, 4, -9, NULL)) return -1;
+   if(CheckItemWithIntLabel(&DCtx, QCBOR_TYPE_BYTE_STRING, 3, -10, NULL)) return -1;
+   
+   if(CheckItemWithIntLabel(&DCtx, QCBOR_TYPE_MAP, 1, -22, NULL)) return -1;
+   if(CheckItemWithIntLabel(&DCtx, QCBOR_TYPE_INT64, 2, -5, NULL)) return -1;
+   
+   return 0;
+}
+
+
+
+
+
+   
+