more progress
diff --git a/inc/qcbor/qcbor_decode.h b/inc/qcbor/qcbor_decode.h
index 7b66d92..1357beb 100644
--- a/inc/qcbor/qcbor_decode.h
+++ b/inc/qcbor/qcbor_decode.h
@@ -245,12 +245,14 @@
 #define QCBOR_TYPE_URI           33 // TODO: implement this
 
 #define QCBOR_TYPE_MIME          34 // TODO: implement this
+#define QCBOR_TYPE_BINARY_MIME          35 // TODO: implement this
 
-#define QCBOR_TYPE_REGEX         35
 
-#define QCBOR_TYPE_BASE64URL     36
+#define QCBOR_TYPE_REGEX         36
 
-#define QCBOR_TYPE_BASE64        37
+#define QCBOR_TYPE_BASE64URL     37
+
+#define QCBOR_TYPE_BASE64        38
 
 
 #define QCBOR_TYPE_OPTTAG       254 // Used internally; never returned
@@ -1262,45 +1264,94 @@
 
 
 
+/*
+@brief Decode the next item as a date string
 
+@param[in] pCtx             The decode context.
+@param[in] uTagRequirement  One of @c QCBOR_TAGSPEC_MATCH_XXX.
+@param[out] pURI            The decoded URI.
 
+Error handling is like QCBORDecode_GetBytes().
 
-
-void QCBORDecode_GetBignum(QCBORDecodeContext *pCtx,  bool bMustBeTagged, UsefulBufC *pValue, bool *pbIsNegative);
-
-void QCBORDecode_GetBignumInMapN(QCBORDecodeContext *pCtx, int64_t nLabel, bool bMustBeTagged, UsefulBufC *pValue, bool *pbIsNegative);
-
-void QCBORDecode_GetBignumInMapSz(QCBORDecodeContext *pCtx, const char *szLabel, bool bMustBeTagged, UsefulBufC *pValue, bool *pbIsNegative);
-
-
-
-
+See XYZ for discussion on tag requirements.
+*/
 static void QCBORDecode_GetDateString(QCBORDecodeContext *pCtx, uint8_t uTagRequired, UsefulBufC *pValue);
 
 static void QCBORDecode_GetDateStringInMapN(QCBORDecodeContext *pCtx, uint8_t uTagRequired, int64_t nLabel, UsefulBufC *pValue);
 
-void QCBORDecode_GetDateStringInMapSZXX(QCBORDecodeContext *pCtx, uint8_t uTagRequired, const char *szLabel, UsefulBufC *pValue);
-
- void QCBORDecode_GetEpocDate(QCBORDecodeContext *pCtx, uint8_t uTagRequired, int64_t *puTime);
-
- static void QCBORDecode_GetEpochDateInMapN(QCBORDecodeContext *pCtx, uint8_t uTagRequired, int64_t nLabel, int64_t *puTime);
-
- void QCBORDecode_GetEpochDateInMapSZ(QCBORDecodeContext *pCtx, uint8_t uTagRequired, const char *szLabel, int64_t *puTime);
+void QCBORDecode_GetDateStringInMapSZXX(QCBORDecodeContext *pCtx,
+                                        uint8_t uTagRequired,
+                                        const char *szLabel,
+                                        UsefulBufC *pValue);
 
 
-static inline void QCBORDecode_GetURI(QCBORDecodeContext *pCtx,
-                                      uint8_t             uTagRequirement,
-                                      UsefulBufC         *pUUID);
 
