Index: Include/Classes/System/String.ab
===================================================================
--- Include/Classes/System/String.ab	(revision 125)
+++ Include/Classes/System/String.ab	(revision 132)
@@ -1,2 +1,6 @@
+' Classes/System/String.ab
+
+#require <basic/function.sbp>
+
 Class String
 	m_Length As Long
@@ -57,14 +61,14 @@
 	End Sub
 
-	Const Function Operator[] (n As Long) As Char
+	Const Function Operator [] (n As Long) As Char
 		Return Chars[n]
 	End Function
 
-	Sub Operator[]= (n As Long, c As Char)
+	Sub Operator []= (n As Long, c As Char)
 		Chars[n] = c
 	End Sub
 
-	Const Function Operator + (lpszText As *Char) As String
-		Return Concat(lpszText, lstrlen(lpszText))
+	Const Function Operator + (pszText As *Char) As String
+		Return Concat(pszText, lstrlen(pszText))
 	End Function
 
@@ -73,6 +77,6 @@
 	End Function
 
-	Const Function Operator & (lpszText As *Char) As String
-		Dim tempString = This + lpszText
+	Const Function Operator & (pszText As *Char) As String
+		Dim tempString = This + pszText
 		Return tempString
 	End Function
@@ -83,93 +87,53 @@
 	End Function
 
-	Function Operator== (ByRef objString As String) As Long
-		If lstrcmp(This, objString) = 0 Then
-			Return _System_TRUE
-		Else
-			Return _System_FALSE
-		End If
-	End Function
-
-	Function Operator== (lpszText As *Char) As Long
-		If lstrcmp(This, lpszText) = 0 Then
-			Return _System_TRUE
-		Else
-			Return _System_FALSE
-		End If
-	End Function
-
-	Function Operator<> (ByRef objString As String) As Long
-		Return lstrcmp(This, objString)
-	End Function
-
-	Function Operator<> (lpszText As *Char) As Long
-		Return lstrcmp(This, lpszText)
-	End Function
-
-	Function Operator< (ByRef objString As String) As Long
-		If lstrcmp(This, objString) < 0 Then
-			Return _System_TRUE
-		Else
-			Return _System_FALSE
-		End If
-	End Function
-
-	Function Operator< (lpszText As *Char) As Long
-		If lstrcmp(This, lpszText) < 0 Then
-			Return _System_TRUE
-		Else
-			Return _System_FALSE
-		End If
-	End Function
-
-	Function Operator> (ByRef objString As String) As Long
-		If lstrcmp(This, objString) > 0 Then
-			Return _System_TRUE
-		Else
-			Return _System_FALSE
-		End If
-	End Function
-
-	Function Operator> (lpszText As *Char) As Long
-		If lstrcmp(This, lpszText) > 0 Then
-			Return _System_TRUE
-		Else
-			Return _System_FALSE
-		End If
-	End Function
-
-	Function Operator<= (ByRef objString As String) As Long
-		If lstrcmp(This, objString) <= 0 Then
-			Return _System_TRUE
-		Else
-			Return _System_FALSE
-		End If
-	End Function
-
-	Function Operator<= (lpszText As *Char) As Long
-		If lstrcmp(This, lpszText) <= 0 Then
-			Return _System_TRUE
-		Else
-			Return _System_FALSE
-		End If
-	End Function
-
-	Function Operator>= (ByRef objString As String) As Long
-		If lstrcmp(This, objString) => 0 Then
-			Return _System_TRUE
-		Else
-			Return _System_FALSE
-		End If
-	End Function
-
-	Function Operator>= (lpszText As *Char) As Long
-		If lstrcmp(This, lpszText) => 0 Then
-			Return _System_TRUE
-		Else
-			Return _System_FALSE
-		End If
-	End Function
-
-	Function StrPtr() As *Char
+	Const Function Operator == (ByRef objString As String) As Boolean
+		Return _System_StrCmp(This, objString) = 0
+	End Function
+
+	Const Function Operator == (text As *Char) As Long
+		Return _System_StrCmp(This, text) = 0
+	End Function
+
+	Const Function Operator <> (ByRef objString As String) As Boolean
+		Return _System_StrCmp(This, objString)
+	End Function
+
+	Const Function Operator <> (text As *Char) As Boolean
+		Return _System_StrCmp(This, text)
+	End Function
+
+	Const Function Operator < (ByRef objString As String) As Boolean
+		Return _System_StrCmp(This, objString) < 0
+	End Function
+
+	Const Function Operator < (text As *Char) As Boolean
+		Return _System_StrCmp(This, text) < 0
+	End Function
+
+	Const Function Operator > (ByRef objString As String) As Boolean
+		Return _System_StrCmp(This, objString) > 0
+	End Function
+
+	Const Function Operator > (text As *Char) As Boolean
+		Return _System_StrCmp(This, text) > 0
+	End Function
+
+	Const Function Operator <= (ByRef objString As String) As Boolean
+		Return _System_StrCmp(This, objString) <= 0
+	End Function
+
+	Const Function Operator <= (text As *Char) As Boolean
+		Return _System_StrCmp(This, text) <= 0
+	End Function
+
+	Const Function Operator >= (ByRef objString As String) As Boolean
+		Return _System_StrCmp(This, objString) => 0
+	End Function
+
+	Const Function Operator >= (text As *Char) As Boolean
+		Return _System_StrCmp(This, text) => 0
+	End Function
+
+	Const Function StrPtr() As *Char
 		Return Chars
 	End Function
