#include "ZUnitTest.hpp"
#include <ZSTL/ZString.hpp>
#include <ZSTL/ZBasicStringAlgo.hpp>
#include <stdexcept>

static const char* test_Append();
static const char* test_Append_Region();
static const char* test_BuildNumeric_Double();
static const char* test_BuildNumeric_Int();
static const char* test_BuildPrintf();
static const char* test_BuildRepeat();
static const char* test_Contains();
static const char* test_Contains_Region();
static const char* test_ContainsSub();
static const char* test_ContainsSub_Region();
static const char* test_Copy();
static const char* test_Copy_Region();
static const char* test_EndsWith();
static const char* test_EndsWith_Region();
static const char* test_Equal();
static const char* test_Equal_Region();
static const char* test_EqualIgnoreCase();
static const char* test_EqualIgnoreCase_Region();
static const char* test_Fill();
static const char* test_Fill_Region();
static const char* test_Find();
static const char* test_Find_Region();
static const char* test_FindAll();
static const char* test_FindAll_Region();
static const char* test_FindAllOf();
static const char* test_FindAllOf_Region();
static const char* test_FindFirst();
static const char* test_FindFirst_Region();
static const char* test_FindFirstOf();
static const char* test_FindFirstOf_Region();
static const char* test_FindFirstNot();
static const char* test_FindFirstNot_Region();
static const char* test_FindFirstNotOf();
static const char* test_FindFirstNotOf_Region();
static const char* test_FindLast();
static const char* test_FindLast_In_Region();
static const char* test_FindLastOf();
static const char* test_FindLastOf_In_Region();
static const char* test_FindLastNot();
static const char* test_FindLastNot_In_Region();
static const char* test_FindLastNotOf();
static const char* test_FindLastNotOf_In_Region();
static const char* test_FindSub();
static const char* test_FindSub_Region();
static const char* test_IsNumeric();
static const char* test_IsNumeric_Region();
static const char* test_Remove();
static const char* test_Remove_In_Region();
static const char* test_RemoveAll();
static const char* test_RemoveAll_In_Region();
static const char* test_RemoveUpTo();
static const char* test_RemoveUpTo_In_Region();
static const char* test_Replace();
#if 0
static const char* test_ReplaceSub();
#endif
static const char* test_Replace_In_Region();
static const char* test_Reverse();
static const char* test_Reverse_Region();
static const char* test_Slice();
static const char* test_Split();
static const char* test_Split_Count();
static const char* test_Split_Count_Region();
static const char* test_StartsWith();
static const char* test_StartsWith_Region();
static const char* test_Strip();
static const char* test_Strip_Region();
static const char* test_Tokenize();
static const char* test_ToLower();
static const char* test_ToLower_Region();
static const char* test_ToUpper();
static const char* test_ToUpper_Region();
static const char* test_TrimLeft();
static const char* test_TrimLeft_Region();
static const char* test_TrimRight();
static const char* test_TrimRight_Region();
static const char* test_Trim();
static const char* test_Trim_Region();

ZUnitTest ZBasicStringAlgoUnitTests[] =
{
	{ "ZBasicStringAlgo: Append",					test_Append },
	{ "ZBasicStringAlgo: Append in region",			test_Append_Region },
	{ "ZBasicStringAlgo: BuildNumeric_Double",		test_BuildNumeric_Double },
	{ "ZBasicStringAlgo: BuildNumeric_Int",			test_BuildNumeric_Int },
	{ "ZBasicStringAlgo: BuildPrintf",				test_BuildPrintf },
	{ "ZBasicStringAlgo: BuildRepeat",				test_BuildRepeat },
	{ "ZBasicStringAlgo: Contains",					test_Contains },
	{ "ZBasicStringAlgo: Contains region",			test_Contains_Region },
	{ "ZBasicStringAlgo: ContainsSub",				test_ContainsSub },
	{ "ZBasicStringAlgo: ContainsSub region",		test_ContainsSub_Region },
	{ "ZBasicStringAlgo: Copy",						test_Copy },
	{ "ZBasicStringAlgo: Copy region",				test_Copy_Region },
	{ "ZBasicStringAlgo: EndsWith",					test_EndsWith },
	{ "ZBasicStringAlgo: EndsWith region",			test_EndsWith_Region },
	{ "ZBasicStringAlgo: Equal",					test_Equal },
	{ "ZBasicStringAlgo: Equal region",				test_Equal_Region },
	{ "ZBasicStringAlgo: EqualIgnoreCase",			test_EqualIgnoreCase },
	{ "ZBasicStringAlgo: EqualIgnoreCase in region",test_EqualIgnoreCase_Region },
	{ "ZBasicStringAlgo: Fill",						test_Fill },
	{ "ZBasicStringAlgo: Fill region",				test_Fill_Region },
	{ "ZBasicStringAlgo: Find",						test_Find },
	{ "ZBasicStringAlgo: Find in region",			test_Find_Region },
	{ "ZBasicStringAlgo: FindAll",					test_FindAll },
	{ "ZBasicStringAlgo: FindAll in region",		test_FindAll_Region },
	{ "ZBasicStringAlgo: FindAllOf",				test_FindAllOf },
	{ "ZBasicStringAlgo: FindAllOf region",			test_FindAllOf_Region },
	{ "ZBasicStringAlgo: FindFirst",				test_FindFirst },
	{ "ZBasicStringAlgo: FindFirst in region",		test_FindFirst_Region },
	{ "ZBasicStringAlgo: FindFirstOf",				test_FindFirstOf },
	{ "ZBasicStringAlgo: FindFirstOf in region",	test_FindFirstOf_Region },
	{ "ZBasicStringAlgo: FindFirstNot",				test_FindFirstNot },
	{ "ZBasicStringAlgo: FindFirstNot region",		test_FindFirstNot_Region },
	{ "ZBasicStringAlgo: FindFirstNotof",			test_FindFirstNotOf },
	{ "ZBasicStringAlgo: FindFirstNotOf region",	test_FindFirstNotOf_Region },
	{ "ZBasicStringAlgo: FindLast",					test_FindLast },
	{ "ZBasicStringAlgo: FindLast in region",		test_FindLast_In_Region },
	{ "ZBasicStringAlgo: FindLastOf",				test_FindLastOf },
	{ "ZBasicStringAlgo: FindLastOf in region",		test_FindLastOf_In_Region },
	{ "ZBasicStringAlgo: FindLastNot",				test_FindLastNot },
	{ "ZBasicStringAlgo: FindLastNot in region",	test_FindLastNot_In_Region },
	{ "ZBasicStringAlgo: FindLastNotOf",			test_FindLastNotOf },
	{ "ZBasicStringAlgo: FindLastNotOf in region",	test_FindLastNotOf_In_Region },
	{ "ZBasicStringAlgo: FindSub",					test_FindSub },
	{ "ZBasicStringAlgo: FindSub region",			test_FindSub_Region },
	{ "ZBasicStringAlgo: IsNumeric",				test_IsNumeric },
	{ "ZBasicStringAlgo: IsNumeric region",			test_IsNumeric_Region },
	{ "ZBasicStringAlgo: Remove",					test_Remove },
	{ "ZBasicStringAlgo: Remove in region",			test_Remove_In_Region },
	{ "ZBasicStringAlgo: RemoveAll",				test_RemoveAll },
	{ "ZBasicStringAlgo: RemoveAll in region",		test_RemoveAll_In_Region },
	{ "ZBasicStringAlgo: RemoveUpTo",				test_RemoveUpTo },
	{ "ZBasicStringAlgo: RemoveUpTo in region",		test_RemoveUpTo_In_Region },
	{ "ZBasicStringAlgo: Replace",					test_Replace },
#if 0
	{ "ZBasicStringAlgo: ReplaceSub",				test_ReplaceSub },
#endif
	{ "ZBasicStringAlgo: Replace in region",		test_Replace_In_Region },
	{ "ZBasicStringAlgo: Reverse",					test_Reverse },
	{ "ZBasicStringAlgo: Reverse region",			test_Reverse_Region },
	{ "ZBasicStringAlgo: Slice",					test_Slice },
	{ "ZBasicStringAlgo: Split",					test_Split },
	{ "ZBasicStringAlgo: Split Count",				test_Split_Count },
	{ "ZBasicStringAlgo: Split Count region",		test_Split_Count_Region },
	{ "ZBasicStringAlgo: StartsWith",				test_StartsWith },
	{ "ZBasicStringAlgo: StartsWith region",		test_StartsWith_Region },
	{ "ZBasicStringAlgo: Strip",					test_Strip },
	{ "ZBasicStringAlgo: Strip region",				test_Strip_Region },
	{ "ZBasicStringAlgo: Tokenize",					test_Tokenize },
	{ "ZBasicStringAlgo: ToLower",					test_ToLower },
	{ "ZBasicStringAlgo: ToLower region",			test_ToLower_Region },
	{ "ZBasicStringAlgo: ToUpper",					test_ToUpper },
	{ "ZBasicStringAlgo: ToUpper region",			test_ToUpper_Region },
	{ "ZBasicStringAlgo: Trim left",				test_TrimLeft },
	{ "ZBasicStringAlgo: Trim left region",			test_TrimLeft_Region },
	{ "ZBasicStringAlgo: Trim right",				test_TrimRight },
	{ "ZBasicStringAlgo: Trim right region",		test_TrimRight_Region },
	{ "ZBasicStringAlgo: Trim",						test_Trim },
	{ "ZBasicStringAlgo: Trim region",				test_Trim_Region },
};

DECLARE_ZTESTBLOCK(ZBasicStringAlgo);

/*************************************************************************/

