diff --git a/bstest.c b/bstest.c
index ec2e2969892422c1e4856310b98f9ae939eb3500_YnN0ZXN0LmM=..ca4a485f8d8477316f90e04acfccdb1d07c1a0b9_YnN0ZXN0LmM= 100644
--- a/bstest.c
+++ b/bstest.c
@@ -63,6 +63,36 @@
 	return (char *) dumpOut[rot]->data;
 }
 
+static char* dumpCstring (const char* s) {
+	rot = (rot + 1) % (unsigned)16;
+	if (dumpOut[rot] == NULL) {
+		dumpOut[rot] = bfromcstr ("");
+		if (dumpOut[rot] == NULL) return "FATAL INTERNAL ERROR";
+	}
+	dumpOut[rot]->slen = 0;
+	if (s == NULL) {
+		bcatcstr (dumpOut[rot], "NULL");
+	} else {
+		static char msg[64];
+		int i;
+
+		sprintf (msg, "cstr[%p] -> ", (void *)s);
+		bcatcstr (dumpOut[rot], msg);
+
+		bcatStatic (dumpOut[rot], "\"");
+		for (i = 0; s[i]; i++) {
+			if (i > 1024) {
+				bcatStatic (dumpOut[rot], " ...");
+				break;
+			}
+			bconchar (dumpOut[rot], s[i]);
+		}
+		bcatStatic (dumpOut[rot], "\"");
+	}
+
+	return (char *) dumpOut[rot]->data;
+}
+
 static int test0_0 (const char * s, const char * res) {
 bstring b0 = bfromcstr (s);
 int ret = 0;
@@ -107,6 +137,51 @@
 #define EIGHT_CHAR_STRING "Waterloo"
 #define LONG_STRING  "This is a bogus but reasonably long string.  Just long enough to cause some mallocing."
 
+static int test0_2 (char* s) {
+int l = s?strlen(s):2;
+int i, j, k;
+int ret = 0;
+
+	for (i = 0; i < l*2; i++) {
+		for (j = 0; j < l*2; j++) {
+			for (k = 0; k <= l; k++) {
+				char* t = s ? (s + k) : NULL;
+				bstring b = bfromcstrrangealloc (i, j, t);
+				if (NULL == b) {
+					if (i < j && t != NULL) {
+						printf ("[%d] i = %d, j = %d, l = %d, k = %d\n", __LINE__, i, j, l, k);
+					}
+					ret += (i < j && t != NULL);
+					continue;
+				}
+				if (NULL == t) {
+					printf ("[%d] i = %d, j = %d, l = %d, k = %d\n", __LINE__, i, j, l, k);
+					ret++;
+					bdestroy (b);
+					continue;
+				}
+				if (b->data == NULL) {
+					printf ("[%d] i = %d, j = %d, l = %d, k = %d\n", __LINE__, i, j, l, k);
+					ret++;
+					continue;
+				}
+				if (b->slen != l-k || b->data[l-k] != '\0' || b->mlen <= b->slen) {
+					printf ("[%d] i = %d, j = %d, l = %d, k = %d, b->slen = %d\n", __LINE__, i, j, l, k, b->slen);
+					ret++;
+				} else if (0 != memcmp (t, b->data, l-k+1)) {
+					printf ("[%d] \"%s\" != \"%s\"\n", b->data, t);
+					ret++;
+				}
+				bdestroy (b);
+				continue;
+			}
+		}
+	}
+
+	printf (".\tbfromcstrrangealloc (*,*,%s) correct\n", dumpCstring(s));
+	return ret;
+}
+
 static int test0 (void) {
 int ret = 0;
 
@@ -134,6 +209,13 @@
 	ret += test0_1 (SHORT_STRING, 30, SHORT_STRING);
 	ret += test0_1 ( LONG_STRING,  0,  LONG_STRING);
 	ret += test0_1 ( LONG_STRING, 30,  LONG_STRING);
+
+	printf ("TEST: bstring bfromcstrrangealloc (int minl, int maxl, const char * str);\n");
+
+	ret += test0_2 (NULL);
+	ret += test0_2 (EMPTY_STRING);
+	ret += test0_2 ( LONG_STRING);
+
 	printf ("\t# failures: %d\n", ret);
 
 	return ret;
diff --git a/bstraux.c b/bstraux.c
index ec2e2969892422c1e4856310b98f9ae939eb3500_YnN0cmF1eC5j..ca4a485f8d8477316f90e04acfccdb1d07c1a0b9_YnN0cmF1eC5j 100644
--- a/bstraux.c
+++ b/bstraux.c
@@ -950,10 +950,9 @@
 	if ((c = UCHAR_MAX + 1) == termchar) c++;
 
 	for (i=0; ; i++) {
-		if (termchar == c || (maxlen > 0 && i >= maxlen)) c = EOF;
-		else c = vgetchar (vgcCtx);
-
+		if (termchar == c || (maxlen > 0 && i >= maxlen)) break;
+		c = vgetchar (vgcCtx);
 		if (EOF == c) break;
 
 		if (i+1 >= b->mlen) {
 
@@ -956,11 +955,10 @@
 		if (EOF == c) break;
 
 		if (i+1 >= b->mlen) {
 
-			/* Double size, but deal with unusual case of numeric
-			   overflows */
+			/* Double size, and deal with numeric overflows */
 
 			if (b->mlen <= INT_MAX / 2) m = b->mlen << 1;
 			else if (b->mlen <= INT_MAX - 1024) m = b->mlen + 1024;
 			else if (b->mlen <= INT_MAX - 16) m = b->mlen + 16;
 			else if (b->mlen <= INT_MAX - 1) m = b->mlen + 1;
@@ -962,8 +960,10 @@
 
 			if (b->mlen <= INT_MAX / 2) m = b->mlen << 1;
 			else if (b->mlen <= INT_MAX - 1024) m = b->mlen + 1024;
 			else if (b->mlen <= INT_MAX - 16) m = b->mlen + 16;
 			else if (b->mlen <= INT_MAX - 1) m = b->mlen + 1;
-			else return NULL;
-			t = bfromcstralloc (m, "");
+			else {
+				bSecureDestroy (b); /* Cleanse partial buffer */
+				return NULL;
+			}
 
@@ -969,2 +969,3 @@
 
+			t = bfromcstrrangealloc (b->mlen + 1, m, "");
 			if (t) memcpy (t->data, b->data, i);
@@ -970,5 +971,5 @@
 			if (t) memcpy (t->data, b->data, i);
-			bSecureDestroy (b); /* Cleanse previous buffer */
+			bSecureDestroy (b);     /* Cleanse previous buffer */
 			b = t;
 			if (!b) return b;
 		}
diff --git a/bstraux.h b/bstraux.h
index ec2e2969892422c1e4856310b98f9ae939eb3500_YnN0cmF1eC5o..ca4a485f8d8477316f90e04acfccdb1d07c1a0b9_YnN0cmF1eC5o 100644
--- a/bstraux.h
+++ b/bstraux.h
@@ -28,9 +28,10 @@
 #define bstrFree(b)                  {if ((b) != NULL && (b)->slen >= 0 && (b)->mlen >= (b)->slen) { bdestroy (b); (b) = NULL; }}
 
 /* Backward compatibilty with previous versions of Bstrlib */
+#if !defined(BSTRLIB_REDUCE_NAMESPACE_POLLUTION)
 #define bAssign(a,b)                 ((bassign)((a), (b)))
 #define bSubs(b,pos,len,a,c)         ((breplace)((b),(pos),(len),(a),(unsigned char)(c)))
 #define bStrchr(b,c)                 ((bstrchr)((b), (c)))
 #define bStrchrFast(b,c)             ((bstrchr)((b), (c)))
 #define bCatCstr(b,s)                ((bcatcstr)((b), (s)))
 #define bCatBlk(b,s,len)             ((bcatblk)((b),(s),(len)))
@@ -31,10 +32,10 @@
 #define bAssign(a,b)                 ((bassign)((a), (b)))
 #define bSubs(b,pos,len,a,c)         ((breplace)((b),(pos),(len),(a),(unsigned char)(c)))
 #define bStrchr(b,c)                 ((bstrchr)((b), (c)))
 #define bStrchrFast(b,c)             ((bstrchr)((b), (c)))
 #define bCatCstr(b,s)                ((bcatcstr)((b), (s)))
 #define bCatBlk(b,s,len)             ((bcatblk)((b),(s),(len)))
-#define bCatStatic(b,s)              bCatBlk ((b), ("" s ""), sizeof (s) - 1)
+#define bCatStatic(b,s)              bcatStatic(b,s)
 #define bTrunc(b,n)                  ((btrunc)((b), (n)))
 #define bReplaceAll(b,find,repl,pos) ((bfindreplace)((b),(find),(repl),(pos)))
 #define bUppercase(b)                ((btoupper)(b))
@@ -43,6 +44,7 @@
 #define bCaselessNCmp(a,b,n)         ((bstrnicmp)((a), (b), (n)))
 #define bBase64Decode(b)             (bBase64DecodeEx ((b), NULL))
 #define bUuDecode(b)                 (bUuDecodeEx ((b), NULL))
+#endif
 
 /* Unusual functions */
 extern struct bStream * bsFromBstr (const_bstring b);
diff --git a/bstrlib.c b/bstrlib.c
index ec2e2969892422c1e4856310b98f9ae939eb3500_YnN0cmxpYi5j..ca4a485f8d8477316f90e04acfccdb1d07c1a0b9_YnN0cmxpYi5j 100644
--- a/bstrlib.c
+++ b/bstrlib.c
@@ -211,5 +211,5 @@
 	return b;
 }
 
-/*  bstring bfromcstralloc (int mlen, const char * str)
+/*  bstring bfromcstrrangealloc (int minl, int maxl, const char* str)
  *
@@ -215,5 +215,6 @@
  *
- *  Create a bstring which contains the contents of the '\0' terminated char *
- *  buffer str.  The memory buffer backing the string is at least len
- *  characters in length.
+ *  Create a bstring which contains the contents of the '\0' terminated
+ *  char* buffer str.  The memory buffer backing the string is at least
+ *  minl characters in length, but an attempt is made to allocate up to
+ *  maxl characters.
  */
@@ -219,6 +220,6 @@
  */
-bstring bfromcstralloc (int mlen, const char * str) {
+bstring bfromcstrrangealloc (int minl, int maxl, const char* str) {
 bstring b;
 int i;
 size_t j;
 
@@ -221,5 +222,6 @@
 bstring b;
 int i;
 size_t j;
 
+	/* Bad parameters? */
 	if (str == NULL) return NULL;
@@ -225,2 +227,5 @@
 	if (str == NULL) return NULL;
+	if (maxl < minl || minl < 0) return NULL;
+
+	/* Adjust lengths */
 	j = (strlen) (str);
@@ -226,7 +231,8 @@
 	j = (strlen) (str);
-	i = snapUpSize ((int) (j + (2 - (j != 0))));
-	if (i <= (int) j) return NULL;
+	if ((size_t) minl < (j+1)) minl = (int) (j+1);
+	if (maxl < minl) maxl = minl;
+	i = maxl;
 
 	b = (bstring) bstr__alloc (sizeof (struct tagbstring));
 	if (b == NULL) return NULL;
 	b->slen = (int) j;
@@ -229,15 +235,18 @@
 
 	b = (bstring) bstr__alloc (sizeof (struct tagbstring));
 	if (b == NULL) return NULL;
 	b->slen = (int) j;
-	if (i < mlen) i = mlen;
-
-	if (NULL == (b->data = (unsigned char *) bstr__alloc (b->mlen = i))) {
-		bstr__free (b);
-		return NULL;
+
+	while (NULL == (b->data = (unsigned char *) bstr__alloc (b->mlen = i))) {
+		int k = (i >> 1) + (minl >> 1);
+		if (i == k || i < minl) {
+			bstr__free (b);
+			return NULL;
+		}
+		i = k;
 	}
 
 	bstr__memcpy (b->data, str, j+1);
 	return b;
 }
 
@@ -238,9 +247,19 @@
 	}
 
 	bstr__memcpy (b->data, str, j+1);
 	return b;
 }
 
+/*  bstring bfromcstralloc (int mlen, const char * str)
+ *
+ *  Create a bstring which contains the contents of the '\0' terminated
+ *  char* buffer str.  The memory buffer backing the string is at least
+ *  mlen characters in length.
+ */
+bstring bfromcstralloc (int mlen, const char * str) {
+	return bfromcstrrangealloc (mlen, mlen, str);
+}
+
 /*  bstring blk2bstr (const void * blk, int len)
  *
  *  Create a bstring which contains the content of the block blk of length
@@ -1566,8 +1585,8 @@
 
 	if (b == NULL || b->data == NULL || find == NULL ||
 		find->data == NULL || repl == NULL || repl->data == NULL ||
-		pos < 0 || find->slen <= 0 || b->mlen < 0 || b->slen > b->mlen ||
-		b->mlen <= 0 || b->slen < 0 || repl->slen < 0) return BSTR_ERR;
+		pos < 0 || find->slen <= 0 || b->mlen <= 0 || b->slen > b->mlen ||
+		b->slen < 0 || repl->slen < 0) return BSTR_ERR;
 	if (pos > b->slen - find->slen) return BSTR_OK;
 
 	/* Alias with find string */
diff --git a/bstrlib.h b/bstrlib.h
index ec2e2969892422c1e4856310b98f9ae939eb3500_YnN0cmxpYi5o..ca4a485f8d8477316f90e04acfccdb1d07c1a0b9_YnN0cmxpYi5o 100644
--- a/bstrlib.h
+++ b/bstrlib.h
@@ -40,6 +40,7 @@
 #define cstr2bstr bfromcstr
 extern bstring bfromcstr (const char * str);
 extern bstring bfromcstralloc (int mlen, const char * str);
+extern bstring bfromcstrrangealloc (int minl, int maxl, const char* str);
 extern bstring blk2bstr (const void * blk, int len);
 extern char * bstr2cstr (const_bstring s, char z);
 extern int bcstrfree (char * s);
@@ -212,6 +213,11 @@
 /* Static constant block parameter pair */
 #define bsStaticBlkParms(q) ((void *)("" q "")), ((int) sizeof(q)-1)
 
+#define bcatStatic(b,s)     ((bcatblk)((b), bsStaticBlkParms(s)))
+#define bfromStatic(s)      ((blk2bstr)(bsStaticBlkParms(s)))
+#define bassignStatic(b,s)  ((bassignblk)((b), bsStaticBlkParms(s)))
+#define bisstemeqcaselessStatic(b,s) ((bisstemeqcaselessblk)((b), bsStaticBlkParms(s)))
+
 /* Reference building macros */
 #define cstr2tbstr btfromcstr
 #define btfromcstr(t,s) {                                            \
diff --git a/bstrlib.txt b/bstrlib.txt
index ec2e2969892422c1e4856310b98f9ae939eb3500_YnN0cmxpYi50eHQ=..ca4a485f8d8477316f90e04acfccdb1d07c1a0b9_YnN0cmxpYi50eHQ= 100644
--- a/bstrlib.txt
+++ b/bstrlib.txt
@@ -574,5 +574,6 @@
 Files
 -----
 
+Core C files (required for C and C++):
 bstrlib.c       - C implementaion of bstring functions.
 bstrlib.h       - C header file for bstring functions.
@@ -577,8 +578,6 @@
 bstrlib.c       - C implementaion of bstring functions.
 bstrlib.h       - C header file for bstring functions.
-bstraux.c       - C example that implements trivial additional functions.
-bstraux.h       - C header for bstraux.c
-bstest.c        - C unit/regression test for bstrlib.c
-
+
+Core C++ files (required for C++):
 bstrwrap.cpp    - C++ implementation of CBString.
 bstrwrap.h      - C++ header file for CBString.
@@ -583,12 +582,9 @@
 bstrwrap.cpp    - C++ implementation of CBString.
 bstrwrap.h      - C++ header file for CBString.
-test.cpp        - C++ unit/regression test for bstrwrap.cpp
-
-bsafe.c         - C runtime stubs to abort usage of unsafe C functions.
-bsafe.h         - C header file for bsafe.c functions.
-
+
+Base Unicode support:
 utf8util.c      - C implemention of generic utf8 parsing functions.
 utf8util.h      - C head file for generic utf8 parsing functions.
 buniutil.c      - C implemention utf8 bstring packing and unpacking functions.
 buniutil.c      - C header file for utf8 bstring functions.
 
@@ -590,8 +586,18 @@
 utf8util.c      - C implemention of generic utf8 parsing functions.
 utf8util.h      - C head file for generic utf8 parsing functions.
 buniutil.c      - C implemention utf8 bstring packing and unpacking functions.
 buniutil.c      - C header file for utf8 bstring functions.
 
+Extra utility functions:
+bstraux.c       - C example that implements trivial additional functions.
+bstraux.h       - C header for bstraux.c
+
+Miscellaneous:
+bstest.c        - C unit/regression test for bstrlib.c
+test.cpp        - C++ unit/regression test for bstrwrap.cpp
+bsafe.c         - C runtime stubs to abort usage of unsafe C functions.
+bsafe.h         - C header file for bsafe.c functions.
+
 C modules need only include bstrlib.h and compile/link bstrlib.c to use the
 basic bstring library.  C++ projects need to additionally include bstrwrap.h
 and compile/link bstrwrap.cpp.  For both, there may be a need to make choices
@@ -632,7 +638,9 @@
 
     Create a bstring which contains the contents of the '\0' terminated
     char * buffer str.  The memory buffer backing the bstring is at least
-    mlen characters in length.  If an error occurs NULL is returned.
+    mlen characters in length.  The buffer is also at least size required
+    to hold the string with the '\0' terminator.  If an error occurs NULL
+    is returned.
 
     So for example:
 
@@ -646,6 +654,27 @@
 
     ..........................................................................
 
+    extern bstring bfromcstrrangealloc (int minl, int maxl, const char* str);
+
+    Create a bstring which contains the contents of the '\0' terminated
+    char * buffer str.  The memory buffer backing the string is at least
+    minl characters in length, but an attempt is made to allocate up to
+    maxl characters.  The buffer is also at least size required to hold
+    the string with the '\0' terminator.  If an error occurs NULL is
+    returned.
+
+    So for example:
+
+    bstring b = bfromcstrrangealloc (0, 128, "Hello.");
+    if (b) b->data[5] = '!';
+
+    The idea is that this will set the 6th character of b to '!' if it was
+    allocated otherwise do nothing.  And we know this is well defined so
+    long as b was successfully created, since it will have been allocated
+    with at least 7 (strlen("Hello.")) characters.
+
+    ..........................................................................
+
     extern bstring blk2bstr (const void * blk, int len);
 
     Create a bstring whose contents are described by the contiguous buffer
@@ -1922,6 +1951,40 @@
 
     ..........................................................................
 
+    bstring bfromStatic("...");
+
+    Allocate a bstring with the contents of a string literal.  Returns
+    NULL if an error has occurred (ran out of memory).  The string literal
+    parameter is enforced as literal at compile time.
+
+    ..........................................................................
+
+    int bcatStatic (bstring b, "...");
+
+    Append a string literal to bstring b.  Returns 0 if successful, or
+    BSTR_ERR if some error has occurred.  The string literal parameter is
+    enforced as literal at compile time.
+
+    ..........................................................................
+
+    int bassignStatic (bstring b, " ... ");
+
+    Assign the contents of a string literal to the bstring b.  The string
+    literal parameter is enforced as literal at compile time.
+
+    ..........................................................................
+
+    int bisstemeqcaselessStatic (bstring b, " ... ");
+
+    Compare beginning of bstring b with a string literal without
+    differentiating between case for equality.  If the beginning of b differs
+    from the memory block other than in case (or if b0 is too short), 0 is
+    returned, if the bstrings are the same, 1 is returned, if there is an
+    error, -1 is returned.  The string literal parameter is enforced as
+    literal at compile time.
+
+    ..........................................................................
+
     void bvformata (int& ret, bstring b, const char * format, lastarg);
 
     Append the bstring b with printf like formatting with the format control
@@ -3256,6 +3319,23 @@
 it seems marginal (i.e., to want a string that cannot be resized, yet can be
 modified and yet where a fixed sized buffer is undesirable.)
 
+Libsrt
+------
+
+This is a length based string library based on a slightly different strategy.
+The string contents are appended to the end of the header directly so strings
+only require a single allocation.  However, whenever a reallocation occurs,
+the header is replicated and the base pointer for the string is changed.
+That means references to the string are only valid so long as they are not
+resized after any such reference is cached.  The internal structure maintains
+a lot some state used to accelerate unicode manipulation.  This makes
+sustainable usage of the library essentially opaque.  This also creates a
+bottleneck for whatever extensions to the library one desires (write all
+extensions on top of the base library, put in a request to the author, or
+dedicate an expert to learn the internals of the library).  The library is
+committed to Unicode representation of its string data, and therefore cannot
+be used as a generic buffer library.
+
 ===============================================================================
 
 Examples
diff --git a/test.cpp b/test.cpp
index ec2e2969892422c1e4856310b98f9ae939eb3500_dGVzdC5jcHA=..ca4a485f8d8477316f90e04acfccdb1d07c1a0b9_dGVzdC5jcHA= 100644
--- a/test.cpp
+++ b/test.cpp
@@ -1347,6 +1347,8 @@
 	return ret;
 }
 
+#if !defined(BSTRLIB_CANNOT_USE_STL)
+
 int test28 (void) {
 int ret = 0;
 
@@ -1456,6 +1458,8 @@
 	return ret;
 }
 
+#endif
+
 int test29 (void) {
 int ret = 0;
 
@@ -1559,5 +1563,5 @@
 	return ret;
 }
 
-/*  int bMultiCountConcat (bstring dst, int n, ...)
+/*  int bMultiConcatNeedNULLAsLastArgument (bstring dst, ...)
  *
@@ -1563,3 +1567,3 @@
  *
- *  Concatenate a sequence of exactly n bstring arguments to dst.
+ *  Concatenate a sequence of exactly n char * arguments to dst.
  */
@@ -1565,3 +1569,3 @@
  */
-int bMultiCountConcat (bstring dst, int n, ...) {
+int bMultiConcatNeedNULLAsLastArgument (bstring dst, ...) {
 va_list arglist;
@@ -1567,11 +1571,17 @@
 va_list arglist;
-int i, ret = 0;
-	va_start (arglist, n);
-	for (i = 0; i < n; i++) {
-		ret = bconcat (dst, va_arg (arglist, bstring));
-		if (0 > ret) break;
-	}
+int ret = 0;
+	va_start (arglist, dst);
+	do {
+		bstring parm = va_arg (arglist, bstring);
+		if (NULL == parm) break;
+		if (NULL == parm->data || parm->slen > parm->mlen ||
+		    parm->mlen < 0 || parm->slen < 0) {
+			ret = BSTR_ERR;
+			break;
+		}
+		ret = bconcat (dst, parm);
+	} while (0 <= ret);
 	va_end (arglist);
 	return ret;
 }
 
@@ -1574,8 +1584,8 @@
 	va_end (arglist);
 	return ret;
 }
 
-/*  int bMultiCountCatCstr (bstring dst, int n, ...)
+/*  int bMultiCatCstrNeedNULLAsLastArgument (bstring dst, ...)
  *
  *  Concatenate a sequence of exactly n char * arguments to dst.
  */
@@ -1579,5 +1589,5 @@
  *
  *  Concatenate a sequence of exactly n char * arguments to dst.
  */
-int bMultiCountCatCstr (bstring dst, int n, ...) {
+int bMultiCatCstrNeedNULLAsLastArgument (bstring dst, ...) {
 va_list arglist;
@@ -1583,12 +1593,13 @@
 va_list arglist;
-int i, ret = 0;
-	va_start (arglist, n);
-	for (i = 0; i < n; i++) {
-		ret = bcatcstr (dst, va_arg (arglist, char *));
-		if (0 > ret) break;
-	}
+int ret = 0;
+	va_start (arglist, dst);
+	do {
+		char* parm = va_arg (arglist, char *);
+		if (NULL == parm) break;
+		ret = bcatcstr (dst, parm);
+	} while (0 <= ret);
 	va_end (arglist);
 	return ret;
 }
 
 /*
@@ -1590,9 +1601,11 @@
 	va_end (arglist);
 	return ret;
 }
 
 /*
- *  These can be dangerous because there is no compiler time type checking
- *  on the arguments.
+ * The following macros are only available on more recent compilers that
+ * support variable length macro arguments and __VA_ARGS__.  These can also
+ * be dangerous because there is no compiler time type checking on the 
+ * arguments.
  */
 
@@ -1597,5 +1610,3 @@
  */
 
-extern int bMultiCountConcat (bstring dst, int n, ...);
-extern int bMultiCountCatCstr (bstring dst, int n, ...);
 
@@ -1601,26 +1612,6 @@
 
-#if defined(__GNUC__)
-# define COUNT_ARGS(...) COUNT_ARGS_(,##__VA_ARGS__,99,98,97,96,95,94,93,92,91,90,89,88,87,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)
-# define COUNT_ARGS_(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59,_60,_61,_62,_63,_64,_65,_66,_67,_68,_69,_70,_71,_72,_73,_74,_75,_76,_77,_78,_79,_80,_81,_82,_83,_84,_85,_86,_87,_88,_89,_90,_91,_92,_93,_94,_95,_96,_97,_98,_99,cnt,...) cnt
-#else
-# if defined(__WATCOMC__) || defined(_MSC_VER)
-#  define COUNT_ARGS(...) ARGCNT_ARGINDEX100((ARGCNT_0_LENGTH_ ## __VA_ARGS__ ## _SPECIAL_CASE,100,99,98,97,96,95,94,93,92,91,90,89,88,87,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1))
-#  define ARGCNT_ARGINDEX100(__args) ARGCNT_ARGINDEX100_RAW __args
-#  define ARGCNT_0_LENGTH__SPECIAL_CASE ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0
-#  define ARGCNT_ARGINDEX100_RAW(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59,_60,_61,_62,_63,_64,_65,_66,_67,_68,_69,_70,_71,_72,_73,_74,_75,_76,_77,_78,_79,_80,_81,_82,_83,_84,_85,_86,_87,_88,_89,_90,_91,_92,_93,_94,_95,_96,_97,_98,_99,n,...) n
-# endif
-#endif
-
-/*
- * The following macros are only available on more recent compilers.
- * Can process up to 100 arguments.  These can also be dangerous because
- * there is no compiler time type checking on the arguments.
- */
-
-#if defined(COUNT_ARGS)
-# define bMultiConcat(dst,...)  bMultiCountConcat((dst),COUNT_ARGS(__VA_ARGS__),##__VA_ARGS__)
-# define bMultiCatCstr(dst,...) bMultiCountCatCstr((dst),COUNT_ARGS(__VA_ARGS__),##__VA_ARGS__)
-#endif
+#define bMultiConcat(dst,...)  bMultiConcatNeedNULLAsLastArgument((dst),##__VA_ARGS__,NULL)
+#define bMultiCatCstr(dst,...) bMultiCatCstrNeedNULLAsLastArgument((dst),##__VA_ARGS__,NULL)
 
 int main () {
 int ret = 0;
@@ -1655,4 +1646,5 @@
 	ret += test25 ();
 	ret += test26 ();
 	ret += test27 ();
+#if !defined(BSTRLIB_CANNOT_USE_STL)
 	ret += test28 ();
@@ -1658,4 +1650,5 @@
 	ret += test28 ();
+#endif
 	ret += test29 ();
 	ret += test30 ();
 	ret += test31 ();
diff --git a/testaux.c b/testaux.c
index ec2e2969892422c1e4856310b98f9ae939eb3500_dGVzdGF1eC5j..ca4a485f8d8477316f90e04acfccdb1d07c1a0b9_dGVzdGF1eC5j 100644
--- a/testaux.c
+++ b/testaux.c
@@ -349,7 +349,7 @@
 }
 
 int test13 (void) {
-struct tagbstring t0 = bsStatic ("Random String");
+struct tagbstring t0 = bsStatic ("Random String, long enough to cause to reallocing");
 struct vfgetc vctx;
 bstring b;
 int ret = 0;
@@ -368,7 +368,7 @@
 		h = b->data;
 		bSecureDestroy (b);
 
-		/* WARNING! Technically unsound code follows: */
+		/* WARNING! Technically undefined code follows (h has been freed): */
 		ret += (0 == memcmp (h, t0.data, t0.slen));
 
 		if (ret) break;