@@ -248,5 +212,9 @@
 	End Sub
 
-	Function Concat(lpszText As *Char, textLength As Long) As String
+	Const Function Clone() As String
+		Return This
+	End Function
+
+	Const Function Concat(lpszText As *Char, textLength As Long) As String
 		Dim tempString As String
 		With tempString
@@ -259,31 +227,22 @@
 	End Function
 
-	Function Contains(ByRef objString As String) As BOOL
-		If IndexOf(objString, 0, m_Length) >= 0 Then
-			Return _System_TRUE
-		Else
-			Return _System_FALSE
-		End If
-	End Function
-
-	Function Contains(lpszText As *Char) As BOOL
-		If IndexOf(lpszText, 0, m_Length) >= 0 Then
-			Return _System_TRUE
-		Else
-			Return _System_FALSE
-		End If
-	End Function
-
-	Function IndexOf(lpszText As *Char) As Long
+	Const Function Contains(ByRef objString As String) As Boolean
+		Return IndexOf(objString, 0, m_Length) >= 0
+	End Function
+
+	Const Function Contains(lpszText As *Char) As Boolean
+		Return IndexOf(lpszText, 0, m_Length) >= 0
+	End Function
+
+	Const Function IndexOf(lpszText As *Char) As Long
 		Return IndexOf(lpszText, 0, m_Length)
 	End Function
 
-	Function IndexOf(lpszText As *Char, startIndex As Long) As Long
+	Const Function IndexOf(lpszText As *Char, startIndex As Long) As Long
 		Return IndexOf(lpszText, startIndex, m_Length - startIndex)
 	End Function
 
-	Function IndexOf(lpszText As *Char, startIndex As Long, count As Long) As Long
-		Dim length As Long
-		length = lstrlen(lpszText)
+	Const Function IndexOf(lpszText As *Char, startIndex As Long, count As Long) As Long
+		Dim length = lstrlen(lpszText)
 
 		If startIndex < 0 Then Return -1
@@ -306,15 +265,14 @@
 	End Function
 
-	Function LastIndexOf(lpszText As *Char) As Long
+	Const Function LastIndexOf(lpszText As *Char) As Long
 		Return LastIndexOf(lpszText, m_Length - 1, m_Length)
 	End Function
 
-	Function LastIndexOf(lpszText As *Char, startIndex As Long) As Long
+	Const Function LastIndexOf(lpszText As *Char, startIndex As Long) As Long
 		Return LastIndexOf(lpszText As *Char, startIndex, startIndex + 1)
 	End Function
 
-	Function LastIndexOf(lpszText As *Char, startIndex As Long, count As Long) As Long
-		Dim length As Long
-		length = lstrlen(lpszText)
+	Const Function LastIndexOf(lpszText As *Char, startIndex As Long, count As Long) As Long
+		Dim length = lstrlen(lpszText)
 
 		If startIndex < 0 Or startIndex > m_Length - 1 Then Return -1
@@ -337,45 +295,36 @@
 	End Function
 
