New tag encoder basically working
diff --git a/inc/qcbor.h b/inc/qcbor.h
index 7b649a3..814f129 100644
--- a/inc/qcbor.h
+++ b/inc/qcbor.h
@@ -193,6 +193,10 @@
    void *pStringAllocator;
 };
 
+// Used internally in the impementation here
+// Must not conflict with any of the official CBOR types
+#define CBOR_MAJOR_NONE_TYPE_RAW  9
+#define CBOR_MAJOR_NONE_TAG_LABEL_REORDER 10
 
 /* ===========================================================================
    END OF PRIVATE PART OF THIS FILE
@@ -446,8 +450,9 @@
  buffers need only to be valid during the "Add" calls. The 
  data is copied into the output buf during the "Add" call.
  
+ TODO: remote discussion of tags
  There are several "Add" functions / macros for each type. The one
- with named ending in "_3", for example QCBOREncode_AddInt64_3(),
+ with named ending in "_2", for example QCBOREncode_AddInt64_3(),
  takes parameters for labels and tags and is the most powerful.
  Generally it is better to use the macros that only take the
  parameters necessary. For example, QCBOREncode_AddInt64(),
@@ -825,7 +830,6 @@
  @param[in] pCtx      The encoding context to add the integer to.
  @param[in] szLabel   The string map label for this integer value.
  @param[in] nLabel    The integer map label for this integer value.
- @param[in] uTag      A CBOR type 6 tag
  @param[in] nNum      The integer to add.
  
  The functions and macros with a "U" add unsigned integers and those
@@ -894,32 +898,31 @@
  @param[in] pCtx      The encoding context to add the float to.
  @param[in] szLabel   The string map label for this integer value.
  @param[in] nLabel    The integer map label for this integer value.
- @param[in] uTag      A CBOR type 6 tag
  @param[in] fNum       The float to add.
  
- This works the same as QCBOREncode_AddInt64_3() except it is for floats and doubles.
+ This works the same as QCBOREncode_AddInt64_2() except it is for floats and doubles.
  
  */
-void QCBOREncode_AddFloat_3(QCBOREncodeContext *pCtx, const char *szLabel, int64_t nLabel, uint64_t uTag, float fNum);
-void QCBOREncode_AddDouble_3(QCBOREncodeContext *pCtx, const char *szLabel, int64_t nLabel, uint64_t uTag, double dNum);
+void QCBOREncode_AddFloat_2(QCBOREncodeContext *pCtx, const char *szLabel, int64_t nLabel, float fNum);
+void QCBOREncode_AddDouble_2(QCBOREncodeContext *pCtx, const char *szLabel, int64_t nLabel, double dNum);
 
 #define QCBOREncode_AddFloat(pCtx, fNum) \
-      QCBOREncode_AddFloat_3((pCtx), NULL, QCBOR_NO_INT_LABEL, CBOR_TAG_NONE, (fNum))
+      QCBOREncode_AddFloat_2((pCtx), NULL, QCBOR_NO_INT_LABEL, (fNum))
 
 #define QCBOREncode_AddFloatToMap(pCtx, szLabel, fNum) \
-      QCBOREncode_AddFloat_3((pCtx), (szLabel), QCBOR_NO_INT_LABEL, CBOR_TAG_NONE, (fNum))
+      QCBOREncode_AddFloat_2((pCtx), (szLabel), QCBOR_NO_INT_LABEL, (fNum))
 
 #define QCBOREncode_AddFloatToMapN(pCtx, nLabel, fNum) \
-      QCBOREncode_AddFloat_3((pCtx), NULL, (nLabel), CBOR_TAG_NONE, (fNum))
+      QCBOREncode_AddFloat_2((pCtx), NULL, (nLabel), (fNum))
 
 #define QCBOREncode_AddDouble(pCtx, dNum) \
-      QCBOREncode_AddDouble_3((pCtx), NULL, QCBOR_NO_INT_LABEL, CBOR_TAG_NONE, (dNum))
+      QCBOREncode_AddDouble_2((pCtx), NULL, QCBOR_NO_INT_LABEL, (dNum))
 
 #define QCBOREncode_AddDoubleToMap(pCtx, szLabel, dNum) \
-      QCBOREncode_AddDouble_3((pCtx), (szLabel), QCBOR_NO_INT_LABEL, CBOR_TAG_NONE, (dNum))
+      QCBOREncode_AddDouble_2((pCtx), (szLabel), QCBOR_NO_INT_LABEL, (dNum))
 
 #define QCBOREncode_AddDoubleToMapN(pCtx, nLabel, dNum) \
-      QCBOREncode_AddDouble_3((pCtx), NULL, (nLabel), CBOR_TAG_NONE, (dNum))
+      QCBOREncode_AddDouble_2((pCtx), NULL, (nLabel), (dNum))
 
 /*
  @brief  Add a half-precision floating point number to the encoded output
@@ -940,20 +943,20 @@
  
  Half-precision floating point number take up 2 bytes, half that of single-precision.
  
- This works the same as QCBOREncode_AddInt64_3() except it is for half-precision floats.
+ This works the same as QCBOREncode_AddInt64_2() except it is for half-precision floats.
 
  */
 
-void QCBOREncode_AddFloatAsHalf_3(QCBOREncodeContext *me, const char *szLabel, int64_t nLabel, uint64_t uTag, float fNum);
+void QCBOREncode_AddFloatAsHalf_2(QCBOREncodeContext *me, const char *szLabel, int64_t nLabel, float fNum);
 
 #define QCBOREncode_AddFloatAsHalf(pCtx, fNum) \
-      QCBOREncode_AddFloatAsHalf_3((pCtx), NULL, QCBOR_NO_INT_LABEL, CBOR_TAG_NONE, (fNum))
+      QCBOREncode_AddFloatAsHalf_2((pCtx), NULL, QCBOR_NO_INT_LABEL, (fNum))
 
 #define QCBOREncode_AddFloatAsHalfToMap(pCtx, szLabel, fNum) \
-      QCBOREncode_AddFloatAsHalf_3((pCtx), (szLabel), QCBOR_NO_INT_LABEL, CBOR_TAG_NONE, (fNum))
+      QCBOREncode_AddFloatAsHalf_2((pCtx), (szLabel), QCBOR_NO_INT_LABEL, (fNum))
 
 #define QCBOREncode_AddFloatAsHalfToMapN(pCtx, nLabel, fNum) \
-      QCBOREncode_AddFloatAsHalf_3((pCtx), NULL, (nLabel), CBOR_TAG_NONE, (fNum))
+      QCBOREncode_AddFloatAsHalf_2((pCtx), NULL, (nLabel), (fNum))
 
 
 /*
@@ -978,20 +981,20 @@
  These will always be decoded into a float as standard C doesn't have a widely used
  standard representation for half-precision floats yet.
  
- This works the same as QCBOREncode_AddInt64_3() except it is for single and half-precision floats.
+ This works the same as QCBOREncode_AddInt64_2() except it is for single and half-precision floats.
  
  */
 
-void QCBOREncode_AddFloatAsSmallest_3(QCBOREncodeContext *me, const char *szLabel, int64_t nLabel, uint64_t uTag, float fNum);
+void QCBOREncode_AddFloatAsSmallest_2(QCBOREncodeContext *me, const char *szLabel, int64_t nLabel, float fNum);
 
 #define QCBOREncode_AddFloatAsSmallest(pCtx, fNum) \
-      QCBOREncode_AddFloatAsSmallest_3((pCtx), NULL, QCBOR_NO_INT_LABEL, CBOR_TAG_NONE, (fNum))
+      QCBOREncode_AddFloatAsSmallest_2((pCtx), NULL, QCBOR_NO_INT_LABEL, CBOR_TAG_NONE, (fNum))
 
 #define QCBOREncode_AddFloatAsSmallestToMap(pCtx, szLabel, fNum) \
-      QCBOREncode_AddFloatAsSmallest_3((pCtx), (szLabel), QCBOR_NO_INT_LABEL, CBOR_TAG_NONE, (fNum))
+      QCBOREncode_AddFloatAsSmallest_2((pCtx), (szLabel), QCBOR_NO_INT_LABEL, (fNum))
 
 #define QCBOREncode_AddFloatAsSmallestToMapN(pCtx, nLabel, fNum) \
-      QCBOREncode_AddFloatAsSmallest_3((pCtx), NULL, (nLabel), CBOR_TAG_NONE, (fNum))
+      QCBOREncode_AddFloatAsSmallest_2((pCtx), NULL, (nLabel), (fNum))
 
 
 /*
@@ -1022,20 +1025,20 @@
  using this approach can / should assume that floats received actually have the precision
  of double. They should probably cast the float received to double.
  
- This works the same as QCBOREncode_AddInt64_3() except it is for floating point types.
+ This works the same as QCBOREncode_AddInt64_2() except it is for floating point types.
  
  */
 
