bounded indefinite length arrays starting to work
diff --git a/README.md b/README.md
index 5ebc8f6..113c542 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,11 @@
   highly portable. No #ifdefs or compiler options need to be set for it
   to run correctly.
 
-**Focused on C / native data representation** – Simpler code because
+**Focused on C / native data representation** – Careful conversion
+  of CBOR data types in to C data types, carefully handling
+  over and underflow, strict typing and such to so the caller
+  doesn't have to worry so much about this and so code
+  using QCBOR passes static analyzers easier.  Simpler code because
   there is no support for encoding/decoding to/from JSON, pretty
   printing, diagnostic notation... Only encoding from native C
   representations and decoding to native C representations is supported.
diff --git a/inc/qcbor/qcbor_private.h b/inc/qcbor/qcbor_private.h
index fa66be9..0f754f5 100644
--- a/inc/qcbor/qcbor_private.h
+++ b/inc/qcbor/qcbor_private.h
@@ -152,7 +152,8 @@
        Item tracking can either be for definite or indefinite length
        maps / arrays. For definite lengths, the total count and
        current position is tracked. For indefinite length, uTotalCount
-       is UINT16_MAX and there is no tracking in this data structure.
+       is QCBOR_COUNT_INDICATES_INDEFINITE_LENGTH (UINT16_MAX) and
+       there is no tracking in this data structure.
 
        This also records whether a level is bounded or not.  All
        byte-count tracked levels (the top-level sequence and
@@ -162,7 +163,7 @@
        by uStartOffset not being UINT32_MAX.
        */
       /*
-       If uLevelType can put in a separatly indexed array, the union /
+       If uLevelType can put in a separately indexed array, the union /
        struct will be 8 bytes rather than 9 and a lot of wasted
        padding for alignment will be saved.
        */
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index 515f58f..810a814 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -181,7 +181,7 @@
       /* Not a map or array */
       return false;
    }
-   if(pNesting->pCurrent->u.ma.uCountCursor != QCBOR_COUNT_INDICATES_INDEFINITE_LENGTH) {
+   if(pNesting->pCurrent->u.ma.uCountTotal != QCBOR_COUNT_INDICATES_INDEFINITE_LENGTH) {
       /* Not indefinte length */
       return false;
    }
@@ -197,7 +197,7 @@
       /* Not a map or array */
       return false;
    }
-   if(pNesting->pCurrent->u.ma.uCountCursor == QCBOR_COUNT_INDICATES_INDEFINITE_LENGTH) {
+   if(pNesting->pCurrent->u.ma.uCountTotal == QCBOR_COUNT_INDICATES_INDEFINITE_LENGTH) {
       /* Is indefinite */
       return false;
    }
@@ -258,7 +258,7 @@
       /* Not in bounded mode. */
       return false;
    }
-   if(pNesting->pCurrentBounded->u.ma.uCountCursor == QCBOR_COUNT_INDICATES_INDEFINITE_LENGTH) {
+   if(pNesting->pCurrentBounded->u.ma.uCountTotal == QCBOR_COUNT_INDICATES_INDEFINITE_LENGTH) {
       /* An indefinite length map or array */
       return false;
    }
@@ -270,6 +270,34 @@
    return true;
 }
 
+inline static bool
+DecodeNesting_IsAtEndOfBoundedFarf(const QCBORDecodeNesting *pNesting)
+{
+   if(pNesting->pCurrentBounded == NULL) {
+      /* No bounded map or array or... set up. */
+      return false;
+   }
+   if(pNesting->pCurrent->uLevelType == QCBOR_TYPE_BYTE_STRING) {
+      /* Not a map or array */
+      return false;
+   }
+   if(!DecodeNesting_IsCurrentBounded(pNesting)) { // TODO: pCurrent vs pCurrentBounded
+      /* Not in bounded mode. */
+      return false;
+   }
+#if 0
+   if(pNesting->pCurrentBounded->u.ma.uCountTotal == QCBOR_COUNT_INDICATES_INDEFINITE_LENGTH) {
+      /* An indefinite length map or array */
+      return false;
+   }
+   if(pNesting->pCurrentBounded->u.ma.uCountCursor != 0) {
+      /* Count is not zero, still unconsumed items. */
+      return false;
+   }
+#endif
+   /* All checks passed, got to the end of a definite length map or array */
+   return true;
+}
 
 inline static bool
 DecodeNesting_IsEndOfDefiniteLengthMapOrArray(QCBORDecodeNesting *pNesting)