-	Function StartsWith(lpszText As *Char) As BOOL
-		If IndexOf(lpszText) = 0 Then
-			Return _System_TRUE
-		Else
-			Return _System_FALSE
-		End If
-	End Function
-
-	Function EndsWith(lpszText As *Char) As BOOL
-		If LastIndexOf(lpszText) = m_Length - lstrlen(lpszText) Then
-			Return _System_TRUE
-		Else
-			Return _System_FALSE
-		End If
-	End Function
-
-	Function Insert(startIndex As Long, text As *Char) As Long
-		Dim length As Long
-		length = lstrlen(text)
-
-		If startIndex < 0 Or startIndex > m_Length Then Return -1
-
-		Dim newChars As *Char
-		newChars = _System_malloc(SizeOf (Char) * (length + m_Length + 1))
-		If newChars = 0 Then Return -1
-
-		memcpy(newChars, Chars, SizeOf (Char) * startIndex)
-		memcpy(VarPtr(newChars[startIndex]), text, SizeOf (Char) * length)
-		memcpy(VarPtr(newChars[startIndex + length]), VarPtr(Chars[startIndex]), SizeOf (Char) * (m_Length - startIndex + 1))
-
-		_System_free(Chars)
-		Chars = newChars
-		m_Length = length + m_Length
-		Return m_Length
-	End Function
-
-	Function SubString(startIndex As Long) As String
+	Const Function StartsWith(lpszText As *Char) As Boolean
+		Return IndexOf(lpszText) = 0
+	End Function
+
+	Const Function EndsWith(lpszText As *Char) As Boolean
+		Return LastIndexOf(lpszText) = m_Length - lstrlen(lpszText)
+	End Function
+
+	Const Function Insert(startIndex As Long, text As String) As String
+		Return Insert(startIndex, text.Chars, text.Length)
+	End Function
+
+	Const Function Insert(startIndex As Long, text As *Char) As String
+		Return Insert(startIndex, text, lstrlen(text))
+	End Function
+
+	Const Function Insert(startIndex As Long, text As *Char, length As Long) As String
+		If startIndex < 0 Or startIndex > m_Length Or length < 0 Then
+			Debug 'ArgumentOutOfRangeException
+
+		End If
+		Insert.ReSize(m_Length + length)
+		memcpy(Insert.Chars, Chars, SizeOf (Char) * startIndex)
+		memcpy(VarPtr(Insert.Chars[startIndex]), text, SizeOf (Char) * length)
+		memcpy(VarPtr(Insert.Chars[startIndex + length]), VarPtr(Chars[startIndex]), SizeOf (Char) * (m_Length - startIndex + 1))
+	End Function
+
+	Const Function SubString(startIndex As Long) As String
 		Return SubString(startIndex, m_Length - startIndex)
 	End Function
 
-	Function SubString(startIndex As Long, length As Long) As String
+	Const Function SubString(startIndex As Long, length As Long) As String
 		If startIndex < 0 Or length <= 0 Then Return ""
 		If startIndex + length > m_Length Then Return ""
@@ -388,73 +337,60 @@
 	End Function
 
-	Function Remove(startIndex As Long) As Long
-		If startIndex < 0 Or startIndex > m_Length Then Return -1
-		Chars[startIndex] = 0
-		m_Length = startIndex
-		Return m_Length
-	End Function
-
-	Function Remove(startIndex As Long, count As Long) As Long
-		If startIndex < 0 Or count < 0 Then Return -1
-		If startIndex + count > m_Length Then Return -1
-
-		Dim newChars As *Char
-		newChars = _System_malloc(SizeOf (Char) * (m_Length - count + 1))
-		If newChars = 0 Then Return -1
-
-		memcpy(newChars, Chars, SizeOf (Char) * startIndex)
-		memcpy(VarPtr(newChars[startIndex]), VarPtr(Chars[startIndex + count]), SizeOf (Char) * (m_Length - startIndex - count))
-		newChars[m_Length - count] = 0
-
-		_System_free(Chars)
-		Chars = newChars
-		m_Length = m_Length - count
-		Return m_Length
-	End Function
-
-	Function IsNullOrEmpty() As BOOL
-		If m_Length = 0 Then
-			Return _System_TRUE
-		Else
-			Return _System_FALSE
-		End If
-	End Function
-
-
-	Sub Replace(oldChar As Char, newChar As Char)
-		Dim i As Long
-		For i = 0 To ELM(m_Length)
-			If Chars[i] = oldChar Then
-				Chars[i] = newChar
+	Const Function Remove(startIndex As Long) As String
+		Remove.ReSize(startIndex)
+		memcpy(Remove.Chars, This.Chars, SizeOf (Char) * startIndex)
+	End Function
+
+	Const Function Remove(startIndex As Long, count As Long) As String
+		Remove.ReSize(m_Length - count)
+		memcpy(Remove.Chars, This.Chars, SizeOf (Char) * startIndex)
+		memcpy(VarPtr(Remove.Chars[startIndex]), VarPtr(This.Chars[startIndex + count]), SizeOf (Char) * startIndex)
+	End Function
+/*
+	Static Function IsNullOrEmpty(s As String) As Boolean
+		If s <> Nothing Then
+			If s.m_Length > 0 Then
+				Return True
 			End If
-		Next
-	End Sub
-
-	Sub Replace(ByRef oldStr As String, ByRef newStr As String)
-		Replace(oldStr, oldStr.m_Length, newStr, newStr.m_Length)
-	End Sub
-
-	Sub Replace(oldStr As PCSTR, newStr As PCSTR)
-		Replace(oldStr, lstrlen(oldStr), newStr, lstrlen(newStr))
-	End Sub
-
-	Sub Replace(oldStr As PCSTR, oldLen As Long, newStr As PCSTR, newLen As Long)
-		Dim tempString As String
-		With tempString
-			Dim current = 0 As Long
-			Do
-				Dim pos As Long
-				pos = IndexOf(oldStr, current)
-				If pos = -1 Then
-					Exit Do
+		End If
+		Return False
+	End Function
+*/
+	Const Function Replace(oldChar As Char, newChar As Char) As String
+		Replace = Copy(This)
+		With Replace
+			Dim i As Long
+			For i = 0 To ELM(.m_Length)
+				If .Chars[i] = .oldChar Then
+					.Chars[i] = .newChar
 				End If
