2004-04-02 Dick Porter <dick@ximian.com>
[mono.git] / mcs / class / corlib / System / String.cs
index a214af92de241003d61c67bb24bd410485d90098..6d92bf96d80c38354604421e4c379c89efe85963 100644 (file)
@@ -2,7 +2,7 @@
 // System.String.cs
 //
 // Authors:
-//       Patrik Torstensson (patrik.torstensson@labs2.com)
+//   Patrik Torstensson
 //   Jeffrey Stedfast (fejj@ximian.com)
 //   Dan Lewis (dihlewis@yahoo.co.uk)
 //
@@ -15,11 +15,13 @@ using System.Collections;
 using System.Globalization;
 using System.Runtime.CompilerServices;
 
-namespace System {
+namespace System
+{
        [Serializable]
-       public sealed class String : IConvertible, IComparable, ICloneable, IEnumerable {
-               [NonSerialized]
-               private int length;
+       public sealed class String : IConvertible, IComparable, ICloneable, IEnumerable
+       {
+               [NonSerialized] private int length;
+               [NonSerialized] private char start_char;
 
                private const int COMPARE_CASE = 0;
                private const int COMPARE_INCASE = 1;
@@ -27,96 +29,124 @@ namespace System {
 
                public static readonly String Empty = "";
 
-               public static bool Equals(String str1, String str2) {
-                       if ((str1 as object) == (str2 as object))
+               public static unsafe bool Equals (string a, string b)
+               {
+                       if ((a as object) == (b as object))
                                return true;
-           
-                       if (null == str1 || null == str2)
+
+                       if (a == null || b == null)
                                return false;
 
-                       int len = str1.length;
-                       
-                       if (len != str2.length)
+                       int len = a.length;
+
+                       if (len != b.length)
                                return false;
 
-                       for (int i = 0; i < len; i++)
-                               if (str1 [i] != str2 [i])
-                                       return false;
+                       if (len == 0)
+                               return true;
 
-                       return true;
+                       fixed (char * s1 = &a.start_char, s2 = &b.start_char) {
+                               // it must be one char, because 0 len is done above
+                               if (len < 2)
+                                       return *s1 == *s2;
+
+                               // check by twos
+                               int * sint1 = (int *) s1, sint2 = (int *) s2;
+                               int n2 = len >> 1;
+                               do {
+                                       if (*sint1++ != *sint2++)
+                                               return false;
+                               } while (--n2 != 0);
+
+                               // nothing left
+                               if ((len & 1) == 0)
+                                       return true;
+
+                               // check the last one
+                               return *(char *) sint1 == *(char *) sint2;
+                       }
                }
 
-               public static bool operator == (String str1, String str2) {
-                       return Equals(str1, str2);
+               public static bool operator == (String a, String b)
+               {
+                       return Equals (a, b);
                }
 
-               public static bool operator != (String str1, String str2) {
-                       return !Equals(str1, str2);
+               public static bool operator != (String a, String b)
+               {
+                       return !Equals (a, b);
                }
 
-               public override bool Equals(Object obj) {
+               public override bool Equals (Object obj)
+               {
                        return Equals (this, obj as String);
                }
 
-               public bool Equals(String value) {
+               public bool Equals (String value)
+               {
                        return Equals (this, value);
                }
 
-               [IndexerName("Chars")]
-               public extern char this[int index] {
-                       [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               [IndexerName ("Chars")]
+               public extern char this [int index] {
+                       [MethodImplAttribute (MethodImplOptions.InternalCall)]
                        get;
                }
 
-               public Object Clone() {
+               public Object Clone ()
+               {
                        return this;
                }
 
-               public TypeCode GetTypeCode () {
+               public TypeCode GetTypeCode ()
+               {
                        return TypeCode.String;
                }
 
-               public void CopyTo(int sindex, char[] dest, int dindex, int count) {
+               public void CopyTo (int sourceIndex, char[] destination, int destinationIndex, int count)
+               {
                        // LAMESPEC: should I null-terminate?
-                       
-                       if (dest == null)
-                               throw new ArgumentNullException();
+                       if (destination == null)
+                               throw new ArgumentNullException ("destination");
 
-                       if (sindex < 0 || dindex < 0 || count < 0)
+                       if (sourceIndex < 0 || destinationIndex < 0 || count < 0)
                                throw new ArgumentOutOfRangeException (); 
 
-                       if (sindex + count > Length)
+                       if (sourceIndex + count > Length)
                                throw new ArgumentOutOfRangeException ();
 
-                       if (dindex + count > dest.Length)
+                       if (destinationIndex + count > destination.Length)
                                throw new ArgumentOutOfRangeException ();
 
-                       InternalCopyTo(sindex, dest, dindex, count);
+                       InternalCopyTo (sourceIndex, destination, destinationIndex, count);
                }
 
-               public char[] ToCharArray() {
-                       return ToCharArray(0, length);
+               public char[] ToCharArray ()
+               {
+                       return ToCharArray (0, length);
                }
 
-               public char[] ToCharArray(int sindex, int length) {
-                       if (sindex < 0 || length < 0 || sindex + length > this.length)
+               public char[] ToCharArray (int startIndex, int length)
+               {
+                       if (startIndex < 0 || length < 0 || startIndex + length > this.length)
                                throw new ArgumentOutOfRangeException (); 
 
                        char [] tmp = new char[length];
 
-                       InternalCopyTo(sindex, tmp, 0, length);
+                       InternalCopyTo (startIndex, tmp, 0, length);
 
                        return tmp;
                }
-               
-               public String [] Split(params char [] separator) {
-                       return Split(separator, Int32.MaxValue);
+
+               public String [] Split (params char [] separator)
+               {
+                       return Split (separator, Int32.MaxValue);
                }
 
-               public String[] Split(char[] separator, int count) {
-                       if (null == separator || separator.Length == 0) {
+               public String[] Split (char[] separator, int count)
+               {
+                       if (separator == null || separator.Length == 0)
                                separator = WhiteChars;
-                       }
 
                        if (count < 0)
                                throw new ArgumentOutOfRangeException ();
@@ -127,568 +157,590 @@ namespace System {
                        if (count == 1) 
                                return new String[1] { ToString() };
 
-                       return InternalSplit(separator, count);
+                       return InternalSplit (separator, count);
                }
 
-               public String Substring (int sindex) {
-                       if (sindex < 0 || sindex > this.length) {
-                               throw new ArgumentOutOfRangeException();
-                       }
+               public String Substring (int startIndex)
+               {
+                       if (startIndex < 0 || startIndex > this.length)
+                               throw new ArgumentOutOfRangeException ("startIndex");
+
+                       string tmp = InternalAllocateStr (this.length - startIndex);
+                       InternalStrcpy (tmp, 0, this, startIndex, length - startIndex);
 
-                       string tmp = InternalAllocateStr(this.length - sindex);
-                       InternalStrcpy(tmp, 0, this, sindex, length - sindex);
-                       
                        return tmp;
                }
 
-               public String Substring (int sindex, int length) {
-                       if (length < 0 || sindex < 0 || sindex + length > this.length) {
-                               throw new ArgumentOutOfRangeException();
-                       }
+               public String Substring (int startIndex, int length)
+               {
+                       if (length < 0 || startIndex < 0 || startIndex + length > this.length)
+                               throw new ArgumentOutOfRangeException ();
 
                        if (length == 0)
                                return String.Empty;
 
-                       string tmp = InternalAllocateStr(length);
-                       InternalStrcpy(tmp, 0, this, sindex, length);
+                       string tmp = InternalAllocateStr (length);
+                       InternalStrcpy (tmp, 0, this, startIndex, length);
 
                        return tmp;
                }       
 
-               private static readonly char[] WhiteChars = {  (char) 0x9, (char) 0xA, (char) 0xB, (char) 0xC, (char) 0xD, (char) 0x20, (char) 0xA0, (char) 0x2000, (char) 0x2001, (char) 0x2002, (char) 0x2003, (char) 0x2004, (char) 0x2005,
-                                                                                                                                         (char) 0x2006, (char) 0x2007, (char) 0x2008, (char) 0x2009, (char) 0x200A, (char) 0x200B, (char) 0x3000, (char) 0xFEFF };
+               private static readonly char[] WhiteChars = { (char) 0x9, (char) 0xA, (char) 0xB, (char) 0xC, (char) 0xD,
+                       (char) 0x20, (char) 0xA0, (char) 0x2000, (char) 0x2001, (char) 0x2002, (char) 0x2003, (char) 0x2004,
+                       (char) 0x2005, (char) 0x2006, (char) 0x2007, (char) 0x2008, (char) 0x2009, (char) 0x200A, (char) 0x200B,
+                       (char) 0x3000, (char) 0xFEFF };
 
-               public String Trim(params char[] chars) {
-                       if (null == chars || chars.Length == 0)
-                               chars = WhiteChars;
+               public String Trim (params char[] trimChars)
+               {
+                       if (trimChars == null || trimChars.Length == 0)
+                               trimChars = WhiteChars;
 
-                       return InternalTrim(chars, 0);
+                       return InternalTrim (trimChars, 0);
                }
 
-               public String TrimStart(params char[] chars) {
-                       if (null == chars || chars.Length == 0)
-                               chars = WhiteChars;
+               public String TrimStart (params char[] trimChars)
+               {
+                       if (trimChars == null || trimChars.Length == 0)
+                               trimChars = WhiteChars;
 
-                       return InternalTrim(chars, 1);
+                       return InternalTrim (trimChars, 1);
                }
 
-               public String TrimEnd(params char[] chars) {
-                       if (null == chars || chars.Length == 0)
-                               chars = WhiteChars;
+               public String TrimEnd (params char[] trimChars)
+               {
+                       if (trimChars == null || trimChars.Length == 0)
+                               trimChars = WhiteChars;
 
-                       return InternalTrim(chars, 2);
+                       return InternalTrim (trimChars, 2);
                }
 
-               public static int Compare(String s1, String s2) {
-                       return(Compare(s1, s2, false,
-                                      CultureInfo.CurrentCulture));
+               public static int Compare (String strA, String strB)
+               {
+                       return Compare (strA, strB, false, CultureInfo.CurrentCulture);
                }
 
-               public static int Compare(String s1, String s2, bool inCase) {
-                       return(Compare (s1, s2, inCase,
-                                       CultureInfo.CurrentCulture));
+               public static int Compare (String strA, String strB, bool ignoreCase)
+               {
+                       return Compare (strA, strB, ignoreCase, CultureInfo.CurrentCulture);
                }
-               
-               public static int Compare(String s1, String s2, bool inCase,
-                                         CultureInfo culture) {
-                       if (culture == null) {
+
+               public static int Compare (String strA, String strB, bool ignoreCase, CultureInfo culture)
+               {
+                       if (culture == null)
                                throw new ArgumentNullException ("culture");
+
+                       if (strA == null) {
+                               if (strB == null)
+                                       return 0;
+                               else
+                                       return -1;
+
                        }
-                       
-                       if (s1 == null) {
-                               if (s2 == null) {
-                                       return(0);
-                               } else {
-                                       return(-1);
-                               }
-                       } else if (s2 == null) {
-                               return(1);
+                       else if (strB == null) {
+                               return 1;
                        }
 
                        CompareOptions compopts;
-                       
-                       if(inCase) {
-                               compopts=CompareOptions.IgnoreCase;
-                       } else {
-                               compopts=CompareOptions.None;
-                       }
-                       
-                       return(culture.CompareInfo.Compare (s1, s2, compopts));
+
+                       if (ignoreCase)
+                               compopts = CompareOptions.IgnoreCase;
+                       else
+                               compopts = CompareOptions.None;
+
+                       return culture.CompareInfo.Compare (strA, strB, compopts);
                }
 
-               public static int Compare(String s1, int i1, String s2, int i2,
-                                         int length) {
-                       return(Compare(s1, i1, s2, i2, length, false,
-                                      CultureInfo.CurrentCulture));
+               public static int Compare (String strA, int indexA, String strB, int indexB, int length)
+               {
+                       return Compare (strA, indexA, strB, indexB, length, false, CultureInfo.CurrentCulture);
                }
 
-               public static int Compare(String s1, int i1, String s2, int i2,
-                                         int length, bool inCase) {
-                       return(Compare (s1, i1, s2, i2, length, inCase,
-                                       CultureInfo.CurrentCulture));
+               public static int Compare (String strA, int indexA, String strB, int indexB, int length, bool ignoreCase)
+               {
+                       return Compare (strA, indexA, strB, indexB, length, ignoreCase, CultureInfo.CurrentCulture);
                }
                
-               public static int Compare(String s1, int i1, String s2, int i2,
-                                         int length, bool inCase,
-                                         CultureInfo culture) {
-                       if(culture==null) {
+               public static int Compare (String strA, int indexA, String strB, int indexB, int length, bool ignoreCase, CultureInfo culture)
+               {
+                       if (culture == null)
                                throw new ArgumentNullException ("culture");
-                       }
 
-                       if((i1 > s1.Length) ||
-                          (i2 > s2.Length) ||
-                          (i1 < 0) || (i2 < 0) || (length < 0)) {
+                       if ((indexA > strA.Length) || (indexB > strB.Length) || (indexA < 0) || (indexB < 0) || (length < 0))
                                throw new ArgumentOutOfRangeException ();
-                       }
+
+                       if (length == 0)
+                               return 0;
                        
-                       if (s1 == null) {
-                               if (s2 == null) {
-                                       return(0);
+                       if (strA == null) {
+                               if (strB == null) {
+                                       return 0;
                                } else {
-                                       return(-1);
+                                       return -1;
                                }
-                       } else if (s2 == null) {
-                               return(1);
                        }
-                       
-                       CompareOptions compopts;
-                       
-                       if(inCase) {
-                               compopts=CompareOptions.IgnoreCase;
-                       } else {
-                               compopts=CompareOptions.None;
+                       else if (strB == null) {
+                               return 1;
                        }
-                       
+
+                       CompareOptions compopts;
+
+                       if (ignoreCase)
+                               compopts = CompareOptions.IgnoreCase;
+                       else
+                               compopts = CompareOptions.None;
+
                        /* Need to cap the requested length to the
                         * length of the string, because
-                        * CompareInfo.Compare will call
-                        * String.Substring on its arguments.
+                        * CompareInfo.Compare will insist that length
+                        * <= (string.Length - offset)
                         */
-                       int len1=length;
-                       int len2=length;
+                       int len1 = length;
+                       int len2 = length;
                        
-                       if(length > (s1.Length - i1)) {
-                               len1=s1.Length - i1;
+                       if (length > (strA.Length - indexA)) {
+                               len1 = strA.Length - indexA;
                        }
 
-                       if(length > (s2.Length - i2)) {
-                               len2=s2.Length - i2;
+                       if (length > (strB.Length - indexB)) {
+                               len2 = strB.Length - indexB;
                        }
 
-                       return(culture.CompareInfo.Compare(s1, i1, len1,
-                                                          s2, i2, len2,
-                                                          compopts));
+                       return culture.CompareInfo.Compare (strA, indexA, len1, strB, indexB, len2, compopts);
                }
 
-               public int CompareTo(Object value) {
-                       if (null == value)
+               public int CompareTo (Object value)
+               {
+                       if (value == null)
                                return 1;
-            
+
                        if (!(value is String))
-                               throw new ArgumentException();
+                               throw new ArgumentException ();
 
-                       return String.Compare(this, (String) value, false);
+                       return String.Compare (this, (String) value, false);
                }
 
-               public int CompareTo(String str) {
-                       if (null == str)
+               public int CompareTo (String strB)
+               {
+                       if (strB == null)
                                return 1;
 
-                       return Compare(this, str, false);
+                       return Compare (this, strB, false);
                }
 
-               public static int CompareOrdinal(String s1, String s2) {
-                       if (s1 == null) {
-                               if (s2 == null) {
-                                       return(0);
-                               } else {
-                                       return(-1);
-                               }
-                       } else if (s2 == null) {
-                               return(1);
+               public static int CompareOrdinal (String strA, String strB)
+               {
+                       if (strA == null) {
+                               if (strB == null)
+                                       return 0;
+                               else
+                                       return -1;
+                       }
+                       else if (strB == null) {
+                               return 1;
                        }
 
                        /* Invariant, because that is cheaper to
                         * instantiate (and chances are it already has
                         * been.)
                         */
-                       return(CultureInfo.InvariantCulture.CompareInfo.Compare (s1, s2, CompareOptions.Ordinal));
+                       return CultureInfo.InvariantCulture.CompareInfo.Compare (strA, strB, CompareOptions.Ordinal);
                }
 
-               public static int CompareOrdinal(String s1, int i1, String s2,
-                                                int i2, int length)
+               public static int CompareOrdinal (String strA, int indexA, String strB, int indexB, int length)
                {
-                       if ((i1 > s1.Length) ||
-                           (i2 > s2.Length) ||
-                           (i1 < 0) || (i2 < 0) || (length < 0)) {
+                       if ((indexA > strA.Length) || (indexB > strB.Length) || (indexA < 0) || (indexB < 0) || (length < 0))
                                throw new ArgumentOutOfRangeException ();
-                       }
 
-                       if (s1 == null) {
-                               if (s2 == null) {
-                                       return(0);
-                               } else {
-                                       return(-1);
-                               }
-                       } else if (s2 == null) {
-                               return(1);
+                       if (strA == null) {
+                               if (strB == null)
+                                       return 0;
+                               else
+                                       return -1;
+                       }
+                       else if (strB == null) {
+                               return 1;
                        }
 
                        /* Need to cap the requested length to the
                         * length of the string, because
-                        * CompareInfo.Compare will call
-                        * String.Substring on its arguments.
+                        * CompareInfo.Compare will insist that length
+                        * <= (string.Length - offset)
                         */
-                       int len1=length;
-                       int len2=length;
-                       
-                       if(length > (s1.Length - i1)) {
-                               len1=s1.Length - i1;
+                       int len1 = length;
+                       int len2 = length;
+
+                       if (length > (strA.Length - indexA)) {
+                               len1 = strA.Length - indexA;
                        }
 
-                       if(length > (s2.Length - i2)) {
-                               len2=s2.Length - i2;
+                       if (length > (strB.Length - indexB)) {
+                               len2 = strB.Length - indexB;
                        }
 
-                       return(CultureInfo.InvariantCulture.CompareInfo.Compare(s1, i1, len1, s2, i2, len2, CompareOptions.Ordinal));
+                       return CultureInfo.InvariantCulture.CompareInfo.Compare (strA, indexA, len1, strB, indexB, len2, CompareOptions.Ordinal);
                }
 
-               public bool EndsWith(String value) {
-                       if (null == value)
-                               throw new ArgumentNullException();
+               public bool EndsWith (String value)
+               {
+                       if (value == null)
+                               throw new ArgumentNullException ("value");
+
+                       if (value == String.Empty)
+                               return true;
 
-                       if (value.length > this.length) {
+                       if (value.length > this.length)
                                return false;
-                       }
 
-                       return (0 == Compare(this, length - value.length, value, 0, value.length));
+                       return (0 == Compare (this, length - value.length, value, 0, value.length));
                }
-       
-               public int IndexOfAny(char [] arr) {
-                       if (null == arr)
-                               throw new ArgumentNullException();
 
-                       return InternalIndexOfAny(arr, 0, this.length);
+               public int IndexOfAny (char [] anyOf)
+               {
+                       if (anyOf == null)
+                               throw new ArgumentNullException ("anyOf");
+
+                       return InternalIndexOfAny (anyOf, 0, this.length);
                }
 
-               public int IndexOfAny(char [] arr, int sindex) {
-                       if (null == arr)
-                               throw new ArgumentNullException();
-                       if (sindex < 0 || sindex >= this.length)
-                               throw new ArgumentOutOfRangeException();
+               public int IndexOfAny (char [] anyOf, int startIndex)
+               {
+                       if (anyOf == null)
+                               throw new ArgumentNullException ("anyOf");
+                       if (startIndex < 0 || startIndex >= this.length)
+                               throw new ArgumentOutOfRangeException ("sourceIndex");
 
-                       return InternalIndexOfAny(arr, sindex, this.length - sindex);
+                       return InternalIndexOfAny (anyOf, startIndex, this.length - startIndex);
                }
 
-               public int IndexOfAny(char [] arr, int sindex, int count) {
-                       if (null == arr)
-                               throw new ArgumentNullException();
-                       if (sindex < 0 || count < 0 || sindex + count > this.length)
+               public int IndexOfAny (char [] anyOf, int startIndex, int count)
+               {
+                       if (anyOf == null)
+                               throw new ArgumentNullException ("anyOf");
+                       if (startIndex < 0 || count < 0 || startIndex + count > this.length)
                                throw new ArgumentOutOfRangeException ();
 
-                       return InternalIndexOfAny(arr, sindex, count);
+                       return InternalIndexOfAny (anyOf, startIndex, count);
                }
 
-               public int IndexOf(char value) {
-                       return(IndexOf(value, 0, this.length));
+               public int IndexOf (char value)
+               {
+                       return IndexOf (value, 0, this.length);
                }
 
-               public int IndexOf(String value) {
-                       return(IndexOf(value, 0, this.length));
+               public int IndexOf (String value)
+               {
+                       return IndexOf (value, 0, this.length);
                }
 
-               public int IndexOf(char value, int sindex) {
-                       return(IndexOf(value, sindex, this.length - sindex));
+               public int IndexOf (char value, int startIndex)
+               {
+                       return IndexOf (value, startIndex, this.length - startIndex);
                }
 
-               public int IndexOf(String value, int sindex) {
-                       return(IndexOf(value, sindex, this.length - sindex));
+               public int IndexOf (String value, int startIndex)
+               {
+                       return IndexOf (value, startIndex, this.length - startIndex);
                }
 
                /* This method is culture-insensitive */
-               public int IndexOf(char value, int sindex, int count) {
-                       if (sindex < 0 || count < 0 ||
-                           sindex + count > this.length) {
+               public int IndexOf (char value, int startIndex, int count)
+               {
+                       if (startIndex < 0 || count < 0 || startIndex + count > this.length)
                                throw new ArgumentOutOfRangeException ();
-                       }
 
-                       if ((sindex == 0 && this.length == 0) ||
-                           (sindex == this.length) ||
-                           (count == 0)) {
-                               return(-1);
+                       if ((startIndex == 0 && this.length == 0) || (startIndex == this.length) || (count == 0))
+                               return -1;
+
+                       for (int pos = startIndex; pos < startIndex + count; pos++) {
+                               if (this[pos] == value)
+                                       return(pos);
                        }
-                       
-                       return(CultureInfo.InvariantCulture.CompareInfo.IndexOf (this, value, sindex, count));
+                       return -1;
                }
-               
+
                /* But this one is culture-sensitive */
-               public int IndexOf(String value, int sindex, int count) {
-                       if (value == null) {
-                               throw new ArgumentNullException();
-                       }
+               public int IndexOf (String value, int startIndex, int count)
+               {
+                       if (value == null)
+                               throw new ArgumentNullException ("value");
 
-                       if (sindex < 0 || count < 0 ||
-                           sindex + count > this.length) {
+                       if (startIndex < 0 || count < 0 || startIndex + count > this.length)
                                throw new ArgumentOutOfRangeException ();
-                       }
 
-                       if (value.length == 0) {
-                               return sindex;
-                       }
-                       
-                       if (sindex == 0 && this.length == 0) {
+                       if (value.length == 0)
+                               return startIndex;
+
+                       if (startIndex == 0 && this.length == 0)
                                return -1;
-                       }
 
-                       if (count == 0) {
-                               return(-1);
-                       }
-                       
-                       return(CultureInfo.CurrentCulture.CompareInfo.IndexOf (this, value, sindex, count));
+                       if (count == 0)
+                               return -1;
+
+                       return CultureInfo.CurrentCulture.CompareInfo.IndexOf (this, value, startIndex, count);
                }
 
-               public int LastIndexOfAny(char [] arr) {
-                       if (null == arr) 
-                               throw new ArgumentNullException();
+               public int LastIndexOfAny (char [] anyOf)
+               {
+                       if (anyOf == null)
+                               throw new ArgumentNullException ("anyOf");
 
-                       return InternalLastIndexOfAny(arr, this.length - 1, this.length);
+                       return InternalLastIndexOfAny (anyOf, this.length - 1, this.length);
                }
 
-               public int LastIndexOfAny(char [] arr, int sindex) {
-                       if (null == arr) 
-                               throw new ArgumentNullException();
+               public int LastIndexOfAny (char [] anyOf, int startIndex)
+               {
+                       if (anyOf == null) 
+                               throw new ArgumentNullException ("anyOf");
 
-                       if (sindex < 0 || sindex > this.length)
-                               throw new ArgumentOutOfRangeException();
+                       if (startIndex < 0 || startIndex > this.length)
+                               throw new ArgumentOutOfRangeException ();
 
                        if (this.length == 0)
                                return -1;
 
-                       return InternalLastIndexOfAny(arr, sindex, sindex + 1);
+                       return InternalLastIndexOfAny (anyOf, startIndex, startIndex + 1);
                }
 
-               public int LastIndexOfAny(char [] arr, int sindex, int count) {
-                       if (null == arr) 
-                               throw new ArgumentNullException();
+               public int LastIndexOfAny (char [] anyOf, int startIndex, int count)
+               {
+                       if (anyOf == null) 
+                               throw new ArgumentNullException ("anyOf");
 
-                       if (sindex < 0 || count < 0 || sindex > this.length || sindex - count < -1)
-                               throw new ArgumentOutOfRangeException();
+                       if (startIndex < 0 || count < 0 || startIndex > this.length || startIndex - count < -1)
+                               throw new ArgumentOutOfRangeException ();
 
                        if (this.length == 0)
                                return -1;
 
-                       return InternalLastIndexOfAny(arr, sindex, count);
+                       return InternalLastIndexOfAny (anyOf, startIndex, count);
                }
 
-               public int LastIndexOf(char value) {
-                       if(this.length==0) {
-                               return(-1);
-                       } else {
-                               return(LastIndexOf(value, this.length - 1,
-                                                  this.length));
-                       }
-                       
+               public int LastIndexOf (char value)
+               {
+                       if (this.length == 0)
+                               return -1;
+                       else
+                               return LastIndexOf (value, this.length - 1, this.length);
                }
 
-               public int LastIndexOf(String value) {
-                       if(this.length==0) {
+               public int LastIndexOf (String value)
+               {
+                       if (this.length == 0)
                                /* This overload does additional checking */
-                               return(LastIndexOf(value, 0, 0));
-                       } else {
-                               return(LastIndexOf(value, this.length - 1,
-                                                  this.length));
-                       }
+                               return LastIndexOf (value, 0, 0);
+                       else
+                               return LastIndexOf (value, this.length - 1, this.length);
                }
 
-               public int LastIndexOf(char value, int sindex){
-                       return(LastIndexOf(value, sindex, sindex + 1));
+               public int LastIndexOf (char value, int startIndex)
+               {
+                       return LastIndexOf (value, startIndex, startIndex + 1);
                }
 
-               public int LastIndexOf(String value, int sindex) {
-                       return(LastIndexOf(value, sindex, sindex + 1));
+               public int LastIndexOf (String value, int startIndex)
+               {
+                       return LastIndexOf (value, startIndex, startIndex + 1);
                }
 
                /* This method is culture-insensitive */
-               public int LastIndexOf(char value, int sindex, int count) {
-                       if (sindex == 0 && this.length == 0) {
+               public int LastIndexOf (char value, int startIndex, int count)
+               {
+                       if (startIndex == 0 && this.length == 0)
                                return -1;
-                       }
 
-                       if (sindex < 0 || count < 0) {
+                       if (startIndex < 0 || count < 0)
                                throw new ArgumentOutOfRangeException ();
-                       }
 
-                       if (sindex >= this.length || sindex - count + 1 < 0) {
+                       if (startIndex >= this.length || startIndex - count + 1 < 0)
                                throw new ArgumentOutOfRangeException ();
+
+                       for(int pos = startIndex; pos > startIndex - count; pos--) {
+                               if (this [pos] == value)
+                                       return pos;
                        }
-                       if (count == 0) {
-                               return(-1);
-                       }
-                       
-                       return(CultureInfo.InvariantCulture.CompareInfo.LastIndexOf (this, value, sindex, count));
+                       return -1;
                }
 
                /* But this one is culture-sensitive */
-               public int LastIndexOf(String value, int sindex, int count) {
-                       if (null == value) {
-                               throw new ArgumentNullException();
-                       }
+               public int LastIndexOf (String value, int startIndex, int count)
+               {
+                       if (value == null)
+                               throw new ArgumentNullException ("value");
 
-                       if (value == String.Empty) {
-                               return(0);
-                       }
+                       if (value == String.Empty)
+                               return 0;
 
-                       if (sindex == 0 && this.length == 0) {
+                       if (startIndex == 0 && this.length == 0)
                                return -1;
-                       }
 
                        // This check is needed to match undocumented MS behaviour
-                       if (this.length == 0 && value.length > 0) {
-                               return(-1);
-                       }
+                       if (this.length == 0 && value.length > 0)
+                               return -1;
 
-                       if (value.length > sindex) {
+                       if (value.length > startIndex)
                                return -1;
-                       }
 
-                       if (count == 0) {
-                               return(-1);
-                       }
+                       if (count == 0)
+                               return -1;
 
-                       if (sindex < 0 || sindex > this.length) {
+                       if (startIndex < 0 || startIndex > this.length)
                                throw new ArgumentOutOfRangeException ();
-                       }
 
-                       if (count < 0 || sindex - count + 1 < 0) {
+                       if (count < 0 || startIndex - count + 1 < 0)
                                throw new ArgumentOutOfRangeException ();
-                       }
-                       
-                       return(CultureInfo.CurrentCulture.CompareInfo.LastIndexOf (this, value, sindex, count));
+
+                       return CultureInfo.CurrentCulture.CompareInfo.LastIndexOf (this, value, startIndex, count);
                }
 
-               public String PadLeft(int width) {
-                       return PadLeft(width, ' ');
+               public String PadLeft (int totalWidth)
+               {
+                       return PadLeft (totalWidth, ' ');
                }
 
-               public String PadLeft(int width, char chr) {
-                       if (width < 0)
-                               throw new ArgumentException();
+               public String PadLeft (int totalWidth, char paddingChar)
+               {
+                       if (totalWidth < 0)
+                               throw new ArgumentException ();
 
-                       if (width < this.length)
-                               return String.Copy(this);
+                       if (totalWidth < this.length)
+                               return String.Copy (this);
 
-                       return InternalPad(width, chr, false);
+                       return InternalPad (totalWidth, paddingChar, false);
                }
 
-               public String PadRight(int width) {
-                       return PadRight(width, ' ');
+               public String PadRight (int totalWidth)
+               {
+                       return PadRight (totalWidth, ' ');
                }
 
-               public String PadRight(int width, char chr) {
-                       if (width < 0)
-                               throw new ArgumentException();
+               public String PadRight (int totalWidth, char paddingChar)
+               {
+                       if (totalWidth < 0)
+                               throw new ArgumentException ();
 
-                       if (width < this.length)
-                               return String.Copy(this);
+                       if (totalWidth < this.length)
+                               return String.Copy (this);
 
-                       return InternalPad(width, chr, true);
+                       return InternalPad (totalWidth, paddingChar, true);
                }
 
-               public bool StartsWith(String value) {
-                       if (value == null) {
-                               throw new ArgumentNullException("value");
-                       }
+               public bool StartsWith (String value)
+               {
+                       if (value == null)
+                               throw new ArgumentNullException ("value");
+                       
+                       if (value == String.Empty)
+                               return true;
 
-                       if (this.length < value.length) {
-                               return(false);
-                       }
+                       if (this.length < value.length)
+                               return false;
 
-                       return (0 == Compare(this, 0, value, 0 , value.length));
+                       return (0 == Compare (this, 0, value, 0 , value.length));
                }
-       
-    
+
                /* This method is culture insensitive */
-               public String Replace (char oldChar, char newChar) {
-                       return(InternalReplace(oldChar, newChar));
+               public String Replace (char oldChar, char newChar)
+               {
+                       return InternalReplace (oldChar, newChar);
                }
 
                /* This method is culture sensitive */
-               public String Replace(String oldValue, String newValue) {
-                       if(oldValue==null) {
+               public String Replace (String oldValue, String newValue)
+               {
+                       if (oldValue == null)
                                throw new ArgumentNullException ("oldValue");
-                       }
-                       if(oldValue==String.Empty) {
+
+                       if (oldValue == String.Empty)
                                throw new ArgumentException ("oldValue is the empty string.");
-                       }
 
-                       if(newValue==null) {
-                               newValue=String.Empty;
+                       if (this == String.Empty)
+                               return this;
+
+                       if (oldValue.Length == 0 || oldValue[0] == '\0') {
+                               return(this);
                        }
                        
-                       return(InternalReplace (oldValue, newValue, CultureInfo.CurrentCulture.CompareInfo));
+                       if (newValue == null)
+                               newValue = String.Empty;
+
+                       return InternalReplace (oldValue, newValue, CultureInfo.CurrentCulture.CompareInfo);
                }
 
-               public String Remove(int sindex, int count) {
-                       if (sindex < 0 || count < 0 || sindex + count > this.length)
+               public String Remove (int startIndex, int count)
+               {
+                       if (startIndex < 0 || count < 0 || startIndex + count > this.length)
                                throw new ArgumentOutOfRangeException ();
 
-                       return InternalRemove(sindex, count);
+                       return InternalRemove (startIndex, count);
                }
 
-               public String ToLower() {
-                       return(InternalToLower(CultureInfo.CurrentCulture));
+               public String ToLower ()
+               {
+                       return InternalToLower (CultureInfo.CurrentCulture);
                }
 
-               public String ToLower(CultureInfo culture) {
-                       return(InternalToLower(culture));
+               public String ToLower (CultureInfo culture)
+               {
+                       return InternalToLower (culture);
                }
 
-               public String ToUpper() {
-                       return(InternalToUpper(CultureInfo.CurrentCulture));
+               public String ToUpper ()
+               {
+                       return InternalToUpper (CultureInfo.CurrentCulture);
                }
 
-               public String ToUpper(CultureInfo culture) {
-                       return(InternalToUpper(culture));
+               public String ToUpper (CultureInfo culture)
+               {
+                       return InternalToUpper (culture);
                }
 
-               public override String ToString() {
+               public override String ToString ()
+               {
                        return this;
                }
 
-               public String ToString(IFormatProvider provider) {
+               public String ToString (IFormatProvider provider)
+               {
                        return this;
                }
 
-               public String Trim() {
-                       return Trim(null);
+               public String Trim ()
+               {
+                       return Trim (null);
                }
 
-               public static String Format(String format, Object arg0) {
-                       return Format(null, format, new Object[] {arg0});
+               public static String Format (String format, Object arg0)
+               {
+                       return Format (null, format, new Object[] {arg0});
                }
 
-               public static String Format(String format, Object arg0, Object arg1) {
-                       return Format(null, format, new Object[] {arg0, arg1});
+               public static String Format (String format, Object arg0, Object arg1)
+               {
+                       return Format (null, format, new Object[] {arg0, arg1});
                }
 
-               public static String Format(String format, Object arg0, Object arg1, Object arg2) {
-                       return Format(null, format, new Object[] {arg0, arg1, arg2});
+               public static String Format (String format, Object arg0, Object arg1, Object arg2)
+               {
+                       return Format (null, format, new Object[] {arg0, arg1, arg2});
                }
 
-               public static string Format (string format, params object[] args) {
+               public static string Format (string format, params object[] args)
+               {
                        return Format (null, format, args);
                }
        
-               public static string Format (IFormatProvider provider, string format, params object[] args) {
+               public static string Format (IFormatProvider provider, string format, params object[] args)
+               {
                        StringBuilder b = new StringBuilder ();
                        FormatHelper (b, provider, format, args);
                        return b.ToString ();
                }
                
-               internal static void FormatHelper (StringBuilder result, IFormatProvider provider, string format, params object[] args) {
+               internal static void FormatHelper (StringBuilder result, IFormatProvider provider, string format, params object[] args)
+               {
                        if (format == null || args == null)
                                throw new ArgumentNullException ();
-                       
+
                        int ptr = 0;
                        int start = ptr;
                        while (ptr < format.length) {
@@ -758,38 +810,41 @@ namespace System {
                                result.Append (format.Substring (start));
                }
 
-               public static String Copy (String str) {
+               public static String Copy (String str)
+               {
                        if (str == null)
-                               throw new ArgumentNullException ();
+                               throw new ArgumentNullException ("str");
 
                        int length = str.length;
 
-                       String tmp = InternalAllocateStr(length);
-                       InternalStrcpy(tmp, 0, str);
+                       String tmp = InternalAllocateStr (length);
+                       InternalStrcpy (tmp, 0, str);
                        return tmp;
                }
 
-               public static String Concat(Object obj) {
-                       if (null == obj)
+               public static String Concat (Object obj)
+               {
+                       if (obj == null)
                                return String.Empty;
 
-                       return obj.ToString();
+                       return obj.ToString ();
                }
 
-               public static String Concat(Object obj1, Object obj2)
+               public static String Concat (Object obj1, Object obj2)
                {
                        string s1, s2;
 
-                       if (obj1 == null){
-                               if (obj2 == null)
+                       s1 = (obj1 != null) ? obj1.ToString () : null;
+                       s2 = (obj2 != null) ? obj2.ToString () : null;
+                       
+                       if (s1 == null) {
+                               if (s2 == null)
                                        return String.Empty;
                                else
-                                       return obj2.ToString ();
-                       } else if (obj2 == null)
-                               return obj1.ToString ();
+                                       return s2;
+                       } else if (s2 == null)
+                               return s1;
 
-                       s1 = obj1.ToString ();
-                       s2 = obj2.ToString ();
                        String tmp = InternalAllocateStr (s1.Length + s2.Length);
                        InternalStrcpy (tmp, 0, s1);
                        InternalStrcpy (tmp, s1.length, s2);
@@ -797,24 +852,24 @@ namespace System {
                        return tmp;
                }
 
-               public static String Concat(Object obj1, Object obj2, Object obj3)
+               public static String Concat (Object obj1, Object obj2, Object obj3)
                {
                        string s1, s2, s3;
                        if (obj1 == null)
                                s1 = String.Empty;
                        else
                                s1 = obj1.ToString ();
-    
+
                        if (obj2 == null)
                                s2 = String.Empty;
                        else
                                s2 = obj2.ToString ();
-    
+
                        if (obj3 == null)
                                s3 = String.Empty;
                        else
                                s3 = obj3.ToString ();
-    
+
                        return Concat (s1, s2, s3);
                }
 
@@ -826,12 +881,12 @@ namespace System {
                                s1 = String.Empty;
                        else
                                s1 = obj1.ToString ();
-    
+
                        if (obj2 == null)
                                s2 = String.Empty;
                        else
                                s2 = obj2.ToString ();
-    
+
                        if (obj3 == null)
                                s3 = String.Empty;
                        else
@@ -841,12 +896,12 @@ namespace System {
                                s4 = String.Empty;
                        else
                                s4 = obj4.ToString ();
-                       
+
                        return Concat (s1, s2, s3, s4);
                        
                }
 
-               public static String Concat(String s1, String s2)
+               public static String Concat (String s1, String s2)
                {
                        if (s1 == null) {
                                if (s2 == null)
@@ -857,15 +912,15 @@ namespace System {
                        if (s2 == null)
                                return s1; 
 
-                       String tmp = InternalAllocateStr(s1.length + s2.length);
-            
-                       InternalStrcpy(tmp, 0, s1);
-                       InternalStrcpy(tmp, s1.length, s2);
-            
+                       String tmp = InternalAllocateStr (s1.length + s2.length);
+
+                       InternalStrcpy (tmp, 0, s1);
+                       InternalStrcpy (tmp, s1.length, s2);
+
                        return tmp;
                }
 
-               public static String Concat(String s1, String s2, String s3)
+               public static String Concat (String s1, String s2, String s3)
                {
                        if (s1 == null){
                                if (s2 == null){
@@ -888,42 +943,48 @@ namespace System {
                                                s3 = String.Empty;
                                }
                        }
-                       
-                       String tmp = InternalAllocateStr(s1.length + s2.length + s3.length);
 
-                       InternalStrcpy(tmp, 0, s1);
-                       InternalStrcpy(tmp, s1.length, s2);
-                       InternalStrcpy(tmp, s1.length + s2.length, s3);
+                       //return InternalConcat (s1, s2, s3);
+                       String tmp = InternalAllocateStr (s1.length + s2.length + s3.length);
+
+                       InternalStrcpy (tmp, 0, s1);
+                       InternalStrcpy (tmp, s1.length, s2);
+                       InternalStrcpy (tmp, s1.length + s2.length, s3);
 
                        return tmp;
                }
 
-               public static String Concat(String s1, String s2, String s3, String s4) {
-                       if (null == s1 && null == s2 && null == s3 && null == s4) {
+               public static String Concat (String s1, String s2, String s3, String s4)
+               {
+                       if (s1 == null && s2 == null && s3 == null && s4 == null)
                                return String.Empty;
-                       }
 
-                       if (null == s1) { s1 = String.Empty; }
-                       if (null == s2) { s2 = String.Empty; }
-                       if (null == s3) { s3 = String.Empty; }
-                       if (null == s4) { s4 = String.Empty; }
+                       if (s1 == null)
+                               s1 = String.Empty;
+                       if (s2 == null)
+                               s2 = String.Empty;
+                       if (s3 == null)
+                               s3 = String.Empty;
+                       if (s4 == null)
+                               s4 = String.Empty;
 
-                       String tmp = InternalAllocateStr(s1.length + s2.length + s3.length + s4.length);
+                       String tmp = InternalAllocateStr (s1.length + s2.length + s3.length + s4.length);
 
-                       InternalStrcpy(tmp, 0, s1);
-                       InternalStrcpy(tmp, s1.length, s2);
-                       InternalStrcpy(tmp, s1.length + s2.length, s3);
-                       InternalStrcpy(tmp, s1.length + s2.length + s3.length, s4);
+                       InternalStrcpy (tmp, 0, s1);
+                       InternalStrcpy (tmp, s1.length, s2);
+                       InternalStrcpy (tmp, s1.length + s2.length, s3);
+                       InternalStrcpy (tmp, s1.length + s2.length + s3.length, s4);
 
                        return tmp;
                }
 
-               public static String Concat(params Object[] args) {
+               public static String Concat (params Object[] args)
+               {
                        string [] strings;
                        int len, i, currentpos;
 
-                       if (null == args)
-                               throw new ArgumentNullException ();
+                       if (args == null)
+                               throw new ArgumentNullException ("args");
 
                        strings = new string [args.Length];
                        len = 0;
@@ -943,20 +1004,21 @@ namespace System {
 
                        currentpos = 0;
 
-                       String tmp = InternalAllocateStr(len);
+                       String tmp = InternalAllocateStr (len);
                        for (i = 0; i < strings.Length; i++) {
-                               InternalStrcpy(tmp, currentpos, strings[i]);
+                               InternalStrcpy (tmp, currentpos, strings[i]);
                                currentpos += strings[i].length;
                        }
 
                        return tmp;
                }
 
-               public static String Concat(params String[] values) {
+               public static String Concat (params String[] values)
+               {
                        int len, i, currentpos;
 
                        if (values == null)
-                               throw new ArgumentNullException ();
+                               throw new ArgumentNullException ("values");
 
                        len = 0;
                        foreach (string value in values)
@@ -967,131 +1029,154 @@ namespace System {
 
                        currentpos = 0;
 
-                       String tmp = InternalAllocateStr(len);
+                       String tmp = InternalAllocateStr (len);
                        for (i = 0; i < values.Length; i++) {
                                if (values[i] == null)
                                        continue;
 
-                               InternalStrcpy(tmp, currentpos, values[i]);
+                               InternalStrcpy (tmp, currentpos, values[i]);
                                currentpos += values[i].length;
                        }       
-       
+
                        return tmp;
                }
 
-               public String Insert(int sindex, String value) {
-                       if (null == value)
-                               throw new ArgumentNullException();
+               public String Insert (int startIndex, String value)
+               {
+                       if (value == null)
+                               throw new ArgumentNullException ("value");
+
+                       if (startIndex < 0 || startIndex > this.length)
+                               throw new ArgumentOutOfRangeException ();
 
-                       if (sindex < 0 || sindex > this.length)
-                               throw new ArgumentOutOfRangeException();
-       
-                       return InternalInsert(sindex, value);
+                       return InternalInsert (startIndex, value);
                }
 
 
-               public static string Intern (string str) {
-                       if (null == str)
-                               throw new ArgumentNullException ();
+               public static string Intern (string str)
+               {
+                       if (str == null)
+                               throw new ArgumentNullException ("str");
 
-                       return InternalIntern(str);
+                       return InternalIntern (str);
                }
 
-               public static string IsInterned (string str) {
-                       if (null == str)
-                               throw new ArgumentNullException();
+               public static string IsInterned (string str)
+               {
+                       if (str == null)
+                               throw new ArgumentNullException ("str");
 
-                       return InternalIsInterned(str);
+                       return InternalIsInterned (str);
                }
        
-               public static string Join (string separator, string [] value) {
+               public static string Join (string separator, string [] value)
+               {
                        if (value == null)
-                               throw new ArgumentNullException ();
+                               throw new ArgumentNullException ("value");
 
-                       return Join(separator, value, 0, value.Length);
+                       return Join (separator, value, 0, value.Length);
                }
 
-               public static string Join(string separator, string[] value, int sindex, int count) {
+               public static string Join (string separator, string[] value, int startIndex, int count)
+               {
                        if (value == null)
-                               throw new ArgumentNullException ();
+                               throw new ArgumentNullException ("value");
 
-                       if (sindex + count > value.Length)
+                       if (startIndex + count > value.Length)
                                throw new ArgumentOutOfRangeException ();
 
-                       if (sindex == value.Length)
+                       if (startIndex == value.Length)
                                return String.Empty;
 
-                       return InternalJoin(separator, value, sindex, count);
+                       return InternalJoin (separator, value, startIndex, count);
                }
 
-               bool IConvertible.ToBoolean (IFormatProvider provider) {
-                       return Convert.ToBoolean (this);
+               bool IConvertible.ToBoolean (IFormatProvider provider)
+               {
+                       return Convert.ToBoolean (this, provider);
                }
-               
-               byte IConvertible.ToByte (IFormatProvider provider) {
-                       return Convert.ToByte (this);
+
+               byte IConvertible.ToByte (IFormatProvider provider)
+               {
+                       return Convert.ToByte (this, provider);
                }
-               
-               char IConvertible.ToChar (IFormatProvider provider) {
-                       return Convert.ToChar (this);
+
+               char IConvertible.ToChar (IFormatProvider provider)
+               {
+                       return Convert.ToChar (this, provider);
                }
 
-               DateTime IConvertible.ToDateTime (IFormatProvider provider) {
-                       return Convert.ToDateTime (this);
+               DateTime IConvertible.ToDateTime (IFormatProvider provider)
+               {
+                       return Convert.ToDateTime (this, provider);
                }
 
-               decimal IConvertible.ToDecimal (IFormatProvider provider) {
-                       return Convert.ToDecimal (this);
+               decimal IConvertible.ToDecimal (IFormatProvider provider)
+               {
+                       return Convert.ToDecimal (this, provider);
                }
 
-               double IConvertible.ToDouble (IFormatProvider provider) {
-                       return Convert.ToDouble (this);
+               double IConvertible.ToDouble (IFormatProvider provider)
+               {
+                       return Convert.ToDouble (this, provider);
                }
 
-               short IConvertible.ToInt16 (IFormatProvider provider) {
-                       return Convert.ToInt16 (this);
+               short IConvertible.ToInt16 (IFormatProvider provider)
+               {
+                       return Convert.ToInt16 (this, provider);
                }
 
-               int IConvertible.ToInt32 (IFormatProvider provider) {
-                       return Convert.ToInt32 (this);
+               int IConvertible.ToInt32 (IFormatProvider provider)
+               {
+                       return Convert.ToInt32 (this, provider);
                }
 
-               long IConvertible.ToInt64 (IFormatProvider provider) {
-                       return Convert.ToInt64 (this);
+               long IConvertible.ToInt64 (IFormatProvider provider)
+               {
+                       return Convert.ToInt64 (this, provider);
                }
        
-               [CLSCompliant(false)]
-               sbyte IConvertible.ToSByte (IFormatProvider provider) {
-                       return Convert.ToSByte (this);
+               [CLSCompliant (false)]
+               sbyte IConvertible.ToSByte (IFormatProvider provider)
+               {
+                       return Convert.ToSByte (this, provider);
                }
 
-               float IConvertible.ToSingle (IFormatProvider provider) {
-                       return Convert.ToSingle (this);
+               float IConvertible.ToSingle (IFormatProvider provider)
+               {
+                       return Convert.ToSingle (this, provider);
                }
-               string IConvertible.ToString (IFormatProvider format) {
+
+               string IConvertible.ToString (IFormatProvider format)
+               {
                        return this;
                }
 
-               object IConvertible.ToType (Type conversionType, IFormatProvider provider) {
+               object IConvertible.ToType (Type conversionType, IFormatProvider provider)
+               {
                        return Convert.ToType (this, conversionType,  provider);
                }
 
-               [CLSCompliant(false)]
-               ushort IConvertible.ToUInt16 (IFormatProvider provider) {
-                       return Convert.ToUInt16 (this);
+               [CLSCompliant (false)]
+               ushort IConvertible.ToUInt16 (IFormatProvider provider)
+               {
+                       return Convert.ToUInt16 (this, provider);
                }
 
-               [CLSCompliant(false)]
-               uint IConvertible.ToUInt32 (IFormatProvider provider) {
-                       return Convert.ToUInt32 (this);
+               [CLSCompliant (false)]
+               uint IConvertible.ToUInt32 (IFormatProvider provider)
+               {
+                       return Convert.ToUInt32 (this, provider);
                }
 
-               [CLSCompliant(false)]
-               ulong IConvertible.ToUInt64 (IFormatProvider provider) {
-                       return Convert.ToUInt64 (this);
+               [CLSCompliant (false)]
+               ulong IConvertible.ToUInt64 (IFormatProvider provider)
+               {
+                       return Convert.ToUInt64 (this, provider);
                }
 
-               TypeCode IConvertible.GetTypeCode () {
+               TypeCode IConvertible.GetTypeCode ()
+               {
                        return TypeCode.String;
                }
 
@@ -1101,15 +1186,19 @@ namespace System {
                        }
                }
 
-               public CharEnumerator GetEnumerator () {
+               public CharEnumerator GetEnumerator ()
+               {
                        return new CharEnumerator (this);
                }
-               
-               IEnumerator IEnumerable.GetEnumerator () {
+
+               IEnumerator IEnumerable.GetEnumerator ()
+               {
                        return new CharEnumerator (this);
                }
 
-               private static void ParseFormatSpecifier (string str, ref int ptr, out int n, out int width, out bool left_align, out string format) {
+               private static void ParseFormatSpecifier (string str, ref int ptr, out int n, out int width,
+                                                         out bool left_align, out string format)
+               {
                        // parses format specifier of form:
                        //   N,[\ +[-]M][:F]}
                        //
@@ -1117,11 +1206,11 @@ namespace System {
 
                        try {
                                // N = argument number (non-negative integer)
-                       
+
                                n = ParseDecimal (str, ref ptr);
                                if (n < 0)
                                        throw new FormatException ("Input string was not in a correct format.");
-                               
+
                                // M = width (non-negative integer)
 
                                if (str[ptr] == ',') {
@@ -1166,7 +1255,8 @@ namespace System {
                        }
                }
 
-               private static int ParseDecimal (string str, ref int ptr) {
+               private static int ParseDecimal (string str, ref int ptr)
+               {
                        int p = ptr;
                        int n = 0;
                        while (true) {
@@ -1180,90 +1270,114 @@ namespace System {
 
                        if (p == ptr)
                                return -1;
-                       
+
                        ptr = p;
                        return n;
                }
-               
-               [CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
-               unsafe public extern String(char *value);
 
-               [CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
-               unsafe public extern String(char *value, int sindex, int length);
-    
-               [CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
-               unsafe public extern String(sbyte *value);
+               internal unsafe void InternalSetChar (int idx, char val)
+               {
+                       if ((uint) idx >= (uint) Length)
+                               throw new ArgumentOutOfRangeException ("idx");
+
+                       fixed (char * pStr = &start_char) 
+                       {
+                               pStr [idx] = val;
+                       }
+               }
+
+               internal unsafe void InternalSetLength (int newLength)
+               {
+                       if (newLength > length)
+                               throw new ArgumentOutOfRangeException ("newLength", "newLength as to be <= length");
 
-               [CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
-               unsafe public extern String(sbyte *value, int sindex, int length);
+                       length = newLength;
 
-               [CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
-               unsafe public extern String(sbyte *value, int sindex, int length, Encoding enc);
+                       // zero terminate, we can pass string objects directly via pinvoke
+                       fixed (char * pStr = &start_char) {
+                               pStr [length] = '\0';
+                       }
+               }
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               public extern String(char [] val, int sindex, int length);
-               
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               public extern String(char [] val);
+               [CLSCompliant (false), MethodImplAttribute (MethodImplOptions.InternalCall)]
+               unsafe public extern String (char *value);
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               public extern String(char c, int count);
-       
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               public extern override int GetHashCode();
+               [CLSCompliant (false), MethodImplAttribute (MethodImplOptions.InternalCall)]
+               unsafe public extern String (char *value, int startIndex, int length);
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern static string InternalJoin(string separator, string[] value, int sindex, int count);
-               
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern String InternalInsert(int sindex, String value);
+               [CLSCompliant (false), MethodImplAttribute (MethodImplOptions.InternalCall)]
+               unsafe public extern String (sbyte *value);
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern String InternalReplace(char oldChar, char newChar);
+               [CLSCompliant (false), MethodImplAttribute (MethodImplOptions.InternalCall)]
+               unsafe public extern String (sbyte *value, int startIndex, int length);
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern String InternalReplace(String oldValue, string newValue, CompareInfo comp);
-               
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern String InternalRemove(int sindex, int count);
-               
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern void InternalCopyTo(int sindex, char[] dest, int dindex, int count);
+               [CLSCompliant (false), MethodImplAttribute (MethodImplOptions.InternalCall)]
+               unsafe public extern String (sbyte *value, int startIndex, int length, Encoding enc);
+
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               public extern String (char [] val, int startIndex, int length);
+
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               public extern String (char [] val);
+
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               public extern String (char c, int count);
+
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               public extern override int GetHashCode ();
+
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               private extern static string InternalJoin (string separator, string[] value, int sIndex, int count);
+
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               private extern String InternalInsert (int sourceIndex, String value);
+
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               private extern String InternalReplace (char oldChar, char newChar);
+
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               private extern String InternalReplace (String oldValue, string newValue, CompareInfo comp);
+
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               private extern String InternalRemove (int sIndex, int count);
+
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               private extern void InternalCopyTo (int sIndex, char[] dest, int destIndex, int count);
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern String[] InternalSplit(char[] separator, int count);
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               private extern String[] InternalSplit (char[] separator, int count);
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern String InternalTrim(char[] chars, int typ);
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               private extern String InternalTrim (char[] chars, int typ);
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern int InternalIndexOfAny(char [] arr, int sindex, int count);
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               private extern int InternalIndexOfAny (char [] arr, int sIndex, int count);
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern int InternalLastIndexOfAny(char [] anyOf, int sindex, int count);
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               private extern int InternalLastIndexOfAny (char [] anyOf, int sIndex, int count);
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern String InternalPad(int width, char chr, bool right);
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               private extern String InternalPad (int width, char chr, bool right);
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern String InternalToLower(CultureInfo culture);
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               private extern String InternalToLower (CultureInfo culture);
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern String InternalToUpper(CultureInfo culture);
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               private extern String InternalToUpper (CultureInfo culture);
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern static String InternalAllocateStr(int length);
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               internal extern static String InternalAllocateStr (int length);
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern static void InternalStrcpy(String dest, int destPos, String src);
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               internal extern static void InternalStrcpy (String dest, int destPos, String src);
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern static void InternalStrcpy(String dest, int destPos, String src, int startPos, int count);
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               internal extern static void InternalStrcpy (String dest, int destPos, String src, int sPos, int count);
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern static string InternalIntern(string str);
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               private extern static string InternalIntern (string str);
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern static string InternalIsInterned(string str);
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               private extern static string InternalIsInterned (string str);
        }
 }