-void QCBOREncode_AddDoubleAsSmallest_3(QCBOREncodeContext *me, const char *szLabel, int64_t nLabel, uint64_t uTag, double dNum);
+void QCBOREncode_AddDoubleAsSmallest_2(QCBOREncodeContext *me, const char *szLabel, int64_t nLabel, double dNum);
 
 #define QCBOREncode_AddDoubleAsSmallest(pCtx, dNum) \
-      QCBOREncode_AddDoubleAsSmallest_3((pCtx), NULL, QCBOR_NO_INT_LABEL, CBOR_TAG_NONE, (dNum))
+      QCBOREncode_AddDoubleAsSmallest_2((pCtx), NULL, QCBOR_NO_INT_LABEL, (dNum))
 
 #define QCBOREncode_AddDoubleAsSmallestToMap(pCtx, szLabel, dNum) \
-      QCBOREncode_AddDoubleAsSmallest_3((pCtx), (szLabel), QCBOR_NO_INT_LABEL, CBOR_TAG_NONE, (dNum))
+      QCBOREncode_AddDoubleAsSmallest_2((pCtx), (szLabel), QCBOR_NO_INT_LABEL, (dNum))
 
 #define QCBOREncode_AddDoubleAsSmallestToMapN(pCtx, nLabel, dNum) \
-      QCBOREncode_AddDoubleAsSmallest_3((pCtx), NULL, (nLabel), CBOR_TAG_NONE, (dNum))
+      QCBOREncode_AddDoubleAsSmallest_2((pCtx), NULL, (nLabel), (dNum))
 
 
 
@@ -1064,10 +1067,10 @@
  
  This implementation cannot encode fractional seconds using float or double
  even though that is allowed by CBOR, but you can encode them if you
- want to by calling QCBOREncode_AddFloat_3() or QCBOREncode_AddDouble_3()
+ want to by calling QCBOREncode_AddFloat_2() or QCBOREncode_AddDouble_2()
  with the right parameters.
  
- Error handling is the same as QCBOREncode_AddInt64_3().
+ Error handling is the same as QCBOREncode_AddInt64_2().
  */
 
 static inline void QCBOREncode_AddDateEpoch_2(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t nLabel, int64_t date)
@@ -1086,6 +1089,8 @@
       QCBOREncode_AddDateEpoch_2((pCtx), NULL, (nLabel), (date))
 
 
+// TODO: document this
+void QCBOREncode_AddBytes_2(QCBOREncodeContext *me, uint8_t uMajorType, const char *szLabel, int64_t nLabel, UsefulBufC Bytes);
 
 
 /**
@@ -1105,46 +1110,64 @@
  
  */
 
-void QCBOREncode_AddBytes_3(QCBOREncodeContext *pCtx, const char *szLabel, int64_t nLabel, uint64_t uTag, UsefulBufC Bytes);
-
 #define QCBOREncode_AddBytes(pCtx, Bytes) \
-      QCBOREncode_AddBytes_3((pCtx), NULL, QCBOR_NO_INT_LABEL, CBOR_TAG_NONE, (Bytes))
+      QCBOREncode_AddBytes_2((pCtx), CBOR_MAJOR_TYPE_BYTE_STRING, NULL, QCBOR_NO_INT_LABEL, Bytes)
 
 #define QCBOREncode_AddBytesToMap(pCtx, szLabel, Bytes) \
-      QCBOREncode_AddBytes_3((pCtx), (szLabel), QCBOR_NO_INT_LABEL, CBOR_TAG_NONE, (Bytes))
+      QCBOREncode_AddBytes_2((pCtx), CBOR_MAJOR_TYPE_BYTE_STRING, (szLabel), QCBOR_NO_INT_LABEL, (Bytes))
 
 #define QCBOREncode_AddBytesToMapN(pCtx, nLabel, Bytes) \
-      QCBOREncode_AddBytes_3((pCtx), NULL, (nLabel), CBOR_TAG_NONE, (Bytes))
+      QCBOREncode_AddBytes_2((pCtx), CBOR_MAJOR_TYPE_BYTE_STRING, NULL, (nLabel), (Bytes))
+
+
+
+static inline void QCBOREncode_AddBinaryUUID_2(QCBOREncodeContext *pCtx, const char *szLabel, int64_t nLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_BIN_UUID);
+   QCBOREncode_AddBytes_2(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING, szLabel, nLabel, Bytes);
+}
 
 
 #define QCBOREncode_AddBinaryUUID(pCtx, Bytes) \
-      QCBOREncode_AddBytes_3((pCtx), NULL, QCBOR_NO_INT_LABEL, CBOR_TAG_BIN_UUID, (Bytes))
+      QCBOREncode_AddBinaryUUID_2((pCtx), NULL, QCBOR_NO_INT_LABEL, (Bytes))
 
 #define QCBOREncode_AddBinaryUUIDToMap(pCtx, szLabel, Bytes) \
-      QCBOREncode_AddBytes_3((pCtx), (szLabel), QCBOR_NO_INT_LABEL, CBOR_TAG_BIN_UUID, (Bytes))
+      QCBOREncode_AddBinaryUUID_2((pCtx), (szLabel), QCBOR_NO_INT_LABEL, (Bytes))
 
 #define QCBOREncode_AddBinaryUUIDToMapN(pCtx, nLabel, Bytes) \
-      QCBOREncode_AddBytes_3((pCtx), NULL, (nLabel), CBOR_TAG_BIN_UUID, (Bytes))
+      QCBOREncode_AddBinaryUUID_2((pCtx), NULL, (nLabel), (Bytes))
 
 
+static inline void QCBOREncode_AddPositiveBignum_2(QCBOREncodeContext *pCtx, const char *szLabel, int64_t nLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_POS_BIGNUM);
+   QCBOREncode_AddBytes_2(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING, szLabel, nLabel, Bytes);
+}
+
 #define QCBOREncode_AddPositiveBignum(pCtx, Bytes) \
-      QCBOREncode_AddBytes_3((pCtx), NULL, QCBOR_NO_INT_LABEL, CBOR_TAG_POS_BIGNUM, (Bytes))
+      QCBOREncode_AddPositiveBignum_2((pCtx), NULL, QCBOR_NO_INT_LABEL, (Bytes))
 
 #define QCBOREncode_AddPositiveBignumToMap(pCtx, szLabel, Bytes) \
-      QCBOREncode_AddBytes_3((pCtx), (szLabel), QCBOR_NO_INT_LABEL, CBOR_TAG_POS_BIGNUM, (Bytes))
+      QCBOREncode_AddPositiveBignum_2((pCtx), (szLabel), QCBOR_NO_INT_LABEL, (Bytes))
 
 #define QCBOREncode_AddPositiveBignumToMapN(pCtx, nLabel, Bytes) \
-      QCBOREncode_AddBytes_3((pCtx), NULL, (nLabel), CBOR_TAG_POS_BIGNUM, (Bytes))
+      QCBOREncode_AddPositiveBignum_2((pCtx), NULL, (nLabel), (Bytes))
 
 
+static inline void QCBOREncode_AddNegativeBignum_2(QCBOREncodeContext *pCtx, const char *szLabel, int64_t nLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_NEG_BIGNUM);
+   QCBOREncode_AddBytes_2(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING, szLabel, nLabel, Bytes);
+}
+
 #define QCBOREncode_AddNegativeBignum(pCtx, Bytes) \
-      QCBOREncode_AddBytes_3((pCtx), NULL, QCBOR_NO_INT_LABEL, CBOR_TAG_NEG_BIGNUM, (Bytes))
+      QCBOREncode_AddNegativeBignum_2((pCtx), NULL, QCBOR_NO_INT_LABEL, (Bytes))
 
 #define QCBOREncode_AddNegativeBignumToMap(pCtx, szLabel, Bytes) \
-      QCBOREncode_AddBytes_3((pCtx), (szLabel), QCBOR_NO_INT_LABEL, CBOR_TAG_NEG_BIGNUM, (Bytes))
+      QCBOREncode_AddNegativeBignum_2((pCtx), (szLabel), QCBOR_NO_INT_LABEL, (Bytes))
 
 #define QCBOREncode_AddNegativeBignumToMapN(pCtx, nLabel, Bytes) \
-      QCBOREncode_AddBytes_3((pCtx), NULL, (nLabel), CBOR_TAG_NEG_BIGNUM, (Bytes))
+      QCBOREncode_AddNegativeBignum_2((pCtx), NULL, (nLabel), (Bytes))
 
 
 
@@ -1170,78 +1193,119 @@
  lengths greater. This limit to 4GB for a text string should not be a
  problem.
  
- Error handling is the same as QCBOREncode_AddInt64_3().
+ Error handling is the same as QCBOREncode_AddInt64_2().
  
  */
 