-inline static void QCBORDecode_GetURIInMapN(QCBORDecodeContext *pCtx,
-                                            uint8_t             uTagRequirement,
-                                            int64_t             nLabel,
-                                            UsefulBufC         *pUUID);
+/*
+@brief Decode the next item as an epoch date.
 
-inline static void QCBORDecode_GetURIInMapSZ(QCBORDecodeContext *pCtx,
-                                             uint8_t             uTagRequirement,
-                                             const char *        szLabel,
-                                             UsefulBufC         *pUUID);
+@param[in] pCtx             The decode context.
+@param[in] uTagRequirement  One of @c QCBOR_TAGSPEC_MATCH_XXX.
+@param[out] pURI            The decoded URI.
+
+Error handling is like QCBORDecode_GetBytes().
+
+See XYZ for discussion on tag requirements.
+*/
+void QCBORDecode_GetEpocDate(QCBORDecodeContext *pCtx, uint8_t uTagRequired, int64_t *puTime);
+
+static void QCBORDecode_GetEpochDateInMapN(QCBORDecodeContext *pCtx, uint8_t uTagRequired, int64_t nLabel, int64_t *puTime);
+
+void QCBORDecode_GetEpochDateInMapSZ(QCBORDecodeContext *pCtx, uint8_t uTagRequired, const char *szLabel, int64_t *puTime);
+
+
+/*
+@brief Decode the next item as a big number.
+
+@param[in] pCtx             The decode context.
+@param[in] uTagRequirement  One of @c QCBOR_TAGSPEC_MATCH_XXX.
+@param[out] pURI            The decoded URI.
+
+Error handling is like QCBORDecode_GetBytes().
+
+See XYZ for discussion on tag requirements.
+*/
+void QCBORDecode_GetBignum(QCBORDecodeContext *pCtx,
+                           uint8_t             uTagRequirement,
+                           UsefulBufC         *pValue,
+                           bool               *pbIsNegative);
+
+void QCBORDecode_GetBignumInMapN(QCBORDecodeContext *pCtx,
+                                 int64_t             nLabel,
+                                 uint8_t             uTagRequirement,
+                                 UsefulBufC         *pValue,
+                                 bool               *pbIsNegative);
+
+void QCBORDecode_GetBignumInMapSz(QCBORDecodeContext *pCtx,
+                                  const char         *szLabel,
+                                  uint8_t             uTagRequirement,
+                                  UsefulBufC         *pValue,
+                                  bool               *pbIsNegative);
+
+
+void QCBORDecode_GetDecimalFraction(QCBORDecodeContext *pCtx,
+                                    uint8_t             uTagRequirement,
+                                    int64_t             *pnMantissa,
+                                    int64_t             *pnExponent);
+
+void QCBORDecode_GetDecimalFractionBig(QCBORDecodeContext *pCtx,
+                                       uint8_t             uTagRequirement,
+                                       UsefulBufC         *pMantissa,
+                                       int64_t            *pnExponent);
+
+void QCBORDecode_GetBigFloat(QCBORDecodeContext *pCtx,
+                             uint8_t             uTagRequirement,
+                             int64_t             *pnMantissa,
+                             int64_t             *pnExponent);
+
+void QCBORDecode_GetBigFloatBig(QCBORDecodeContext *pCtx,
+                                uint8_t             uTagRequirement,
+                                UsefulBufC          *pMantissa,
+                                int64_t             *pnExponent);
 
 /*
  @brief Decode the next item as a URI.
@@ -1381,6 +1432,73 @@
                                         UsefulBufC         *pRegex);
 
 
+/*
+ @brief Decode the next item as a MIME message
+
+ @param[in] pCtx             The decode context.
+ @param[in] uTagRequirement  One of @c QCBOR_TAGSPEC_MATCH_XXX.
+ @param[out] pMessage        The decoded regular expression.
+ @param[out] pbIsNot7Bit     @c true if MIME is binary or 8-bit.
+
+ Error handling is like QCBORDecode_GetBytes().
+
+ See XYZ for discussion on tag requirements.
+ 
+ The MIME message itself is not parsed.
+ 
+ This decodes both tag 36 and 257. If it is tag 257, pbIsNot7Bit
+ is @c true. While it is clear that tag 36 can't contain,
+ binary or 8-bit MIME, it is probably legal for tag 257
+ to contain 7-bit MIME. Hopefully in most uses the
+ Content-Transfer-Encoding header is present and the
+ contents of pbIsNot7Bit can be ignored. It may be NULL.
+*/
+static void QCBORDecode_GetMIMEMessage(QCBORDecodeContext *pMe,
+                                uint8_t uTagRequirement,
+                                UsefulBufC *pMessage,
+                                bool *pbIsNot7Bit);
+
+static void QCBORDecode_GetMIMEMessageInMapN(QCBORDecodeContext *pMe,
+                                      int64_t             nLabel,
+                                      uint8_t             uTagRequirement,
+                                      UsefulBufC         *pMessage,
+                                      bool               *pbIsNot7Bit);
+
+
+static void QCBORDecode_GetMIMEMessageInMapSZ(QCBORDecodeContext *pMe,
+                                       const char         *szLabel,
+                                       uint8_t             uTagRequirement,
+                                       UsefulBufC         *pMessage,
+                                       bool               *pbIsNot7Bit);
+
+/*
+ @brief Decode the next item as a UUID
+ 
+ @param[in] pCtx             The decode context.
+ @param[in] uTagRequirement  One of @c QCBOR_TAGSPEC_MATCH_XXX.
+ @param[out] pUUID            The decoded UUID
+ 
+ Error handling is like QCBORDecode_GetBytes().
+ 
+ See XYZ for discussion on tag requirements.
+ */
+
+static inline void QCBORDecode_GetBinaryUUID(QCBORDecodeContext *pMe,
+                                             uint8_t             uTagRequirement,
+                                             UsefulBufC         *pUUID);
+
+inline static void QCBORDecode_GetBinaryUUIDInMapN(QCBORDecodeContext *pMe,
+                                                   uint8_t             uTagRequirement,
+                                                   int64_t             nLabel,
+                                                   UsefulBufC         *pUUID);
+
+inline static void QCBORDecode_GetBinaryUUIDInMapSZ(QCBORDecodeContext *pMe,
+                                                    uint8_t             uTagRequirement,
+                                                    const char         *szLabel,
+                                                    UsefulBufC         *pUUID);
+
+
+
 /**
  @brief Enter a map for decoding and searching.
 
@@ -1862,7 +1980,6 @@
    QCBORDecode_GetInt64ConvertInternalInMapSZ(pMe, szLabel, uOptions, pnValue, &Item);
 }
 
-
 inline static void QCBORDecode_GetInt64(QCBORDecodeContext *pMe, int64_t *pnValue)
 {
     QCBORDecode_GetInt64Convert(pMe, QCBOR_CONVERT_TYPE_INT64, pnValue);
@@ -1880,6 +1997,9 @@
 
 
 
+
+
+
 // Semi-private
 void QCBORDecode_GetUInt64ConvertInternal(QCBORDecodeContext *pMe, uint32_t uOptions, uint64_t *puValue, QCBORItem *pItem);
 
@@ -1923,6 +2043,51 @@
    QCBORDecode_GetUInt64ConvertInMapSZ(pMe, szLabel, QCBOR_CONVERT_TYPE_UINT64, puValue);
 }
 
+
+
+
+void QCBORDecode_GetInt8ConvertInternal(QCBORDecodeContext *pMe, uint32_t uOptions, int8_t *pnValue, QCBORItem *pItem);
+
+void QCBORDecode_GetInt8ConvertInternalInMapN(QCBORDecodeContext *pMe, int64_t nLabel, uint32_t uOptions, int8_t *pnValue, QCBORItem *pItem);
+
+void QCBORDecode_GetInt8ConvertInternalInMapSZ(QCBORDecodeContext *pMe, const char *szLabel, uint32_t uOptions, int8_t *pnValue, QCBORItem *pItem);
+
+
+inline static void QCBORDecode_GetInt8Convert(QCBORDecodeContext *pMe, uint32_t uOptions, int8_t *pnValue)
+{
+    QCBORItem Item;
+    QCBORDecode_GetInt8ConvertInternal(pMe, uOptions, pnValue, &Item);
+}
+
+inline static void QCBORDecode_GetInt8ConvertInMapN(QCBORDecodeContext *pMe, int64_t nLabel, uint32_t uOptions, int8_t *pnValue)
+{
+   QCBORItem Item;
+   QCBORDecode_GetInt8ConvertInternalInMapN(pMe, nLabel, uOptions, pnValue, &Item);
+}
+
+inline static void QCBORDecode_GetInt8ConvertInMapSZ(QCBORDecodeContext *pMe, const char *szLabel, uint32_t uOptions, int8_t *pnValue)
+{
+   QCBORItem Item;
+   QCBORDecode_GetInt8ConvertInternalInMapSZ(pMe, szLabel, uOptions, pnValue, &Item);
+}
+
+inline static void QCBORDecode_GetInt8(QCBORDecodeContext *pMe, int8_t *pnValue)
+{
+    QCBORDecode_GetInt8Convert(pMe, QCBOR_CONVERT_TYPE_INT64, pnValue);
+}
+
+inline static void QCBORDecode_GetInt8InMapN(QCBORDecodeContext *pMe, int64_t nLabel, int8_t *pnValue)
+{
+   QCBORDecode_GetInt8ConvertInMapN(pMe, nLabel, QCBOR_CONVERT_TYPE_INT64, pnValue);
+}
+
+inline static void QCBORDecode_GetInt8InMapSZ(QCBORDecodeContext *pMe, const char *szLabel, int8_t *pnValue)
+{
+   QCBORDecode_GetInt8ConvertInMapSZ(pMe, szLabel, QCBOR_CONVERT_TYPE_INT64, pnValue);
+}
+
+
+
 void QCBORDecode_GetDoubleConvertInternal(QCBORDecodeContext *pMe, uint32_t uOptions, double *pValue, QCBORItem *pItem);
 
 void QCBORDecode_GetDoubleConvertInternalInMapN(QCBORDecodeContext *pMe, int64_t nLabel, uint32_t uOptions, double *pdValue, QCBORItem *pItem);
@@ -2005,6 +2170,9 @@
                                         TagSpecification    TagSpec,
                                         UsefulBufC          *pString);
 
+QCBORError FarfMIME(uint8_t uTagRequirement, const QCBORItem *pItem, UsefulBufC *pMessage, bool *pbIsNot7Bit);
+
+
 
 static inline void QCBORDecode_GetBytes(QCBORDecodeContext *pMe,  UsefulBufC *pValue)
 {
@@ -2178,6 +2346,50 @@
 }
 
 
+static inline void QCBORDecode_GetMIMEMessage(QCBORDecodeContext *pMe,
+                                              uint8_t uTagRequirement,
+                                              UsefulBufC *pMessage,
+                                              bool *pbIsNot7Bit)
+{
+   if(pMe->uLastError != QCBOR_SUCCESS) {
+      // Already in error state, do nothing
+      return;
+   }
+
+   QCBORItem  Item;
+   QCBORError uError = QCBORDecode_GetNext(pMe, &Item);
+   if(uError != QCBOR_SUCCESS) {
+      pMe->uLastError = (uint8_t)uError;
+      return;
+   }
+
+   pMe->uLastError = (uint8_t)FarfMIME(uTagRequirement, &Item, pMessage, pbIsNot7Bit);
+}
+
+static inline void QCBORDecode_GetMIMEMessageInMapN(QCBORDecodeContext *pMe,
+                                      int64_t             nLabel,
+                                      uint8_t             uTagRequirement,
+                                      UsefulBufC         *pMessage,
+                                      bool               *pbIsNot7Bit)
+{
+   QCBORItem Item;
+   QCBORDecode_GetItemInMapN(pMe, nLabel, QCBOR_TYPE_ANY, &Item);
+
+   pMe->uLastError = (uint8_t)FarfMIME(uTagRequirement, &Item, pMessage, pbIsNot7Bit);
+}
+
+static inline void QCBORDecode_GetMIMEMessageInMapSZ(QCBORDecodeContext *pMe,
+                                       const char         *szLabel,
+                                       uint8_t             uTagRequirement,
+                                       UsefulBufC         *pMessage,
+                                       bool               *pbIsNot7Bit)
+{
+   QCBORItem Item;
+   QCBORDecode_GetItemInMapSZ(pMe, szLabel, QCBOR_TYPE_ANY, &Item);
+
+   pMe->uLastError = (uint8_t)FarfMIME(uTagRequirement, &Item, pMessage, pbIsNot7Bit);
+}
+
 
 
 static inline void QCBORDecode_GetBinaryUUID(QCBORDecodeContext *pMe,
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index d5c4634..3913e7e 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -1359,88 +1359,6 @@
 
 
 /*
- Mostly just assign the right data type for the bignum.
- */
-inline static QCBORError DecodeBigNum(QCBORItem *pDecodedItem)
-{
-   // Stack Use: UsefulBuf 1  -- 16
-   if(pDecodedItem->uDataType != QCBOR_TYPE_BYTE_STRING) {
-      return QCBOR_ERR_BAD_OPT_TAG;
-   }
-   const UsefulBufC Temp    = pDecodedItem->val.string;
-   pDecodedItem->val.bigNum = Temp;
-   const bool bIsPosBigNum = (bool)(pDecodedItem->uTags[0] == CBOR_TAG_POS_BIGNUM);
-   pDecodedItem->uDataType  = (uint8_t)(bIsPosBigNum ? QCBOR_TYPE_POSBIGNUM
-                                                     : QCBOR_TYPE_NEGBIGNUM);
-   return QCBOR_SUCCESS;
-}
-
-
-/*
- */
-inline static QCBORError DecodeUUID(QCBORItem *pDecodedItem)
-{
-   if(pDecodedItem->uDataType != QCBOR_TYPE_BYTE_STRING) {
-      return QCBOR_ERR_BAD_OPT_TAG;
-   }
-   pDecodedItem->uDataType = QCBOR_TYPE_UUID;
-   return QCBOR_SUCCESS;
-}
-
-
-/*
- */
-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
  */