@@ -430,8 +458,9 @@
    return uError;;
 }
 
-
-static inline void
+#include <stdlib.h>
+// TODO: use or get rid of
+void
 DecodeNesting_ZeroDefiniteLengthCount(QCBORDecodeNesting *pNesting)
 {
    pNesting->pCurrent->u.ma.uCountCursor = 0;
@@ -480,19 +509,68 @@
 
 
 #include <stdio.h>
+
+const char *TypeStr(uint8_t type)
+{
+   switch(type) {
+      case QCBOR_TYPE_MAP: return "  map";
+      case QCBOR_TYPE_ARRAY: return "array";
+      case QCBOR_TYPE_BYTE_STRING: return " bstr";
+      default: return " --- ";
+   }
+}
+
+static char buf[20]; // Not thread safe, but that is OK
+const char *CountString(uint16_t uCount, uint16_t uTotal)
+{
+   if(uTotal == QCBOR_COUNT_INDICATES_INDEFINITE_LENGTH) {
+      strcpy(buf, "indefinite");
+   } else {
+      sprintf(buf, "%d/%d", uCount, uTotal);
+   }
+   return buf;
+}
+
 void DecodeNesting_Print(QCBORDecodeNesting *pNesting, UsefulInputBuf *pBuf, const char *szName)
 {
-   printf("---%s--%d--%d--\narrow is current bounded level\nLevel   Count   Type S-Offset  SaveCount  Bounded E-Offset\n",
+   printf("---%s--%d/%d--\narrow is current bounded level\n",
           szName,
           (uint32_t)pBuf->cursor,
           (uint32_t)pBuf->UB.len);
+
+   printf("Level   Type       Count  Offsets \n");
    for(int i = 0; i < QCBOR_MAX_ARRAY_NESTING; i++) {
       if(&(pNesting->pMapsAndArrays[i]) > pNesting->pCurrent) {
          break;
       }
 
-      // TODO: print different for BS and MA
-      printf("%2s %2d   %5d  %s   %6u      %5d        %d    %5d\n",
+      printf("%2s %2d  %s  ",
+             pNesting->pCurrentBounded == &(pNesting->pMapsAndArrays[i]) ? "->": "  ",
+             i,
+             TypeStr(pNesting->pMapsAndArrays[i].uLevelType));
+
+      if(pNesting->pMapsAndArrays[i].uLevelType == QCBOR_TYPE_BYTE_STRING) {
+         printf("               %5d   %5d",
+                pNesting->pMapsAndArrays[i].u.bs.uEndOfBstr,
+                pNesting->pMapsAndArrays[i].u.bs.uPreviousEndOffset);
+
+      } else {
+         printf("%10.10s  ",
+                CountString(pNesting->pMapsAndArrays[i].u.ma.uCountCursor,
+                            pNesting->pMapsAndArrays[i].u.ma.uCountTotal));
+         if(pNesting->pMapsAndArrays[i].u.ma.uStartOffset != UINT32_MAX) {
+            printf("Bounded start: %u",pNesting->pMapsAndArrays[i].u.ma.uStartOffset);
+         }
+      }
+
+      printf("\n");
+         /*
+          TYPE
+          count/total
+          start offset/unbound
+          */
+
+/*      printf("%2s %2d   %5d  %s   %6u      %5d        %d    %5d\n",
              pNesting->pCurrentBounded == &(pNesting->pMapsAndArrays[i]) ? "->": "  ",
              i,
              pNesting->pMapsAndArrays[i].u.ma.uCountCursor,
@@ -505,7 +583,7 @@
              0, // TODO: fix this
              pNesting->pMapsAndArrays[i].u.bs.uPreviousEndOffset
              );
-
+*/
    }
    printf("\n");
 }
@@ -1286,7 +1364,7 @@
  end of an array or map that can be closed out. That
  may in turn close out another map or array.
 */
-static QCBORError NestLevelAscender(QCBORDecodeContext *pMe)
+static QCBORError NestLevelAscender(QCBORDecodeContext *pMe, bool *pbHitBound)
 {
    QCBORError uReturn;
 
@@ -1333,6 +1411,10 @@
       /* But ascent in bounded mode is only by explicit call to QCBORDecode_ExitBoundedMode() */
       if(DecodeNesting_IsCurrentBounded(&(pMe->nesting))) {
          /* Set the count to zero for definite length arrays to indicate cursor is at end of bounded map / array */
+         if(pbHitBound) {
+            *pbHitBound = true;
+         }
+         // Used for definite and indefinite to signal end
          DecodeNesting_ZeroDefiniteLengthCount(&(pMe->nesting));
          break;
       }
@@ -1387,6 +1469,7 @@
     array. The check for the end of an indefinite length array is
     later.
     */
+   // TODO: this doesn't work for bounded indefinite length maps and arrays
    if(DecodeNesting_IsAtEndOfBoundedDefiniteLenMapOrArray(&(me->nesting))) {
       uReturn = QCBOR_ERR_NO_MORE_ITEMS;
       goto Done;
@@ -1436,6 +1519,8 @@
       }
    }
 
+   bool bHitBounded = false;
+
    if(!QCBORItem_IsMapOrArray(pDecodedItem) ||
        QCBORItem_IsEmptyDefiniteLengthMapOrArray(pDecodedItem) ||
        QCBORItem_IsIndefiniteLengthMapOrArray(pDecodedItem)) {
@@ -1450,7 +1535,7 @@
        length map/array. If the end of the map/array was reached, then
        it ascends nesting levels, possibly all the way to the top level.
        */
-      uReturn = NestLevelAscender(me);
+      uReturn = NestLevelAscender(me, &bHitBounded);
       if(uReturn) {
          goto Done;
       }
@@ -1463,7 +1548,7 @@
     reconstruct the tree with just the information returned in
     a QCBORItem.
    */
-   if(DecodeNesting_IsAtEndOfBoundedDefiniteLenMapOrArray(&(me->nesting))) {
+   if(DecodeNesting_IsAtEndOfBoundedFarf(&(me->nesting)) && bHitBounded) {
       /* At end of a bounded map/array; uNextNestLevel 0 to indicate this */
       pDecodedItem->uNextNestLevel = 0;
    } else {
@@ -1484,7 +1569,6 @@
  */
 inline static QCBORError DecodeDateString(QCBORItem *pDecodedItem)
 {
-   // Stack Use: UsefulBuf 1 16
    if(pDecodedItem->uDataType != QCBOR_TYPE_TEXT_STRING) {
       return QCBOR_ERR_BAD_OPT_TAG;
    }
@@ -1502,7 +1586,6 @@
  */
 static QCBORError DecodeDateEpoch(QCBORItem *pDecodedItem)
 {
-   // Stack usage: 1
    QCBORError nReturn = QCBOR_SUCCESS;
 
    pDecodedItem->val.epochDate.fSecondsFraction = 0;
@@ -2643,7 +2726,7 @@
    }
 
    /* Need to get the current pre-order nesting level and cursor to be
-      at the first item in the map/array just entered.
+      at the map/array about to be entered.
 
     Also need to current map nesting level and start cursor to
     be at the right place.
@@ -2789,7 +2872,7 @@
     reached.  It may do nothing, or ascend all the way to the top
     level.
     */
-   uErr = NestLevelAscender(pMe);
+   uErr = NestLevelAscender(pMe, NULL);
    if(uErr != QCBOR_SUCCESS) {
       goto Done;
    }
diff --git a/test/qcbor_decode_tests.c b/test/qcbor_decode_tests.c
index fd2bb97..c74c429 100644
--- a/test/qcbor_decode_tests.c
+++ b/test/qcbor_decode_tests.c
@@ -540,6 +540,26 @@
    0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63,
    0x73 };
 
+// Same as above, but with indefinite lengths.
+static const uint8_t pValidMapIndefEncoded[] = {
+0xbf, 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, 0x9f, 0x67, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31,
+0x67, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32, 0xff, 0x6c, 0x6d,
+0x61, 0x70, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x6d, 0x61,
+0x70, 0xbf, 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, 0xff, 0xff};
+
+
 static int32_t ParseOrderedArray(const uint8_t *pEncoded,
                                  size_t nLen,
                                  int64_t *pInt1,
@@ -646,29 +666,29 @@
 /* Same as above, but with indefinte lengths */
 static uint8_t sEmptiesIndef[] = {
 0x9F,
-0x00,
-0x9F,
-0xFF,
-0x9F,
-0x9F,
-0xFF,
-0x9F,
-0x00,
-0xFF,
-0xBF,
-0xFF,
-0xBF,
-0x01,
-0xBF,
-0xFF,
-0x02,
-0xBF,
-0xFF,
-0x03,
-0x9F,
-0xFF,
-0xFF,
-0xFF,
+   0x00,
+   0x9F,
+      0xFF,
+   0x9F,
+      0x9F,
+         0xFF,
+      0x9F,
+         0x00,
+         0xFF,
+      0xBF,
+         0xFF,
+      0xBF,
+         0x01,
+         0xBF,
+            0xFF,
+         0x02,
+         0xBF,
+            0xFF,
+         0x03,
+         0x9F,
+            0xFF,
+         0xFF,
+      0xFF,
    0xFF};
 
 
@@ -3915,95 +3935,118 @@
 }
 
 
+int32_t EMap(UsefulBufC input)
+{
+     QCBORItem Item1, Item2, Item3;
+     int64_t nDecodedInt1, nDecodedInt2;
+     UsefulBufC B1, B2, S1, S2, S3;
+
+     QCBORDecodeContext DCtx;
+     QCBORError nCBORError;
+
+     QCBORDecode_Init(&DCtx, input, 0);
+
+     QCBORDecode_EnterMap(&DCtx);
+
+        QCBORDecode_GetInt64InMapSZ(&DCtx, "first integer",  &nDecodedInt1);
+
+        QCBORDecode_EnterMapFromMapSZ(&DCtx, "map in a map");
+           QCBORDecode_GetInt64InMapSZ(&DCtx,  "another int",  &nDecodedInt2);
+           QCBORDecode_GetBytesInMapSZ(&DCtx, "bytes 1",  &B1);
+           QCBORDecode_GetBytesInMapSZ(&DCtx, "bytes 2",  &B2);
+           QCBORDecode_GetTextInMapSZ(&DCtx, "text 2",  &S1);
+        QCBORDecode_ExitMap(&DCtx);
+
+        QCBORDecode_EnterArrayFromMapSZ(&DCtx, "an array of two strings");
+           QCBORDecode_GetNext(&DCtx, &Item1);
+           QCBORDecode_GetNext(&DCtx, &Item2);
+           if(QCBORDecode_GetNext(&DCtx, &Item3) != QCBOR_ERR_NO_MORE_ITEMS) {
+              return -400;
+           }
+        QCBORDecode_ExitArray(&DCtx);
+
+        // Parse the same array again using GetText() instead of GetItem()
+        QCBORDecode_EnterArrayFromMapSZ(&DCtx, "an array of two strings");
+           QCBORDecode_GetText(&DCtx, &S2);
+           QCBORDecode_GetText(&DCtx, &S3);
+           if(QCBORDecode_GetError(&DCtx) != QCBOR_SUCCESS) {
+              return 5000;
+           }
+      /*     QCBORDecode_GetText(&DCtx, &S3);
+           if(QCBORDecode_GetAndResetError(&DCtx) != QCBOR_ERR_NO_MORE_ITEMS) {
+               return 5001;
+           } */
+
+        QCBORDecode_ExitArray(&DCtx);
+
+     QCBORDecode_ExitMap(&DCtx);
+
+     nCBORError = QCBORDecode_Finish(&DCtx);
+
+     if(nCBORError) {
+        return (int32_t)nCBORError;
+     }
+
+     if(nDecodedInt1 != 42) {
+        return 1001;
+     }
+
+     if(nDecodedInt2 != 98) {
+        return 1002;
+     }
+
+     if(Item1.uDataType != QCBOR_TYPE_TEXT_STRING ||
+        UsefulBuf_Compare(Item1.val.string, UsefulBuf_FromSZ("string1"))){
+        return 1003;
+     }
+
+     if(Item1.uDataType != QCBOR_TYPE_TEXT_STRING ||
+        UsefulBuf_Compare(Item2.val.string, UsefulBuf_FromSZ("string2"))){
+        return 1004;
+     }
+
+     if(UsefulBuf_Compare(S1, UsefulBuf_FromSZ("lies, damn lies and statistics"))){
+        return 1005;
+     }
+
+     if(UsefulBuf_Compare(B1, UsefulBuf_FromSZ("xxxx"))){
+        return 1006;
+     }
+
+     if(UsefulBuf_Compare(B2, UsefulBuf_FromSZ("yyyy"))){
+        return 1007;
+     }
+
+     if(UsefulBuf_Compare(S2, UsefulBuf_FromSZ("string1"))){
+        return 1008;
+     }
+
+     if(UsefulBuf_Compare(S3, UsefulBuf_FromSZ("string2"))){
+        return 1009;
+     }
+
+   return 0;
+}
+
 int32_t EnterMapTest()
 {
-   QCBORItem Item1, Item2, Item3;
-   int64_t nDecodedInt1, nDecodedInt2;
-   UsefulBufC B1, B2, S1, S2, S3;
-
+   QCBORItem Item1;
    QCBORDecodeContext DCtx;
-   QCBORError nCBORError;
 
-   QCBORDecode_Init(&DCtx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pValidMapEncoded), 0);
- 
-   QCBORDecode_EnterMap(&DCtx);
+   int32_t nReturn;
 
-      QCBORDecode_GetInt64InMapSZ(&DCtx, "first integer",  &nDecodedInt1);
-   
-      QCBORDecode_EnterMapFromMapSZ(&DCtx, "map in a map");
-         QCBORDecode_GetInt64InMapSZ(&DCtx,  "another int",  &nDecodedInt2);
-         QCBORDecode_GetBytesInMapSZ(&DCtx, "bytes 1",  &B1);
-         QCBORDecode_GetBytesInMapSZ(&DCtx, "bytes 2",  &B2);
-         QCBORDecode_GetTextInMapSZ(&DCtx, "text 2",  &S1);
-      QCBORDecode_ExitMap(&DCtx);
-   
-      QCBORDecode_EnterArrayFromMapSZ(&DCtx, "an array of two strings");
-         QCBORDecode_GetNext(&DCtx, &Item1);
-         QCBORDecode_GetNext(&DCtx, &Item2);
-         if(QCBORDecode_GetNext(&DCtx, &Item3) != QCBOR_ERR_NO_MORE_ITEMS) {
-            return -400;
-         }
-      QCBORDecode_ExitArray(&DCtx);
-
-      // Parse the same array again using GetText() instead of GetItem()
-      QCBORDecode_EnterArrayFromMapSZ(&DCtx, "an array of two strings");
-         QCBORDecode_GetText(&DCtx, &S2);
-         QCBORDecode_GetText(&DCtx, &S3);
-         if(QCBORDecode_GetError(&DCtx) != QCBOR_SUCCESS) {
-            return 5000;
-         }
-         QCBORDecode_GetText(&DCtx, &S3);
-         if(QCBORDecode_GetAndResetError(&DCtx) != QCBOR_ERR_NO_MORE_ITEMS) {
-             return 5001;
-         }
-
-      QCBORDecode_ExitArray(&DCtx);
-   
-   QCBORDecode_ExitMap(&DCtx);
-   
-   nCBORError = QCBORDecode_Finish(&DCtx);
-   
-   if(nCBORError) {
-      return (int32_t)nCBORError;
-   }
-   
-   if(nDecodedInt1 != 42) {
-      return 1001;
+   (void)pValidMapIndefEncoded;
+   nReturn = EMap( UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pValidMapIndefEncoded));
+   if(nReturn) {
+      return nReturn + 20000;
    }
 
-   if(nDecodedInt2 != 98) {
-      return 1002;
-   }
-   
-   if(Item1.uDataType != QCBOR_TYPE_TEXT_STRING ||
-      UsefulBuf_Compare(Item1.val.string, UsefulBuf_FromSZ("string1"))){
-      return 1003;
-   }
-   
-   if(Item1.uDataType != QCBOR_TYPE_TEXT_STRING ||
-      UsefulBuf_Compare(Item2.val.string, UsefulBuf_FromSZ("string2"))){
-      return 1004;
-   }
-      
-   if(UsefulBuf_Compare(S1, UsefulBuf_FromSZ("lies, damn lies and statistics"))){
-      return 1005;
-   }
+   nReturn = EMap( UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pValidMapEncoded));
+    if(nReturn) {
+       return nReturn;
+    }
 
-   if(UsefulBuf_Compare(B1, UsefulBuf_FromSZ("xxxx"))){
-      return 1006;
-   }
 
-   if(UsefulBuf_Compare(B2, UsefulBuf_FromSZ("yyyy"))){
-      return 1007;
-   }
-   
-   if(UsefulBuf_Compare(S2, UsefulBuf_FromSZ("string1"))){
-      return 1008;
-   }
-   
-   if(UsefulBuf_Compare(S3, UsefulBuf_FromSZ("string2"))){
-      return 1009;
-   }
 
    // These tests confirm the cursor is at the right place after entering a map or array