-void QCBOREncode_AddText_3(QCBOREncodeContext *pCtx, const char *szLabel, int64_t nLabel, uint64_t uTag, UsefulBufC Bytes);
-
+// TODO: AddText_2? 
 #define QCBOREncode_AddText(pCtx, Bytes) \
-      QCBOREncode_AddText_3((pCtx), NULL, QCBOR_NO_INT_LABEL, CBOR_TAG_NONE, (Bytes))
+      QCBOREncode_AddBytes_2((pCtx), CBOR_MAJOR_TYPE_TEXT_STRING, NULL, QCBOR_NO_INT_LABEL, (Bytes))
 
 #define QCBOREncode_AddTextToMap(pCtx, szLabel, Bytes) \
-      QCBOREncode_AddText_3((pCtx), (szLabel), QCBOR_NO_INT_LABEL, CBOR_TAG_NONE, (Bytes))
+      QCBOREncode_AddBytes_2((pCtx), CBOR_MAJOR_TYPE_TEXT_STRING, (szLabel), QCBOR_NO_INT_LABEL, (Bytes))
 
 #define QCBOREncode_AddTextToMapN(pCtx, nLabel, Bytes) \
-      QCBOREncode_AddText_3((pCtx), NULL, (nLabel), CBOR_TAG_NONE, (Bytes))
+      QCBOREncode_AddBytes_2((pCtx), CBOR_MAJOR_TYPE_TEXT_STRING, NULL, (nLabel),  (Bytes))
 
-inline static void QCBOREncode_AddSZString_3(QCBOREncodeContext *pCtx, const char *szLabel, int64_t nLabel, uint64_t uTag, const char *szString) {
-   QCBOREncode_AddText_3(pCtx, szLabel, nLabel, uTag, UsefulBuf_FromSZ(szString));
+
+inline static void QCBOREncode_AddSZString_2(QCBOREncodeContext *pCtx, const char *szLabel, int64_t nLabel, const char *szString)
+{
+   QCBOREncode_AddBytes_2(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, szLabel, nLabel,UsefulBuf_FromSZ(szString));
 }
 
 #define QCBOREncode_AddSZString(pCtx, szString) \
-      QCBOREncode_AddSZString_3((pCtx), NULL, QCBOR_NO_INT_LABEL, CBOR_TAG_NONE, (szString))
+      QCBOREncode_AddSZString_2((pCtx), NULL, QCBOR_NO_INT_LABEL, (szString))
 
 #define QCBOREncode_AddSZStringToMap(pCtx, szLabel, szString) \
-      QCBOREncode_AddSZString_3((pCtx), (szLabel), QCBOR_NO_INT_LABEL, CBOR_TAG_NONE, (szString))
+      QCBOREncode_AddSZString_2((pCtx), (szLabel), QCBOR_NO_INT_LABEL, (szString))
 
 #define QCBOREncode_AddSZStringToMapN(pCtx, nLabel, szString) \
-      QCBOREncode_AddSZString_3((pCtx), NULL, (nLabel), CBOR_TAG_NONE, (szString))
+      QCBOREncode_AddSZString_2((pCtx), NULL, (nLabel), (szString))
+
+
+
+
+static inline void QCBOREncode_AddURI_2(QCBOREncodeContext *pCtx, const char *szLabel, int64_t nLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_URI);
+   QCBOREncode_AddBytes_2(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, szLabel, nLabel, Bytes);
+}
 
 #define QCBOREncode_AddURI(pCtx, Bytes) \
-      QCBOREncode_AddText_3((pCtx), NULL, QCBOR_NO_INT_LABEL, CBOR_TAG_URI, (Bytes))
+      QCBOREncode_AddURI_2((pCtx), NULL, QCBOR_NO_INT_LABEL, (Bytes))
 
 #define QCBOREncode_AddURIToMap(pCtx, szLabel, Bytes) \
-      QCBOREncode_AddText_3((pCtx), (szLabel), QCBOR_NO_INT_LABEL, CBOR_TAG_URI, (Bytes))
+      QCBOREncode_AddURI_2((pCtx), (szLabel), QCBOR_NO_INT_LABEL, (Bytes))
 
 #define QCBOREncode_AddURIToMapN(pCtx, nLabel, Bytes) \
-      QCBOREncode_AddText_3((pCtx), NULL, (nLabel), CBOR_TAG_URI, (Bytes))
+      QCBOREncode_AddURI_2((pCtx), NULL, (nLabel), (Bytes))
+
+
+static inline void QCBOREncode_AddB64Text_2(QCBOREncodeContext *pCtx, const char *szLabel, int64_t nLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_B64);
+   QCBOREncode_AddBytes_2(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, szLabel, nLabel, Bytes);
+}
 
 #define QCBOREncode_AddB64Text(pCtx, Bytes) \
-      QCBOREncode_AddText_3((pCtx), NULL, QCBOR_NO_INT_LABEL, CBOR_TAG_B64, (Bytes))
+      QCBOREncode_AddB64Text_2((pCtx), NULL, QCBOR_NO_INT_LABEL, (Bytes))
 
 #define QCBOREncode_AddB64TextToMap(pCtx, szLabel, Bytes) \
-      QCBOREncode_AddText_3((pCtx), (szLabel), QCBOR_NO_INT_LABEL, CBOR_TAG_B64, (Bytes))
+      QCBOREncode_AddB64Text_2((pCtx), (szLabel), QCBOR_NO_INT_LABEL, (Bytes))
 
 #define QCBOREncode_AddB64TextToMapN(pCtx, nLabel, Bytes) \
-      QCBOREncode_AddText_3((pCtx), NULL, (nLabel), CBOR_TAG_B64, (Bytes))
+      QCBOREncode_AddB64Text_2((pCtx), NULL, (nLabel), (Bytes))
+
+
+
+static inline void QCBOREncode_AddB64URLText_2(QCBOREncodeContext *pCtx, const char *szLabel, int64_t nLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_B64URL);
+   QCBOREncode_AddBytes_2(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, szLabel, nLabel, Bytes);
+}
 
 #define QCBOREncode_AddB64URLText(pCtx, Bytes) \
-      QCBOREncode_AddText_3((pCtx), NULL, QCBOR_NO_INT_LABEL, CBOR_TAG_B64URL, (Bytes))
+      QCBOREncode_AddB64URLText_2((pCtx), NULL, QCBOR_NO_INT_LABEL, CBOR_TAG_B64URL, (Bytes))
 
 #define QCBOREncode_AddB64URLTextToMap(pCtx, szLabel, Bytes) \
-      QCBOREncode_AddText_3((pCtx), (szLabel), QCBOR_NO_INT_LABEL, CBOR_TAG_B64URL, (Bytes))
+      QCBOREncode_AddB64URLText_2((pCtx), (szLabel), QCBOR_NO_INT_LABEL, CBOR_TAG_B64URL, (Bytes))
 
 #define QCBOREncode_AddB64URLTextToMapN(pCtx, nLabel, Bytes) \
-      QCBOREncode_AddText_3((pCtx), NULL, (nLabel), CBOR_TAG_B64URL, (Bytes))
+      QCBOREncode_AddB64URLText_2((pCtx), NULL, (nLabel), CBOR_TAG_B64URL, (Bytes))
+
+
+
+static inline void QCBOREncode_AddRegex_2(QCBOREncodeContext *pCtx, const char *szLabel, int64_t nLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_REGEX);
+   QCBOREncode_AddBytes_2(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, szLabel, nLabel, Bytes);
+}
 
 #define QCBOREncode_AddRegex(pCtx, Bytes) \
-      QCBOREncode_AddText_3((pCtx), NULL, QCBOR_NO_INT_LABEL, CBOR_TAG_REGEX, (Bytes))
+      QCBOREncode_AddRegex_2((pCtx), NULL, QCBOR_NO_INT_LABEL, (Bytes))
 
 #define QCBOREncode_AddRegexToMap(pCtx, szLabel, Bytes) \
-      QCBOREncode_AddText_3((pCtx), (szLabel), QCBOR_NO_INT_LABEL, CBOR_TAG_REGEX, (Bytes))
+      QCBOREncode_AddRegex_2((pCtx), (szLabel), QCBOR_NO_INT_LABEL, (Bytes))
 
 #define QCBOREncode_AddRegexToMapN(pCtx, nLabel, Bytes) \
-      QCBOREncode_AddText_3((pCtx), NULL, (nLabel), CBOR_TAG_REGEX, (Bytes))
+      QCBOREncode_AddRegex_2((pCtx), NULL, (nLabel), (Bytes))
+
+
+
+static inline void QCBOREncode_AddMIMEData_2(QCBOREncodeContext *pCtx, const char *szLabel, int64_t nLabel, UsefulBufC Bytes)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_MIME);
+   QCBOREncode_AddBytes_2(pCtx, CBOR_MAJOR_TYPE_TEXT_STRING, szLabel, nLabel, Bytes);
+}
 
 #define QCBOREncode_AddMIMEData(pCtx, Bytes) \