@@ -1508,6 +1426,24 @@
 }
 
 
+/*
+ Mostly just assign the right data type for the bignum.
+ */
+inline static QCBORError DecodeBigNum(QCBORItem *pDecodedItem)
+{
+   // Stack Use: UsefulBuf 1  -- 16
+   if(pDecodedItem->uDataType != QCBOR_TYPE_BYTE_STRING) {
+      return QCBOR_ERR_BAD_OPT_TAG;
+   }
+   const UsefulBufC Temp    = pDecodedItem->val.string;
+   pDecodedItem->val.bigNum = Temp;
+   const bool bIsPosBigNum = (bool)(pDecodedItem->uTags[0] == CBOR_TAG_POS_BIGNUM);
+   pDecodedItem->uDataType  = (uint8_t)(bIsPosBigNum ? QCBOR_TYPE_POSBIGNUM
+                                                     : QCBOR_TYPE_NEGBIGNUM);
+   return QCBOR_SUCCESS;
+}
+
+
 #ifndef QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
 /*
  Decode decimal fractions and big floats.
@@ -1609,6 +1545,74 @@
 #endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
 
 
+
+/*
+ */
+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 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 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 DecodeMIME(QCBORItem *pDecodedItem)
+{
+   if(pDecodedItem->uDataType == QCBOR_TYPE_TEXT_STRING) {
+      pDecodedItem->uDataType = QCBOR_TYPE_MIME;
+   } else if(pDecodedItem->uDataType != QCBOR_TYPE_BYTE_STRING) {
+      pDecodedItem->uDataType = QCBOR_TYPE_BINARY_MIME;
+   } else {
+      return QCBOR_ERR_BAD_OPT_TAG;
+   }
+   return QCBOR_SUCCESS;
+}
+
+
+/*
+ */
+inline static QCBORError DecodeUUID(QCBORItem *pDecodedItem)
+{
+   if(pDecodedItem->uDataType != QCBOR_TYPE_BYTE_STRING) {
+      return QCBOR_ERR_BAD_OPT_TAG;
+   }
+   pDecodedItem->uDataType = QCBOR_TYPE_UUID;
+   return QCBOR_SUCCESS;
+}
+
+
 /*
  Public function, see header qcbor/qcbor_decode.h file
  */