-				.Append(Chars + current, pos - current)
-				.Append(newStr, newLen)
-				current = pos + oldLen
-			Loop
-			.Append(Chars + current, m_Length - current)
+			Next
 		End With
-		Swap(tempString)
-	End Sub
+	End Function
+
+	Const Function Replace(ByRef oldStr As String, ByRef newStr As String) As String
+'		If oldStr = Nothing Then Throw ArgumentNullException
+'
+'		If newStr = Nothing Then
+'			Return ReplaceCore(oldStr, oldStr.m_Length, "", 0)
+'		Else
+			Return ReplaceCore(oldStr, oldStr.m_Length, newStr, newStr.m_Length)
+'		End If
+	End Function
+
+	Const Function Replace(oldStr As *Char, newStr As *Char)
+		If oldStr = 0 Then Debug 'Throw ArgumentNullException
+		If newStr = 0 Then newStr = ""
+		Return ReplaceCore(oldStr, lstrlen(oldStr), newStr, lstrlen(newStr)) As String
+	End Function
+
+	Const Function Replace(oldStr As *Char, oldLen As Long, newStr As *Char, newLen As Long) As String
+		If oldStr = 0 Then Debug 'Throw ArgumentNullException
+		If newStr = 0 Then
+			newStr = ""
+			newLen = 0
+		End If
+		Return ReplaceCore(oldStr, oldLen, newStr, newLen)
+	End Function
 
 	Sub ToLower()
@@ -474,5 +410,5 @@
 	Sub Swap(ByRef x As String)
 		Dim tempLen As Long
-		Dim tempChars As PSTR
+		Dim tempChars As *Char
 		tempLen = x.m_Length
 		tempChars = x.Chars
@@ -485,4 +421,9 @@
 	Override Function ToString() As String
 		Return This
+	End Function
+
+	Static Function Copy(s As String) As String
+		Copy.Resize(s.m_Length)
+		memcpy(Copy.Chars, This.Chars, SizeOf (Char) * m_Length)
 	End Function
 
@@ -504,4 +445,25 @@
 	End Function
 
+	Function ReplaceCore(oldStr As *Char, oldLen As Long, newStr As *Char, newLen As Long) As String
+		If oldLen = 0 Then
+			Debug 'Throw ArgumentException
+		End If
+		Dim tmp As String
+		With tmp
+			Dim current = 0 As Long
+			Do
+				Dim pos = IndexOf(oldStr, current)
+				If pos = -1 Then
+					Exit Do
+				End If
+				.Append(VarPtr(Chars[current]), pos - current)
+				.Append(newStr, newLen)
+				current = pos + oldLen
+			Loop
+			.Append(VarPtr(Chars[current]), m_Length - current)
+		End With
+		Return tmp
+	End Function
+
 End Class
 