-      QCBOREncode_AddText_3((pCtx), NULL, QCBOR_NO_INT_LABEL, CBOR_TAG_MIME, (Bytes))
+      QCBOREncode_AddMIMEData_2((pCtx), NULL, QCBOR_NO_INT_LABEL, (Bytes))
 
 #define QCBOREncode_AddMIMEDataToMap(pCtx, szLabel, Bytes) \
-      QCBOREncode_AddText_3((pCtx), (szLabel), QCBOR_NO_INT_LABEL, CBOR_TAG_MIME, (Bytes))
+      QCBOREncode_AddMIMEData_2((pCtx), (szLabel), QCBOR_NO_INT_LABEL, (Bytes))
 
 #define QCBOREncode_AddMIMEDataToMapN(pCtx, nLabel, Bytes) \
-      QCBOREncode_AddText_3((pCtx), NULL, (nLabel), CBOR_TAG_MIME, (Bytes))
+      QCBOREncode_AddMIMEData_2((pCtx), NULL, (nLabel), (Bytes))
 
 
 
@@ -1254,7 +1318,6 @@
  @param[in] szLabel   A string label for the bytes to add. NULL if no label.
  @param[in] nLabel    The integer map label for this integer value.
  
- @return
  None.
  
  The string szDate should be in the form of RFC 3339 as refined by section
@@ -1264,18 +1327,23 @@
  at all. If you add an incorrect format date string, the generated
  CBOR will be incorrect and the receiver may not be able to handle it.
  
- Error handling is the same as QCBOREncode_AddInt64_3().
+ Error handling is the same as QCBOREncode_AddInt64_2().
  
  */
+static inline void QCBOREncode_AddDateString_2(QCBOREncodeContext *pCtx, const char *szLabel, int64_t nLabel, const char *szDate)
+{
+   QCBOREncode_AddTag(pCtx, CBOR_TAG_DATE_STRING);
+   QCBOREncode_AddSZString_2(pCtx, szLabel, nLabel, szDate);
+}
 
 #define QCBOREncode_AddDateString(pCtx, szDate) \
-      QCBOREncode_AddSZString_3((pCtx), NULL, QCBOR_NO_INT_LABEL, CBOR_TAG_DATE_STRING, (szDate))
+      QCBOREncode_AddDateString_2((pCtx), NULL, QCBOR_NO_INT_LABEL, (szDate))
 
 #define QCBOREncode_AddDateStringToMap(pCtx, szLabel, szDate)  \
-      QCBOREncode_AddSZString_3(pCtx, (szLabel), QCBOR_NO_INT_LABEL, CBOR_TAG_DATE_STRING, (szDate))
+      QCBOREncode_AddDateString_2(pCtx, szLabel, QCBOR_NO_INT_LABEL, (szDate))
 
 #define QCBOREncode_AddDateStringToMapN(pCtx, nLabel, szDate)  \
-      QCBOREncode_AddSZString_3(pCtx, NULL, (nLabel), CBOR_TAG_DATE_STRING, (szDate))
+      QCBOREncode_AddDateString_2(pCtx, NULL, (nLabel), (szDate))
 
 
 
@@ -1287,24 +1355,26 @@
  @param[in] pCtx      The encoding context to add the simple value to.
  @param[in] szLabel   A string label for the bytes to add. NULL if no label.
  @param[in] nLabel    The integer map label for this integer value.
- @param[in] uTag      Optional CBOR data tag or CBOR_TAG_NONE.
  @param[in] uSimple   One of CBOR_SIMPLEV_FALSE through _UNDEF
 
  CBOR defines encoding for special values "true", "false", "null" and "undef". This
  function can add these values.
  
- Error handling is the same as QCBOREncode_AddInt64_3().
+ Error handling is the same as QCBOREncode_AddInt64_2().
  */
-void QCBOREncode_AddSimple_3(QCBOREncodeContext *pCtx, const char *szLabel, int64_t nLabel, uint64_t uTag, uint8_t uSimple);
+void QCBOREncode_AddSimple_2(QCBOREncodeContext *pCtx, const char *szLabel, int64_t nLabel, uint8_t uSimple);
+
 
 #define QCBOREncode_AddSimple(pCtx, uSimple) \
-      QCBOREncode_AddSimple_3((pCtx), NULL,  QCBOR_NO_INT_LABEL, CBOR_TAG_NONE, (uSimple))
+      QCBOREncode_AddSimple_2((pCtx), NULL,  QCBOR_NO_INT_LABEL, (uSimple))
 
 #define QCBOREncode_AddSimpleToMap(pCtx, szLabel, uSimple) \
-      QCBOREncode_AddSimple_3((pCtx), (szLabel),  QCBOR_NO_INT_LABEL, CBOR_TAG_NONE, (uSimple))
+      QCBOREncode_AddSimple_2((pCtx), (szLabel),  QCBOR_NO_INT_LABEL, (uSimple))
 
 #define QCBOREncode_AddSimpleToMapN(pCtx, nLabel, uSimple) \
-      QCBOREncode_AddSimple_3((pCtx), NULL, (nLabel), CBOR_TAG_NONE, (uSimple))
+      QCBOREncode_AddSimple_2((pCtx), NULL, (nLabel), (uSimple))
+
+
 
 
 /**
@@ -1314,29 +1384,34 @@
  @param[in] pCtx      The encoding context to add the simple value to.
  @param[in] szLabel   A string label for the bytes to add. NULL if no label.
  @param[in] nLabel    The integer map label for this integer value.
- @param[in] uTag      Optional CBOR data tag or CBOR_TAG_NONE.
  @param[in] b      true or false from stdbool. Anything will result in an error.
  
- Error handling is the same as QCBOREncode_AddInt64_3().
+ Error handling is the same as QCBOREncode_AddInt64_2().
  */
 