@@ -1624,10 +1628,6 @@
 
    for(int i = 0; i < QCBOR_MAX_TAGS_PER_ITEM; i++) {
       switch(pDecodedItem->uTags[i] ) {
-         case 0xffff:
-         // The end of the tag list or no tags
-         // Successful exit from the loop.
-         goto Done;
 
          case CBOR_TAG_DATE_STRING:
          nReturn = DecodeDateString(pDecodedItem);
@@ -1653,34 +1653,35 @@
          break;
    #endif /* QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA */
 
-         case CBOR_TAG_BIN_UUID:
-         nReturn = DecodeUUID(pDecodedItem);
-         break;
-            
          case CBOR_TAG_URI:
          nReturn = DecodeURI(pDecodedItem);
          break;
 
+         case CBOR_TAG_B64URL:
+         nReturn = DecodeB64URL(pDecodedItem);
+         break;
+            
+         case CBOR_TAG_B64:
+         nReturn = DecodeB64(pDecodedItem);
+         break;
+
+         case CBOR_TAG_MIME:
+         case CBOR_TAG_BINARY_MIME:
+         nReturn = DecodeMIME(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);
+         case CBOR_TAG_BIN_UUID:
+         nReturn = DecodeUUID(pDecodedItem);
          break;
             
-         case CBOR_TAG_MIME:
-         case CBOR_TAG_BINARY_MIME:
-// TODO: should binary and text MIME be distinguished?
-         nReturn = DecodeMIME(pDecodedItem);
-         break;
-
+         case 0xffff:
+         // The end of the tag list or no tags
+         // Successful exit from the loop.
+         goto Done;
             
          default:
          // A tag that is not understood
@@ -1794,8 +1795,8 @@
  Public function, see header qcbor/qcbor_decode.h file
  */
 int QCBORDecode_IsTagged(QCBORDecodeContext *me,
-                         const QCBORItem *pItem,
-                         uint64_t uTag)
+                         const QCBORItem   *pItem,
+                         uint64_t           uTag)
 {
    for(int i = 0; i < QCBOR_MAX_TAGS_PER_ITEM; i++ ) {
       if(pItem->uTags[i] == 0xffff) {
@@ -2821,11 +2822,11 @@
 
 
 
-static QCBORError ConvertBigNum(const QCBORItem *pItem, UsefulBufC *pValue, bool *pbIsNegative)
+static QCBORError ConvertBigNum(uint8_t uTagRequirement, const QCBORItem *pItem, UsefulBufC *pValue, bool *pbIsNegative)
 {
    *pbIsNegative = false;
 
-   bool bMustBeTagged = true; // TODO: fix this
+   bool bMustBeTagged = true; // TODO: fix this --- they have to tell us if they are expecting positive or negative
 
    switch(pItem->uDataType) {
       case QCBOR_TYPE_BYTE_STRING:
@@ -2856,7 +2857,7 @@
 }
 
 
-/**
+/*
  @param[in] bMustBeTagged  If \c true, then the data item must be tagged as either
  a positive or negative bignum. If \c false, then it only must be a byte string and bIsNegative
  will always be false on the asumption that it is positive, but it can be interpretted as
@@ -2868,7 +2869,7 @@
  a positive big num or a negative big num.
 
  */
-void QCBORDecode_GetBignum(QCBORDecodeContext *pMe, bool bMustBeTagged, UsefulBufC *pValue, bool *pbIsNegative)
+void QCBORDecode_GetBignum(QCBORDecodeContext *pMe, uint8_t uTagRequirement, UsefulBufC *pValue, bool *pbIsNegative)
 {
    if(pMe->uLastError != QCBOR_SUCCESS) {
       // Already in error state, do nothing
@@ -2882,20 +2883,65 @@
       return;
    }
 
-   pMe->uLastError = (uint8_t)ConvertBigNum(&Item, pValue, pbIsNegative);
+   pMe->uLastError = (uint8_t)ConvertBigNum(uTagRequirement, &Item, pValue, pbIsNegative);
 }
 
 /*
 Public function, see header qcbor/qcbor_decode.h file
 */
-void QCBORDecode_GetBignumInMapN(QCBORDecodeContext *pMe, int64_t nLabel, bool bMustBeTagged, UsefulBufC *pValue, bool *pbIsNegative)
+void QCBORDecode_GetBignumInMapN(QCBORDecodeContext *pMe, int64_t nLabel, uint8_t uTagRequirement, UsefulBufC *pValue, bool *pbIsNegative)
 {
    QCBORItem Item;
    QCBORDecode_GetItemInMapN(pMe, nLabel, QCBOR_TYPE_ANY, &Item);
 
-   pMe->uLastError = (uint8_t)ConvertBigNum(&Item, pValue, pbIsNegative);
+   pMe->uLastError = (uint8_t)ConvertBigNum(uTagRequirement, &Item, pValue, pbIsNegative);
 }
 
+/*
+Public function, see header qcbor/qcbor_decode.h file
+*/
+void QCBORDecode_GetBignumInMapSZ(QCBORDecodeContext *pMe, const char *szLabel, uint8_t uTagRequirement, UsefulBufC *pValue, bool *pbIsNegative)
+{
+   QCBORItem Item;
+   QCBORDecode_GetItemInMapSZ(pMe, szLabel, QCBOR_TYPE_ANY, &Item);
+
+   pMe->uLastError = (uint8_t)ConvertBigNum(uTagRequirement, &Item, pValue, pbIsNegative);
+}
+
+
+
+// Semi private
+QCBORError FarfMIME(uint8_t uTagRequirement, const QCBORItem *pItem, UsefulBufC *pMessage, bool *pbIsNot7Bit)
+{
+   const TagSpecification TagSpecText = {uTagRequirement, QCBOR_TYPE_MIME, {QCBOR_TYPE_TEXT_STRING, 0,0,0,0,0}};
+   const TagSpecification TagSpecBinary = {uTagRequirement, QCBOR_TYPE_BINARY_MIME, {QCBOR_TYPE_BYTE_STRING, 0,0,0,0,0}};
+   
+   QCBORError uReturn;
+   
+   if(CheckTagRequirement(TagSpecText, pItem->uDataType)) {
+      *pMessage = pItem->val.string;
+      if(pbIsNot7Bit != NULL) {
+         *pbIsNot7Bit = false;
+      }
+      uReturn = QCBOR_SUCCESS;
+   } else if(CheckTagRequirement(TagSpecBinary, pItem->uDataType)) {
+      *pMessage = pItem->val.string;
+      if(pbIsNot7Bit != NULL) {
+         *pbIsNot7Bit = true;
+      }
+      uReturn = QCBOR_SUCCESS;
+
+   } else {
+      uReturn = QCBOR_ERR_UNEXPECTED_TYPE;
+   }
+   
+   return uReturn;
+}
+
+
+
+
+
 
 
 
@@ -3476,6 +3522,48 @@
 }
 
 
+void QCBORDecode_GetInt8ConvertInternal(QCBORDecodeContext *pMe, uint32_t uOptions, int8_t *pnValue, QCBORItem *pItem)
+{
+   int64_t uValue;
+   QCBORDecode_GetInt64ConvertInternal(pMe, uOptions, &uValue, pItem);
+   if(pMe->uLastError != QCBOR_SUCCESS) {
+      return;
+   }
+
+   if(QCBOR_Int64ToInt8(uValue, pnValue)) {
+      pMe->uLastError = QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW;
+   }
+}
+
+void QCBORDecode_GetInt8ConvertInternalInMapN(QCBORDecodeContext *pMe, int64_t nLabel, uint32_t uOptions, int8_t *pnValue, QCBORItem *pItem)
+{
+   int64_t uValue;
+   QCBORDecode_GetInt64ConvertInternalInMapN(pMe, nLabel, uOptions, &uValue, pItem);
+   if(pMe->uLastError != QCBOR_SUCCESS) {
+      return;
+   }
+
+   if(QCBOR_Int64ToInt8(uValue, pnValue)) {
+      pMe->uLastError = QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW;
+   }
+}
+
+void QCBORDecode_GetInt8ConvertInternalInMapSZ(QCBORDecodeContext *pMe, const char *szLabel, uint32_t uOptions, int8_t *pnValue, QCBORItem *pItem)
+{
+   int64_t uValue;
+   QCBORDecode_GetInt64ConvertInternalInMapSZ(pMe, szLabel, uOptions, &uValue, pItem);
+   if(pMe->uLastError != QCBOR_SUCCESS) {
+      return;
+   }
+
+   if(QCBOR_Int64ToInt8(uValue, pnValue)) {
+      pMe->uLastError = QCBOR_ERR_CONVERSION_UNDER_OVER_FLOW;
+   }
+}
+
+
+
+
 void QCBORDecode_GetUint64ConvertInternalInMapN(QCBORDecodeContext *pMe,
                                                int64_t             nLabel,
                                                uint32_t            uOptions,
@@ -3944,3 +4032,160 @@
 
    pMe->uLastError = (uint8_t)DoubleConvertAll(&Item, uOptions, pdValue);
 }
+
+
+void FarfDecimalFraction(QCBORDecodeContext *pMe,
+                         uint8_t             uTagRequirement,
+                         QCBORItem          *pItem,
+                         int64_t             *pnMantissa,
+                         int64_t             *pnExponent)
+{
+   QCBORError uErr;
+   
+   if(pItem->uDataType == QCBOR_TYPE_ARRAY) {
+      if(uTagRequirement == QCBOR_TAGSPEC_MATCH_TAG_CONTENT_TYPE) {
+         pMe->uLastError = QCBOR_ERR_UNEXPECTED_TYPE;
+         return;
+      }
+      uErr = QCBORDecode_MantissaAndExponent(pMe, pItem);
+       if(uErr != QCBOR_SUCCESS) {
+          pMe->uLastError = (uint8_t)uErr;
+          return;
+       }
+    }
+   
+   if(uTagRequirement == QCBOR_TAGSPEC_MATCH_TAG_CONTENT_TYPE) {
+      pMe->uLastError = QCBOR_ERR_UNEXPECTED_TYPE;
+      return;
+   }
+    
+    switch (pItem->uDataType) {
+          
+       case QCBOR_TYPE_DECIMAL_FRACTION:
+          *pnMantissa = pItem->val.expAndMantissa.Mantissa.nInt;
+          *pnExponent = pItem->val.expAndMantissa.nExponent;
+          break;
+          
+       case QCBOR_TYPE_DECIMAL_FRACTION_POS_BIGNUM:
+          *pnExponent = pItem->val.expAndMantissa.nExponent;
+          
+          uErr = ConvertPositiveBigNumToSigned(pItem->val.expAndMantissa.Mantissa.bigNum, pnMantissa);
+          if(uErr != QCBOR_SUCCESS) {
+             pMe->uLastError = (uint8_t)uErr;
+          }
+          break;
+
+       case QCBOR_TYPE_DECIMAL_FRACTION_NEG_BIGNUM:
+          *pnExponent = pItem->val.expAndMantissa.nExponent;
+          
+          uErr = ConvertNegativeBigNumToSigned(pItem->val.expAndMantissa.Mantissa.bigNum, pnMantissa);
+          if(uErr != QCBOR_SUCCESS) {
+             pMe->uLastError = (uint8_t)uErr;
+          }
+          break;
+          
+       default:
+          pMe->uLastError = QCBOR_ERR_UNEXPECTED_TYPE;
+    }
+}
+
+void QCBORDecode_GetDecimalFractionN(QCBORDecodeContext *pMe,
+                                     uint8_t             uTagRequirement,
+                                     int64_t             nLabel,
+                                     int64_t             *pnMantissa,
+                                     int64_t             *pnExponent)
+{
+   QCBORItem Item;
+   
+   QCBORDecode_GetItemInMapN(pMe, nLabel, QCBOR_TYPE_ANY, &Item);
+   FarfDecimalFraction(pMe, uTagRequirement, &Item, pnMantissa, pnExponent);
+}
+
+
+
+void QCBORDecode_GetDecimalFractionSZ(QCBORDecodeContext *pMe,
+                                     uint8_t             uTagRequirement,
+                                     const char         *szLabel,
+                                     int64_t             *pnMantissa,
+                                     int64_t             *pnExponent)
+{
+   QCBORItem Item;
+   
+   QCBORDecode_GetItemInMapSZ(pMe, szLabel, QCBOR_TYPE_ANY, &Item);
+   
+   FarfDecimalFraction(pMe, uTagRequirement, &Item, pnMantissa, pnExponent);
+}
+
+
+UsefulBufC ConvertIntToBigNum(uint64_t uInt, UsefulBuf Buffer)
+{
+   while(uInt & 0xff0000000000UL) {
+      uInt = uInt << 8;
+   };
+   
+   UsefulOutBuf UOB;
+   
+   UsefulOutBuf_Init(&UOB, Buffer);
+   
+   while(uInt) {
+      UsefulOutBuf_AppendByte(&UOB, (uint8_t)((uInt & 0xff0000000000UL) >> 56));
+      uInt = uInt << 8;
+   }
+   
+   return UsefulOutBuf_OutUBuf(&UOB);
+}
+
+
+void QCBORDecode_GetDecimalFractionBigN(QCBORDecodeContext *pMe,
+                                        uint8_t             uTagRequirement,
+                                        int64_t             nLabel,
+                                        UsefulBuf           pBufferForMantissa,
+                                        UsefulBufC         *pMantissa,
+                                        bool               *pbIsNegative,
+                                        int64_t            *pnExponent)
+{
+   QCBORItem Item;
+   QCBORError uErr;
+   
+   QCBORDecode_GetItemInMapN(pMe, nLabel, QCBOR_TYPE_ANY, &Item);
+   
+   if(Item.uDataType == QCBOR_TYPE_ARRAY) {
+      uErr = QCBORDecode_MantissaAndExponent(pMe, &Item);
+      if(uErr != QCBOR_SUCCESS) {
+         pMe->uLastError = (uint8_t)uErr;
+         return;
+      }
+   }
+   
+   uint64_t uMantissa;
+   
+   switch (Item.uDataType) {
+         
+      case QCBOR_TYPE_DECIMAL_FRACTION:
+         if(Item.val.expAndMantissa.Mantissa.nInt >= 0) {
+            uMantissa = (uint64_t)Item.val.expAndMantissa.Mantissa.nInt;
+            *pbIsNegative = false;
+         } else {
+            uMantissa = (uint64_t)-Item.val.expAndMantissa.Mantissa.nInt;
+            *pbIsNegative = true;
+         }
+         *pMantissa = ConvertIntToBigNum(uMantissa, pBufferForMantissa);
+         *pnExponent = Item.val.expAndMantissa.nExponent;
+         break;
+         
+      case QCBOR_TYPE_DECIMAL_FRACTION_POS_BIGNUM:
+         *pnExponent = Item.val.expAndMantissa.nExponent;
+         *pMantissa = Item.val.expAndMantissa.Mantissa.bigNum;
+         *pbIsNegative = false;
+         break;
+
+      case QCBOR_TYPE_DECIMAL_FRACTION_NEG_BIGNUM:
+         *pnExponent = Item.val.expAndMantissa.nExponent;
+         *pMantissa = Item.val.expAndMantissa.Mantissa.bigNum;
+         *pbIsNegative = true;
+         break;
+         
+      default:
+         pMe->uLastError = QCBOR_ERR_UNEXPECTED_TYPE;
+   }
+}