almost everything working...
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index 0bd481b..bc21df9 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -132,7 +132,7 @@
 }
 
 
-inline static bool InBoundMode(const QCBORDecodeNesting *pNesting)
+inline static bool DecodeNesting_InBoundedMode(const QCBORDecodeNesting *pNesting)
 {
    return pNesting->pCurrent->uType & QCBOR_NEST_TYPE_IS_BOUND;
 }
@@ -166,9 +166,8 @@
 inline static bool
 DecodeNesting_AtEnd(const QCBORDecodeNesting *pNesting)
 {
-   if(pNesting->pCurrentMap && InBoundMode(pNesting)) {
+   if(pNesting->pCurrentMap && DecodeNesting_InBoundedMode(pNesting)) {
       if(pNesting->pCurrentMap->uCount == 0) {
-         // TODO: won't work for indefinite length
          // In map mode and consumed all items, so it is the end
          return true;
       } else {
@@ -189,16 +188,9 @@
    //return pNesting->pCurrent->uType & QCBOR_NEST_TYPE_IS_INDEFINITE;
 }
 
-inline static int
-DecodeNesting_InMapMode(const QCBORDecodeNesting *pNesting)
-{
-   return (bool)InBoundMode(pNesting);
-}
-
-
 
 inline static uint8_t
-DecodeNesting_GetMapModeLevel(QCBORDecodeNesting *pNesting)
+DecodeNesting_GetBoundedModeLevel(QCBORDecodeNesting *pNesting)
 {
    // Check in DecodeNesting_Descend and never having
    // QCBOR_MAX_ARRAY_NESTING > 255 gaurantees cast is safe
@@ -215,30 +207,27 @@
    return CBOR_MAJOR_TYPE_MAP == pNesting->pCurrent->uMajorType;
 }
 
-// Process a break. This will either ascend the nesting or error out
-inline static QCBORError
-DecodeNesting_BreakAscend(QCBORDecodeNesting *pNesting)
+
+// return 1 if closed out an array or map
+inline static int
+DecodeNesting_Decrement(QCBORDecodeNesting *pNesting)
 {
-   // breaks must always occur when there is nesting
-   if(DecodeNesting_IsAtTop(pNesting)) {
-      return QCBOR_ERR_BAD_BREAK;
+   pNesting->pCurrent->uCount--;
+
+   if(pNesting->pCurrent->uCount != 0) {
+      return 0;
    }
 
-   // breaks can only occur when the map/array is indefinite length
-   if(!DecodeNesting_IsIndefiniteLength(pNesting)) {
-      return QCBOR_ERR_BAD_BREAK;
-   }
-
-   if(InBoundMode(pNesting)) {
-      return QCBOR_SUCCESS;
-   }
-
-   // if all OK, the break reduces the level of nesting
-   pNesting->pCurrent--;
-
-   return QCBOR_SUCCESS;
+   return 1;
 }
 
+inline static void
+DecodeNesting_Ascend(QCBORDecodeNesting *pNesting)
+{
+   pNesting->pCurrent--;
+}
+
+
 // Called on every single item except breaks including decode of a map/array
 /* Decrements the map/array counter if possible. If decrement
  closed out a map or array, then level up in nesting and decrement
@@ -266,7 +255,7 @@
          break;
       }
       
-      if(InBoundMode(pNesting)) {
+      if(DecodeNesting_InBoundedMode(pNesting)) {
          // In map mode the level-up must be done explicitly
          break;
       }
@@ -299,13 +288,14 @@
 DecodeNesting_Exit(QCBORDecodeNesting *pNesting)
 {
    pNesting->pCurrentMap->uType &= ~QCBOR_NEST_TYPE_IS_BOUND;
+   // TODO: rewrite this. Gonna need a lot of code to ascend through indefinite length maps and arrays
    pNesting->pCurrent = pNesting->pCurrentMap - 1; // TODO error check
    
    DecodeNesting_DecrementCount(pNesting);
 
    while(1) {
       pNesting->pCurrentMap--;
-      if(InBoundMode(pNesting)) {
+      if(DecodeNesting_InBoundedMode(pNesting)) {
          break;
       }
       if(pNesting->pCurrentMap == &(pNesting->pMapsAndArrays[0])) {
@@ -314,46 +304,9 @@
    }
 }
 
-// Called on every map/array
-QCBORError
-DecodeNesting_Descend(QCBORDecodeNesting *pNesting, QCBORItem *pItem)
-{
-   QCBORError nReturn = QCBOR_SUCCESS;
-
-   if(pItem->val.uCount == 0) {
-      // Nothing to do for empty definite lenth arrays. They are just are
-      // effectively the same as an item that is not a map or array
-      goto Done;
-      // Empty indefinite length maps and arrays are handled elsewhere
-   }
-
-   // Error out if arrays is too long to handle
-   if(pItem->val.uCount != UINT16_MAX && pItem->val.uCount > QCBOR_MAX_ITEMS_IN_ARRAY) {
-      nReturn = QCBOR_ERR_ARRAY_TOO_LONG;
-      goto Done;
-   }
-
-   // Error out if nesting is too deep
-   if(pNesting->pCurrent >= &(pNesting->pMapsAndArrays[QCBOR_MAX_ARRAY_NESTING])) {
-      nReturn = QCBOR_ERR_ARRAY_NESTING_TOO_DEEP;
-      goto Done;
-   }
-
-   // The actual descend
-   pNesting->pCurrent++;
-
-   // Record a few details for this nesting level
-   pNesting->pCurrent->uMajorType = pItem->uDataType;
-   pNesting->pCurrent->uCount     = pItem->val.uCount;
-   pNesting->pCurrent->uSaveCount = pItem->val.uCount;
-   pNesting->pCurrent->uMapMode   = 0;
-
-Done:
-   return nReturn;;
-}
 
 inline static QCBORError
-DecodeNesting_Descend2(QCBORDecodeNesting *pNesting, uint8_t uQCBORType, uint64_t uCount, uint32_t uEndOffset)
+DecodeNesting_Descend(QCBORDecodeNesting *pNesting, uint8_t uQCBORType, uint64_t uCount, uint32_t uEndOffset)
 {
    QCBORError nReturn = QCBOR_SUCCESS;
 
@@ -437,8 +390,6 @@
 
 Done:
    return uReturn;
-
-
 }
 
 
@@ -1183,6 +1134,30 @@
 }
 
 
+static QCBORError
+NextIsBreak(UsefulInputBuf *pUIB, bool *pbNextIsBreak)
+{
+   *pbNextIsBreak = false;
+   if(UsefulInputBuf_BytesUnconsumed(pUIB) != 0) {
+      // TODO: use the Peek method?
+      QCBORItem Peek;
+      size_t uPeek = UsefulInputBuf_Tell(pUIB);
+      QCBORError uReturn = GetNext_Item(pUIB, &Peek, NULL);
+      if(uReturn != QCBOR_SUCCESS) {
+         return uReturn;
+      }
+      if(Peek.uDataType != QCBOR_TYPE_BREAK) {
+        // It is not a break, rewind so it can be processed normally.
+        UsefulInputBuf_Seek(pUIB, uPeek);
+      } else {
+         *pbNextIsBreak = true;
+      }
+   }
+   
+   return QCBOR_SUCCESS;
+}
+
+
 /*
  Public function, see header qcbor/qcbor_decode.h file
  TODO: correct this comment
@@ -1190,9 +1165,7 @@
 static QCBORError
 QCBORDecode_GetNextMapOrArray(QCBORDecodeContext *me, QCBORItem *pDecodedItem)
 {
-   // Stack ptr/int: 2, QCBORItem : 64
-
-   QCBORError nReturn;
+   QCBORError uReturn;
    /* === First figure out if at the end of traversal === */
 
    /* Case 1. Out of bytes to consume.
@@ -1219,7 +1192,7 @@
 
     This handles the end of CBOR sequences as well as non-sequences. */
    if(UsefulInputBuf_BytesUnconsumed(&(me->InBuf)) == 0 && DecodeNesting_IsAtTop(&(me->nesting))) {
-      nReturn = QCBOR_ERR_NO_MORE_ITEMS;
+      uReturn = QCBOR_ERR_NO_MORE_ITEMS;
       goto Done;
    }
 
@@ -1241,22 +1214,22 @@
     is at the end of the map */
 
 
-   // This is to handle map and array mode
+   // This is to handle bounded mode
    if(DecodeNesting_AtEnd(&(me->nesting))) {
-      nReturn = QCBOR_ERR_NO_MORE_ITEMS;
+      uReturn = QCBOR_ERR_NO_MORE_ITEMS;
       goto Done;
    }
 
    /* === Not at the end; get another item === */
-   nReturn = GetNext_MapEntry(me, pDecodedItem);
-   if(nReturn) {
+   uReturn = GetNext_MapEntry(me, pDecodedItem);
+   if(uReturn) {
       goto Done;
    }
 
    // Breaks ending arrays/maps are always processed at the end of this function.
    // They should never show up here.
    if(pDecodedItem->uDataType == QCBOR_TYPE_BREAK) {
-      nReturn = QCBOR_ERR_BAD_BREAK;
+      uReturn = QCBOR_ERR_BAD_BREAK;
       goto Done;
    }
 
@@ -1268,17 +1241,24 @@
    // ascend if decrements are enough to close out a definite length array/map
    if(IsMapOrArray(pDecodedItem->uDataType) && pDecodedItem->val.uCount != 0) {
       // If the new item is array or map, the nesting level descends
-      nReturn = DecodeNesting_Descend2(&(me->nesting), pDecodedItem->uDataType, pDecodedItem->val.uCount, 0L);
+      uReturn = DecodeNesting_Descend(&(me->nesting), pDecodedItem->uDataType, pDecodedItem->val.uCount, 0L);
       // Maps and arrays do count in as items in the map/array that encloses
       // them so a decrement needs to be done for them too, but that is done
       // only when all the items in them have been processed, not when they
       // are opened with the exception of an empty map or array.
+      if(uReturn != QCBOR_SUCCESS) {
+         goto Done;
+      }
    }
 
-   if(!IsMapOrArray(pDecodedItem->uDataType) || pDecodedItem->val.uCount == 0) {
-      // Decrement happns for non-aggregate and empty aggregate
-
-      // TODO: what about empty indefinite?
+   if(!IsMapOrArray(pDecodedItem->uDataType) ||
+      pDecodedItem->val.uCount == 0 || pDecodedItem->val.uCount == UINT16_MAX) {
+      /* The following cases are handled here:
+         - A non-aggregate like an integer or string
+         - An empty definite length map or array
+         - An indefinite length map or array that might be empty or might not.
+       */
+      
 
 
       /* === Figure out if item got closed out maps or arrays === */
@@ -1307,53 +1287,83 @@
       // If the count in the enclosing map/array goes to zero, that
       // triggers a decrement in the map/array above that and
       // an ascend in nesting level.
+      /* If the just consumed item is at the end of a map or
+       array ascend in the nesting tracking. That may
+       in turn may be the end of the above nesting level
+       and so on up to the end of the whole encoded CBOR.
+       
+       Each level could be a definite or indefinte length
+       map or array. These are handled very differently.
+       
+      */
       while(1) {
-         if(DecodeNesting_IsIndefiniteLength(&(me->nesting))) {
-            while(UsefulInputBuf_BytesUnconsumed(&(me->InBuf))) {
-                // Peek forward one item to see if it is a break.
-                QCBORItem Peek;
-                size_t uPeek = UsefulInputBuf_Tell(&(me->InBuf));
-                nReturn = GetNext_Item(&(me->InBuf), &Peek, NULL);
-                if(nReturn != QCBOR_SUCCESS) {
-                   goto Done;
-                }
-                if(Peek.uDataType != QCBOR_TYPE_BREAK) {
-                   // It is not a break, rewind so it can be processed normally.
-                   UsefulInputBuf_Seek(&(me->InBuf), uPeek);
-                   goto Done2;
-                }
-                // It is a break. Ascend one nesting level.
-                // The break is consumed.
-                nReturn = DecodeNesting_BreakAscend(&(me->nesting));
-                if(nReturn != QCBOR_SUCCESS) {
-                   // break occured outside of an indefinite length array/map
-                   goto Done;
-                }
+         
+         /* three cases:
+           1) at top
+           2) not at top and in indefinite
+           3) not at top and not in indefinite */
+         
+         if(!DecodeNesting_IsAtTop(&(me->nesting)) && !DecodeNesting_IsIndefiniteLength(&(me->nesting))) {
+            /* The simple cases of a non-aggregate type or an empty
+               definite-length array. Decrement the counter and
+               if nothing was closed out, all is done.
+               case 3
+             */
+            if(!DecodeNesting_Decrement(&(me->nesting))) {
+               // Done leveling up
+               break;
             }
-            goto Done2; // Out of bytes to decode
+            
          } else {
-            if(DecodeNesting_DecrementCount(&(me->nesting)) == 0) {
-               /* There was no level up. Did not consume to the
-                end of an array or map so done with the work. */
-               goto Done2;
+            /* cases 1 and 2 */
+            /* either at the top or in an indefinite length map / array */
+            /* The cases of an
+               1) indefinite length level
+               2) a sequence (at the top and not in error)
+               3) the error case of extra breaks after reaching the top level
+             For all of these we have to see if next is a break.
+             */
+            bool bIsBreak = false;
+            uReturn = NextIsBreak(&(me->InBuf), &bIsBreak);
+            if(uReturn != QCBOR_SUCCESS) {
+               goto Done;
+            }
+            
+            if(bIsBreak) {
+               if(DecodeNesting_IsAtTop(&(me->nesting))) {
+                  uReturn = QCBOR_ERR_BAD_BREAK;
+                  goto Done;
+               } else {
+                  // A break ending an indefinite length array
+                  // continue with loop and ascend
+               }
+               
+            } else {
+               // Just an item in either an indefinte length amap/arry or in sequence at top level.
+               break;
             }
          }
-      }
+         
+         if(DecodeNesting_InBoundedMode(&(me->nesting))) {
+            /* Can't ascend because we are in bounded mode where ascent has to be explicit */
+            /* Set the count to zero for indefinite length arrays to indicate cursor is at end of bounded map / array */
+            me->nesting.pCurrent->uCount = 0;
+            break;
+         }
 
-   Done2:
-      if(nReturn) {
-         goto Done;
+         DecodeNesting_Ascend(&(me->nesting));
       }
    }
 
 
+
    /* === Tell the caller the nest level of the next item === */
 
    // Tell the caller what level is next. This tells them what maps/arrays
    // were closed out and makes it possible for them to reconstruct
    // the tree with just the information returned by GetNext
    // TODO: pull this into DecodeNesting_GetLevel
-   if(InBoundMode(&(me->nesting)) && me->nesting.pCurrent->uCount == 0) {
+   if(DecodeNesting_InBoundedMode(&(me->nesting)) && me->nesting.pCurrent->uCount == 0) {
       // At end of a map / array in map mode, so next nest is 0 to
       // indicate this end.
       pDecodedItem->uNextNestLevel = 0;
@@ -1362,11 +1372,11 @@
    }
 
 Done:
-   if(nReturn != QCBOR_SUCCESS) {
+   if(uReturn != QCBOR_SUCCESS) {
       // Make sure uDataType and uLabelType are QCBOR_TYPE_NONE
       memset(pDecodedItem, 0, sizeof(QCBORItem));
    }
-   return nReturn;
+   return uReturn;
 }
 
 
@@ -1406,7 +1416,6 @@
 
 
 /*
- Mostly just assign the right data type for the bignum.
  */
 inline static QCBORError DecodeUUID(QCBORItem *pDecodedItem)
 {
@@ -1419,6 +1428,58 @@
 
 
 /*
+ */
+inline static QCBORError DecodeURI(QCBORItem *pDecodedItem)
+{
+   if(pDecodedItem->uDataType != QCBOR_TYPE_TEXT_STRING) {
+      return QCBOR_ERR_BAD_OPT_TAG;
+   }
+   pDecodedItem->uDataType = QCBOR_TYPE_URI;
+   return QCBOR_SUCCESS;
+}
+
+
+inline static QCBORError DecodeRegex(QCBORItem *pDecodedItem)
+{
+   if(pDecodedItem->uDataType != QCBOR_TYPE_TEXT_STRING) {
+      return QCBOR_ERR_BAD_OPT_TAG;
+   }
+   pDecodedItem->uDataType = QCBOR_TYPE_REGEX;
+   return QCBOR_SUCCESS;
+}
+
+
+inline static QCBORError DecodeB64URL(QCBORItem *pDecodedItem)
+{
+   if(pDecodedItem->uDataType != QCBOR_TYPE_TEXT_STRING) {
+      return QCBOR_ERR_BAD_OPT_TAG;
+   }
+   pDecodedItem->uDataType = QCBOR_TYPE_BASE64URL;
+   return QCBOR_SUCCESS;
+}
+
+
+inline static QCBORError DecodeB64(QCBORItem *pDecodedItem)
+{
+   if(pDecodedItem->uDataType != QCBOR_TYPE_TEXT_STRING) {
+      return QCBOR_ERR_BAD_OPT_TAG;
+   }
+   pDecodedItem->uDataType = QCBOR_TYPE_BASE64;
+   return QCBOR_SUCCESS;
+}
+
+
+inline static QCBORError DecodeMIME(QCBORItem *pDecodedItem)
+{
+   if(pDecodedItem->uDataType != QCBOR_TYPE_TEXT_STRING &&
+      pDecodedItem->uDataType != QCBOR_TYPE_BYTE_STRING) {
+      return QCBOR_ERR_BAD_OPT_TAG;
+   }
+   pDecodedItem->uDataType = QCBOR_TYPE_MIME;
+   return QCBOR_SUCCESS;
+}
+
+/*
  The epoch formatted date. Turns lots of different forms of encoding
  date into uniform one
  */
@@ -1633,7 +1694,33 @@
 
          case CBOR_TAG_BIN_UUID:
          nReturn = DecodeUUID(pDecodedItem);
+         break;
+            
+         case CBOR_TAG_URI:
+         nReturn = DecodeURI(pDecodedItem);
+         break;
 
+         case CBOR_TAG_REGEX:
+         nReturn = DecodeRegex(pDecodedItem);
+         break;
+
+
+         case CBOR_TAG_B64:
+         nReturn = DecodeB64(pDecodedItem);
+         break;
+
+
+         case CBOR_TAG_B64URL:
+         nReturn = DecodeB64URL(pDecodedItem);
+         break;
+            
+         case CBOR_TAG_MIME:
+         case CBOR_TAG_BINARY_MIME:
+// TODO: should binary and text MIME be distinguished?
+         nReturn = DecodeMIME(pDecodedItem);
+         break;
+
+            
          default:
          // A tag that is not understood
          // A successful exit from the loop
@@ -2155,7 +2242,7 @@
    QCBORError  uReturn;
 
    // TODO: what if pre-order cursor is not at the same level as map? This should be OK.
-   if(!DecodeNesting_InMapMode(&(pMe->nesting))) {
+   if(!DecodeNesting_InBoundedMode(&(pMe->nesting))) {
       return QCBOR_ERR_NOT_ENTERED;
    }
 
@@ -2168,7 +2255,7 @@
    * deeply nested and this should handle both definite
    * and indefinite length maps and arrays, so this
    * adds some complexity. */
-   const uint8_t uMapNestLevel = DecodeNesting_GetMapModeLevel(&(pMe->nesting));
+   const uint8_t uMapNestLevel = DecodeNesting_GetBoundedModeLevel(&(pMe->nesting));
 
    uint_fast8_t uNextNestLevel;
    
@@ -2622,7 +2709,7 @@
    UsefulInputBuf_SetBufferLen(&(pMe->InBuf), uEndOffset);
 
    // TODO: comment on cast
-   pMe->uLastError = (uint8_t)DecodeNesting_Descend2(&(pMe->nesting), QCBOR_TYPE_BYTE_STRING, UINT16_MAX, (uint32_t)uEndOffset);
+   pMe->uLastError = (uint8_t)DecodeNesting_Descend(&(pMe->nesting), QCBOR_TYPE_BYTE_STRING, UINT16_MAX, (uint32_t)uEndOffset);
 }