-inline static void QCBOREncode_AddBool_3(QCBOREncodeContext *pCtx, const char *szLabel, int64_t nLabel, uint64_t uTag, bool b) {
+
+inline static void QCBOREncode_AddBool_2(QCBOREncodeContext *pCtx, const char *szLabel, int64_t nLabel, bool b)
+{
    uint8_t uSimple = CBOR_SIMPLE_BREAK; // CBOR_SIMPLE_BREAK is invalid here. The point is to cause an error later
    if(b == true || b == false)
       uSimple = CBOR_SIMPLEV_FALSE + b;;
-   QCBOREncode_AddSimple_3(pCtx, szLabel, nLabel, uTag, uSimple);
+   QCBOREncode_AddSimple_2(pCtx, szLabel, nLabel, uSimple);
 }
 
 #define QCBOREncode_AddBool(pCtx, bool) \
-   QCBOREncode_AddBool_3((pCtx), NULL,  QCBOR_NO_INT_LABEL, CBOR_TAG_NONE, (bool))
+   QCBOREncode_AddBool_2((pCtx), NULL,  QCBOR_NO_INT_LABEL, (bool))
 
 #define QCBOREncode_AddBoolToMap(pCtx, szLabel, bool) \
-   QCBOREncode_AddBool_3((pCtx), (szLabel),  QCBOR_NO_INT_LABEL, CBOR_TAG_NONE, (bool))
+   QCBOREncode_AddBool_2((pCtx), (szLabel),  QCBOR_NO_INT_LABEL, (bool))
 
 #define QCBOREncode_AddBoolToMapN(pCtx, nLabel, bool) \
-   QCBOREncode_AddBool_3((pCtx), NULL, (nLabel), CBOR_TAG_NONE, (bool))
+   QCBOREncode_AddBool_2((pCtx), NULL, (nLabel), (bool))
 
 
+
+// TODO: document this
+void OpenMapOrArray_2(QCBOREncodeContext *me, uint8_t uMajorType, const char *szLabel, uint64_t nLabel);
+
 /**
  
  @brief  Indicates that the next items added are in an array.
@@ -1344,7 +1419,6 @@
  @param[in] pCtx The encoding context to open the array in.
  @param[in] szLabel A NULL-terminated string label for the map. May be a NULL pointer.
  @param[in] nLabel An integer label for the whole map. QCBOR_NO_INT_LABEL for no integer label.
- @param[in] uTag A tag for the whole map or CBOR_TAG_NONE.
  
  Arrays are the basic CBOR aggregate or structure type. Call this
  function to start or open an array. The call the various AddXXX
@@ -1383,16 +1457,19 @@
  to get to all the data needed for a signature verification.
  */
 
-void QCBOREncode_OpenArray_3(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t nLabel, uint64_t uTag);
+static inline void QCBOREncode_OpenArray_2(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t nLabel)
+{
+   OpenMapOrArray_2(pCtx, CBOR_MAJOR_TYPE_ARRAY, szLabel, nLabel);
+}
 
 #define QCBOREncode_OpenArray(pCtx) \
-      QCBOREncode_OpenArray_3((pCtx), NULL, QCBOR_NO_INT_LABEL, CBOR_TAG_NONE)
+      QCBOREncode_OpenArray_2((pCtx), NULL, QCBOR_NO_INT_LABEL)
 
 #define QCBOREncode_OpenArrayInMap(pCtx, szLabel) \
-      QCBOREncode_OpenArray_3((pCtx), (szLabel), QCBOR_NO_INT_LABEL, CBOR_TAG_NONE)
+      QCBOREncode_OpenArray_2((pCtx), (szLabel), QCBOR_NO_INT_LABEL)
 
 #define QCBOREncode_OpenArrayInMapN(pCtx, nLabel) \
-      QCBOREncode_OpenArray_3((pCtx), NULL, (nLabel), CBOR_TAG_NONE)
+      QCBOREncode_OpenArray_2((pCtx), NULL, (nLabel))
 
 
 /**
@@ -1402,7 +1479,6 @@
  @param[in] pCtx The context to add to.
  @param[in] szLabel A NULL-terminated string label for the map. May be a NULL pointer.
  @param[in] nLabel An integer label for the whole map. QCBOR_NO_INT_LABEL for no integer label.
- @param[in] uTag A tag for the whole map or CBOR_TAG_NONE.
  
  See QCBOREncode_OpenArray() for more information.
  
@@ -1423,16 +1499,20 @@
  
  */
 
-void QCBOREncode_OpenMap_3(QCBOREncodeContext *pCtx, const char *szLabel,  uint64_t nLabel, uint64_t uTag);
+static inline void QCBOREncode_OpenMap_2(QCBOREncodeContext *pCtx, const char *szLabel,  uint64_t nLabel)
+{
+   OpenMapOrArray_2(pCtx, CBOR_MAJOR_TYPE_MAP, szLabel, nLabel);
+}
+
 
 #define QCBOREncode_OpenMap(pCtx) \
-      QCBOREncode_OpenMap_3((pCtx), NULL, QCBOR_NO_INT_LABEL, CBOR_TAG_NONE)
+      QCBOREncode_OpenMap_2((pCtx), NULL, QCBOR_NO_INT_LABEL)
 
 #define QCBOREncode_OpenMapInMap(pCtx, szLabel) \
-      QCBOREncode_OpenMap_3((pCtx), (szLabel), QCBOR_NO_INT_LABEL, CBOR_TAG_NONE)
+      QCBOREncode_OpenMap_2((pCtx), (szLabel), QCBOR_NO_INT_LABEL)
 
 #define QCBOREncode_OpenMapInMapN(pCtx, nLabel) \
-      QCBOREncode_OpenMap_3((pCtx), NULL, (nLabel), CBOR_TAG_NONE)
+      QCBOREncode_OpenMap_2((pCtx), NULL, (nLabel))
 
 
 /**
@@ -1482,7 +1562,6 @@
  @param[in] pCtx The context to add to.
  @param[in] szLabel A NULL-terminated string label for the map. May be a NULL pointer.
  @param[in] nLabel An integer label for the whole map. QCBOR_NO_INT_LABEL for no integer label.
- @param[in] uTag A tag for the whole map or CBOR_TAG_NONE.
 
  All added encoded items between this call and a call to
  QCBOREncode_CloseBstrWrap() will be wrapped in a bstr. They will
@@ -1497,16 +1576,19 @@
  Sig_structure) potentially saving a lot of memory.
 
  */
-void QCBOREncode_OpenBstrWrap_3(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t nLabel, uint64_t uTag);
+static inline void QCBOREncode_OpenBstrWrap_2(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t nLabel)
+{
+   OpenMapOrArray_2(pCtx, CBOR_MAJOR_TYPE_BYTE_STRING, szLabel, nLabel);
+}
 
 #define QCBOREncode_BstrWrap(pCtx) \
-      QCBOREncode_OpenBstrWrap_3((pCtx), NULL, QCBOR_NO_INT_LABEL, CBOR_TAG_NONE)
+      QCBOREncode_OpenBstrWrap_2((pCtx), NULL, QCBOR_NO_INT_LABEL)
 
 #define QCBOREncode_BstrWrapInMap(pCtx, szLabel) \
-      QCBOREncode_OpenBstrWrap_3((pCtx), (szLabel), QCBOR_NO_INT_LABEL, CBOR_TAG_NONE)
+      QCBOREncode_OpenBstrWrap_2((pCtx), (szLabel), QCBOR_NO_INT_LABEL)
 
 #define QCBOREncode_BstrWrapMapN(pCtx, nLabel) \
-      QCBOREncode_OpenBstrWrap_3((pCtx), NULL, (nLabel), CBOR_TAG_NONE)
+      QCBOREncode_OpenBstrWrap_2((pCtx), NULL, (nLabel))
 
 
 
@@ -1516,7 +1598,6 @@
  @param[in] pCtx The context to add to.
  @param[in] szLabel A NULL-terminated string label for the map. May be a NULL pointer.
  @param[in] nLabel An integer label for the whole map. QCBOR_NO_INT_LABEL for no integer label.
- @param[in] uTag A tag for the whole map or CBOR_TAG_NONE.
  @param[in] Encoded The already-encoded CBOR to add to the context.
  
  The encoded CBOR being added must be fully conforming CBOR. It must
@@ -1534,16 +1615,19 @@
  
  */
 
-void QCBOREncode_AddEncodedToMap_3(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t nLabel, uint64_t uTag, UsefulBufC Encoded);
+static inline void QCBOREncode_AddEncodedToMap_2(QCBOREncodeContext *pCtx, const char *szLabel, uint64_t nLabel, UsefulBufC Encoded)
+{
+   QCBOREncode_AddBytes_2(pCtx, CBOR_MAJOR_NONE_TYPE_RAW, szLabel, nLabel, Encoded);
+}
 
 #define QCBOREncode_AddEncodedToMapN(pCtx, nLabel, Encoded) \
-      QCBOREncode_AddEncodedToMap_3((pCtx), NULL, (nLabel), CBOR_TAG_NONE, Encoded)
+      QCBOREncode_AddEncodedToMap_2((pCtx), NULL, (nLabel), Encoded)
 
 #define QCBOREncode_AddEncoded(pCtx, Encoded) \
-      QCBOREncode_AddEncodedToMap_3((pCtx), NULL, QCBOR_NO_INT_LABEL, CBOR_TAG_NONE, (Encoded))
+      QCBOREncode_AddEncodedToMap_2((pCtx), NULL, QCBOR_NO_INT_LABEL, (Encoded))
 
 #define QCBOREncode_AddEncodedToMap(pCtx, szLabel, Encoded) \
-      QCBOREncode_AddEncodedToMap_3((pCtx), (szLabel), QCBOR_NO_INT_LABEL, CBOR_TAG_NONE, (Encoded))
+      QCBOREncode_AddEncodedToMap_2((pCtx), (szLabel), QCBOR_NO_INT_LABEL, (Encoded))
 
 
 /**
@@ -1553,7 +1637,6 @@
  @param[in] pCtx      The encoding context to add the simple value to.
  @param[in] szLabel   A string label for the bytes to add. NULL if no label.
  @param[in] nLabel    The integer map tag / label for this integer value.
- @param[in] uTag      Optional CBOR data tag or CBOR_TAG_NONE.
  @param[in] uSimple   One of CBOR_SIMPLEV_xxx.
  
  There should be no need to use this function directly unless some
@@ -1562,9 +1645,9 @@
  below. Float and double are also simple types and have functions to
  add them above.
  
- Error handling is the same as QCBOREncode_AddInt64_3().
+ Error handling is the same as QCBOREncode_AddInt64_2().
  */
-void QCBOREncode_AddRawSimple_3(QCBOREncodeContext *pCtx, const char *szLabel, int64_t nLabel, uint64_t uTag, uint8_t uSimple);
+void QCBOREncode_AddRawSimple_2(QCBOREncodeContext *pCtx, const char *szLabel, int64_t nLabel, uint8_t uSimple);
 
 
 
diff --git a/src/qcbor_encode.c b/src/qcbor_encode.c
index 7a93614..e1c6387 100644
--- a/src/qcbor_encode.c
+++ b/src/qcbor_encode.c
@@ -82,14 +82,6 @@
 /*...... This is a ruler that is 80 characters long...........................*/
 
 
-// Used internally in the impementation here
-// Must not conflict with any of the official CBOR types
-#define CBOR_MAJOR_NONE_TYPE_RAW  9
-
-
-
-
-
 /*
  CBOR's two nesting types, arrays and maps, are tracked here. There is a
  limit of QCBOR_MAX_ARRAY_NESTING to the number of arrays and maps
@@ -325,7 +317,7 @@
 /*
  Internal function for adding positive and negative integers of all different sizes
  */
-void InsertInt64(QCBOREncodeContext *me, int64_t nNum, uint32_t uPos)
+void InsertInt64(QCBOREncodeContext *me, int64_t nNum, size_t uPos)
 {
    uint8_t      uMajorType;
    uint64_t     uValue;
@@ -339,6 +331,7 @@
    }
    
    InsertEncodedTypeAndNumber(me, uMajorType, 0, uValue, uPos);
+   me->uError = Nesting_Increment(&(me->nesting), 1);
 }
 
 /*
@@ -347,7 +340,7 @@
  different major types.  This is also used to insert raw
  pre-encoded CBOR.
  */