static const char* test_Append()
{
	ZBasicString<> str;

	ZBasicStringAlgo::Append(str, "ABC");

	TASSERT(str == "ABC", "Append() did not correctly append first string!");

	ZBasicStringAlgo::Append(str, "DEF");

	TASSERT(str == "ABCDEF", "Append() did not correctly append first string!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_Append_Region()
{
	ZBasicString<> str;

	ZBasicStringAlgo::Append(str, "ABC", 0, 1);

	TASSERT(str == "A", "Append() did not correctly append first string!");

	ZBasicStringAlgo::Append(str, "DEF", 1, 3);

	TASSERT(str == "AEF", "Append() did not correctly append first string!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_BuildNumeric_Double()
{
	ZBasicString<> str;

	ZBasicStringAlgo::BuildNumeric(str, 0.0);

	TASSERT(str == "0.000000", "BuildNumeric() failed to build correct string!");

	ZBasicStringAlgo::BuildNumeric(str, "%.2f", 0.0);

	TASSERT(str == "0.00", "BuildNumeric(double) failed to build correct formatted string!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_BuildNumeric_Int()
{
	ZBasicString<> str;

	ZBasicStringAlgo::BuildNumeric(str, 12345);

	TASSERT(str == "12345", "BuildNumeric() failed to build correct string!");

	ZBasicStringAlgo::BuildNumeric(str, "%+i", 12345);

	TASSERT(str == "+12345", "BuildNumeric(int) failed to build correct formatted string!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_BuildPrintf()
{
	ZBasicString<> str;

	ZBasicStringAlgo::BuildPrintf(str, " %3ist ", 1);
	TASSERT(str == "   1st ", "BuildPrintf() failed to produce correct formatted string!");

	ZBasicStringAlgo::BuildPrintf(str, " %3i %3.1f  %3i %3.1f  %3i %3.1f  %3i %3.1f  %3i %3.1f  %3i %3.1f  %3i %3.1f  %3i %3.1f  %3i %3.1f  %3i %3.1f  %3i %3.1f  %3i %3.1f  %3i %3.1f  %3i %3.1f  %3i %3.1f  %3i %3.1f  %3i %3.1f  %3i %3.1f  %3i %3.1f  %3i %3.1f  %3i %3.1f  %3i %3.1f  %3i %3.1f  %3i %3.1f  %3i %3.1f ", 1, 2.0f, 1, 2.0f, 1, 2.0f, 1, 2.0f, 1, 2.0f, 1, 2.0f, 1, 2.0f, 1, 2.0f, 1, 2.0f, 1, 2.0f, 1, 2.0f, 1, 2.0f, 1, 2.0f, 1, 2.0f, 1, 2.0f, 1, 2.0f, 1, 2.0f, 1, 2.0f, 1, 2.0f, 1, 2.0f, 1, 2.0f, 1, 2.0f, 1, 2.0f, 1, 2.0f, 1, 2.0f);
	TASSERT(str == "   1 2.0    1 2.0    1 2.0    1 2.0    1 2.0    1 2.0    1 2.0    1 2.0    1 2.0    1 2.0    1 2.0    1 2.0    1 2.0    1 2.0    1 2.0    1 2.0    1 2.0    1 2.0    1 2.0    1 2.0    1 2.0    1 2.0    1 2.0    1 2.0    1 2.0 ", "BuildPrintf() failed to produce correct formatted string 2!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_BuildRepeat()
{
	ZBasicString<> str;

	ZBasicStringAlgo::BuildRepeat(str, "abc", 5);

	TASSERT(str == "abcabcabcabcabc", "BuildRepeat() failed to build abc * 5!");

	ZBasicStringAlgo::BuildRepeat(str, "", 20);

	TASSERT(str.Empty(), "BuildRepeat() failed to build empty string with '' * 20!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_Contains()
{
	ZBasicString<> str("abcdef");

	TASSERT(ZBasicStringAlgo::Contains(str, 'a'), "Contains('a') on 'abcdef' returns false!");
	TASSERT(ZBasicStringAlgo::Contains(str, 'b'), "Contains('b') on 'abcdef' returns false!");
	TASSERT(ZBasicStringAlgo::Contains(str, 'c'), "Contains('c') on 'abcdef' returns false!");
	TASSERT(ZBasicStringAlgo::Contains(str, 'd'), "Contains('d') on 'abcdef' returns false!");
	TASSERT(ZBasicStringAlgo::Contains(str, 'e'), "Contains('e') on 'abcdef' returns false!");
	TASSERT(ZBasicStringAlgo::Contains(str, 'f'), "Contains('f') on 'abcdef' returns false!");

	TASSERT(!ZBasicStringAlgo::Contains(str, 'g'), "Contains('g') on 'abcdef' returns true!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_Contains_Region()
{
	ZBasicString<> str("abcdef");

	TASSERT(ZBasicStringAlgo::Contains(str, 'a', 0, 1), "Contains('a', 0, 1) on 'abcdef' returns false!");
	TASSERT(!ZBasicStringAlgo::Contains(str, 'b', 0, 1), "Contains('b', 0, 1) on 'abcdef' returns true!");
	TASSERT(ZBasicStringAlgo::Contains(str, 'c', 1, 3), "Contains('c, 1, 3') on 'abcdef' returns false!");
	TASSERT(!ZBasicStringAlgo::Contains(str, 'd', 0, 2), "Contains('d', 0, 2) on 'abcdef' returns true!");
	TASSERT(ZBasicStringAlgo::Contains(str, 'e', 4, 5), "Contains('e', 4, 5) on 'abcdef' returns false!");
	TASSERT(!ZBasicStringAlgo::Contains(str, 'f', 4, 5), "Contains('f', 4, 5) on 'abcdef' returns true!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_ContainsSub()
{
	ZBasicString<> str("abcdef");

	TASSERT(ZBasicStringAlgo::ContainsSub(str, "a"), "ContainsSub('a') on 'abcdef' returns false!");
	TASSERT(ZBasicStringAlgo::ContainsSub(str, "ab"), "ContainsSub('ab') on 'abcdef' returns false!");
	TASSERT(ZBasicStringAlgo::ContainsSub(str, "abc"), "ContainsSub('abc') on 'abcdef' returns false!");
	TASSERT(ZBasicStringAlgo::ContainsSub(str, "abcd"), "ContainsSub('abcd') on 'abcdef' returns false!");
	TASSERT(ZBasicStringAlgo::ContainsSub(str, "abcde"), "ContainsSub('abcde') on 'abcdef' returns false!");
	TASSERT(ZBasicStringAlgo::ContainsSub(str, "abcdef"), "ContainsSub('abcdef') on 'abcdef' returns false!");

	TASSERT(ZBasicStringAlgo::ContainsSub(str, "f"), "ContainsSub('f') on 'abcdef' returns false!");
	TASSERT(!ZBasicStringAlgo::ContainsSub(str, "ac"), "ContainsSub('ac') on 'abcdef' returns true!");
	TASSERT(ZBasicStringAlgo::ContainsSub(str, "bc"), "ContainsSub('abc') on 'abcdef' returns false!");
	TASSERT(!ZBasicStringAlgo::ContainsSub(str, "bde"), "ContainsSub('bde') on 'abcdef' returns true!");
	TASSERT(ZBasicStringAlgo::ContainsSub(str, "cdef"), "ContainsSub('cdef') on 'abcdef' returns false!");
	TASSERT(!ZBasicStringAlgo::ContainsSub(str, "cfed"), "ContainsSub('cfed') on 'abcdef' returns true!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_ContainsSub_Region()
{
	ZBasicString<> str("abcdef");

	TASSERT(!ZBasicStringAlgo::ContainsSub(str, 1, 3, "a", 0, 1), "ContainsSub(1, 3, 'a', 0, 1) on 'abcdef' returns true!");
	TASSERT(ZBasicStringAlgo::ContainsSub(str, 0, 2, "ab", 0, 2), "ContainsSub(0, 2, 'ab', 0, 2) on 'abcdef' returns false!");
	TASSERT(ZBasicStringAlgo::ContainsSub(str, 1, 3, "abc", 1, 3), "ContainsSub(1, 3, 'abc', 1, 3) on 'abcdef' returns false!");
	TASSERT(!ZBasicStringAlgo::ContainsSub(str, 2, 6, "abcd", 0, 4), "ContainsSub(2, 6, 'abcd', 0, 4) on 'abcdef' returns true!");
	TASSERT(ZBasicStringAlgo::ContainsSub(str, 4, 6, "abcde", 4, 5), "ContainsSub(4, 6, 'abcde', 4, 5) on 'abcdef' returns false!");
	TASSERT(!ZBasicStringAlgo::ContainsSub(str, 0, 3, "abcdef", 0, 6), "ContainsSub(0, 3, 'abcdef', 0, 6) on 'abcdef' returns true!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_Copy()
{
	ZBasicString<> str;

	ZBasicStringAlgo::Copy(str, "abcdef");

	TASSERT(str.Empty(), "Copy('abcdef') failed to keep string!");

	str.Copy("abcdef");

	ZBasicStringAlgo::Copy(str, "");

	TASSERT(str == "abcdef", "Copy('') failed to keep 'abcdef'!");

	ZBasicStringAlgo::Copy(str, "cba");

	TASSERT(str == "cbadef", "Copy('cba') did not copy correctly!");

	ZBasicStringAlgo::Copy(str, "abcdefghijklmnopqrstuvwxyz");

	TASSERT(str == "abcdef", "Copy('abcdefghijklmnopqrstuvwxyz') failed to copy just 'abcdef'!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_Copy_Region()
{
	ZBasicString<> str("abcdef");

	ZBasicStringAlgo::Copy(str, 2, 4, "dc", 0, 2);

	TASSERT(str == "abdcef", "Copy(2, 4, 'dc', 0, 2) region on string 'abcdef' failed to copy correct string!");

	ZBasicStringAlgo::Copy(str, 1, 5, "wxyz", 1, 4);

	TASSERT(str == "axyzef", "Copy(1, 5, 'wxyz', 1, 4) region on string 'abdcef' failed to copy correct string!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_EndsWith()
{
	ZBasicString<> str("abcdef");

	TASSERT(ZBasicStringAlgo::EndsWith(str, "f"), "EndsWith('f') with string 'abcdef' returns false!");
	TASSERT(ZBasicStringAlgo::EndsWith(str, "ef"), "EndsWith('ef') with string 'abcdef' returns false!");
	TASSERT(ZBasicStringAlgo::EndsWith(str, "def"), "EndsWith('def') with string 'abcdef' returns false!");
	TASSERT(ZBasicStringAlgo::EndsWith(str, "cdef"), "EndsWith('cdef') with string 'abcdef' returns false!");
	TASSERT(ZBasicStringAlgo::EndsWith(str, "bcdef"), "EndsWith('bcdef') with string 'abcdef' returns false!");
	TASSERT(ZBasicStringAlgo::EndsWith(str, "abcdef"), "EndsWith('abcdef') with string 'abcdef' returns false!");

	TASSERT(!ZBasicStringAlgo::EndsWith(str, "e"), "EndsWith('e') with string 'abcdef' returns true!");
	TASSERT(!ZBasicStringAlgo::EndsWith(str, "df"), "EndsWith('e') with string 'abcdef' returns true!");
	TASSERT(!ZBasicStringAlgo::EndsWith(str, "1bcdef"), "EndsWith('1bcdef') with string 'abcdef' returns true!");
	TASSERT(!ZBasicStringAlgo::EndsWith(str, "123abcdef"), "EndsWith('123abcdef') with string 'abcdef' returns true!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_EndsWith_Region()
{
	ZBasicString<> str("abcdef");

	TASSERT(ZBasicStringAlgo::EndsWith(str, 2, 4, "cd", 0, 2), "EndsWith(2, 4, 'cd', 0, 2) with string 'abcdef' returns false!");
	
	TASSERT(!ZBasicStringAlgo::EndsWith(str, 2, 4, "cd", 0, 1), "EndsWith(2, 4, 'cd', 0, 1) with string 'abcdef' returns true!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_Equal()
{
	ZBasicString<> str1("abc");
	ZBasicString<> str2("abcd");
	ZBasicString<> str3("ab");
	ZBasicString<> str4("ace");

	TASSERT(ZBasicStringAlgo::Equal(str1, str1), "Equal('abc', 'abc') did not return true!");
	TASSERT(ZBasicStringAlgo::Equal(str1, str2), "Equal('abc', 'abcd') did not return true!");
	TASSERT(ZBasicStringAlgo::Equal(str1, str3), "Equal('abc', 'ab') did not return true!");
	TASSERT(!ZBasicStringAlgo::Equal(str1, str4), "Equal('abc', 'ace') did not return false!");

	TASSERT(ZBasicStringAlgo::Equal(str2, str1), "Equal('abcd', 'abc') did not return true!");
	TASSERT(ZBasicStringAlgo::Equal(str2, str2), "Equal('abcd', 'abcd') did not return true!");
	TASSERT(ZBasicStringAlgo::Equal(str2, str3), "Equal('abcd', 'ab') did not return true!");
	TASSERT(!ZBasicStringAlgo::Equal(str2, str4), "Equal('abcd', 'ace') did not return false!");

	TASSERT(ZBasicStringAlgo::Equal(str3, str1), "Equal('ab', 'abc') did not return true!");
	TASSERT(ZBasicStringAlgo::Equal(str3, str2), "Equal('ab', 'abcd') did not return true!");
	TASSERT(ZBasicStringAlgo::Equal(str3, str3), "Equal('ab', 'ab') did not return true!");
	TASSERT(!ZBasicStringAlgo::Equal(str3, str4), "Equal('ab', 'ace') did not return false!");

	TASSERT(!ZBasicStringAlgo::Equal(str4, str1), "Equal('ace', 'abc') did not return false!");
	TASSERT(!ZBasicStringAlgo::Equal(str4, str2), "Equal('ace', 'abcd') did not return false!");
	TASSERT(!ZBasicStringAlgo::Equal(str4, str3), "Equal('ace', 'ab') did not return false!");
	TASSERT(ZBasicStringAlgo::Equal(str4, str4), "Equal('ace', 'ace') did not return true!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_Equal_Region()
{
	ZBasicString<> str1("abc");
	ZBasicString<> str2("abcd");
	ZBasicString<> str3("ab");
	ZBasicString<> str4("ace");

	TASSERT(ZBasicStringAlgo::Equal(str1, 1, 2, str2, 1, 2), "Equal('abc', 1, 2, 'abcd', 1, 2) did not return true!");

	TASSERT(ZBasicStringAlgo::Equal(str1, 0, 2, str3, 0, 1), "Equal('abc', 0, 2, 'ab', 0, 1) did not return true!");

	TASSERT(!ZBasicStringAlgo::Equal(str2, 1, 4, str1, 0, 3), "Equal('abcd', 1, 4, 'abc', 0, 3) returned true!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_EqualIgnoreCase()
{
	ZBasicString<> str1("abC");
	ZBasicString<> str2("ABcd");
	ZBasicString<> str3("aB");
	ZBasicString<> str4("aCE");

	TASSERT(ZBasicStringAlgo::EqualIgnoreCase(str1, str1), "EqualIgnoreCase('abC', 'abc') did not return true!");
	TASSERT(ZBasicStringAlgo::EqualIgnoreCase(str1, str2), "EqualIgnoreCase('abC', 'ABcd') did not return true!");
	TASSERT(ZBasicStringAlgo::EqualIgnoreCase(str1, str3), "EqualIgnoreCase('abC', 'aB') did not return true!");
	TASSERT(!ZBasicStringAlgo::EqualIgnoreCase(str1, str4), "EqualIgnoreCase('abC', 'aCE') did not return false!");

	TASSERT(ZBasicStringAlgo::EqualIgnoreCase(str2, str1), "EqualIgnoreCase('ABcd', 'abC') did not return true!");
	TASSERT(ZBasicStringAlgo::EqualIgnoreCase(str2, str2), "EqualIgnoreCase('ABcd', 'ABcd') did not return true!");
	TASSERT(ZBasicStringAlgo::EqualIgnoreCase(str2, str3), "EqualIgnoreCase('ABcd', 'aB') did not return true!");
	TASSERT(!ZBasicStringAlgo::EqualIgnoreCase(str2, str4), "EqualIgnoreCase('ABcd', 'aCE') did not return false!");

	TASSERT(ZBasicStringAlgo::EqualIgnoreCase(str3, str1), "EqualIgnoreCase('aB', 'abC') did not return true!");
	TASSERT(ZBasicStringAlgo::EqualIgnoreCase(str3, str2), "EqualIgnoreCase('aB', 'ABcd') did not return true!");
	TASSERT(ZBasicStringAlgo::EqualIgnoreCase(str3, str3), "EqualIgnoreCase('aB', 'aB') did not return true!");
	TASSERT(!ZBasicStringAlgo::EqualIgnoreCase(str3, str4), "EqualIgnoreCase('aB', 'aCE') did not return false!");

	TASSERT(!ZBasicStringAlgo::EqualIgnoreCase(str4, str1), "EqualIgnoreCase('aCE', 'abC') did not return false!");
	TASSERT(!ZBasicStringAlgo::EqualIgnoreCase(str4, str2), "EqualIgnoreCase('aCE', 'ABcd') did not return false!");
	TASSERT(!ZBasicStringAlgo::EqualIgnoreCase(str4, str3), "EqualIgnoreCase('aCE', 'aB') did not return false!");
	TASSERT(ZBasicStringAlgo::EqualIgnoreCase(str4, str4), "EqualIgnoreCase('aCE', 'aCE') did not return true!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_EqualIgnoreCase_Region()
{
	ZBasicString<> str1("abC");
	ZBasicString<> str2("ABcd");
	ZBasicString<> str3("aB");
	ZBasicString<> str4("aCE");

	TASSERT(ZBasicStringAlgo::EqualIgnoreCase(str1, 1, 2, str2, 1, 2), "Equal('abc', 1, 2, 'abcd', 1, 2) did not return true!");

	TASSERT(ZBasicStringAlgo::EqualIgnoreCase(str1, 0, 2, str3, 0, 1), "Equal('abc', 0, 2, 'ab', 0, 1) did not return true!");

	TASSERT(!ZBasicStringAlgo::EqualIgnoreCase(str2, 1, 4, str1, 0, 3), "Equal('abcd', 1, 4, 'abc', 0, 3) returned true!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_Fill()
{
	ZBasicString<> str1;
	ZBasicString<> str2("abcdef");

	ZBasicStringAlgo::Fill(str1, ' ');
	ZBasicStringAlgo::Fill(str2, 'a');

	TASSERT(str1.Empty(), "Fill(' ') on empty string did not leave empty string!");
	TASSERT(str2 == "aaaaaa", "Fill('a') on 'abcdef' did not create correct string!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_Fill_Region()
{
	ZBasicString<> str("abcdef");

	ZBasicStringAlgo::Fill(str, 'a', 2, 5);

	TASSERT(str == "abaaaf", "Fill('a', 2, 5) on string 'abcdef' did not produce correct string!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_Find()
{
	ZBasicString<> str1;
	ZBasicString<> str2("abcdef");
	ZBasicString<> str3("abcdefabcdef");

	TASSERT(ZBasicStringAlgo::Find(str1, 'a', 0) == ZSTL::InvalidPos, "Find('a', 0) with empty string did not return InvalidPos!");
	TASSERT(ZBasicStringAlgo::Find(str1, 'a', 1) == ZSTL::InvalidPos, "Find('a', 1) with empty string did not return InvalidPos!");

	TASSERT(ZBasicStringAlgo::Find(str2, 'a', 0) == 0, "Find('a', 0) with 'abcdef' did not return index 0!");
	TASSERT(ZBasicStringAlgo::Find(str2, 'a', 1) == ZSTL::InvalidPos, "Find('a', 1) with 'abcdef' did not return InvalidPos!");
	TASSERT(ZBasicStringAlgo::Find(str2, 'c', 0) == 2, "Find('c', 0) with 'abcdef' did not return index 2!");
	TASSERT(ZBasicStringAlgo::Find(str2, 'c', 1) == ZSTL::InvalidPos, "Find('a', 1) with 'abcdef' did not return InvalidPos!");
	TASSERT(ZBasicStringAlgo::Find(str2, 'f', 0) == 5, "Find('f', 0) with 'abcdef' did not return index 5!");
	TASSERT(ZBasicStringAlgo::Find(str2, 'f', 1) == ZSTL::InvalidPos, "Find('a', 1) with 'abcdef' did not return InvalidPos!");

	TASSERT(ZBasicStringAlgo::Find(str3, 'a', 0) == 0, "Find('a', 0) with 'abcdef' did not return index 0!");
	TASSERT(ZBasicStringAlgo::Find(str3, 'a', 1) == 6, "Find('a', 1) with 'abcdef' did not return index 6!");
	TASSERT(ZBasicStringAlgo::Find(str3, 'c', 0) == 2, "Find('c', 0) with 'abcdef' did not return index 2!");
	TASSERT(ZBasicStringAlgo::Find(str3, 'c', 1) == 8, "Find('a', 1) with 'abcdef' did not return index 8!");
	TASSERT(ZBasicStringAlgo::Find(str3, 'f', 0) == 5, "Find('f', 0) with 'abcdef' did not return index 5!");
	TASSERT(ZBasicStringAlgo::Find(str3, 'f', 1) == 11, "Find('a', 1) with 'abcdef' did not return index 11!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_Find_Region()
{
	ZBasicString<> str1;
	ZBasicString<> str2("abcdef");
	ZBasicString<> str3("abcdefabcdef");

	TASSERT(ZBasicStringAlgo::Find(str2, 'a', 0, 2, 4) == ZSTL::InvalidPos, "Find('a', 0, 2, 4) with 'abcdef' did not return InvalidPos!");
	TASSERT(ZBasicStringAlgo::Find(str2, 'a', 0, 0, 1) == 0, "Find('a', 0, 0, 1) with 'abcdef' did not return index 0!");

	TASSERT(ZBasicStringAlgo::Find(str3, 'a', 1, 3, 7) == ZSTL::InvalidPos, "Find('a', 1, 3, 7) with string 'abcdefabcdef' did not return InvalidPos!");
	TASSERT(ZBasicStringAlgo::Find(str3, 'f', 1, 5, 12) == 11, "Find('f', 1, 5, 12) with string 'abcdefabcdef' did not return index 11!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_FindAll()
{
	ZBasicString<> str1;
	ZBasicString<> str2("abcdef");
	ZBasicString<> str3("abcdefabcdef");

	ZArray<size_t> results;

	results = ZBasicStringAlgo::FindAll(str1, 'a');
	TASSERT(results.Empty(), "FindAll('a') on empty string returned values!");


	results = ZBasicStringAlgo::FindAll(str2, 'a');
	TASSERT(results.Size() == 1, "FindAll('a') on string 'abcdef' returned incorrect number of results!");
	TASSERT(results[0] == 0, "FindAll('a') on string 'abcdef' returned incorrect result!");

	results = ZBasicStringAlgo::FindAll(str2, 'b');
	TASSERT(results.Size() == 1, "FindAll('b') on string 'abcdef' returned incorrect number of results!");
	TASSERT(results[0] == 1, "FindAll('b') on string 'abcdef' returned incorrect result!");

	results = ZBasicStringAlgo::FindAll(str2, 'c');
	TASSERT(results.Size() == 1, "FindAll('c') on string 'abcdef' returned incorrect number of results!");
	TASSERT(results[0] == 2, "FindAll('c') on string 'abcdef' returned incorrect result!");

	results = ZBasicStringAlgo::FindAll(str2, 'd');
	TASSERT(results.Size() == 1, "FindAll('d') on string 'abcdef' returned incorrect number of results!");
	TASSERT(results[0] == 3, "FindAll('d') on string 'abcdef' returned incorrect result!");

	results = ZBasicStringAlgo::FindAll(str2, 'e');
	TASSERT(results.Size() == 1, "FindAll('e') on string 'abcdef' returned incorrect number of results!");
	TASSERT(results[0] == 4, "FindAll('e') on string 'abcdef' returned incorrect result!");

	results = ZBasicStringAlgo::FindAll(str2, 'f');
	TASSERT(results.Size() == 1, "FindAll('f') on string 'abcdef' returned incorrect number of results!");
	TASSERT(results[0] == 5, "FindAll('f') on string 'abcdef' returned incorrect result!");

	results = ZBasicStringAlgo::FindAll(str2, 'g');
	TASSERT(results.Empty(), "FindAll('g') on string 'abcdef' returned values!");


	results = ZBasicStringAlgo::FindAll(str3, 'a');
	TASSERT(results.Size() == 2, "FindAll('a') on string 'abcdefabcdef' returned incorrect number of results!");
	TASSERT(results[0] == 0, "FindAll('a') on string 'abcdefabcdef' returned incorrect result!");
	TASSERT(results[1] == 6, "FindAll('a') on string 'abcdefabcdef' returned incorrect result!");

	results = ZBasicStringAlgo::FindAll(str3, 'b');
	TASSERT(results.Size() == 2, "FindAll('b') on string 'abcdefabcdef' returned incorrect number of results!");
	TASSERT(results[0] == 1, "FindAll('b') on string 'abcdefabcdef' returned incorrect result!");
	TASSERT(results[1] == 7, "FindAll('b') on string 'abcdefabcdef' returned incorrect result!");

	results = ZBasicStringAlgo::FindAll(str3, 'c');
	TASSERT(results.Size() == 2, "FindAll('c') on string 'abcdefabcdef' returned incorrect number of results!");
	TASSERT(results[0] == 2, "FindAll('c') on string 'abcdefabcdef' returned incorrect result!");
	TASSERT(results[1] == 8, "FindAll('c') on string 'abcdefabcdef' returned incorrect result!");

	results = ZBasicStringAlgo::FindAll(str3, 'd');
	TASSERT(results.Size() == 2, "FindAll('d') on string 'abcdefabcdef' returned incorrect number of results!");
	TASSERT(results[0] == 3, "FindAll('d') on string 'abcdefabcdef' returned incorrect result!");
	TASSERT(results[1] == 9, "FindAll('d') on string 'abcdefabcdef' returned incorrect result!");

	results = ZBasicStringAlgo::FindAll(str3, 'e');
	TASSERT(results.Size() == 2, "FindAll('e') on string 'abcdefabcdef' returned incorrect number of results!");
	TASSERT(results[0] == 4, "FindAll('e') on string 'abcdefabcdef' returned incorrect result!");
	TASSERT(results[1] == 10, "FindAll('e') on string 'abcdefabcdef' returned incorrect result!");

	results = ZBasicStringAlgo::FindAll(str3, 'f');
	TASSERT(results.Size() == 2, "FindAll('f') on string 'abcdefabcdef' incorrect number of results!");
	TASSERT(results[0] == 5, "FindAll('f') on string 'abcdefabcdef' returned incorrect result!");
	TASSERT(results[1] == 11, "FindAll('f') on string 'abcdefabcdef' returned incorrect result!");

	results = ZBasicStringAlgo::FindAll(str3, 'g');
	TASSERT(results.Empty(), "FindAll('g') on string 'abcdefabcdef' returned values!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_FindAll_Region()
{
	ZBasicString<> str1;
	ZBasicString<> str2("abcdef");
	ZBasicString<> str3("abcdefabcdef");

	ZArray<size_t> results;

	results = ZBasicStringAlgo::FindAll(str2, 'a', 2, 4);
	TASSERT(results.Size() == 0, "FindAll('abcdef', 'a', 2, 4) returned too many results!");

	results = ZBasicStringAlgo::FindAll(str2, 'c', 2, 4);
	TASSERT(results.Size() == 1, "FindAll('abcdef', 'c', 2, 4) returned incorrect number of results!");
	TASSERT(results[0] == 2, "FindAll('abcdef', 'c', 2, 4) returned incorrect index!");

	results = ZBasicStringAlgo::FindAll(str3, 'd', 2, 9);
	TASSERT(results.Size() == 1, "FindAll('abcdef', 'd', 2, 9) returned incorrect number of results!");
	TASSERT(results[0] == 3, "FindAll('abcdef', 'd', 2, 9) returned incorrect index!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_FindAllOf()
{
	ZBasicString<> str1;
	ZBasicString<> str2("abcdef");
	ZBasicString<> str3("abcdefabcdef");

	ZArray<size_t> results;

	results = ZBasicStringAlgo::FindAllOf(str1, "acg");
	TASSERT(results.Empty(), "FindAllOf('acg') on empty string returned values!");


	results = ZBasicStringAlgo::FindAllOf(str2, "b");
	TASSERT(results.Size() == 1, "FindAllOf('b') on string 'abcdef' returned wrong number of results!");
	TASSERT(results[0] == 1, "FindAllOf('b') on string 'abcdef' returned incorrect results!");

	results = ZBasicStringAlgo::FindAllOf(str2, "acg");
	TASSERT(results.Size() == 2, "FindAllOf('acg') on string 'abcdef' returned wrong number of results!");
	TASSERT(results[0] == 0, "FindAllOf('acg') on string 'abcdef' returned incorrect result!");
	TASSERT(results[1] == 2, "FindAllOf('acg') on string 'abcdef' returned incorrect result!");

	results = ZBasicStringAlgo::FindAllOf(str2, "acgab");
	TASSERT(results.Size() == 3, "FindAllOf('acgab') on string 'abcdef' returned wrong number of results!");
	TASSERT(results[0] == 0, "FindAllOf('acgab') on string 'abcdef' returned incorrect result!");
	TASSERT(results[1] == 1, "FindAllOf('acgab') on string 'abcdef' returned incorrect result!");
	TASSERT(results[2] == 2, "FindAllOf('acgab') on string 'abcdef' returned incorrect result!");

	results = ZBasicStringAlgo::FindAllOf(str2, "sr g");
	TASSERT(results.Empty(), "FindAllOf('sr g') on string 'abcdef' returned values!");


	results = ZBasicStringAlgo::FindAllOf(str3, "e");
	TASSERT(results.Size() == 2, "FindAllOf('e') on string 'abcdef' returned wrong number of results!");
	TASSERT(results[0] == 4, "FindAllOf('e') on string 'abcdef' returned incorrect results!");
	TASSERT(results[1] == 10, "FindAllOf('e') on string 'abcdef' returned incorrect results!");

	results = ZBasicStringAlgo::FindAllOf(str3, "afk");
	TASSERT(results.Size() == 4, "FindAllOf('afk') on string 'abcdefabcdef' returned wrong number of results!");
	TASSERT(results[0] == 0, "FindAllOf('afk') on string 'abcdefabcdef' returned incorrect result!");
	TASSERT(results[1] == 5, "FindAllOf('afk') on string 'abcdefabcdef' returned incorrect result!");
	TASSERT(results[2] == 6, "FindAllOf('afk') on string 'abcdefabcdef' returned incorrect result!");
	TASSERT(results[3] == 11, "FindAllOf('afk') on string 'abcdefabcdef' returned incorrect result!");

	results = ZBasicStringAlgo::FindAllOf(str3, "qrg ");
	TASSERT(results.Empty(), "FindAllOf('qrg ') on string 'abcdefabcdef' returned values!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_FindAllOf_Region()
{
	ZBasicString<> str1;
	ZBasicString<> str2("abcdef");
	ZBasicString<> str3("abcdefabcdef");

	ZArray<size_t> results;

	results = ZBasicStringAlgo::FindAllOf(str2, 2, 4, "ab", 0, 2);
	TASSERT(results.Size() == 0, "FindAll('abcdef', 2, 4, 'ab', 0, 2) returned too many results!");

	results = ZBasicStringAlgo::FindAllOf(str2, 2, 4, "cde", 1, 3);
	TASSERT(results.Size() == 1, "FindAll('abcdef', 2, 4, 'cde', 1, 3) returned incorrect number of results!");
	TASSERT(results[0] == 3, "FindAll('abcdef', 2, 4, 'cde', 1, 3) returned incorrect second index!");

	results = ZBasicStringAlgo::FindAllOf(str3, 2, 9, "ade", 0, 2);
	TASSERT(results.Size() == 2, "FindAll('abcdefabcdef', 2, 9, 'ade', 0, 2) returned incorrect number of results!");
	TASSERT(results[0] == 3, "FindAll('abcdefabcdef', 2, 9, 'ade', 0, 2) returned incorrect first index!");
	TASSERT(results[1] == 6, "FindAll('abcdefabcdef', 2, 9, 'ade', 0, 2) return incorrect second index!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_FindFirst()
{
	ZBasicString<> str1;
	ZBasicString<> str2("abcdef");
	ZBasicString<> str3("abcdefabcdef");

	TASSERT(ZBasicStringAlgo::FindFirst(str1, 'a') == ZSTL::InvalidPos, "FindFirst('a') on empty string did not return InvalidPos!");
	
	TASSERT(ZBasicStringAlgo::FindFirst(str2, 'a') == 0, "FindFirst('a') on string 'abcdef' did not return index 0!");
	TASSERT(ZBasicStringAlgo::FindFirst(str2, 'b') == 1, "FindFirst('b') on string 'abcdef' did not return index 1!");
	TASSERT(ZBasicStringAlgo::FindFirst(str2, 'c') == 2, "FindFirst('c') on string 'abcdef' did not return index 2!");
	TASSERT(ZBasicStringAlgo::FindFirst(str2, 'd') == 3, "FindFirst('d') on string 'abcdef' did not return index 3!");
	TASSERT(ZBasicStringAlgo::FindFirst(str2, 'e') == 4, "FindFirst('e') on string 'abcdef' did not return index 4!");
	TASSERT(ZBasicStringAlgo::FindFirst(str2, 'f') == 5, "FindFirst('f') on string 'abcdef' did not return index 5!");

	TASSERT(ZBasicStringAlgo::FindFirst(str2, 'g') == ZSTL::InvalidPos, "FindFirst('g') on string 'abcdef' did not return InvalidPos!");

	TASSERT(ZBasicStringAlgo::FindFirst(str3, 'a') == 0, "FindFirst('a') on string 'abcdefabcdef' did not return index 0!");
	TASSERT(ZBasicStringAlgo::FindFirst(str3, 'b') == 1, "FindFirst('b') on string 'abcdefabcdef' did not return index 1!");
	TASSERT(ZBasicStringAlgo::FindFirst(str3, 'c') == 2, "FindFirst('c') on string 'abcdefabcdef' did not return index 2!");
	TASSERT(ZBasicStringAlgo::FindFirst(str3, 'd') == 3, "FindFirst('d') on string 'abcdefabcdef' did not return index 3!");
	TASSERT(ZBasicStringAlgo::FindFirst(str3, 'e') == 4, "FindFirst('e') on string 'abcdefabcdef' did not return index 4!");
	TASSERT(ZBasicStringAlgo::FindFirst(str3, 'f') == 5, "FindFirst('f') on string 'abcdefabcdef' did not return index 5!");

	TASSERT(ZBasicStringAlgo::FindFirst(str3, 'g') == ZSTL::InvalidPos, "FindFirst('g') on string 'abcdefabcdef' did not return InvalidPos!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_FindFirst_Region()
{
	ZBasicString<> str1;
	ZBasicString<> str2("abcdef");
	ZBasicString<> str3("abcdefabcdef");

	TASSERT(ZBasicStringAlgo::FindFirst(str2, 'a', 2, 5) == ZSTL::InvalidPos, "FindFirst('abcdef', 'a', 2, 5) did not return InvalidPos!");
	TASSERT(ZBasicStringAlgo::FindFirst(str2, 'd', 2, 5) == 3, "FindFirst('abcdef', 'd', 2, 5) did not return index 3!");
	TASSERT(ZBasicStringAlgo::FindFirst(str3, 'c', 1, 11) == 2, "FindFirst('abcdefabcdef', 'c', 1, 11) did not return index 2!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_FindFirstOf()
{
	ZBasicString<> str1;
	ZBasicString<> str2("abcdef");

	TASSERT(ZBasicStringAlgo::FindFirstOf(str1, "abc") == ZSTL::InvalidPos, "FindFirstOf('abc') on empty string did not return InvalidPos!");
	
	TASSERT(ZBasicStringAlgo::FindFirstOf(str2, "ace") == 0, "FindFirstOf('ace') on string 'abcdef' did not return index 0!");
	TASSERT(ZBasicStringAlgo::FindFirstOf(str2, "ce") == 2, "FindFirstOf('ce') on string 'abcdef' did not return index 2!");
	TASSERT(ZBasicStringAlgo::FindFirstOf(str2, "e") == 4, "FindFirstOf('e') on string 'abcdef' did not return index 4!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_FindFirstOf_Region()
{
	ZBasicString<> str1;
	ZBasicString<> str2("abcdef");

	TASSERT(ZBasicStringAlgo::FindFirstOf(str2, 2, 4, "ace", 0, 3) == 2, "FindFirstOf('abcdef', 2, 4, 'ace', 0, 3) did not return index 2!");
	TASSERT(ZBasicStringAlgo::FindFirstOf(str2, 0, 2, "ce", 0, 2) == ZSTL::InvalidPos, "FindFirstOf('abcdef', 0, 2, 'ce', 0, 2) did not return index InvalidPos!");
	TASSERT(ZBasicStringAlgo::FindFirstOf(str2, 1, 6, "e", 0, 1) == 4, "FindFirstOf('abcdef, 1, 6, 'e', 0, 1) did not return index 4!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_FindFirstNot()
{
	ZBasicString<> str1;
	ZBasicString<> str2("abcdef");
	ZBasicString<> str3("aacdef");
	ZBasicString<> str4("aaadef");
	ZBasicString<> str5("aaaaef");
	ZBasicString<> str6("aaaaaf");
	ZBasicString<> str7("aaaaaa");

	TASSERT(ZBasicStringAlgo::FindFirstNot(str1, 'a') == ZSTL::InvalidPos, "FindFirstNot('a') on empty string did not return InvalidPos!");
	TASSERT(ZBasicStringAlgo::FindFirstNot(str2, 'a') == 1, "FindFirstNot('a') on string 'abcdef' did not return index 1!");
	TASSERT(ZBasicStringAlgo::FindFirstNot(str3, 'a') == 2, "FindFirstNot('a') on string 'aacdef' did not return index 2!");
	TASSERT(ZBasicStringAlgo::FindFirstNot(str4, 'a') == 3, "FindFirstNot('a') on string 'aaadef' did not return index 3!");
	TASSERT(ZBasicStringAlgo::FindFirstNot(str5, 'a') == 4, "FindFirstNot('a') on string 'aaaaef' did not return index 4!");
	TASSERT(ZBasicStringAlgo::FindFirstNot(str6, 'a') == 5, "FindFirstNot('a') on string 'aaaaaf' did not return index 5!");
	TASSERT(ZBasicStringAlgo::FindFirstNot(str7, 'a') == ZSTL::InvalidPos, "FindFirstNot('a') on string 'aaaaaa' did not return InvalidPos!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_FindFirstNot_Region()
{
	ZBasicString<> str1;
	ZBasicString<> str2("abcdef");
	ZBasicString<> str3("aacdef");
	ZBasicString<> str4("aaadef");

	TASSERT(ZBasicStringAlgo::FindFirstNot(str2, 'a', 0, 1) == ZSTL::InvalidPos, "FindFirstNot('abcdef', 'a', 0, 1) did not return index InvalidPos!");
	TASSERT(ZBasicStringAlgo::FindFirstNot(str3, 'a', 1, 4) == 2, "FindFirstNot('abcdef', 'a', 1, 4) did not return index 2!");
	TASSERT(ZBasicStringAlgo::FindFirstNot(str4, 'a', 0, 4) == 3, "FindFirstNot('a') on string 'aaadef' did not return index 3!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_FindFirstNotOf()
{
	ZBasicString<> str1;
	ZBasicString<> str2("abcdef");

	TASSERT(ZBasicStringAlgo::FindFirstNotOf(str1, "abc") == ZSTL::InvalidPos, "FindFirstNotOf('abc') on empty string did not return InvalidPos!");

	TASSERT(ZBasicStringAlgo::FindFirstNotOf(str2, " ") == 0, "FindFirstNotOf(' ') on string 'abcdef' did not return index 0!");
	TASSERT(ZBasicStringAlgo::FindFirstNotOf(str2, "a") == 1, "FindFirstNotOf('a') on string 'abcdef' did not return index 1!");
	TASSERT(ZBasicStringAlgo::FindFirstNotOf(str2, "ab") == 2, "FindFirstNotOf('ab') on string 'abcdef' did not return index 2!");
	TASSERT(ZBasicStringAlgo::FindFirstNotOf(str2, "abc") == 3, "FindFirstNotOf('abc') on string 'abcdef' did not return index 3!");
	TASSERT(ZBasicStringAlgo::FindFirstNotOf(str2, "abcd") == 4, "FindFirstNotOf('abcd') on string 'abcdef' did not return index 4!");
	TASSERT(ZBasicStringAlgo::FindFirstNotOf(str2, "abcde") == 5, "FindFirstNotOf('abcde') on string 'abcdef' did not return index 5!");
	TASSERT(ZBasicStringAlgo::FindFirstNotOf(str2, "abcdef") == ZSTL::InvalidPos, "FindFirstNotOf('abcdef') on string 'abcdef' did not return InvalidPos!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_FindFirstNotOf_Region()
{
	ZBasicString<> str1;
	ZBasicString<> str2("abcdef");

	TASSERT(ZBasicStringAlgo::FindFirstNotOf(str2, 2, 4, " ", 0, 1) == 2, "FindFirstNotOf('abcdef', 2, 4, ' ', 0 , 1) did not return index 2!");
	TASSERT(ZBasicStringAlgo::FindFirstNotOf(str2, 2, 4, "a", 0, 1) == 2, "FindFirstNotOf('abcdef', 2, 4, 'a', 0, 1) did not return index 2!");
	TASSERT(ZBasicStringAlgo::FindFirstNotOf(str2, 1, 6, "abcd", 1, 3) == 3, "FindFirstNotOf('abcdef', 1, 6, 'abcd', 1, 3) did not return index 3!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_FindLast()
{
	ZBasicString<> str1;
	ZBasicString<> str2("abcdef");
	ZBasicString<> str3("abcdefabcdef");

	TASSERT(ZBasicStringAlgo::FindLast(str1, 'a') == ZSTL::InvalidPos, "FindLast('a') on empty string did not return InvalidPos!");

	TASSERT(ZBasicStringAlgo::FindLast(str2, 'a') == 0, "FindLast('a') on string 'abcdef' did not return index 0!");
	TASSERT(ZBasicStringAlgo::FindLast(str2, 'b') == 1, "FindLast('b') on string 'abcdef' did not return index 1!");
	TASSERT(ZBasicStringAlgo::FindLast(str2, 'c') == 2, "FindLast('c') on string 'abcdef' did not return index 2!");
	TASSERT(ZBasicStringAlgo::FindLast(str2, 'd') == 3, "FindLast('d') on string 'abcdef' did not return index 3!");
	TASSERT(ZBasicStringAlgo::FindLast(str2, 'e') == 4, "FindLast('e') on string 'abcdef' did not return index 4!");
	TASSERT(ZBasicStringAlgo::FindLast(str2, 'f') == 5, "FindLast('f') on string 'abcdef' did not return index 5!");

	TASSERT(ZBasicStringAlgo::FindLast(str2, 'g') == ZSTL::InvalidPos, "FindLast('g') on string 'abcdef' did not return InvalidPos!");

	TASSERT(ZBasicStringAlgo::FindLast(str3, 'a') == 6, "FindLast('a') on string 'abcdefabcdef' did not return index 6!");
	TASSERT(ZBasicStringAlgo::FindLast(str3, 'b') == 7, "FindLast('b') on string 'abcdefabcdef' did not return index 7!");
	TASSERT(ZBasicStringAlgo::FindLast(str3, 'c') == 8, "FindLast('c') on string 'abcdefabcdef' did not return index 8!");
	TASSERT(ZBasicStringAlgo::FindLast(str3, 'd') == 9, "FindLast('d') on string 'abcdefabcdef' did not return index 9!");
	TASSERT(ZBasicStringAlgo::FindLast(str3, 'e') == 10, "FindLast('e') on string 'abcdefabcdef' did not return index 10!");
	TASSERT(ZBasicStringAlgo::FindLast(str3, 'f') == 11, "FindLast('f') on string 'abcdefabcdef' did not return index 11!");

	TASSERT(ZBasicStringAlgo::FindLast(str3, 'g') == ZSTL::InvalidPos, "FindLast('g') on string 'abcdefabcdef' did not return InvalidPos!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_FindLast_In_Region()
{
	ZBasicString<> str1;
	ZBasicString<> str2("abcdef");
	ZBasicString<> str3("abcdefabcdef");

	TASSERT(ZBasicStringAlgo::FindLast(str2, 'a', 2, 5) == ZSTL::InvalidPos, "FindLast('abcdef', 'a', 2, 5) did not return index InvalidPos!");
	TASSERT(ZBasicStringAlgo::FindLast(str2, 'b', 1, 3) == 1, "FindLast('abcdef', 'b', 1, 3) did not return index 1!");

	TASSERT(ZBasicStringAlgo::FindLast(str3, 'a', 2, 9) == 6, "FindLast('abcdefabcdef', 'a', 2, 9) did not return index 6!");
	TASSERT(ZBasicStringAlgo::FindLast(str3, 'b', 1, 6) == 1, "FindLast('abcdefabcdef', 'b', 1, 6) did not return index 1!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_FindLastOf()
{
	ZBasicString<> str1;
	ZBasicString<> str2("abcdef");
	ZBasicString<> str3("abcdefabcdef");

	TASSERT(ZBasicStringAlgo::FindLastOf(str1, "abc") == ZSTL::InvalidPos, "FindLastOf('abc') on empty string did not return InvalidPos!");

	TASSERT(ZBasicStringAlgo::FindLastOf(str2, "ace") == 4, "FindLastOf('ace') on string 'abcdef' did not return index 4!");
	TASSERT(ZBasicStringAlgo::FindLastOf(str2, "ac") == 2, "FindLastOf('ac') on string 'abcdef' did not return index 2!");
	TASSERT(ZBasicStringAlgo::FindLastOf(str2, "a") == 0, "FindLastOf('a') on string 'abcdef' did not return index 0!");

	TASSERT(ZBasicStringAlgo::FindLastOf(str2, "ghijklmnop") == ZSTL::InvalidPos, "FindLastOf('ghijklmnop') on string 'abcdef' did not return InvalidPos!");

	TASSERT(ZBasicStringAlgo::FindLastOf(str3, "ace") == 10, "FindLastOf('ace') on string 'abcdef' did not return index 10!");
	TASSERT(ZBasicStringAlgo::FindLastOf(str3, "ac") == 8, "FindLastOf('ac') on string 'abcdef' did not return index 8!");
	TASSERT(ZBasicStringAlgo::FindLastOf(str3, "a") == 6, "FindLastOf('a') on string 'abcdef' did not return index 6!");

	TASSERT(ZBasicStringAlgo::FindLastOf(str3, "ghijklmnop") == ZSTL::InvalidPos, "FindLastOf('ghijklmnop') on string 'abcdefabcdef' did not return InvalidPos!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_FindLastOf_In_Region()
{
	ZBasicString<> str1;
	ZBasicString<> str2("abcdef");
	ZBasicString<> str3("abcdefabcdef");

	TASSERT(ZBasicStringAlgo::FindLastOf(str2, 2, 6, "ace", 0, 2) == 2, "FindLastOf('abcdef', 2, 6, 'ace', 0, 2) did not return index 2!");
	TASSERT(ZBasicStringAlgo::FindLastOf(str2, 0, 2, "ac", 0, 2) == 0, "FindLastOf('abcdef', 0, 2, 'ac', 0, 2) did not return index 0!");

	TASSERT(ZBasicStringAlgo::FindLastOf(str3, 0, 6, "ace", 1, 3) == 4, "FindLastOf('abcdef', 0, 6, 'ace', 1, 3) did not return index 4!");
	TASSERT(ZBasicStringAlgo::FindLastOf(str3, 2, 11, "ac", 0, 2) == 8, "FindLastOf('abcdef', 2, 11, 'ac', 0, 2) did not return index 8!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_FindLastNot()
{
	ZBasicString<> str1;
	ZBasicString<> str2("abcdef");
	ZBasicString<> str3("abcdff");
	ZBasicString<> str4("abcfff");
	ZBasicString<> str5("abffff");
	ZBasicString<> str6("afffff");
	ZBasicString<> str7("ffffff");

	TASSERT(ZBasicStringAlgo::FindLastNot(str1, 'f') == ZSTL::InvalidPos, "FindLastNot('f') on empty string did not return InvalidPos!");
	TASSERT(ZBasicStringAlgo::FindLastNot(str2, 'f') == 4, "FindLastNot('f') on string 'abcdef' did not return index 4!");
	TASSERT(ZBasicStringAlgo::FindLastNot(str3, 'f') == 3, "FindLastNot('f') on string 'abcdff' did not return index 3!");
	TASSERT(ZBasicStringAlgo::FindLastNot(str4, 'f') == 2, "FindLastNot('f') on string 'abcfff' did not return index 2!");
	TASSERT(ZBasicStringAlgo::FindLastNot(str5, 'f') == 1, "FindLastNot('f') on string 'abffff' did not return index 1!");
	TASSERT(ZBasicStringAlgo::FindLastNot(str6, 'f') == 0, "FindLastNot('f') on string 'afffff' did not return index 0!");
	TASSERT(ZBasicStringAlgo::FindLastNot(str7, 'f') == ZSTL::InvalidPos, "FindLastNot('f') on string 'ffffff' did not return InvalidPos!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_FindLastNot_In_Region()
{
	ZBasicString<> str1;
	ZBasicString<> str2("abcdef");
	ZBasicString<> str3("abcdff");

	TASSERT(ZBasicStringAlgo::FindLastNot(str2, 'f', 2, 4) == 3, "FindLastNot('abcdef', 'f', 2, 4) did not return index 3!");
	TASSERT(ZBasicStringAlgo::FindLastNot(str3, 'f', 2, 5) == 3, "FindLastNot('abcdef', 'f', 2, 5) did not return index 3!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_FindLastNotOf()
{
	ZBasicString<> str1;
	ZBasicString<> str2("abcdef");

	TASSERT(ZBasicStringAlgo::FindLastNotOf(str1, "abc") == ZSTL::InvalidPos, "FindLastNotOf('abc') on empty string did not return InvalidPos!");

	TASSERT(ZBasicStringAlgo::FindLastNotOf(str2, " ") == 5, "FindLastNotOf(' ') on string 'abcdef' did not return index 5!");
	TASSERT(ZBasicStringAlgo::FindLastNotOf(str2, "f") == 4, "FindLastNotOf('f') on string 'abcdef' did not return index 4!");
	TASSERT(ZBasicStringAlgo::FindLastNotOf(str2, "ef") == 3, "FindLastNotOf('ef') on string 'abcdef' did not return index 3!");
	TASSERT(ZBasicStringAlgo::FindLastNotOf(str2, "def") == 2, "FindLastNotOf('def') on string 'abcdef' did not return index 2!");
	TASSERT(ZBasicStringAlgo::FindLastNotOf(str2, "cdef") == 1, "FindLastNotOf('cdef') on string 'abcdef' did not return index 1!");
	TASSERT(ZBasicStringAlgo::FindLastNotOf(str2, "bcdef") == 0, "FindLastNotOf('bcdef') on string 'abcdef' did not return index 0!");
	TASSERT(ZBasicStringAlgo::FindLastNotOf(str2, "abcdef") == ZSTL::InvalidPos, "FindLastNotOf('abcdef') on string 'abcdef' did not return InvalidPos!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_FindLastNotOf_In_Region()
{
	ZBasicString<> str1;
	ZBasicString<> str2("abcdef");

	TASSERT(ZBasicStringAlgo::FindLastNotOf(str2, 2, 4, " ", 0, 1) == 3, "FindLastNotOf('abcdef', 2, 4, ' ', 0, 1) did not return index 3!");
	TASSERT(ZBasicStringAlgo::FindLastNotOf(str2, 2, 6, "f", 0, 1) == 4, "FindLastNotOf('abcdef', 2, 6, 'f', 0, 1) did not return index 4!");
	TASSERT(ZBasicStringAlgo::FindLastNotOf(str2, 3, 5, "ef", 0, 2) == 3, "FindLastNotOf('abcdef', 3, 5, 'ef', 0, 2) did not return index 3!");
	TASSERT(ZBasicStringAlgo::FindLastNotOf(str2, 1, 5, "def", 1, 2) == 3, "FindLastNotOf('abcdef', 1, 5, 'def', 1, 2) did not return index 3!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_FindSub()
{
	ZBasicString<> str1;
	ZBasicString<> str2("abcdef");

	TASSERT(ZBasicStringAlgo::FindSub(str1, "a") == ZSTL::InvalidPos, "FindSub('a') on empty string does not return InvalidPos!");

	TASSERT(ZBasicStringAlgo::FindSub(str2, "a") == 0, "FindSub('a') on 'abcdef' does not return index 0!");
	TASSERT(ZBasicStringAlgo::FindSub(str2, "abc") == 0, "FindSub('abc') on 'abcdef' does not return index 0!");
	TASSERT(ZBasicStringAlgo::FindSub(str2, "abcdef") == 0, "FindSub('abcdef') on 'abcdef' does not return index 0!");
	TASSERT(ZBasicStringAlgo::FindSub(str2, "abcdefg") == ZSTL::InvalidPos, "FindSub('abcdefg') on 'abcdef' does not return InvalidPos!");

	TASSERT(ZBasicStringAlgo::FindSub(str2, "bc") == 1, "FindSub('bc') on 'abcdef' does not return index 1!");
	TASSERT(ZBasicStringAlgo::FindSub(str2, "def") == 3, "FindSub('def') on 'abcdef' does not return index 3!");
	TASSERT(ZBasicStringAlgo::FindSub(str2, "efg") == ZSTL::InvalidPos, "FindSub('efg') on 'abcdef' does not return InvalidPos!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_FindSub_Region()
{
	ZBasicString<> str1;
	ZBasicString<> str2("abcdef");

	TASSERT(ZBasicStringAlgo::FindSub(str2, 0, 2, "abc", 1, 3) == ZSTL::InvalidPos, "FindSub(\"abcdef\", 0, 2, 'abc, 1, 3) does not return InvalidPos!");
	TASSERT(ZBasicStringAlgo::FindSub(str2, 0, 2, "abc", 0, 2) == 0, "FindSub('abcdef', 0, 2, 'abc', 0, 2) does not return index 0!");

	TASSERT(ZBasicStringAlgo::FindSub(str2, 0, 4, "bc", 1, 2) == 2, "FindSub('abcdef, 0, 4, 'bc', 1, 2) does not return index 2!");
	TASSERT(ZBasicStringAlgo::FindSub(str2, 4, 6, "def", 1, 3) == 4, "FindSub('abcdef', 4, 6, 'def', 1, 3) does not return index 3!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_IsNumeric()
{
	ZBasicString<> str1;
	ZBasicString<> str2("0");
	ZBasicString<> str3("12345");
	ZBasicString<> str4("0.0");
	ZBasicString<> str5("10.01");
	ZBasicString<> str6("-1.5");

	ZBasicString<> str7("123.456.789");
	ZBasicString<> str8("NotANumber");
	ZBasicString<> str9("-1.45 ");
	ZBasicString<> str10("50a00");

	TASSERT(!ZBasicStringAlgo::IsNumeric(str1), "IsNumeric() returns true on empty string!");

	TASSERT(ZBasicStringAlgo::IsNumeric(str2), "IsNumeric() returns false on '0'!");
	TASSERT(ZBasicStringAlgo::IsNumeric(str3), "IsNumeric() returns false on '12345'!");
	TASSERT(ZBasicStringAlgo::IsNumeric(str4), "IsNumeric() returns false on '0.0'!");
	TASSERT(ZBasicStringAlgo::IsNumeric(str5), "IsNumeric() returns false on '10.01'!");
	TASSERT(ZBasicStringAlgo::IsNumeric(str6), "IsNumeric() returns false on '-1.5'!");

	TASSERT(!ZBasicStringAlgo::IsNumeric(str7), "IsNumeric() returns true on '123.456.789'!");
	TASSERT(!ZBasicStringAlgo::IsNumeric(str8), "IsNumeric() returns true on 'NotANumber'!");
	TASSERT(!ZBasicStringAlgo::IsNumeric(str9), "IsNumeric() returns true on '-1.45'!");
	TASSERT(!ZBasicStringAlgo::IsNumeric(str10), "IsNumeric() returns true on '50a00'!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_IsNumeric_Region()
{
	ZBasicString<> str7("123.456.789");
	ZBasicString<> str10("50a00");

	TASSERT(ZBasicStringAlgo::IsNumeric(str7, 0, 3), "IsNumeric('123.456.789', 0, 3) does not return true!");
	TASSERT(ZBasicStringAlgo::IsNumeric(str7, 0, 6), "IsNumeric('123.456.789', 0, 6) does not return true!");
	TASSERT(!ZBasicStringAlgo::IsNumeric(str7, 2, 8), "IsNumeric(123.456.789, 2, 8) does not return false!");

	TASSERT(ZBasicStringAlgo::IsNumeric(str10, 0, 2), "IsNumeric('50a00', 3, 4) does not return true!");
	TASSERT(ZBasicStringAlgo::IsNumeric(str10, 3, 4), "IsNumeric('50a00', 3, 4) does not return true!");
	TASSERT(!ZBasicStringAlgo::IsNumeric(str10, 2, 4), "IsNumeric('50a00', 2, 4) does not return false!");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_Remove()
{
	ZString teststr("abcde");

	// remove nonexistant character
	TASSERT( ZBasicStringAlgo::Remove(teststr, 'z') == ZSTL::InvalidPos, "Remove() claimed removal on nonpresent character!\n");
	TASSERT(teststr.Length() == 5, "Remove() created wrong size string!\n");

	// remove from front
	TASSERT( ZBasicStringAlgo::Remove(teststr, 'c') == 2, "Remove() claimed bad removal on existing character!\n");
	TASSERT(teststr.Length() == 4, "Remove() created wrong size string!\n");

	// remove from front
	TASSERT( ZBasicStringAlgo::Remove(teststr, 'a') == 0, "Remove() claimed bad removal on existing character\n");
	TASSERT(teststr.Length() == 3, "Remove() created wrong size string!\n");

	// remove from back
	TASSERT( ZBasicStringAlgo::Remove(teststr, 'e') == 2, "Remove() claimed bad removal on existing character\n");
	TASSERT(teststr.Length() == 2, "Remove() created wrong size string!\n");
	
	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_Remove_In_Region()
{
	ZString teststr("abccddde");

	// remove nonexistant character
	TASSERT( ZBasicStringAlgo::Remove(teststr, 'z',1,4) == ZSTL::InvalidPos, "Remove() claimed removal on nonpresent character!\n");
	TASSERT(teststr.Length() == 8, "Remove() created wrong size string!\n");

	// remove from back out of range
	TASSERT( ZBasicStringAlgo::Remove(teststr, 'd',1,4) == ZSTL::InvalidPos, "Remove() claimed removal on character not in region!\n");
	TASSERT(teststr.Length() == 8, "Remove() created wrong size string!\n");

	// remove from back
	TASSERT( ZBasicStringAlgo::Remove(teststr, 'c',1,4) == 2, "Remove() claimed bad removal on existing character!\n");
	TASSERT(teststr.Length() == 7, "Remove() created wrong size string!\n");

	// remove from front out of range
	TASSERT( ZBasicStringAlgo::Remove(teststr, 'a',1,4) == ZSTL::InvalidPos, "Remove() claimed removal on character not in region\n");
	TASSERT(teststr.Length() == 7, "Remove() created wrong size string!\n");

	// remove from front
	TASSERT( ZBasicStringAlgo::Remove(teststr, 'b', 1,4) == 1, "Remove() claimed bad removal on existing character\n");
	TASSERT(teststr.Length() == 6, "Remove() created wrong size string!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_RemoveAll()
{
	ZString teststr("aaabcccdeeee");

	// remove nonexistant character
	TASSERT( ZBasicStringAlgo::RemoveAll(teststr, 'z') == 0, "RemoveAll() claimed removal of nonpresent character!\n");
	TASSERT(teststr.Length() == 12, "Remove() created wrong size string!\n");

	// remove from front
	TASSERT( ZBasicStringAlgo::RemoveAll(teststr, 'c') == 3, "RemoveAll() claimed bad removal on existing character!\n");
	TASSERT(teststr.Length() == 9, "Remove() created wrong size string!\n");

	// remove from front
	TASSERT( ZBasicStringAlgo::RemoveAll(teststr, 'a') == 3, "RemoveAll() claimed bad removal on existing character\n");
	TASSERT(teststr.Length() == 6, "Remove() created wrong size string!\n");

	// remove from back
	TASSERT( ZBasicStringAlgo::RemoveAll(teststr, 'e') == 4, "RemoveAll() claimed bad removal on existing character\n");
	TASSERT(teststr.Length() == 2, "Remove() created wrong size string!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_RemoveAll_In_Region()
{
	ZString teststr("aaabcccdeeee");

	// remove nonexistant character
	TASSERT( ZBasicStringAlgo::RemoveAll(teststr, 'z', 1, 8) == 0, "RemoveAll() claimed removal of nonpresent character!\n");
	TASSERT( teststr.Equals("aaabcccdeeee"), "RemoveAll() produced incorrect string!\n");

	// remove from middle
	TASSERT( ZBasicStringAlgo::RemoveAll(teststr, 'c', 1, 8) == 3, "RemoveAll() claimed bad removal on existing character!\n");
	TASSERT( teststr.Equals("aaabdeeee"), "RemoveAll() produced incorrect string!\n");

	// remove from front
	TASSERT( ZBasicStringAlgo::RemoveAll(teststr, 'a', 1, 8) == 2, "RemoveAll() claimed bad removal on existing character\n");
	TASSERT( teststr.Equals("abdeeee"), "RemoveAll() produced incorrect string!\n");

	// remove from back
	TASSERT( ZBasicStringAlgo::RemoveAll(teststr, 'e', 1, 6) == 3, "RemoveAll() claimed bad removal on existing character\n");
	TASSERT( teststr.Equals("abde"), "RemoveAll() produced incorrect string!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_RemoveUpTo()
{
	ZString teststr("aaabcccdeeee");

	// remove nonexistent character
	TASSERT(ZBasicStringAlgo::RemoveUpTo(teststr, 'z', 1) == 0,"RemoveUpTo() removed nonexistent character!\n");
	TASSERT( teststr.Equals("aaabcccdeeee"), "RemoveUpTo() produced incorrect string!\n");

	// remove from middle
	TASSERT(ZBasicStringAlgo::RemoveUpTo(teststr, 'c', 2) == 2,"RemoveUpTo() removed incorrect amounts of character!\n");
	TASSERT( teststr.Equals("aaabcdeeee"), "RemoveUpTo() produced incorrect string!\n");

	// remove from front
	TASSERT(ZBasicStringAlgo::RemoveUpTo(teststr, 'a', 2) == 2,"RemoveUpTo() removed incorrect amounts of character!\n");
	TASSERT( teststr.Equals("abcdeeee"), "RemoveUpTo() produced incorrect string!\n");

	// remove from back
	TASSERT(ZBasicStringAlgo::RemoveUpTo(teststr, 'e', 4) == 4,"RemoveUpTo() removed incorrect amounts of character!\n");
	TASSERT( teststr.Equals("abcd"), "RemoveUpTo() produced incorrect string!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_RemoveUpTo_In_Region()
{
	ZString teststr("aaabcccdeeee");

	// remove nonexistent character
	TASSERT(ZBasicStringAlgo::RemoveUpTo(teststr, 'z', 1, 1, 8) == 0,"RemoveUpTo() removed nonexistent character!\n");
	TASSERT( teststr.Equals("aaabcccdeeee"), "RemoveUpTo() produced incorrect string!\n");

	// remove from outside region
	TASSERT(ZBasicStringAlgo::RemoveUpTo(teststr, 'e', 1, 1, 8) == 0,"RemoveUpTo() removed character from outside region!\n");
	TASSERT( teststr.Equals("aaabcccdeeee"), "RemoveUpTo() produced incorrect string!\n");

	// remove from middle
	TASSERT(ZBasicStringAlgo::RemoveUpTo(teststr, 'c', 2, 1, 8) == 2,"RemoveUpTo() removed incorrect amounts of character!\n");
	TASSERT( teststr.Equals("aaabcdeeee"), "RemoveUpTo() produced incorrect string!\n");

	// remove from front
	TASSERT(ZBasicStringAlgo::RemoveUpTo(teststr, 'a', 2, 1,8) == 2,"RemoveUpTo() removed incorrect amounts of character!\n");
	TASSERT( teststr.Equals("abcdeeee"), "RemoveUpTo() produced incorrect string!\n");

	// remove from back
	TASSERT(ZBasicStringAlgo::RemoveUpTo(teststr, 'e', 4,1,6) == 2,"RemoveUpTo() removed incorrect amounts of character!\n");
	TASSERT( teststr.Equals("abcdee"), "RemoveUpTo() produced incorrect string!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_Replace()
{
	ZString teststr("aabbcc");

	// replace nothing
	ZBasicStringAlgo::Replace(teststr,'d','e');
	TASSERT(teststr.Equals("aabbcc"), "Replace() failed to leave string with no replacements alone!\n");

	// replace in middle
	ZBasicStringAlgo::Replace(teststr,'b','2');
	TASSERT(teststr.Equals("aa22cc"),"Replace() failed to correctly replace chars in middle of string!\n");

	// replace in back
	ZBasicStringAlgo::Replace(teststr,'a','1');
	TASSERT(teststr.Equals("1122cc"),"Replace() failed to correctly replace chars in front of string!\n");

	// replace in front
	ZBasicStringAlgo::Replace(teststr,'c','3');
	TASSERT(teststr.Equals("112233"),"Replace() failed to correctly replace chars in middle of string!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

#if 0
static const char* test_ReplaceSub()
{
    // This function may need to be renamed. What it does is replace a substring of the hoststring with the substring of substr
    // marked by start and end size_t
	ZString hoststr("aabbcc");
	ZString substr("abc");

	// replace in front
	ZBasicStringAlgo::ReplaceSub(hoststr,0,3,substr,0,3);
	TASSERT(hoststr.Equals("abcbcc"), "Replace() failed to correctly replace chars in front of string!\n");

	// replace in middle
	ZBasicStringAlgo::ReplaceSub(hoststr,1,4,substr,0,3);
	TASSERT(hoststr.Equals("aabccc"), "Replace() failed to correctly replace chars in middle of string!\n");

	// replace in back
	ZBasicStringAlgo::ReplaceSub(hoststr,3,6,substr,0,3);
	TASSERT(hoststr.Equals("aababc"), "Replace() failed to correctly replace chars in end of string!\n");

    // replace entire string 
    ZString dullstring("zzzzzz");
	ZBasicStringAlgo::ReplaceSub(hoststr,0,6,dullstring,0,6);
	TASSERT(hoststr.Equals("zzzzzz"), "Replace() failed to replace entire string with same length string!\n");
    
    // replace entire string with shorter string
    hoststr = "abcabc";
	ZBasicStringAlgo::ReplaceSub(hoststr,0,6,dullstring,0,3);
	TASSERT(hoststr.Equals("zzz"), "Replace() failed to replace entire string with shorter string!\n");
 
	// replace entire string with longer string
	ZBasicStringAlgo::ReplaceSub(hoststr,0,3,dullstring,0,6);
	TASSERT(hoststr.Equals("zzzzzz"), "Replace() failed to replace entire string with longer string!\n");

	return ZTEST_SUCCESS;
}
#endif

/*************************************************************************/

static const char* test_Replace_In_Region()
{
	ZString teststr("aabbcc");

	// replace nothing
	ZBasicStringAlgo::Replace(teststr,'d','e',1,5);
	TASSERT(teststr.Equals("aabbcc"), "Replace() failed to leave string with no replacements alone!\n");
	
	// replace in middle
	ZBasicStringAlgo::Replace(teststr,'b','2',1,5);
	TASSERT(teststr.Equals("aa22cc"),"Replace() failed to correctly replace chars in middle of string!\n");

	// replace in back
	ZBasicStringAlgo::Replace(teststr,'a','1',1,5);
	TASSERT(teststr.Equals("a122cc"),"Replace() failed to correctly replace chars in front of string!\n");

	// replace in front
	ZBasicStringAlgo::Replace(teststr,'c','3',1,5);
	TASSERT(teststr.Equals("a1223c"),"Replace() failed to correctly replace chars in middle of string!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_Reverse()
{
	ZString testempty;
	ZString teststr("aabbcc");

	// test reverse empty string
	ZBasicStringAlgo::Reverse(testempty);
	TASSERT(testempty.Equals(""), "Reverse() on empty string resulted in broken string!\n");

	// test on normal string
	ZBasicStringAlgo::Reverse(teststr);
	TASSERT(teststr.Equals("ccbbaa"), "Reverse() created incorrect string!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_Reverse_Region()
{
	ZString testempty;
	ZString teststr("aabbcc");

	// test on normal string
	ZBasicStringAlgo::Reverse(teststr,1,5);
	TASSERT(teststr.Equals("acbbac"), "Reverse() created incorrect string!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_Slice()
{
	ZString emptystr;
	ZString teststr("aaabbbccc");
	ZString slice;

	// slice an empty string
	slice = ZBasicStringAlgo::Slice(emptystr,0,0);
	TASSERT(slice.Empty(), "Slice() on empty string returned nonempty slice!\n");
	TASSERT(emptystr.Empty(), "Slice() on empy string returned nonempty remainder!\n");

	// make an empty slice
	slice = ZBasicStringAlgo::Slice(teststr,0,0);
	TASSERT(slice.Empty(), "Zero-length Slice() on string returned wrong slice!\n");
	TASSERT(teststr.Equals("aaabbbccc"), "Slice() on string returned wrong remainder!\n");

	// make a whole-length slice
	slice = ZBasicStringAlgo::Slice(teststr,0,teststr.Length());
	TASSERT(slice.Equals("aaabbbccc"), "Full-length Slice() on string returned wrong slice!\n");
	TASSERT(teststr.Empty(), "Slice() on string returned wrong remainder!\n");
	
	// slice off the back
	teststr = ZString("aaabbbccc");
	slice = ZBasicStringAlgo::Slice(teststr,3,teststr.Length());
	TASSERT(slice.Equals("bbbccc"), "Slice() on string returned wrong slice!\n");
	TASSERT(teststr.Equals("aaa"), "Slice() on string returned wrong remainder!\n");

	// slice off the front
	teststr = ZString("aaabbbccc");
	slice = ZBasicStringAlgo::Slice(teststr, 0, 3);
	TASSERT(slice.Equals("aaa"), "Slice() on string returned wrong slice!\n");
	TASSERT(teststr.Equals("bbbccc"), "Slice() on string returned wrong remainder!\n");

	// slice off the middle
	teststr = ZString("aaabbbccc");
	slice = ZBasicStringAlgo::Slice(teststr, 3, 6);
	TASSERT(slice.Equals("bbb"), "Slice() on string returned wrong slice!\n");
	TASSERT(teststr.Equals("aaaccc"), "Slice() on string returned wrong remainder!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_Split()
{
	ZString emptystr;
	ZString teststr;
	ZArray< ZString > ret;

	// test on empty string
	ret = ZBasicStringAlgo::Split(emptystr, ",;");
	TASSERT(ret.Empty(), "Split() created nonempty array for empty string!\n");

	// test on legit string with no delimiters on ends
	teststr = ZString("aaa,bbb;ccc;ddd,eee");
	ret = ZBasicStringAlgo::Split(teststr, ",;");
	TASSERT(teststr.Equals("aaa,bbb;ccc;ddd,eee"), "Split() harmed underlying string!\n");
	TASSERT(ret.Size() == 5, "Split() created array of wrong size for string!\n");
	TASSERT(ret.At(0).Equals("aaa"), "Split() created wrong string for section!\n");
	TASSERT(ret.At(1).Equals("bbb"), "Split() created wrong string for section!\n");
	TASSERT(ret.At(2).Equals("ccc"), "Split() created wrong string for section!\n");
	TASSERT(ret.At(3).Equals("ddd"), "Split() created wrong string for section!\n");
	TASSERT(ret.At(4).Equals("eee"), "Split() created wrong string for section!\n");

	// test on legit string with extra delimiters
	teststr = ZString(",aaa,bbb;ccc;");
	ret = ZBasicStringAlgo::Split(teststr, ",;");
	TASSERT(teststr.Equals(",aaa,bbb;ccc;"), "Split() harmed underlying string!\n");
	TASSERT(ret.Size() == 3, "Split() created array of wrong size for string!\n");
	TASSERT(ret.At(0).Equals("aaa"), "Split() created wrong string for section!\n");
	TASSERT(ret.At(1).Equals("bbb"), "Split() created wrong string for section!\n");
	TASSERT(ret.At(2).Equals("ccc"), "Split() created wrong string for section!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_Split_Count()
{
	ZString emptystr;
	ZString teststr;
	ZArray< ZString > ret;

	// test on legit string with no delimiters on ends
	teststr = ZString("aaa,bbb;ccc;ddd,eee");
	ret = ZBasicStringAlgo::Split(teststr, ",;", 2);
	TASSERT(teststr.Equals("aaa,bbb;ccc;ddd,eee"), "Split() harmed underlying string!\n");
	TASSERT(ret.Size() == 3, "Split() created array of wrong size for string!\n");
	TASSERT(ret.At(0).Equals("aaa"), "Split() created wrong string for section!\n");
	TASSERT(ret.At(1).Equals("bbb"), "Split() created wrong string for section!\n");
	TASSERT(ret.At(2).Equals("ccc;ddd,eee"), "Split() created wrong string for section!\n");

	// test on legit string with extra delimiters
	teststr = ZString(",aaa,bbb;;;ccc;");
	ret = ZBasicStringAlgo::Split(teststr, ",;", 2);
	TASSERT(teststr.Equals(",aaa,bbb;;;ccc;"), "Split() harmed underlying string!\n");
	TASSERT(ret.Size() == 3, "Split() created array of wrong size for string given count!\n");
	TASSERT(ret.At(0).Equals("aaa"), "Split() created wrong string for section!\n");
	TASSERT(ret.At(1).Equals("bbb"), "Split() created wrong string for section!\n");
	// note that the below is expected because we had finished our two splits and stopped looking for delimiters
	TASSERT(ret.At(2).Equals(";;ccc;"), "Split() created wrong string for section!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_Split_Count_Region()
{
	ZString emptystr;
	ZString teststr;
	ZArray< ZString > ret;

	// test on legit string with no delimiters on ends
	teststr = ZString("aaa,bbb;ccc;ddd,eee");
	ret = ZBasicStringAlgo::Split(teststr, ",;", 2, 5, teststr.Length() - 1);
	TASSERT(teststr.Equals("aaa,bbb;ccc;ddd,eee"), "Split() harmed underlying string!\n");
	TASSERT(ret.Size() == 3, "Split() created array of wrong size for string!\n");
	TASSERT(ret.At(0).Equals("bb"), "Split() created wrong string for section!\n");
	TASSERT(ret.At(1).Equals("ccc"), "Split() created wrong string for section!\n");
	TASSERT(ret.At(2).Equals("ddd,ee"), "Split() created wrong string for section!\n");

	// test on legit string with extra delimiters
	teststr = ZString(",aaa,bbb;ccc;");
	ret = ZBasicStringAlgo::Split(teststr, ",;", 2, 3, teststr.Length()-2);
	TASSERT(teststr.Equals(",aaa,bbb;ccc;"), "Split() harmed underlying string!\n");
	TASSERT(ret.Size() == 3, "Split() created array of wrong size for string given count!\n");
	TASSERT(ret.At(0).Equals("a"), "Split() created wrong string for section!\n");
	TASSERT(ret.At(1).Equals("bbb"), "Split() created wrong string for section!\n");
	TASSERT(ret.At(2).Equals("cc"), "Split() created wrong string for section!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_StartsWith()
{
	ZString testempty;
	ZString teststr("aaabbbccc");

	// empty string with empty startstring
	TASSERT( ZBasicStringAlgo::StartsWith(testempty, "") == false, "StartsWith() claimed empty string started with empty string!");

	// empty string with empty startstring
	TASSERT( ZBasicStringAlgo::StartsWith(testempty, "aaa") == false, "StartsWith() claimed empty string started with nonempty string!");

	// string with empty startstring
	TASSERT( ZBasicStringAlgo::StartsWith(teststr, "") == false, "StartsWith() claimed string started with empty string!\n");

	// string with wrong startstring
	TASSERT( ZBasicStringAlgo::StartsWith(teststr, "bbbb") == false, "StartsWith() claimed string started with empty string!\n");

	// string with truncated startstring
	TASSERT( ZBasicStringAlgo::StartsWith(teststr, "aa") == true, "StartsWith() claimed string not started with truncated string!\n");

	// string with overlong startstring
	TASSERT( ZBasicStringAlgo::StartsWith(teststr, "aaaa") == false, "StartsWith() claimed string started with overlong string!\n");

	// string with correct startstring
	TASSERT( ZBasicStringAlgo::StartsWith(teststr,"aaa") == true, "StartsWith() failed to match start string correctly!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_StartsWith_Region()
{
	ZString testempty;
	ZString teststr("aaabbbccc");

	// empty string with empty startstring
	TASSERT( ZBasicStringAlgo::StartsWith(testempty, 0, testempty.Length(), "", 0, 0) == false, "StartsWith() claimed empty string started with empty string!");

	// empty string with empty startstring
	TASSERT( ZBasicStringAlgo::StartsWith(testempty, 0, testempty.Length(), "aaaa", 1, 3) == false, "StartsWith() claimed empty string started with nonempty string!");

	// string with empty startstring
	TASSERT( ZBasicStringAlgo::StartsWith(teststr, 1, teststr.Length(), "", 0, 0) == false, "StartsWith() claimed string started with empty string!\n");

	// string with wrong startstring
	TASSERT( ZBasicStringAlgo::StartsWith(teststr, 1, teststr.Length(), "bbbb", 1, 3) == false, "StartsWith() claimed string started with empty string!\n");

	// string with truncated startstring
	TASSERT( ZBasicStringAlgo::StartsWith(teststr, 1, teststr.Length(), "aaaa", 1, 2) == true, "StartsWith() claimed string not started with truncated string!\n");

	// string with overlong startstring
	TASSERT( ZBasicStringAlgo::StartsWith(teststr, 1, teststr.Length(), "aaaa", 1, 4) == false, "StartsWith() claimed string started with overlong string!\n");

	// string with correct startstring
	TASSERT( ZBasicStringAlgo::StartsWith(teststr, 1, teststr.Length(), "aaaa", 1, 3) == true, "StartsWith() failed to match start string correctly!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_Strip()
{
	ZString testempty;
	ZString teststr(" ab\t\t c d  ");

	TASSERT(ZBasicStringAlgo::Strip(testempty) == 0, "Strip() attempted to remove characters from empty string!\n");
	TASSERT(testempty.Equals(""), "Strip() broke empty string!\n");

	TASSERT(ZBasicStringAlgo::Strip(teststr) == 7, "Strip() removed wrong number of characters!\n");
	TASSERT(teststr.Equals("abcd"), "Strip() created wrong string!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_Strip_Region()
{
	ZString testempty;
	ZString teststr(" ab\t\t c d  ");

	TASSERT(ZBasicStringAlgo::Strip(testempty ,0 ,0) == 0, "Strip() attempted to remove characters from empty string!\n");
	TASSERT(testempty.Equals(""), "Strip() broke empty string!\n");

	TASSERT(ZBasicStringAlgo::Strip(teststr, 1, 10) == 5, "Strip() removed wrong number of characters!\n");
	TASSERT(teststr.Equals(" abcd "), "Strip() created wrong string!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_Tokenize()
{
	ZString testempty;
	ZString testcsv(",a,b,c,d,");
	ZString tok;

	// check empty string
	tok = ZBasicStringAlgo::Tokenize(testempty,",");
	TASSERT(tok.Empty(),"Tokenize() on empty string returned nonempty string!\n");

	// check empty delimiter string
	tok = ZBasicStringAlgo::Tokenize(testcsv, "");
	TASSERT( tok.Equals(",a,b,c,d,"), "Tokenize() with empty delimiters returned wrong string!\n");
	TASSERT( testcsv.Empty(), "Tokenize() with empty delimiters did not consume whole string!\n");

	// check delimited string
	testcsv = ZString(",a,b,c,d,");
	tok = ZBasicStringAlgo::Tokenize(testcsv,",");
	TASSERT(tok.Equals(""),"Tokenize() produced wrong token!\n");
	TASSERT(testcsv.Equals("a,b,c,d,"),"Tokenize() produced wrong remainder!\n");

	tok = ZBasicStringAlgo::Tokenize(testcsv,",");
	TASSERT(tok.Equals("a"),"Tokenize() produced wrong token!\n");
	TASSERT(testcsv.Equals("b,c,d,"),"Tokenize() produced wrong remainder!\n");

	tok = ZBasicStringAlgo::Tokenize(testcsv,",");
	TASSERT(tok.Equals("b"),"Tokenize() produced wrong token!\n");
	TASSERT(testcsv.Equals("c,d,"),"Tokenize() produced wrong remainder!\n");

	tok = ZBasicStringAlgo::Tokenize(testcsv,",");
	TASSERT(tok.Equals("c"),"Tokenize() produced wrong token!\n");
	TASSERT(testcsv.Equals("d,"),"Tokenize() produced wrong remainder!\n");

	tok = ZBasicStringAlgo::Tokenize(testcsv,",");
	TASSERT(tok.Equals("d"),"Tokenize() produced wrong token!\n");
	TASSERT(testcsv.Equals(""),"Tokenize() produced wrong remainder!\n");

	// check delimited empty strings
	testcsv = ZString(",,;;");
	tok = ZBasicStringAlgo::Tokenize(testcsv,",;");
	TASSERT(tok.Equals(""),"Tokenize() produced wrong token!\n");
	TASSERT(testcsv.Equals(",;;"),"Tokenize() produced wrong remainder!\n");

	tok = ZBasicStringAlgo::Tokenize(testcsv,",;");
	TASSERT(tok.Equals(""),"Tokenize() produced wrong token!\n");
	TASSERT(testcsv.Equals(";;"),"Tokenize() produced wrong remainder!\n");
	
	tok = ZBasicStringAlgo::Tokenize(testcsv,",;");
	TASSERT(tok.Equals(""),"Tokenize() produced wrong token!\n");
	TASSERT(testcsv.Equals(";"),"Tokenize() produced wrong remainder!\n");
	
	tok = ZBasicStringAlgo::Tokenize(testcsv,",;");
	TASSERT(tok.Equals(""),"Tokenize() produced wrong token!\n");
	TASSERT(testcsv.Equals(""),"Tokenize() produced wrong remainder!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_ToLower()
{
	ZString testempty;
	ZString teststr("AaBbCc");

	ZBasicStringAlgo::ToLower(testempty);
	TASSERT(testempty.Equals(""), "ToLower() produced bad result on empty string!\n");

	ZBasicStringAlgo::ToLower(teststr);
	TASSERT(teststr.Equals("aabbcc"), "ToLower() produced bad result on mixed string!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_ToLower_Region()
{
	ZString testempty;
	ZString teststr("AaBbCcDdEe");

	ZBasicStringAlgo::ToLower(testempty,0,0);
	TASSERT(testempty.Equals(""), "ToLower() produced bad result on empty string!\n");

	ZBasicStringAlgo::ToLower(teststr,2,8);
	TASSERT(teststr.Equals("AabbccddEe"), "ToLower() produced bad result on mixed string!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_ToUpper()
{
	ZString testempty;
	ZString teststr("AaBbCc");

	ZBasicStringAlgo::ToUpper(testempty);
	TASSERT(testempty.Equals(""), "ToUpper() produced bad result on empty string!\n");

	ZBasicStringAlgo::ToUpper(teststr);
	TASSERT(teststr.Equals("AABBCC"), "ToUpper() produced bad result on mixed string!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_ToUpper_Region()
{
	ZString testempty;
	ZString teststr("AaBbCcDdEe");

	ZBasicStringAlgo::ToUpper(testempty,0,0);
	TASSERT(testempty.Equals(""), "ToUpper() produced bad result on empty string!\n");

	ZBasicStringAlgo::ToUpper(teststr,2,8);
	TASSERT(teststr.Equals("AaBBCCDDEe"), "ToUpper() produced bad result on mixed string!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_TrimLeft()
{
	ZString testempty;
	ZString teststr("  test  ");

	TASSERT(ZBasicStringAlgo::TrimLeft(testempty) == 0, "TrimLeft() removed nonzero characters from empty string!");
	TASSERT(testempty.Empty(), "TrimLeft() broke empty string!\n");

	TASSERT(ZBasicStringAlgo::TrimLeft(teststr) == 2, "TrimLeft() removed wrong number of characters!\n");
	TASSERT(teststr.Equals("test  "), "TrimLeft() produced incorrect string!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_TrimLeft_Region()
{
	ZString testempty;
	ZString teststr("  test  ");

	TASSERT(ZBasicStringAlgo::TrimLeft(testempty,0,0) == 0, "TrimLeft() removed nonzero characters from empty string!");
	TASSERT(testempty.Empty(), "TrimLeft() broke empty string!\n");

	TASSERT(ZBasicStringAlgo::TrimLeft(teststr,1,7) == 1, "TrimLeft() removed wrong number of characters!\n");
	TASSERT(teststr.Equals(" test  "), "TrimLeft() produced incorrect string!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_TrimRight()
{
	ZString testempty;
	ZString teststr("  test  ");

	TASSERT(ZBasicStringAlgo::TrimRight(testempty) == 0, "TrimRight() removed nonzero characters from empty string!");
	TASSERT(testempty.Empty(), "TrimRight() broke empty string!\n");

	TASSERT(ZBasicStringAlgo::TrimRight(teststr) == 2, "TrimRight() removed wrong number of characters!\n");
	TASSERT(teststr.Equals("  test"), "TrimRight() produced incorrect string!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_TrimRight_Region()
{
	ZString testempty;
	ZString teststr("  test  ");

	TASSERT(ZBasicStringAlgo::TrimRight(testempty,0,0) == 0, "TrimRight() removed nonzero characters from empty string!");
	TASSERT(testempty.Empty(), "TrimRight() broke empty string!\n");

	TASSERT(ZBasicStringAlgo::TrimRight(teststr,1,7) == 1, "TrimRight() removed wrong number of characters!\n");
	TASSERT(teststr.Equals("  test "), "TrimRight() produced incorrect string!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_Trim()
{
	ZString testempty;
	ZString teststr("  test  ");

	TASSERT(ZBasicStringAlgo::Trim(testempty) == 0, "Trim() removed nonzero characters from empty string!");
	TASSERT(testempty.Empty(), "Trim() broke empty string!\n");

	TASSERT(ZBasicStringAlgo::Trim(teststr) == 4, "Trim() removed wrong number of characters!\n");
	TASSERT(teststr.Equals("test"), "Trim() produced incorrect string!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

static const char* test_Trim_Region()
{
	ZString testempty;
	ZString teststr("  test  ");

	TASSERT(ZBasicStringAlgo::Trim(testempty,0,0) == 0, "Trim() removed nonzero characters from empty string!");
	TASSERT(testempty.Empty(), "Trim() broke empty string!\n");

	TASSERT(ZBasicStringAlgo::Trim(teststr,1,7) == 2, "Trim() removed wrong number of characters!\n");
	TASSERT(teststr.Equals(" test "), "Trim() produced incorrect string!\n");

	return ZTEST_SUCCESS;
}

/*************************************************************************/