-static void AddBytesInternal2(QCBOREncodeContext *me, UsefulBufC Bytes, uint8_t uMajorType, uint32_t uPos)
+static void AddBytesInternal2(QCBOREncodeContext *me, UsefulBufC Bytes, uint8_t uMajorType, size_t uPos)
 {
    if(Bytes.len >= UINT32_MAX) {
       // This implementation doesn't allow buffers larger than UINT32_MAX. This is
@@ -357,20 +350,15 @@
       me->uError = QCBOR_ERR_BUFFER_TOO_LARGE;
       
    } else {
-      
       if(!me->uError) {
-         
          // If it is not Raw CBOR, add the type and the length
-         uint32_t xx = (uint32_t)UsefulOutBuf_GetEndPosition(&(me->OutBuf));
+         const size_t uPosBeforeInsert = UsefulOutBuf_GetEndPosition(&(me->OutBuf));
          if(uMajorType != CBOR_MAJOR_NONE_TYPE_RAW) {
             InsertEncodedTypeAndNumber(me, uMajorType, 0, Bytes.len, uPos);
          }
-         uint32_t yy = (uint32_t)UsefulOutBuf_GetEndPosition(&(me->OutBuf));
-         uPos += yy-xx;
-         
+         uPos += UsefulOutBuf_GetEndPosition(&(me->OutBuf)) - uPosBeforeInsert;
          
          // Actually add the bytes
-         // TODO: how do we know where to insert this?
          UsefulOutBuf_InsertUsefulBuf(&(me->OutBuf), Bytes, uPos);
          
          // Update the array counting if there is any nesting at all
@@ -379,20 +367,23 @@
    }
 }
 
+
 /*
  Add an optional label. It will go in front of a real data item.
  */
-
 static void AddLabel(QCBOREncodeContext *me, const char *szLabel, int64_t nLabel)
 {
-   uint32_t uPos = (uint32_t)UsefulOutBuf_GetEndPosition(&(me->OutBuf)); // TODO: justify cast
-   if(Nesting_GetMajorType(&(me->nesting)) == 0x1f) {
+   size_t uPos = UsefulOutBuf_GetEndPosition(&(me->OutBuf));
+   if(Nesting_GetMajorType(&(me->nesting)) == CBOR_MAJOR_NONE_TAG_LABEL_REORDER) {
+      // Have to insert the label rather than just appen if a tag
+      // has been added. This is so the tag ends up on the value, not
+      // on the label.
       uPos = Nesting_GetStartPos(&(me->nesting));
       Nesting_Decrease(&(me->nesting));
    }
 
    if(szLabel) {
-      UsefulBufC SZText = UsefulBuf_FromSZ(szLabel);
+      const UsefulBufC SZText = UsefulBuf_FromSZ(szLabel);
       AddBytesInternal2(me, SZText, CBOR_MAJOR_TYPE_TEXT_STRING, uPos);
    } else if (QCBOR_NO_INT_LABEL != nLabel) {
       InsertInt64(me, nLabel, uPos);
@@ -400,17 +391,18 @@
 }
 
 
-
 /*
  Public Function
  */
 void QCBOREncode_AddTag(QCBOREncodeContext *me, uint64_t uTag)
 {
    uint8_t uNestingType = Nesting_GetMajorType(&(me->nesting));
-   if(uNestingType == CBOR_MAJOR_TYPE_MAP) {
+   if(uNestingType == CBOR_MAJOR_TYPE_MAP || uNestingType == CBOR_MAJOR_TYPE_ARRAY) { // TODO: really do this for arrays?
       // Remember where the first tag is for this item
       // So we can go back and insert the label in front of it.
-      me->uError = Nesting_Increase(&(me->nesting), 0x1f, (uint32_t)UsefulOutBuf_GetEndPosition(&(me->OutBuf)));
+      // Cast to uint32_t here is OK all sizes are limited to 4GB by other checks
+      const uint32_t uPos = (uint32_t)UsefulOutBuf_GetEndPosition(&(me->OutBuf));
+      me->uError = Nesting_Increase(&(me->nesting), CBOR_MAJOR_NONE_TAG_LABEL_REORDER, uPos);
    }
 
    AppendEncodedTypeAndNumber(me, CBOR_MAJOR_TYPE_OPTIONAL, uTag);
@@ -422,38 +414,21 @@
 {
    AddLabel(me, szLabel, nLabel);
    if(!me->uError) {
-      AddBytesInternal2(me, Bytes, uMajorType, (uint32_t)UsefulOutBuf_GetEndPosition(&(me->OutBuf)));
+      AddBytesInternal2(me, Bytes, uMajorType, UsefulOutBuf_GetEndPosition(&(me->OutBuf)));
    }
 }
 
-/*
- Public functions for adding strings and raw encoded CBOR. See header qcbor.h
- */
-void QCBOREncode_AddBytes_3(QCBOREncodeContext *me, const char *szLabel, int64_t nLabel, uint64_t uTag, UsefulBufC Bytes)
-{
-   QCBOREncode_AddBytes_2(me, CBOR_MAJOR_TYPE_BYTE_STRING, szLabel, nLabel, Bytes);
-}
-
-void QCBOREncode_AddText_3(QCBOREncodeContext *me, const char *szLabel, int64_t nLabel, uint64_t uTag, UsefulBufC Bytes)
-{
-   QCBOREncode_AddBytes_2(me, CBOR_MAJOR_TYPE_TEXT_STRING, szLabel, nLabel, Bytes);
-}
-
-void QCBOREncode_AddEncodedToMap_3(QCBOREncodeContext *me, const char *szLabel, uint64_t nLabel, uint64_t uTag, UsefulBufC Encoded)
-{
-   QCBOREncode_AddBytes_2(me, CBOR_MAJOR_NONE_TYPE_RAW, szLabel, nLabel, Encoded);
-}
-
 
 
 /*
+ TODO: fix docu
  Internal function common to opening an array or a map
  
  QCBOR_MAX_ARRAY_NESTING is the number of times Open can be called
  successfully.  Call it one more time gives an error.
  
  */
-static void OpenMapOrArrayInternal(QCBOREncodeContext *me, uint8_t uMajorType, const char *szLabel, uint64_t nLabel)
+void OpenMapOrArray_2(QCBOREncodeContext *me, uint8_t uMajorType, const char *szLabel, uint64_t nLabel)
 {
    AddLabel(me, szLabel, nLabel);
    
@@ -471,22 +446,8 @@
 
 
 /*
- Public functions for opening / closing arrays and maps. See header qcbor.h
+ Public functions for closing arrays and maps. See header qcbor.h
  */
-void QCBOREncode_OpenArray_3(QCBOREncodeContext *me, const char *szLabel, uint64_t nLabel, uint64_t uTag)
-{
-   OpenMapOrArrayInternal(me, CBOR_MAJOR_TYPE_ARRAY, szLabel, nLabel);
-}
-
-void QCBOREncode_OpenMap_3(QCBOREncodeContext *me, const char *szLabel, uint64_t nLabel, uint64_t uTag)
-{
-   OpenMapOrArrayInternal(me, CBOR_MAJOR_TYPE_MAP, szLabel, nLabel);
-}
-
-void QCBOREncode_OpenBstrWrap_3(QCBOREncodeContext *me, const char *szLabel, uint64_t nLabel, uint64_t uTag)
-{
-   OpenMapOrArrayInternal(me, CBOR_MAJOR_TYPE_BYTE_STRING, szLabel, nLabel);
-}
 
 void QCBOREncode_Close(QCBOREncodeContext *me, uint8_t uMajorType, UsefulBufC *pWrappedCBOR)
 {
@@ -506,6 +467,7 @@
          
          // Cast from size_t to uin32_t is safe because the UsefulOutBuf
          // size is limited to UINT32_MAX in QCBOR_Init().
+         // TODO: can these be size_t? Check them for over/underflow
          const uint32_t uEndPosition = (uint32_t)UsefulOutBuf_GetEndPosition(&(me->OutBuf));
          const uint32_t uLenOfEncodedMapOrArray = uEndPosition - uInsertPosition;
          
@@ -555,7 +517,6 @@
    AddLabel(me, szLabel, nLabel);
    if(!me->uError) {
       InsertInt64(me, nNum, (uint32_t)UsefulOutBuf_GetEndPosition(&(me->OutBuf)));
-      me->uError = Nesting_Increment(&(me->nesting), 1);
    }
 }
 
@@ -576,7 +537,7 @@
      - additional integer 31 is a "break"
      - additional integers 32-255 are unassigned and could be used in an update to CBOR
  */
-static void AddSimpleInternal(QCBOREncodeContext *me, const char *szLabel, int64_t nLabel, uint64_t uTag, size_t uSize, uint64_t uNum)
+static void AddSimpleInternal(QCBOREncodeContext *me, const char *szLabel, int64_t nLabel, size_t uSize, uint64_t uNum)
 {
    AddLabel(me, szLabel, nLabel);
    if(!me->uError) {
@@ -595,21 +556,21 @@
 /*
  Public function for adding simple values. See header qcbor.h
  */
-void QCBOREncode_AddRawSimple_3(QCBOREncodeContext *me, const char *szLabel, int64_t nLabel, uint64_t uTag, uint8_t uSimple)
+void QCBOREncode_AddRawSimple_2(QCBOREncodeContext *me, const char *szLabel, int64_t nLabel, uint8_t uSimple)
 {
-   AddSimpleInternal(me, szLabel, nLabel, uTag, 0, uSimple);
+   AddSimpleInternal(me, szLabel, nLabel, 0, uSimple);
 }
 
 
 /*
  Public function for adding simple values. See header qcbor.h
  */
-void QCBOREncode_AddSimple_3(QCBOREncodeContext *me, const char *szLabel, int64_t nLabel, uint64_t uTag, uint8_t uSimple)
+void QCBOREncode_AddSimple_2(QCBOREncodeContext *me, const char *szLabel, int64_t nLabel, uint8_t uSimple)
 {
    if(uSimple < CBOR_SIMPLEV_FALSE || uSimple > CBOR_SIMPLEV_UNDEF) {
       me->uError = QCBOR_ERR_BAD_SIMPLE;
    } else {
-      QCBOREncode_AddRawSimple_3(me, szLabel, nLabel, uTag, uSimple);
+      QCBOREncode_AddRawSimple_2(me, szLabel, nLabel, uSimple);
    }
 }
 
@@ -617,7 +578,7 @@
 /*
  Public functions for floating point numbers. See header qcbor.h
  */
-void QCBOREncode_AddFloat_3(QCBOREncodeContext *me, const char *szLabel, int64_t nLabel, uint64_t uTag, float fNum)
+void QCBOREncode_AddFloat_2(QCBOREncodeContext *me, const char *szLabel, int64_t nLabel, float fNum)
 {
    // Convert the *type* of the data from a float to a uint so the
    // standard integer encoding can work.  This takes advantage
@@ -626,46 +587,46 @@
    const float *pfNum  = &fNum;
    const uint32_t uNum = *(uint32_t *)pfNum;
       
-   AddSimpleInternal(me, szLabel, nLabel, uTag, sizeof(float), uNum);
+   AddSimpleInternal(me, szLabel, nLabel, sizeof(float), uNum);
 }
 
-void QCBOREncode_AddDouble_3(QCBOREncodeContext *me, const char *szLabel, int64_t nLabel, uint64_t uTag, double dNum)
+void QCBOREncode_AddDouble_2(QCBOREncodeContext *me, const char *szLabel, int64_t nLabel, double dNum)
 {
    // see how it is done for floats above
    const double *pdNum = &dNum;
    const uint64_t uNum = *(uint64_t *)pdNum;
    
-   AddSimpleInternal(me, szLabel, nLabel, uTag, sizeof(double), uNum);
+   AddSimpleInternal(me, szLabel, nLabel, sizeof(double), uNum);
 }
 
-void QCBOREncode_AddFloatAsHalf_3(QCBOREncodeContext *me, const char *szLabel, int64_t nLabel, uint64_t uTag, float fNum)
+void QCBOREncode_AddFloatAsHalf_2(QCBOREncodeContext *me, const char *szLabel, int64_t nLabel, float fNum)
 {
-    AddSimpleInternal(me, szLabel, nLabel, uTag, sizeof(uint16_t), IEEE754_FloatToHalf(fNum));
+    AddSimpleInternal(me, szLabel, nLabel, sizeof(uint16_t), IEEE754_FloatToHalf(fNum));
 }
 
-static void QCBOREncode_AddFUnionAsSmallest_3(QCBOREncodeContext *me, const char *szLabel, int64_t nLabel, uint64_t uTag, IEEE754_union uNum)
+static void QCBOREncode_AddFUnionAsSmallest_2(QCBOREncodeContext *me, const char *szLabel, int64_t nLabel, IEEE754_union uNum)
 {
    switch(uNum.uTag) {
       case IEEE754_UNION_IS_HALF:
-         AddSimpleInternal(me, szLabel, nLabel, uTag, sizeof(uint16_t), uNum.u16);
+         AddSimpleInternal(me, szLabel, nLabel, sizeof(uint16_t), uNum.u16);
          break;
       case IEEE754_UNION_IS_SINGLE:
-         AddSimpleInternal(me, szLabel, nLabel, uTag, sizeof(uint32_t), uNum.u32);
+         AddSimpleInternal(me, szLabel, nLabel, sizeof(uint32_t), uNum.u32);
          break;
       case IEEE754_UNION_IS_DOUBLE:
-         AddSimpleInternal(me, szLabel, nLabel, uTag, sizeof(uint64_t), uNum.u64);
+         AddSimpleInternal(me, szLabel, nLabel, sizeof(uint64_t), uNum.u64);
          break;
    }
 }
 
-void QCBOREncode_AddFloatAsSmallest_3(QCBOREncodeContext *me, const char *szLabel, int64_t nLabel, uint64_t uTag, float fNum)
+void QCBOREncode_AddFloatAsSmallest_2(QCBOREncodeContext *me, const char *szLabel, int64_t nLabel, float fNum)
 {
-   QCBOREncode_AddFUnionAsSmallest_3(me, szLabel, nLabel, uTag, IEEE754_FloatToSmallest(fNum));
+   QCBOREncode_AddFUnionAsSmallest_2(me, szLabel, nLabel, IEEE754_FloatToSmallest(fNum));
 }
 
-void QCBOREncode_AddDoubleAsSmallest_3(QCBOREncodeContext *me, const char *szLabel, int64_t nLabel, uint64_t uTag, double dNum)
+void QCBOREncode_AddDoubleAsSmallest_2(QCBOREncodeContext *me, const char *szLabel, int64_t nLabel, double dNum)
 {
-   QCBOREncode_AddFUnionAsSmallest_3(me, szLabel, nLabel, uTag, IEEE754_DoubleToSmallest(dNum));
+   QCBOREncode_AddFUnionAsSmallest_2(me, szLabel, nLabel, IEEE754_DoubleToSmallest(dNum));
 }
 
 
diff --git a/test/qcbor_encode_tests.c b/test/qcbor_encode_tests.c
index f28671d..77a8a6e 100644
--- a/test/qcbor_encode_tests.c
+++ b/test/qcbor_encode_tests.c
@@ -64,13 +64,13 @@
 
 // TODO: test QCBOR_MAX_ITEMS_IN_ARRAY (this is very large...)
 
-#ifdef PRINT_FUNCTIONS_FOR_DEBUGGINGXX
+#if PRINT_FUNCTIONS_FOR_DEBUGGINGXX
 #include <stdio.h>
 
 // ifdef these out to not have compiler warnings
 static void printencoded(const uint8_t *pEncoded, size_t nLen)
 {
-   int i;
+   size_t i;
    for(i = 0; i < nLen; i++) {
       uint8_t Z = pEncoded[i];
       printf("%02x ", Z);
@@ -84,25 +84,30 @@
 #include <stdio.h>
 
 int Compare(UsefulBufC U1, UsefulBufC U2) {
-   int i;
+   size_t i;
    for(i = 0; i < U1.len; i++) {
       if(((uint8_t *)U1.ptr)[i] != ((uint8_t *)U2.ptr)[i]) {
-         printf("%d 0x%x 0x%x\n", i, ((uint8_t *)U1.ptr)[i], ((uint8_t *)U2.ptr)[i]);
+         printf("Position: %d  Actual: 0x%x   Expected: 0x%x\n", i, ((uint8_t *)U1.ptr)[i], ((uint8_t *)U2.ptr)[i]);
          return 1;
       }
    }
    return 0;
    
 }
-#endif
 
+#define CheckResults(Enc, Expected) \
+   Compare(Enc, (UsefulBufC){Expected, sizeof(Expected)})
 
+#else
 
 #define CheckResults(Enc, Expected) \
    UsefulBuf_Compare(Enc, (UsefulBufC){Expected, sizeof(Expected)})
 
-//#define CheckResults(Enc, Expected) \
-//   Compare(Enc, (UsefulBufC){Expected, sizeof(Expected)})
+#endif
+
+
+
+
 
 
 
@@ -498,8 +503,10 @@
    QCBOREncode_OpenArray(&ECtx);
 
    // Non-map ints
-   // QCBOREncode_AddUInt64_3(&ECtx, "UINT62", QCBOR_NO_INT_LABEL, 100, 89989909); TODO: fix these tests
-   //QCBOREncode_AddInt64_3(&ECtx, "INT64", QCBOR_NO_INT_LABEL, 76, 77689989909);
+   QCBOREncode_AddTag(&ECtx, 100);
+   QCBOREncode_AddUInt64_2(&ECtx, "UINT62", QCBOR_NO_INT_LABEL, 89989909);
+   QCBOREncode_AddTag(&ECtx, 76);
+   QCBOREncode_AddInt64_2(&ECtx, "INT64", QCBOR_NO_INT_LABEL, 77689989909);
    QCBOREncode_AddUInt64(&ECtx,0);
    QCBOREncode_AddInt64(&ECtx, -44);
 
@@ -512,8 +519,10 @@
    QCBOREncode_CloseMap(&ECtx);
 
    // floats and doubles
-   QCBOREncode_AddFloat_3(&ECtx, "Jaime", QCBOR_NO_INT_LABEL, 88, 3.14159);
-   QCBOREncode_AddDouble_3(&ECtx, "Street", QCBOR_NO_INT_LABEL, 99, 8.654309);
+   QCBOREncode_AddTag(&ECtx, 88);
+   QCBOREncode_AddFloat_2(&ECtx, "Jaime", QCBOR_NO_INT_LABEL, 3.14159);
+   QCBOREncode_AddTag(&ECtx, 99);
+   QCBOREncode_AddDouble_2(&ECtx, "Street", QCBOR_NO_INT_LABEL, 8.654309);
    QCBOREncode_AddFloat(&ECtx, 1);
    QCBOREncode_AddDouble(&ECtx, 1);
 
@@ -540,7 +549,8 @@
 
    // binary blobs in maps
    QCBOREncode_OpenMap(&ECtx);
-   QCBOREncode_AddBytes_3(&ECtx, "binbin", QCBOR_NO_INT_LABEL, 100000, ((UsefulBufC) {(uint8_t []){0x00}, 1}));
+   QCBOREncode_AddTag(&ECtx, 100000);
+   QCBOREncode_AddBytes_2(&ECtx, CBOR_MAJOR_TYPE_BYTE_STRING, "binbin", QCBOR_NO_INT_LABEL, ((UsefulBufC) {(uint8_t []){0x00}, 1}));
    QCBOREncode_AddBytesToMap(&ECtx, "blabel", ((UsefulBufC){(uint8_t []){0x01, 0x02, 0x03}, 3}));
    QCBOREncode_AddBytesToMapN(&ECtx, 0, ((UsefulBufC){(uint8_t []){0x04, 0x02, 0x03, 0xfe}, 4}));
    QCBOREncode_CloseMap(&ECtx);
@@ -556,8 +566,9 @@
    // text blobs in maps
    QCBOREncode_OpenMap(&ECtx);
    QCBOREncode_AddTextToMap(&ECtx, "#####", SZLiteralToUsefulBufC("foo bar foo foo"));
-   QCBOREncode_AddText_3(&ECtx, "____", QCBOR_NO_INT_LABEL, CBOR_TAG_NONE, SZLiteralToUsefulBufC("foo bar"));
-   QCBOREncode_AddSZString_3(&ECtx, "()()()", QCBOR_NO_INT_LABEL, 1000, "rab rab oof");
+   QCBOREncode_AddTextToMap(&ECtx, "____", SZLiteralToUsefulBufC("foo bar")); // TODO _2? 
+   QCBOREncode_AddTag(&ECtx, 1000);
+   QCBOREncode_AddSZString_2(&ECtx, "()()()", QCBOR_NO_INT_LABEL, "rab rab oof");
    QCBOREncode_AddTextToMapN(&ECtx,22, SZLiteralToUsefulBufC("foo foo foo foo"));
    QCBOREncode_AddSZStringToMap(&ECtx, "^^", "oooooooof");
    QCBOREncode_AddSZStringToMapN(&ECtx, 99, "ffffoooooooof");
@@ -581,7 +592,8 @@
    // true / false ...
    QCBOREncode_AddSimple(&ECtx, CBOR_SIMPLEV_UNDEF);
    QCBOREncode_OpenMap(&ECtx);
-   QCBOREncode_AddSimple_3(&ECtx, "dare", QCBOR_NO_INT_LABEL, 66, CBOR_SIMPLEV_TRUE);
+   QCBOREncode_AddTag(&ECtx, 66);
+   QCBOREncode_AddSimple_2(&ECtx, "dare", QCBOR_NO_INT_LABEL, CBOR_SIMPLEV_TRUE);
    QCBOREncode_AddSimpleToMap(&ECtx, "uu", CBOR_SIMPLEV_FALSE);
    QCBOREncode_AddSimpleToMapN(&ECtx, 737634, CBOR_SIMPLEV_NULL);
    QCBOREncode_CloseMap(&ECtx);
@@ -592,7 +604,8 @@
 
    // opening arrays in a map
    QCBOREncode_OpenMap(&ECtx);
-   QCBOREncode_OpenArray_3(&ECtx, "label and tagged empty array", QCBOR_NO_INT_LABEL, 1093);
+   QCBOREncode_AddTag(&ECtx, 1093);
+   QCBOREncode_OpenArray_2(&ECtx, "label and tagged empty array", QCBOR_NO_INT_LABEL);
    QCBOREncode_CloseArray(&ECtx);
    QCBOREncode_OpenArrayInMap(&ECtx, "alabl");
    QCBOREncode_CloseArray(&ECtx);
@@ -604,7 +617,8 @@
    QCBOREncode_OpenMap(&ECtx);
    QCBOREncode_OpenMapInMap(&ECtx, "in a map");
    QCBOREncode_OpenMapInMapN(&ECtx, 5556);
-   QCBOREncode_OpenMap_3(&ECtx, "in a in a in a", QCBOR_NO_INT_LABEL, 9087);
+   QCBOREncode_AddTag(&ECtx, 9087);
+   QCBOREncode_OpenMap_2(&ECtx, "in a in a in a", QCBOR_NO_INT_LABEL);
    QCBOREncode_CloseMap(&ECtx);
    QCBOREncode_CloseMap(&ECtx);
    QCBOREncode_CloseMap(&ECtx);
@@ -612,11 +626,15 @@
    
    // Extended simple values (these are not standard...)
    QCBOREncode_OpenMap(&ECtx);
-   QCBOREncode_AddRawSimple_3(&ECtx, "s1", QCBOR_NO_INT_LABEL, 88, 255);
-   QCBOREncode_AddRawSimple_3(&ECtx, "s2", QCBOR_NO_INT_LABEL, CBOR_TAG_NONE, 0);
-   QCBOREncode_AddRawSimple_3(&ECtx, "s3", QCBOR_NO_INT_LABEL, 88, 33);
-   QCBOREncode_AddRawSimple_3(&ECtx, NULL, 88378374, 88, 255);
-   QCBOREncode_AddRawSimple_3(&ECtx, NULL, 89, 88, 19);
+   QCBOREncode_AddTag(&ECtx, 88);
+   QCBOREncode_AddRawSimple_2(&ECtx, "s1", QCBOR_NO_INT_LABEL, 255);
+   QCBOREncode_AddRawSimple_2(&ECtx, "s2", QCBOR_NO_INT_LABEL, 0);
+   QCBOREncode_AddTag(&ECtx, 88);
+   QCBOREncode_AddRawSimple_2(&ECtx, "s3", QCBOR_NO_INT_LABEL, 33);
+   QCBOREncode_AddTag(&ECtx, 88);
+   QCBOREncode_AddRawSimple_2(&ECtx, NULL, 88378374, 255);
+   QCBOREncode_AddTag(&ECtx, 88);
+   QCBOREncode_AddRawSimple_2(&ECtx, NULL, 89, 19);
    QCBOREncode_CloseMap(&ECtx);
    
    
@@ -1596,7 +1614,8 @@
    QCBOREncode_Init(&EC, MemoryForEncoded);
    
    // top level array for cose sign1, 18 is the tag for COSE sign
-   QCBOREncode_OpenArray_3(&EC, NULL, QCBOR_NO_INT_LABEL, 18);
+   QCBOREncode_AddTag(&EC, 18); // TODO: replace with constant
+   QCBOREncode_OpenArray_2(&EC, NULL, QCBOR_NO_INT_LABEL); // TODO: _2
    
    // Add protected headers
    QCBOREncode_AddBytes(&EC, ProtectedHeaders);