Merge pull request #561 from akoeplinger/bufferless-fix
[mono.git] / mcs / class / corlib / System / Convert.cs
1 //
2 // System.Convert.cs
3 //
4 // Author:
5 //   Derek Holden (dholden@draper.com)
6 //   Duncan Mak (duncan@ximian.com)
7 //
8 // (C) Ximian, Inc.  http://www.ximian.com
9 //
10 //
11 // System.Convert class. This was written word for word off the 
12 // Library specification for System.Convert in the ECMA TC39 TG2 
13 // and TG3 working documents. The first page of which has a table
14 // for all legal conversion scenerios.
15 //
16 // This header and the one above it can be formatted however, just trying
17 // to keep it consistent w/ the existing mcs headers.
18 //
19 // This Convert class could be written another way, with each type 
20 // implementing IConvertible and defining their own conversion functions,
21 // and this class just calling the type's implementation. Or, they can 
22 // be defined here and the implementing type can use these functions when 
23 // defining their IConvertible interface. Byte's ToBoolean() calls 
24 // Convert.ToBoolean(byte), or Convert.ToBoolean(byte) calls 
25 // byte.ToBoolean(). The first case is what is done here.
26 //
27 // See http://lists.ximian.com/archives/public/mono-list/2001-July/000525.html
28 //
29 // There are also conversion functions that are not defined in
30 // the ECMA draft, such as there is no bool ToBoolean(DateTime value), 
31 // and placing that somewhere won't compile w/ this Convert since the
32 // function doesn't exist. However calling that when using Microsoft's
33 // System.Convert doesn't produce any compiler errors, it just throws
34 // an InvalidCastException at runtime.
35 //
36 // Whenever a decimal, double, or single is converted to an integer
37 // based type, it is even rounded. This uses Math.Round which only 
38 // has Round(decimal) and Round(double), so in the Convert from 
39 // single cases the value is passed to Math as a double. This 
40 // may not be completely necessary.
41 //
42 // The .NET Framework SDK lists DBNull as a member of this class
43 // as 'public static readonly object DBNull;'. 
44 //
45 // It should also be decided if all the cast return values should be
46 // returned as unchecked or not.
47 //
48 // All the XML function comments were auto generated which is why they
49 // sound someone redundant.
50 //
51 // TYPE | BOOL BYTE CHAR DT DEC DBL I16 I32 I64 SBYT SNGL STR UI16 UI32 UI64
52 // -----+--------------------------------------------------------------------
53 // BOOL |   X    X           X   X   X   X   X    X    X   X    X    X    X
54 // BYTE |   X    X    X      X   X   X   X   X    X    X   X    X    X    X
55 // CHAR |        X    X              X   X   X    X        X    X    X    X
56 // DT   |                 X                                X
57 // DEC  |   X    X           X   X   X   X   X    X    X   X    X    X    X
58 // DBL  |   X    X           X   X   X   X   X    X    X   X    X    X    X
59 // I16  |   X    X    X      X   X   X   X   X    X    X   X    X    X    X
60 // I32  |   X    X    X      X   X   X   X   X    X    X   X    X    X    X
61 // I64  |   X    X    X      X   X   X   X   X    X    X   X    X    X    X
62 // SBYT |   X    X    X      X   X   X   X   X    X    X   X    X    X    X
63 // SNGL |   X    X           X   X   X   X   X    X    X   X    X    X    X
64 // STR  |   X    X    X   X  X   X   X   X   X    X    X   X    X    X    X
65 // UI16 |   X    X    X      X   X   X   X   X    X    X   X    X    X    X
66 // UI32 |   X    X    X      X   X   X   X   X    X    X   X    X    X    X
67 // UI64 |   X    X    X      X   X   X   X   X    X    X   X    X    X    X
68 //
69
70 //
71 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
72 //
73 // Permission is hereby granted, free of charge, to any person obtaining
74 // a copy of this software and associated documentation files (the
75 // "Software"), to deal in the Software without restriction, including
76 // without limitation the rights to use, copy, modify, merge, publish,
77 // distribute, sublicense, and/or sell copies of the Software, and to
78 // permit persons to whom the Software is furnished to do so, subject to
79 // the following conditions:
80 // 
81 // The above copyright notice and this permission notice shall be
82 // included in all copies or substantial portions of the Software.
83 // 
84 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
85 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
86 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
87 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
88 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
89 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
90 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
91 //
92
93 using System.Globalization;
94 using System.IO;
95 using System.Security.Cryptography;
96 using System.Text;
97 using System.Runtime.CompilerServices;
98 using System.Runtime.InteropServices;
99
100 namespace System {
101   
102 //      [CLSCompliant(false)]
103         public static class Convert {
104
105                 // Fields
106                 public static readonly object DBNull = System.DBNull.Value;
107         
108                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
109                 extern static byte [] InternalFromBase64String (string str, bool allowWhitespaceOnly);
110
111                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
112                 extern static byte [] InternalFromBase64CharArray (char [] arr, int offset, int length);
113
114                 public static byte[] FromBase64CharArray (char[] inArray, int offset, int length)
115                 {
116                         if (inArray == null)
117                                 throw new ArgumentNullException ("inArray");
118                         if (offset < 0)
119                                 throw new ArgumentOutOfRangeException ("offset < 0");
120                         if (length < 0)
121                                 throw new ArgumentOutOfRangeException ("length < 0");
122                         // avoid integer overflow
123                         if (offset > inArray.Length - length)
124                                 throw new ArgumentOutOfRangeException ("offset + length > array.Length");
125
126                         return InternalFromBase64CharArray (inArray, offset, length);
127                 }
128
129                 public static byte[] FromBase64String (string s)
130                 {
131                         if (s == null)
132                                 throw new ArgumentNullException ("s");
133
134                         if (s.Length == 0) {
135                                 return EmptyArray<byte>.Value;
136                         }
137
138                         return InternalFromBase64String (s, true);
139                 }
140
141                 public static TypeCode GetTypeCode (object value)
142                 {
143                         if (value == null)
144                                 return TypeCode.Empty;
145                         else 
146                                 return Type.GetTypeCode (value.GetType ());
147                 }
148
149                 public static bool IsDBNull (object value)
150                 {
151                         if (value is DBNull)
152                                 return true;
153                         else
154                                 return false;
155                 }
156                 
157                 public static int ToBase64CharArray (byte[] inArray, int offsetIn, int length, 
158                                                     char[] outArray, int offsetOut)
159                 {
160                         if (inArray == null)
161                                 throw new ArgumentNullException ("inArray");
162                         if (outArray == null)
163                                 throw new ArgumentNullException ("outArray");
164                         if (offsetIn < 0 || length < 0 || offsetOut < 0)
165                                 throw new ArgumentOutOfRangeException ("offsetIn, length, offsetOut < 0");
166                         // avoid integer overflow
167                         if (offsetIn > inArray.Length - length)
168                                 throw new ArgumentOutOfRangeException ("offsetIn + length > array.Length");
169
170                         // note: normally ToBase64Transform doesn't support multiple block processing
171                         byte[] outArr = ToBase64Transform.InternalTransformFinalBlock (inArray, offsetIn, length);
172                         
173                         char[] cOutArr = new ASCIIEncoding ().GetChars (outArr);
174                         
175                         // avoid integer overflow
176                         if (offsetOut > outArray.Length - cOutArr.Length)
177                                 throw new ArgumentOutOfRangeException ("offsetOut + cOutArr.Length > outArray.Length");
178                         
179                         Array.Copy (cOutArr, 0, outArray, offsetOut, cOutArr.Length);
180                         
181                         return cOutArr.Length;
182                 }
183                 
184                 public static string ToBase64String (byte[] inArray)
185                 {
186                         if (inArray == null)
187                                 throw new ArgumentNullException ("inArray");
188
189                         return ToBase64String (inArray, 0, inArray.Length);
190                 }
191                 
192                 public static string ToBase64String (byte[] inArray, int offset, int length)
193                 {
194                         if (inArray == null)
195                                 throw new ArgumentNullException ("inArray");
196                         if (offset < 0 || length < 0)
197                                 throw new ArgumentOutOfRangeException ("offset < 0 || length < 0");
198                         // avoid integer overflow
199                         if (offset > inArray.Length - length)
200                                 throw new ArgumentOutOfRangeException ("offset + length > array.Length");
201                         
202                         // note: normally ToBase64Transform doesn't support multiple block processing
203                         byte[] outArr = ToBase64Transform.InternalTransformFinalBlock (inArray, offset, length);
204                         
205                         return (new ASCIIEncoding ().GetString (outArr));
206                 }
207
208                 [ComVisible (false)]
209                 public static string ToBase64String (byte[] inArray, Base64FormattingOptions options)
210                 {
211                         if (inArray == null)
212                                 throw new ArgumentNullException ("inArray");
213                         return ToBase64String (inArray, 0, inArray.Length, options);
214                 }
215
216                 [ComVisible (false)]
217                 public static string ToBase64String (byte[] inArray, int offset, int length, Base64FormattingOptions options)
218                 {
219                         if (inArray == null)
220                                 throw new ArgumentNullException ("inArray");
221                         if (offset < 0 || length < 0)
222                                 throw new ArgumentOutOfRangeException ("offset < 0 || length < 0");
223                         // avoid integer overflow
224                         if (offset > inArray.Length - length)
225                                 throw new ArgumentOutOfRangeException ("offset + length > array.Length");
226
227                         if (length == 0)
228                                 return String.Empty;
229
230                         if (options == Base64FormattingOptions.InsertLineBreaks)
231                                 return ToBase64StringBuilderWithLine (inArray, offset, length).ToString ();
232                         else
233                                 return Encoding.ASCII.GetString (ToBase64Transform.InternalTransformFinalBlock (inArray, offset, length));
234                 }
235
236                 [ComVisible (false)]
237                 public static int ToBase64CharArray (byte[] inArray, int offsetIn, int length, 
238                                                     char[] outArray, int offsetOut, Base64FormattingOptions options)
239                 {
240                         if (inArray == null)
241                                 throw new ArgumentNullException ("inArray");
242                         if (outArray == null)
243                                 throw new ArgumentNullException ("outArray");
244                         if (offsetIn < 0 || length < 0 || offsetOut < 0)
245                                 throw new ArgumentOutOfRangeException ("offsetIn, length, offsetOut < 0");
246                         // avoid integer overflow
247                         if (offsetIn > inArray.Length - length)
248                                 throw new ArgumentOutOfRangeException ("offsetIn + length > array.Length");
249
250                         if (length == 0)
251                                 return 0;
252
253                         // note: normally ToBase64Transform doesn't support multiple block processing
254                         if (options == Base64FormattingOptions.InsertLineBreaks) {
255                                 StringBuilder sb = ToBase64StringBuilderWithLine (inArray, offsetIn, length);
256                                 sb.CopyTo (0, outArray, offsetOut, sb.Length);
257                                 return sb.Length;
258                         } else {
259                                 byte[] outArr = ToBase64Transform.InternalTransformFinalBlock (inArray, offsetIn, length);
260                         
261                                 char[] cOutArr = Encoding.ASCII.GetChars (outArr);
262                         
263                                 // avoid integer overflow
264                                 if (offsetOut > outArray.Length - cOutArr.Length)
265                                         throw new ArgumentOutOfRangeException ("offsetOut + cOutArr.Length > outArray.Length");
266                         
267                                 Array.Copy (cOutArr, 0, outArray, offsetOut, cOutArr.Length);
268                                 return cOutArr.Length;
269                         }
270                 }
271
272                 private const int MaxBytesPerLine = 57;
273
274                 static StringBuilder ToBase64StringBuilderWithLine (byte [] inArray, int offset, int length)
275                 {
276                         StringBuilder sb = new StringBuilder ();
277
278                         int remainder;
279                         int full = Math.DivRem (length, MaxBytesPerLine, out remainder);
280                         for (int i = 0; i < full; i ++) {
281                                 byte[] data = ToBase64Transform.InternalTransformFinalBlock (inArray, offset, MaxBytesPerLine);
282                                 sb.AppendLine (Encoding.ASCII.GetString (data));
283                                 offset += MaxBytesPerLine;
284                         }
285                         // we never complete (i.e. the last line) with a new line
286                         if (remainder == 0) {
287                                 int nll = Environment.NewLine.Length;
288                                 sb.Remove (sb.Length - nll, nll);
289                         } else {
290                                 byte[] data = ToBase64Transform.InternalTransformFinalBlock (inArray, offset, remainder);
291                                 sb.Append (Encoding.ASCII.GetString (data));
292                         }
293                         return sb;
294                 }
295                 
296                 // ========== Boolean Conversions ========== //
297         
298                 public static bool ToBoolean (bool value) 
299                 { 
300                         return value; 
301                 }
302
303                 public static bool ToBoolean (byte value) 
304                 { 
305                         return (value != 0); 
306                 }
307  
308                 public static bool ToBoolean (char value)
309                 {
310                         throw new InvalidCastException (Locale.GetText ("Can't convert char to bool"));
311                 }
312                 
313                 public static bool ToBoolean (DateTime value)
314                 {
315                         throw new InvalidCastException (Locale.GetText ("Can't convert date to bool"));
316                 }
317                 
318                 public static bool ToBoolean (decimal value) 
319                 { 
320                         return (value != 0M); 
321                 }
322
323                 public static bool ToBoolean (double value) 
324                 { 
325                         return (value != 0); 
326                 }
327
328                 public static bool ToBoolean (float value) 
329                 { 
330                         return (value != 0f); 
331                 }
332
333                 public static bool ToBoolean (int value) 
334                 { 
335                         return (value != 0); 
336                 }
337
338                 public static bool ToBoolean (long value) 
339                 { 
340                         return (value != 0); 
341                 }
342
343                 [CLSCompliant (false)]
344                 public static bool ToBoolean (sbyte value) 
345                 { 
346                         return (value != 0); 
347                 }
348         
349                 public static bool ToBoolean (short value) 
350                 { 
351                         return (value != 0); 
352                 }
353
354                 public static bool ToBoolean (string value) 
355                 {
356                         if (value == null)
357                                 return false; // LAMESPEC: Spec says throw ArgumentNullException
358                         return Boolean.Parse (value);
359                 }
360
361                 public static bool ToBoolean (string value, IFormatProvider provider)
362                 {
363                         if (value == null)
364                                 return false; // LAMESPEC: Spec says throw ArgumentNullException
365                         return Boolean.Parse (value); // provider is ignored.
366                 }
367
368                 [CLSCompliant (false)]
369                 public static bool ToBoolean (uint value) 
370                 { 
371                         return (value != 0);
372                 }
373
374                 [CLSCompliant (false)]
375                 public static bool ToBoolean (ulong value) 
376                 { 
377                         return (value != 0); 
378                 }
379
380                 [CLSCompliant (false)]
381                 public static bool ToBoolean (ushort value) 
382                 { 
383                         //if (value == null)
384                         //      return false;
385                         return (value != 0); 
386                 }
387
388                 public static bool ToBoolean (object value)
389                 {
390                         if (value == null)
391                                 return false;
392                         return ToBoolean (value, null);
393                 }
394
395                 public static bool ToBoolean (object value, IFormatProvider provider)
396                 {
397                         if (value == null)
398                                 return false;
399                         return ((IConvertible) value).ToBoolean (provider);
400                 }
401
402                 // ========== Byte Conversions ========== //
403         
404                 public static byte ToByte (bool value) 
405                 { 
406                         return (byte)(value ? 1 : 0); 
407                 }
408         
409                 public static byte ToByte (byte value) 
410                 { 
411                         return value; 
412                 }
413
414                 public static byte ToByte (char value) 
415                 { 
416                         return checked ((byte) value);
417                 }
418
419                 public static byte ToByte (DateTime value)
420                 {
421                         throw new InvalidCastException ("This conversion is not supported.");
422                 }
423         
424                 public static byte ToByte (decimal value)
425                 { 
426                         // Returned Even-Rounded
427                         return checked ((byte) Math.Round (value));
428                 }
429         
430                 public static byte ToByte (double value) 
431                 { 
432                         // Returned Even-Rounded
433                         return checked ((byte) Math.Round (value));
434                 }
435
436                 public static byte ToByte (float value) 
437                 { 
438                         // Returned Even-Rounded, pass it as a double, could have this
439                         // method just call Convert.ToByte ( (double)value)
440                         return checked ((byte) Math.Round (value));
441                 }
442
443                 public static byte ToByte (int value) 
444                 { 
445                         return checked ((byte) value); 
446                 }
447
448                 public static byte ToByte (long value) 
449                 { 
450                         return checked ((byte) value);
451                 }
452
453                 [CLSCompliant (false)]
454                 public static byte ToByte (sbyte value) 
455                 { 
456                         return checked ((byte) value);
457                 }
458         
459                 public static byte ToByte (short value) 
460                 { 
461                         return checked ((byte) value);
462                 }
463
464                 public static byte ToByte (string value) 
465                 {
466                         if (value == null)
467                                 return 0; // LAMESPEC: Spec says throw ArgumentNullException
468                         return Byte.Parse (value);
469                 }
470
471                 public static byte ToByte (string value, IFormatProvider provider) 
472                 {
473                         if (value == null)
474                                 return 0; // LAMESPEC: Spec says throw ArgumentNullException
475                         return Byte.Parse (value, provider);
476                 }
477
478                 public static byte ToByte (string value, int fromBase)
479                 {
480                         int retVal = ConvertFromBase (value, fromBase, true);
481
482                         return checked ((byte) retVal);
483                 }
484
485                 [CLSCompliant (false)]
486                 public static byte ToByte (uint value) 
487                 { 
488                         return checked ((byte) value);
489                 }
490
491                 [CLSCompliant (false)]
492                 public static byte ToByte (ulong value) 
493                 { 
494                         return checked ((byte) value);
495                 }
496
497                 [CLSCompliant (false)]
498                 public static byte ToByte (ushort value) 
499                 { 
500                         return checked ((byte) value);
501                 }
502
503                 public static byte ToByte (object value)
504                 {
505                         if (value == null)
506                                 return 0;
507                         return ToByte (value, null);
508                 }
509
510                 public static byte ToByte (object value, IFormatProvider provider)
511                 {
512                         if (value == null)
513                                 return 0;
514                         return ((IConvertible) value).ToByte (provider);
515                 }
516
517                 // ========== Char Conversions ========== //
518
519                 public static char ToChar (bool value)
520                 {
521                         throw new InvalidCastException ("This conversion is not supported.");
522                 }
523                 
524                 public static char ToChar (byte value) 
525                 { 
526                         return (char)value;
527                 }
528
529                 public static char ToChar (char value) 
530                 { 
531                         return value;
532                 }
533
534                 public static char ToChar (DateTime value)
535                 {
536                         throw new InvalidCastException ("This conversion is not supported.");
537                 }
538
539                 public static char ToChar (decimal value)
540                 {
541                         throw new InvalidCastException ("This conversion is not supported.");
542                 }
543
544                 public static char ToChar (double value)
545                 {
546                         throw new InvalidCastException ("This conversion is not supported.");
547                 }
548                 
549                 public static char ToChar (int value) 
550                 { 
551                         return checked ((char) value);
552                 }
553
554                 public static char ToChar (long value) 
555                 { 
556                         return checked ((char) value);
557                 }
558
559                 public static char ToChar (float value)
560                 {
561                         throw new InvalidCastException ("This conversion is not supported.");
562                 }
563
564                 [CLSCompliant (false)]
565                 public static char ToChar (sbyte value) 
566                 { 
567                         return checked ((char) value);
568                 }
569         
570                 public static char ToChar (short value) 
571                 { 
572                         return checked ((char) value);
573                 }
574
575                 public static char ToChar (string value) 
576                 {
577                         return Char.Parse (value);
578                 }
579
580                 public static char ToChar (string value, IFormatProvider provider)
581                 {
582                         return Char.Parse (value); // provider is ignored.
583                 }
584
585                 [CLSCompliant (false)]
586                 public static char ToChar (uint value) 
587                 { 
588                         return checked ((char) value);
589                 }
590
591                 [CLSCompliant (false)]
592                 public static char ToChar (ulong value) 
593                 { 
594                         return checked ((char) value);
595                 }
596
597                 [CLSCompliant (false)]
598                 public static char ToChar (ushort value) 
599                 { 
600                         return (char)value; 
601                 }
602
603                 public static char ToChar (object value)
604                 {
605                         if (value == null)
606                                 return '\0';
607                         return ToChar (value, null);
608                 }
609
610                 public static char ToChar (object value, IFormatProvider provider)
611                 {
612                         if (value == null)
613                                 return '\0';
614                         return ((IConvertible) value).ToChar (provider);
615                 }
616
617                 // ========== DateTime Conversions ========== //
618         
619                 public static DateTime ToDateTime (string value) 
620                 { 
621                         if (value == null)
622                                 return DateTime.MinValue; // LAMESPEC: Spec says throw ArgumentNullException
623                         return DateTime.Parse (value);
624                 }
625         
626                 public static DateTime ToDateTime (string value, IFormatProvider provider) 
627                 {
628                         if (value == null)
629                                 return DateTime.MinValue; // LAMESPEC: Spec says throw ArgumentNullException
630                         return DateTime.Parse (value, provider);
631                 }
632
633                 public static DateTime ToDateTime (bool value)
634                 {
635                         throw new InvalidCastException ("This conversion is not supported.");
636                 }
637
638                 public static DateTime ToDateTime (byte value)
639                 {
640                         throw new InvalidCastException ("This conversion is not supported.");
641                 }
642
643                 public static DateTime ToDateTime (char value)
644                 {
645                         throw new InvalidCastException ("This conversion is not supported.");
646                 }
647
648                 public static DateTime ToDateTime (DateTime value)
649                 {
650                         return value;
651                 }
652
653                 public static DateTime ToDateTime (decimal value)
654                 {
655                         throw new InvalidCastException ("This conversion is not supported.");
656                 }
657
658                 public static DateTime ToDateTime (double value)
659                 {
660                         throw new InvalidCastException ("This conversion is not supported.");
661                 }
662
663                 public static DateTime ToDateTime (short value)
664                 {
665                         throw new InvalidCastException ("This conversion is not supported.");
666                 }
667
668                 public static DateTime ToDateTime (int value)
669                 {
670                         throw new InvalidCastException ("This conversion is not supported.");
671                 }
672
673                 public static DateTime ToDateTime (long value)
674                 {
675                         throw new InvalidCastException ("This conversion is not supported.");
676                 }
677
678                 public static DateTime ToDateTime (float value)
679                 {
680                         throw new InvalidCastException ("This conversion is not supported.");
681                 }
682
683                 public static DateTime ToDateTime (object value)
684                 {
685                         if (value == null)
686                                 return DateTime.MinValue;
687                         return ToDateTime (value, null);
688                 }
689
690                 public static DateTime ToDateTime (object value, IFormatProvider provider)
691                 {
692                         if (value == null)
693                                 return DateTime.MinValue;
694                         return ((IConvertible) value).ToDateTime (provider);
695                 }
696
697                 [CLSCompliant (false)]
698                 public static DateTime ToDateTime (sbyte value)
699                 {
700                         throw new InvalidCastException ("This conversion is not supported.");
701                 }
702                 [CLSCompliant (false)]
703                 public static DateTime ToDateTime (ushort value)
704                 {
705                         throw new InvalidCastException ("This conversion is not supported.");
706                 }
707
708                 [CLSCompliant (false)]
709                 public static DateTime ToDateTime (uint value)
710                 {
711                         throw new InvalidCastException ("This conversion is not supported.");
712                 }
713
714                 [CLSCompliant (false)]
715                 public static DateTime ToDateTime (ulong value)
716                 {
717                         throw new InvalidCastException ("This conversion is not supported.");
718                 }
719
720                 // ========== Decimal Conversions ========== //
721         
722                 public static decimal ToDecimal (bool value) 
723                 { 
724                         return value ? 1 : 0; 
725                 }
726         
727                 public static decimal ToDecimal (byte value) 
728                 { 
729                         return (decimal)value; 
730                 }
731
732                 public static decimal ToDecimal (char value)
733                 {
734                         throw new InvalidCastException ("This conversion is not supported.");
735                 }
736
737                 public static decimal ToDecimal (DateTime value)
738                 {
739                         throw new InvalidCastException ("This conversion is not supported.");
740                 }
741                                 
742                 public static decimal ToDecimal (decimal value) 
743                 { 
744                         return value; 
745                 }
746
747                 public static decimal ToDecimal (double value) 
748                 { 
749                         return (decimal) value; 
750                 }
751
752                 public static decimal ToDecimal (float value) 
753                 {
754                         return (decimal) value;
755                 }
756
757                 public static decimal ToDecimal (int value) 
758                 { 
759                         return (decimal)value; 
760                 }
761         
762                 public static decimal ToDecimal (long value) 
763                 { 
764                         return (decimal)value; 
765                 }
766
767                 [CLSCompliant (false)]
768                 public static decimal ToDecimal (sbyte value) 
769                 { 
770                         return (decimal)value; 
771                 }
772         
773                 public static decimal ToDecimal (short value) 
774                 { 
775                         return (decimal)value; 
776                 }
777
778                 public static decimal ToDecimal (string value) 
779                 {
780                         if (value == null)
781                                 return new Decimal (0); // LAMESPEC: Spec says throw ArgumentNullException
782                         return Decimal.Parse (value);
783                 }
784
785                 public static decimal ToDecimal (string value, IFormatProvider provider) 
786                 {
787                         if (value == null)
788                                 return new Decimal (0); // LAMESPEC: Spec says throw ArgumentNullException
789                         return Decimal.Parse (value, provider);
790                 }
791
792                 [CLSCompliant (false)]
793                 public static decimal ToDecimal (uint value) 
794                 { 
795                         return (decimal)value; 
796                 }
797
798                 [CLSCompliant (false)]
799                 public static decimal ToDecimal (ulong value) 
800                 { 
801                         return (decimal)value; 
802                 }
803
804                 [CLSCompliant (false)]
805                 public static decimal ToDecimal (ushort value) 
806                 { 
807                         return (decimal)value; 
808                 }
809
810                 public static decimal ToDecimal (object value)
811                 {
812                         if (value == null)
813                                 return new Decimal (0);
814                         return ToDecimal (value, null);
815                 }
816
817                 public static decimal ToDecimal (object value, IFormatProvider provider)
818                 {
819                         if (value == null)
820                                 return new Decimal (0);
821                         return ((IConvertible) value).ToDecimal (provider);
822                 }
823                                                  
824
825                 // ========== Double Conversions ========== //
826         
827                 public static double ToDouble (bool value) 
828                 { 
829                         return value ? 1 : 0; 
830                 }
831         
832                 public static double ToDouble (byte value) 
833                 { 
834                         return (double) value;
835                 }
836
837                 public static double ToDouble (char value)
838                 {
839                         throw new InvalidCastException ("This conversion is not supported.");
840                 }
841
842                 public static double ToDouble (DateTime value)
843                 {
844                         throw new InvalidCastException ("This conversion is not supported.");
845                 }
846         
847                 public static double ToDouble (decimal value) 
848                 { 
849                         return (double)value; 
850                 }
851
852                 public static double ToDouble (double value) 
853                 { 
854                         return value; 
855                 }
856
857                 public static double ToDouble (float value) 
858                 { 
859                         return (double) value;
860                 }
861
862                 public static double ToDouble (int value) 
863                 { 
864                         return (double)value; 
865                 }
866         
867                 public static double ToDouble (long value) 
868                 { 
869                         return (double)value; 
870                 }
871
872                 [CLSCompliant (false)]
873                 public static double ToDouble (sbyte value) 
874                 { 
875                         return (double)value; 
876                 }
877         
878                 public static double ToDouble (short value) 
879                 { 
880                         return (double)value; 
881                 }
882
883                 public static double ToDouble (string value) 
884                 {
885                         if (value == null)
886                                 return 0.0; // LAMESPEC: Spec says throw ArgumentNullException
887                         return Double.Parse (value);
888                 }
889
890                 public static double ToDouble (string value, IFormatProvider provider) 
891                 {
892                         if (value == null)
893                                 return 0.0; // LAMESPEC: Spec says throw ArgumentNullException
894                         return Double.Parse (value, provider);
895                 }
896
897                 [CLSCompliant (false)]
898                 public static double ToDouble (uint value) 
899                 { 
900                         return (double)value; 
901                 }
902
903                 [CLSCompliant (false)]
904                 public static double ToDouble (ulong value) 
905                 { 
906                         return (double)value; 
907                 }
908
909                 [CLSCompliant (false)]
910                 public static double ToDouble (ushort value) 
911                 { 
912                         return (double)value; 
913                 }
914
915                 public static double ToDouble (object value)
916                 {
917                         if (value == null)
918                                 return 0.0;
919                         return ToDouble (value, null);
920                 }
921
922                 public static double ToDouble (object value, IFormatProvider provider)
923                 {
924                         if (value == null)
925                                 return 0.0;
926                         return ((IConvertible) value).ToDouble (provider);
927                 }
928
929                 // ========== Int16 Conversions ========== //
930
931                 public static short ToInt16 (bool value) 
932                 { 
933                         return (short)(value ? 1 : 0); 
934                 }
935         
936                 public static short ToInt16 (byte value) 
937                 { 
938                         return (short)value; 
939                 }
940
941                 public static short ToInt16 (char value) 
942                 {
943                         return checked ((short) value);
944                 }
945
946                 public static short ToInt16 (DateTime value) 
947                 {
948                         throw new InvalidCastException ("This conversion is not supported.");
949                 }
950         
951                 public static short ToInt16 (decimal value) 
952                 { 
953                         // Returned Even-Rounded
954                         return checked ((short) Math.Round (value));
955                 }
956
957                 public static short ToInt16 (double value) 
958                 { 
959                         // Returned Even-Rounded
960                         return checked ((short) Math.Round (value));
961                 }
962  
963                 public static short ToInt16 (float value) 
964                 { 
965                         // Returned Even-Rounded, use Math.Round pass as a double.
966                         return checked ((short) Math.Round (value));
967                 }
968
969                 public static short ToInt16 (int value) 
970                 { 
971                         return checked ((short) value);
972                 }
973         
974                 public static short ToInt16 (long value) 
975                 { 
976                         return checked ((short) value);
977                 }
978
979                 [CLSCompliant (false)]
980                 public static short ToInt16 (sbyte value) 
981                 { 
982                         return value; 
983                 }
984         
985                 public static short ToInt16 (short value) 
986                 { 
987                         return value; 
988                 }
989
990                 public static short ToInt16 (string value) 
991                 {
992                         if (value == null)
993                                 return 0; // LAMESPEC: Spec says throw ArgumentNullException
994                         return Int16.Parse (value);
995                 }
996
997                 public static short ToInt16 (string value, IFormatProvider provider) 
998                 {
999                         if (value == null)
1000                                 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1001                         return Int16.Parse (value, provider);
1002                 }
1003
1004                 public static short ToInt16 (string value, int fromBase)
1005                 {
1006                         int result = ConvertFromBase (value, fromBase, false);
1007                         if (fromBase != 10) {
1008                                 if (result > ushort.MaxValue) {
1009                                         throw new OverflowException ("Value was either too large or too small for an Int16.");
1010                                 }
1011
1012                                 // note: no sign are available to detect negatives
1013                                 if (result > Int16.MaxValue) {
1014                                         // return negative 2's complement
1015                                         return Convert.ToInt16 (-(65536 - result));
1016                                 }
1017                         }
1018                         return Convert.ToInt16 (result);
1019                 }
1020
1021                 [CLSCompliant (false)]
1022                 public static short ToInt16 (uint value) 
1023                 { 
1024                         return checked ((short) value);
1025                 }
1026
1027                 [CLSCompliant (false)]
1028                 public static short ToInt16 (ulong value) 
1029                 { 
1030                         return checked ((short) value);
1031                 }
1032
1033                 [CLSCompliant (false)]
1034                 public static short ToInt16 (ushort value) 
1035                 { 
1036                         return checked ((short) value);
1037                 }
1038
1039                 public static short ToInt16 (object value)
1040                 {
1041                         if (value == null)
1042                                 return 0;
1043                         return ToInt16 (value, null);
1044                 }
1045
1046                 public static short ToInt16 (object value, IFormatProvider provider)
1047                 {
1048                         if (value == null)
1049                                 return 0;
1050                         return ((IConvertible) value).ToInt16 (provider);
1051                 }
1052         
1053                 // ========== Int32 Conversions ========== //
1054
1055                 public static int ToInt32 (bool value) 
1056                 { 
1057                         return value ? 1 : 0; 
1058                 }
1059         
1060                 public static int ToInt32 (byte value) 
1061                 { 
1062                         return (int)value; 
1063                 }
1064
1065                 public static int ToInt32 (char value) 
1066                 { 
1067                         return (int)value; 
1068                 }
1069
1070                 public static int ToInt32 (DateTime value)
1071                 {
1072                         throw new InvalidCastException ("This conversion is not supported.");
1073                 }
1074         
1075                 public static int ToInt32 (decimal value) 
1076                 { 
1077                         // Returned Even-Rounded
1078                         return checked ((int) Math.Round (value));
1079                 }
1080
1081                 public static int ToInt32 (double value) 
1082                 { 
1083                         // Returned Even-Rounded
1084                         checked {
1085                                 return (int)(Math.Round (value));
1086                         }
1087                 }
1088  
1089                 public static int ToInt32 (float value) 
1090                 { 
1091                         if (value > Int32.MaxValue || value < Int32.MinValue) 
1092                                 throw new OverflowException (Locale.GetText (
1093                                         "Value is greater than Int32.MaxValue or less than Int32.MinValue"));
1094           
1095                         // Returned Even-Rounded, pass as a double, could just call
1096                         // Convert.ToInt32 ( (double)value);
1097                         checked {
1098                                 return (int)(Math.Round ( (double)value));
1099                         }
1100                 }
1101
1102                 public static int ToInt32 (int value) 
1103                 { 
1104                         return value; 
1105                 }
1106         
1107                 public static int ToInt32 (long value) 
1108                 { 
1109                         return checked ((int) value);
1110                 }
1111
1112                 [CLSCompliant (false)]
1113                 public static int ToInt32 (sbyte value) 
1114                 { 
1115                         return (int)value; 
1116                 }
1117         
1118                 public static int ToInt32 (short value) 
1119                 { 
1120                         return (int)value; 
1121                 }
1122
1123                 public static int ToInt32 (string value) 
1124                 {
1125                         if (value == null)
1126                                 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1127                         return Int32.Parse (value);
1128                 }
1129
1130                 public static int ToInt32 (string value, IFormatProvider provider) 
1131                 {
1132                         if (value == null)
1133                                 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1134                         return Int32.Parse (value, provider);
1135                 }
1136
1137                 
1138                 public static int ToInt32 (string value, int fromBase)
1139                 {
1140                         return ConvertFromBase (value, fromBase, false);
1141                 }
1142                 
1143                 [CLSCompliant (false)]
1144                 public static int ToInt32 (uint value) 
1145                 { 
1146                         return checked ((int) value);
1147                 }
1148
1149                 [CLSCompliant (false)]
1150                 public static int ToInt32 (ulong value) 
1151                 { 
1152                         return checked ((int) value);
1153                 }
1154
1155                 [CLSCompliant (false)]
1156                 public static int ToInt32 (ushort value) 
1157                 { 
1158                         return (int)value; 
1159                 }
1160
1161                 public static int ToInt32 (object value)
1162                 {
1163                         if (value == null)
1164                                 return 0;
1165                         return ToInt32 (value, null);
1166                 }
1167
1168                 public static int ToInt32 (object value, IFormatProvider provider)
1169                 {
1170                         if (value == null)
1171                                 return 0;
1172                         return ((IConvertible) value).ToInt32 (provider);
1173                 }
1174
1175                 // ========== Int64 Conversions ========== //
1176
1177                 public static long ToInt64 (bool value) 
1178                 { 
1179                         return value ? 1 : 0; 
1180                 }
1181         
1182                 public static long ToInt64 (byte value) 
1183                 { 
1184                         return (long)(ulong)value; 
1185                 }
1186
1187                 public static long ToInt64 (char value) 
1188                 { 
1189                         return (long)value; 
1190                 }
1191
1192                 public static long ToInt64 (DateTime value)
1193                 {
1194                         throw new InvalidCastException ("This conversion is not supported.");
1195                 }
1196         
1197                 public static long ToInt64 (decimal value) 
1198                 { 
1199                         // Returned Even-Rounded
1200                         return checked ((long) Math.Round (value));
1201                 }
1202
1203                 public static long ToInt64 (double value) 
1204                 { 
1205                         // Returned Even-Rounded
1206                         return checked ((long) Math.Round (value));
1207                 }
1208  
1209                 public static long ToInt64 (float value) 
1210                 { 
1211                         // Returned Even-Rounded, pass to Math as a double, could
1212                         // just call Convert.ToInt64 ( (double)value);
1213                         return checked ((long) Math.Round (value));
1214                 }
1215
1216                 public static long ToInt64 (int value) 
1217                 { 
1218                         return (long)value; 
1219                 }
1220         
1221                 public static long ToInt64 (long value) 
1222                 { 
1223                         return value; 
1224                 }
1225
1226                 [CLSCompliant (false)]
1227                 public static long ToInt64 (sbyte value) 
1228                 { 
1229                         return (long)value; 
1230                 }
1231         
1232                 public static long ToInt64 (short value) 
1233                 { 
1234                         return (long)value; 
1235                 }
1236
1237                 public static long ToInt64 (string value) 
1238                 {
1239                         if (value == null)
1240                                 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1241                         return Int64.Parse (value);
1242                 }
1243
1244                 public static long ToInt64 (string value, IFormatProvider provider) 
1245                 {
1246                         if (value == null)
1247                                 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1248                         return Int64.Parse (value, provider);
1249                 }
1250
1251                 public static long ToInt64 (string value, int fromBase)
1252                 {
1253                         return ConvertFromBase64 (value, fromBase, false);
1254                 }
1255
1256                 [CLSCompliant (false)]
1257                 public static long ToInt64 (uint value) 
1258                 { 
1259                         return (long)(ulong)value; 
1260                 }
1261
1262                 [CLSCompliant (false)]
1263                 public static long ToInt64 (ulong value) 
1264                 { 
1265                         return checked ((long) value);
1266                 }
1267
1268                 [CLSCompliant (false)]
1269                 public static long ToInt64 (ushort value) 
1270                 { 
1271                         return (long)(ulong)value; 
1272                 }
1273
1274                 public static long ToInt64 (object value)
1275                 {
1276                         if (value == null)
1277                                 return 0;
1278                         return ToInt64 (value, null);
1279                 }
1280
1281                 public static long ToInt64 (object value, IFormatProvider provider)
1282                 {
1283                         if (value == null)
1284                                 return 0;
1285                         return ((IConvertible) value).ToInt64 (provider);
1286                 }
1287                 
1288                 // ========== SByte Conversions ========== //
1289
1290                 [CLSCompliant (false)]
1291                 public static sbyte ToSByte (bool value) 
1292                 { 
1293                         return (sbyte)(value ? 1 : 0); 
1294                 }
1295
1296                 [CLSCompliant (false)]
1297                 public static sbyte ToSByte (byte value) 
1298                 { 
1299                         return checked ((sbyte) value);
1300                 }
1301
1302                 [CLSCompliant (false)]
1303                 public static sbyte ToSByte (char value) 
1304                 { 
1305                         return checked ((sbyte) value);
1306                 }
1307
1308                 [CLSCompliant (false)]
1309                 public static sbyte ToSByte (DateTime value)
1310                 {
1311                         throw new InvalidCastException ("This conversion is not supported.");
1312                 }
1313                 
1314                 [CLSCompliant (false)]  
1315                 public static sbyte ToSByte (decimal value) 
1316                 { 
1317                         // Returned Even-Rounded
1318                         return checked ((sbyte) Math.Round (value));
1319                 }
1320
1321                 [CLSCompliant (false)]
1322                 public static sbyte ToSByte (double value) 
1323                 { 
1324                         // Returned Even-Rounded
1325                         return checked ((sbyte) Math.Round (value));
1326                 }
1327
1328                 [CLSCompliant (false)]
1329                 public static sbyte ToSByte (float value) 
1330                 { 
1331                         // Returned Even-Rounded, pass as double to Math
1332                         return checked ((sbyte) Math.Round (value));
1333                 }
1334
1335                 [CLSCompliant (false)]
1336                 public static sbyte ToSByte (int value) 
1337                 { 
1338                         return checked ((sbyte) value);
1339                 }
1340
1341                 [CLSCompliant (false)]
1342                 public static sbyte ToSByte (long value) 
1343                 { 
1344                         return checked ((sbyte) value);
1345                 }
1346
1347                 [CLSCompliant (false)]
1348                 public static sbyte ToSByte (sbyte value) 
1349                 { 
1350                         return value;
1351                 }
1352
1353                 [CLSCompliant (false)]
1354                 public static sbyte ToSByte (short value) 
1355                 { 
1356                         return checked ((sbyte) value);
1357                 }
1358
1359                 [CLSCompliant (false)]
1360                 public static sbyte ToSByte (string value) 
1361                 {
1362                         if (value == null)
1363                                 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1364                         return SByte.Parse (value);
1365                 }
1366                 
1367                 [CLSCompliant (false)]
1368                 public static sbyte ToSByte (string value, IFormatProvider provider) 
1369                 {
1370                         if (value == null)
1371                                 throw new ArgumentNullException ("value");
1372                         return SByte.Parse (value, provider);
1373                 }
1374
1375                 [CLSCompliant (false)]
1376                 public static sbyte ToSByte (string value, int fromBase)
1377                 {
1378                         int result = ConvertFromBase (value, fromBase, false);
1379                         if (fromBase != 10) {
1380                                 // note: no sign are available to detect negatives
1381                                 if (result > SByte.MaxValue) {
1382                                         // return negative 2's complement
1383                                         return Convert.ToSByte (-(256 - result));
1384                                 }
1385                         }
1386                         return Convert.ToSByte (result);
1387                 }
1388                 
1389                 [CLSCompliant (false)]
1390                 public static sbyte ToSByte (uint value) 
1391                 { 
1392                         return checked ((sbyte) value);
1393                 }
1394
1395                 [CLSCompliant (false)]
1396                 public static sbyte ToSByte (ulong value) 
1397                 { 
1398                         return checked ((sbyte) value);
1399                 }
1400
1401                 [CLSCompliant (false)]
1402                 public static sbyte ToSByte (ushort value) 
1403                 { 
1404                         return checked ((sbyte) value);
1405                 }
1406
1407                 [CLSCompliant (false)]
1408                 public static sbyte ToSByte (object value)
1409                 {
1410                         if (value == null)
1411                                 return 0;
1412                         return ToSByte (value, null);
1413                 }
1414
1415                 [CLSCompliant (false)]
1416                 public static sbyte ToSByte (object value, IFormatProvider provider)
1417                 {
1418                         if (value == null)
1419                                 return 0;
1420                         return ((IConvertible) value).ToSByte (provider);
1421                 }
1422
1423                 // ========== Single Conversions ========== //
1424         
1425                 public static float ToSingle (bool value) 
1426                 { 
1427                         return value ? 1 : 0; 
1428                 }
1429         
1430                 public static float ToSingle (byte value) 
1431                 { 
1432                         return (float)value; 
1433                 }
1434
1435                 public static float ToSingle (Char value)
1436                 {
1437                         throw new InvalidCastException ("This conversion is not supported.");
1438                 }
1439
1440                 public static float ToSingle (DateTime value)
1441                 {
1442                         throw new InvalidCastException ("This conversion is not supported.");
1443                 }
1444         
1445                 public static float ToSingle (decimal value) 
1446                 { 
1447                         return (float)value; 
1448                 }
1449
1450                 public static float ToSingle (double value) 
1451                 { 
1452                         return (float)value; 
1453                 }
1454         
1455                 public static float ToSingle (float value) 
1456                 { 
1457                         return value; 
1458                 }
1459
1460                 public static float ToSingle (int value) 
1461                 { 
1462                         return (float)value; 
1463                 }
1464         
1465                 public static float ToSingle (long value) 
1466                 { 
1467                         return (float)value; 
1468                 }
1469
1470                 [CLSCompliant (false)]
1471                 public static float ToSingle (sbyte value) 
1472                 { 
1473                         return (float)value; 
1474                 }
1475         
1476                 public static float ToSingle (short value) 
1477                 { 
1478                         return (float)value; 
1479                 }
1480
1481                 public static float ToSingle (string value) 
1482                 {
1483                         if (value == null)
1484                                 return 0.0f; // LAMESPEC: Spec says throw ArgumentNullException
1485                         return Single.Parse (value);
1486                 }
1487
1488                 public static float ToSingle (string value, IFormatProvider provider) 
1489                 {
1490                         if (value == null)
1491                                 return 0.0f; // LAMESPEC: Spec says throw ArgumentNullException
1492                         return Single.Parse (value, provider);
1493                 }              
1494
1495                 [CLSCompliant (false)]
1496                 public static float ToSingle (uint value) 
1497                 { 
1498                         return (float)value; 
1499                 }
1500
1501                 [CLSCompliant (false)]
1502                 public static float ToSingle (ulong value) 
1503                 { 
1504                         return (float)value; 
1505                 }
1506
1507                 [CLSCompliant (false)]
1508                 public static float ToSingle (ushort value) 
1509                 { 
1510                         return (float)value; 
1511                 }
1512
1513                 public static float ToSingle (object value)
1514                 {
1515                         if (value == null)
1516                                 return 0.0f;
1517                         return ToSingle (value, null);
1518                 }
1519
1520 //              [CLSCompliant (false)]
1521                 public static float ToSingle (object value, IFormatProvider provider)
1522                 {
1523                         if (value == null)
1524                                 return 0.0f;
1525                         return ((IConvertible) value).ToSingle (provider);
1526                 }
1527
1528                 // ========== String Conversions ========== //
1529         
1530                 public static string ToString (bool value) 
1531                 { 
1532                         return value.ToString (); 
1533                 }
1534
1535                 public static string ToString (bool value, IFormatProvider provider)
1536                 {
1537                         return value.ToString (); // the same as ToString (bool).
1538                 }
1539         
1540                 public static string ToString (byte value) 
1541                 { 
1542                         return value.ToString (); 
1543                 }
1544         
1545                 public static string ToString (byte value, IFormatProvider provider) 
1546                 {
1547                         return value.ToString (provider); 
1548                 }
1549
1550                 public static string ToString (byte value, int toBase)
1551                 {
1552                         if (value == 0)
1553                                 return "0";
1554                         if (toBase == 10)
1555                                 return value.ToString ();
1556                         
1557                         byte[] val = BitConverter.GetBytes (value);
1558
1559                         switch (toBase) {
1560                         case 2:
1561                                 return ConvertToBase2 (val);
1562                         case 8:
1563                                 return ConvertToBase8 (val);
1564                         case 16:
1565                                 return ConvertToBase16 (val);
1566                         default:
1567                                 throw new ArgumentException (Locale.GetText ("toBase is not valid."));
1568                         }
1569                 }
1570
1571                 public static string ToString (char value) 
1572                 { 
1573                         return value.ToString (); 
1574                 }
1575
1576                 public static string ToString (char value, IFormatProvider provider)
1577                 {
1578                         return value.ToString (); // the same as ToString (char)
1579                 }
1580
1581                 public static string ToString (DateTime value) 
1582                 { 
1583                         return value.ToString (); 
1584                 }
1585
1586                 public static string ToString (DateTime value, IFormatProvider provider) 
1587                 { 
1588                         return value.ToString (provider); 
1589                 }
1590
1591                 public static string ToString (decimal value) 
1592                 {
1593                         return value.ToString ();
1594                 }
1595
1596                 public static string ToString (decimal value, IFormatProvider provider) 
1597                 { 
1598                         return value.ToString (provider); 
1599                 }
1600         
1601                 public static string ToString (double value) 
1602                 { 
1603                         return value.ToString (); 
1604                 }
1605
1606                 public static string ToString (double value, IFormatProvider provider) 
1607                 { 
1608                         return value.ToString (provider);
1609                 }
1610         
1611                 public static string ToString (float value) 
1612                 { 
1613                         return value.ToString (); 
1614                 }
1615
1616                 public static string ToString (float value, IFormatProvider provider) 
1617                 { 
1618                         return value.ToString (provider); 
1619                 }
1620
1621                 public static string ToString (int value) 
1622                 { 
1623                         return value.ToString (); 
1624                 }
1625
1626                 public static string ToString (int value, int toBase)
1627                 {
1628                         if (value == 0)
1629                                 return "0";
1630                         if (toBase == 10)
1631                                 return value.ToString ();
1632                         
1633                         byte[] val = BitConverter.GetBytes (value);
1634
1635                         switch (toBase) {
1636                         case 2:
1637                                 return ConvertToBase2 (val);
1638                         case 8:
1639                                 return ConvertToBase8 (val);
1640                         case 16:
1641                                 return ConvertToBase16 (val);
1642                         default:
1643                                 throw new ArgumentException (Locale.GetText ("toBase is not valid."));
1644                         }
1645                 }
1646
1647                 public static string ToString (int value, IFormatProvider provider) 
1648                 { 
1649                         return value.ToString (provider); 
1650                 }
1651         
1652                 public static string ToString (long value) 
1653                 { 
1654                         return value.ToString (); 
1655                 }
1656
1657                 public static string ToString (long value, int toBase)
1658                 {
1659                         if (value == 0)
1660                                 return "0";
1661                         if (toBase == 10)
1662                                 return value.ToString ();
1663                         
1664                         byte[] val = BitConverter.GetBytes (value);
1665
1666                         switch (toBase) {
1667                         case 2:
1668                                 return ConvertToBase2 (val);
1669                         case 8:
1670                                 return ConvertToBase8 (val);
1671                         case 16:
1672                                 return ConvertToBase16 (val);
1673                         default:
1674                                 throw new ArgumentException (Locale.GetText ("toBase is not valid."));
1675                         }
1676                 }
1677
1678                 public static string ToString (long value, IFormatProvider provider) 
1679                 { 
1680                         return value.ToString (provider); 
1681                 }
1682
1683                 public static string ToString (object value)
1684                 {
1685                         return ToString (value, null);
1686                 }               
1687
1688                 public static string ToString (object value, IFormatProvider provider)
1689                 {
1690                         if (value is IConvertible)
1691                                 return ((IConvertible) value).ToString (provider);
1692                         else if (value != null)
1693                                 return value.ToString ();
1694                         return String.Empty;
1695                 }                               
1696
1697                 [CLSCompliant (false)]
1698                 public static string ToString (sbyte value) 
1699                 { 
1700                         return value.ToString (); 
1701                 }
1702
1703                 [CLSCompliant (false)]                          
1704                 public static string ToString (sbyte value, IFormatProvider provider) 
1705                 { 
1706                         return value.ToString (provider); 
1707                 }
1708         
1709                 public static string ToString (short value) 
1710                 { 
1711                         return value.ToString (); 
1712                 }
1713
1714                 public static string ToString (short value, int toBase)
1715                 {
1716                         if (value == 0)
1717                                 return "0";
1718                         if (toBase == 10)
1719                                 return value.ToString ();
1720                         
1721                         byte[] val = BitConverter.GetBytes (value);
1722
1723                         switch (toBase) {
1724                         case 2:
1725                                 return ConvertToBase2 (val);
1726                         case 8:
1727                                 return ConvertToBase8 (val);
1728                         case 16:
1729                                 return ConvertToBase16 (val);
1730                         default:
1731                                 throw new ArgumentException (Locale.GetText ("toBase is not valid."));
1732                         }
1733                 }
1734
1735                 public static string ToString (short value, IFormatProvider provider) 
1736                 { 
1737                         return value.ToString (provider); 
1738                 }
1739
1740                 public static string ToString (string value) 
1741                 {
1742                         return value;
1743                 }
1744
1745                 public static string ToString (string value, IFormatProvider provider)
1746                 {
1747                         return value; // provider is ignored.
1748                 }
1749
1750                 [CLSCompliant (false)]
1751                 public static string ToString (uint value) 
1752                 { 
1753                         return value.ToString (); 
1754                 }
1755
1756                 [CLSCompliant (false)]
1757                 public static string ToString (uint value, IFormatProvider provider) 
1758                 { 
1759                         return value.ToString (provider); 
1760                 }
1761
1762                 [CLSCompliant (false)]
1763                 public static string ToString (ulong value) 
1764                 { 
1765                         return value.ToString (); 
1766                 }
1767
1768                 [CLSCompliant (false)]
1769                 public static string ToString (ulong value, IFormatProvider provider) 
1770                 { 
1771                         return value.ToString (provider); 
1772                 }
1773
1774                 [CLSCompliant (false)]
1775                 public static string ToString (ushort value) 
1776                 { 
1777                         return value.ToString (); 
1778                 }
1779
1780                 [CLSCompliant (false)]
1781                 public static string ToString (ushort value, IFormatProvider provider) 
1782                 { 
1783                         return value.ToString (provider); 
1784                 }
1785                 
1786                 // ========== UInt16 Conversions ========== //
1787
1788                 [CLSCompliant (false)]
1789                 public static ushort ToUInt16 (bool value) 
1790                 { 
1791                         return (ushort)(value ? 1 : 0); 
1792                 }
1793
1794                 [CLSCompliant (false)]
1795                 public static ushort ToUInt16 (byte value) 
1796                 { 
1797                         return (ushort)value; 
1798                 }
1799
1800                 [CLSCompliant (false)]
1801                 public static ushort ToUInt16 (char value) 
1802                 { 
1803                         return (ushort)value; 
1804                 }
1805
1806                 [CLSCompliant (false)]
1807                 public static ushort ToUInt16 (DateTime value)
1808                 {
1809                         throw new InvalidCastException ("This conversion is not supported.");
1810                 }
1811
1812                 [CLSCompliant (false)]
1813                 public static ushort ToUInt16 (decimal value) 
1814                 { 
1815                         // Returned Even-Rounded
1816                         return checked ((ushort) Math.Round (value));
1817                 }
1818
1819                 [CLSCompliant (false)]
1820                 public static ushort ToUInt16 (double value) 
1821                 { 
1822                         // Returned Even-Rounded
1823                         return checked ((ushort) Math.Round (value));
1824                 }
1825
1826                 [CLSCompliant (false)]
1827                 public static ushort ToUInt16 (float value) 
1828                 { 
1829                         // Returned Even-Rounded, pass as double to Math
1830                         return checked ((ushort) Math.Round (value));
1831                 }
1832
1833                 [CLSCompliant (false)]
1834                 public static ushort ToUInt16 (int value) 
1835                 { 
1836                         return checked ((ushort) value);
1837                 }
1838
1839                 [CLSCompliant (false)]
1840                 public static ushort ToUInt16 (long value) 
1841                 { 
1842                         return checked ((ushort) value);
1843                 }
1844
1845                 [CLSCompliant (false)]
1846                 public static ushort ToUInt16 (sbyte value) 
1847                 { 
1848                         return checked ((ushort) value);
1849                 }
1850
1851                 [CLSCompliant (false)]
1852                 public static ushort ToUInt16 (short value) 
1853                 { 
1854                         return checked ((ushort) value);
1855                 }
1856                 
1857                 [CLSCompliant (false)]
1858                 public static ushort ToUInt16 (string value) 
1859                 {
1860                         if (value == null)
1861                                 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1862                         return UInt16.Parse (value);
1863                 }
1864
1865                 [CLSCompliant (false)]
1866                 public static ushort ToUInt16 (string value, IFormatProvider provider) 
1867                 {
1868                         if (value == null)
1869                                 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1870                         return UInt16.Parse (value, provider);
1871                 }
1872
1873                 [CLSCompliant (false)]
1874                 public static ushort ToUInt16 (string value, int fromBase) 
1875                 {
1876                         return ToUInt16 (ConvertFromBase (value, fromBase, true));
1877                 } 
1878
1879                 [CLSCompliant (false)]
1880                 public static ushort ToUInt16 (uint value) 
1881                 { 
1882                         return checked ((ushort) value);
1883                 }
1884
1885                 [CLSCompliant (false)]
1886                 public static ushort ToUInt16 (ulong value) 
1887                 { 
1888                         return checked ((ushort) value);
1889                 }
1890
1891                 [CLSCompliant (false)]
1892                 public static ushort ToUInt16 (ushort value) 
1893                 { 
1894                         return value; 
1895                 }
1896
1897                 [CLSCompliant (false)]
1898                 public static ushort ToUInt16 (object value)
1899                 {
1900                         if (value == null)
1901                                 return 0;
1902                         return ToUInt16 (value, null);
1903                 }
1904
1905                 [CLSCompliant (false)]
1906                 public static ushort ToUInt16 (object value, IFormatProvider provider)
1907                 {
1908                         if (value == null)
1909                                 return 0;
1910                         return ((IConvertible) value).ToUInt16 (provider);
1911                 }
1912
1913                 // ========== UInt32 Conversions ========== //
1914
1915                 [CLSCompliant (false)]
1916                 public static uint ToUInt32 (bool value) 
1917                 { 
1918                         return (uint)(value ? 1 : 0); 
1919                 }
1920
1921                 [CLSCompliant (false)]
1922                 public static uint ToUInt32 (byte value) 
1923                 { 
1924                         return (uint)value; 
1925                 }
1926
1927                 [CLSCompliant (false)]
1928                 public static uint ToUInt32 (char value) 
1929                 { 
1930                         return (uint)value; 
1931                 }
1932
1933                 [CLSCompliant (false)]
1934                 public static uint ToUInt32 (DateTime value)
1935                 {
1936                         throw new InvalidCastException ("This conversion is not supported.");
1937                 }
1938                 
1939                 [CLSCompliant (false)]
1940                 public static uint ToUInt32 (decimal value) 
1941                 { 
1942                         // Returned Even-Rounded
1943                         return checked ((uint) Math.Round (value));
1944                 }
1945
1946                 [CLSCompliant (false)]
1947                 public static uint ToUInt32 (double value) 
1948                 { 
1949                         // Returned Even-Rounded
1950                         return checked ((uint) Math.Round (value));
1951                 }
1952
1953                 [CLSCompliant (false)]
1954                 public static uint ToUInt32 (float value) 
1955                 { 
1956                         // Returned Even-Rounded, pass as double to Math
1957                         return checked ((uint) Math.Round (value));
1958                 }
1959
1960                 [CLSCompliant (false)]
1961                 public static uint ToUInt32 (int value) 
1962                 { 
1963                         return checked ((uint) value);
1964                 }
1965
1966                 [CLSCompliant (false)]
1967                 public static uint ToUInt32 (long value) 
1968                 { 
1969                         return checked ((uint) value);
1970                 }
1971
1972                 [CLSCompliant (false)]
1973                 public static uint ToUInt32 (sbyte value) 
1974                 { 
1975                         return checked ((uint) value);
1976                 }
1977
1978                 [CLSCompliant (false)]
1979                 public static uint ToUInt32 (short value) 
1980                 { 
1981                         return checked ((uint) value);
1982                 }
1983
1984                 [CLSCompliant (false)]
1985                 public static uint ToUInt32 (string value) 
1986                 {
1987                         if (value == null)
1988                                 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1989                         return UInt32.Parse (value);
1990                 }
1991
1992                 [CLSCompliant (false)]
1993                 public static uint ToUInt32 (string value, IFormatProvider provider) 
1994                 {
1995                         if (value == null)
1996                                 return 0; // LAMESPEC: Spec says throw ArgumentNullException
1997                         return UInt32.Parse (value, provider);
1998                 }
1999
2000                 [CLSCompliant (false)]
2001                 public static uint ToUInt32 (string value, int fromBase)
2002                 {
2003                         return (uint) ConvertFromBase (value, fromBase, true);
2004                 }
2005
2006                 [CLSCompliant (false)]
2007                 public static uint ToUInt32 (uint value) 
2008                 { 
2009                         return value; 
2010                 }
2011
2012                 [CLSCompliant (false)]
2013                 public static uint ToUInt32 (ulong value) 
2014                 { 
2015                         return checked ((uint) value);
2016                 }
2017
2018                 [CLSCompliant (false)]
2019                 public static uint ToUInt32 (ushort value) 
2020                 { 
2021                         return (uint)value; 
2022                 }
2023
2024                 [CLSCompliant (false)]
2025                 public static uint ToUInt32 (object value)
2026                 {
2027                         if (value == null)
2028                                 return 0;
2029                         return ToUInt32 (value, null);
2030                 }               
2031
2032                 [CLSCompliant (false)]
2033                 public static uint ToUInt32 (object value, IFormatProvider provider)
2034                 {
2035                         if (value == null)
2036                                 return 0;
2037                         return ((IConvertible) value).ToUInt32 (provider);
2038                 }               
2039                 
2040
2041                 // ========== UInt64 Conversions ========== //
2042
2043                 [CLSCompliant (false)]
2044                 public static ulong ToUInt64 (bool value) 
2045                 { 
2046                         return (ulong)(value ? 1 : 0); 
2047                 }
2048
2049                 [CLSCompliant (false)]
2050                 public static ulong ToUInt64 (byte value) 
2051                 { 
2052                         return (ulong)value; 
2053                 }
2054
2055                 [CLSCompliant (false)]
2056                 public static ulong ToUInt64 (char value) 
2057                 { 
2058                         return (ulong)value; 
2059                 }
2060
2061                 [CLSCompliant (false)]
2062                 public static ulong ToUInt64 (DateTime value)
2063                 {
2064                         throw new InvalidCastException ("The conversion is not supported.");
2065                 }
2066
2067                 [CLSCompliant (false)]
2068                 public static ulong ToUInt64 (decimal value) 
2069                 { 
2070                         // Returned Even-Rounded
2071                         return checked ((ulong) Math.Round (value));
2072                 }
2073
2074                 [CLSCompliant (false)]
2075                 public static ulong ToUInt64 (double value) 
2076                 { 
2077                         // Returned Even-Rounded
2078                         return checked ((ulong) Math.Round (value));
2079                 }
2080                 
2081                 [CLSCompliant (false)] 
2082                 public static ulong ToUInt64 (float value) 
2083                 { 
2084                         // Returned Even-Rounded, pass as a double to Math
2085                         return checked ((ulong) Math.Round (value));
2086                 }
2087                 
2088                 [CLSCompliant (false)]
2089                 public static ulong ToUInt64 (int value) 
2090                 { 
2091                         return checked ((ulong) value);
2092                 }
2093                 
2094                 [CLSCompliant (false)]
2095                 public static ulong ToUInt64 (long value) 
2096                 { 
2097                         return checked ((ulong) value);
2098                 }
2099
2100                 [CLSCompliant (false)]
2101                 public static ulong ToUInt64 (sbyte value) 
2102                 { 
2103                         return checked ((ulong) value);
2104                 }
2105                 
2106                 [CLSCompliant (false)]  
2107                 public static ulong ToUInt64 (short value) 
2108                 { 
2109                         return checked ((ulong) value);
2110                 }
2111
2112                 [CLSCompliant (false)]
2113                 public static ulong ToUInt64 (string value) 
2114                 {
2115                         if (value == null)
2116                                 return 0; // LAMESPEC: Spec says throw ArgumentNullException
2117                         return UInt64.Parse (value);
2118                 }
2119
2120                 [CLSCompliant (false)]
2121                 public static ulong ToUInt64 (string value, IFormatProvider provider) 
2122                 {
2123                         if (value == null)
2124                                 return 0; // LAMESPEC: Spec says throw ArgumentNullException
2125                         return UInt64.Parse (value, provider);
2126                 }
2127
2128                 [CLSCompliant (false)]
2129                 public static ulong ToUInt64 (string value, int fromBase)
2130                 {
2131                         return (ulong) ConvertFromBase64 (value, fromBase, true);
2132                 }
2133
2134                 [CLSCompliant (false)]
2135                 public static ulong ToUInt64 (uint value) 
2136                 { 
2137                         return (ulong)value; 
2138                 }
2139
2140                 [CLSCompliant (false)]
2141                 public static ulong ToUInt64 (ulong value) 
2142                 { 
2143                         return value; 
2144                 }
2145                 
2146                 [CLSCompliant (false)]
2147                 public static ulong ToUInt64 (ushort value) 
2148                 { 
2149                         return (ulong)value; 
2150                 }
2151
2152                 [CLSCompliant (false)]
2153                 public static ulong ToUInt64 (object value)
2154                 {
2155                         if (value == null)
2156                                 return 0;
2157                         return ToUInt64 (value, null);
2158                 }               
2159
2160                 [CLSCompliant (false)]
2161                 public static ulong ToUInt64 (object value, IFormatProvider provider)
2162                 {
2163                         if (value == null)
2164                                 return 0;
2165                         return ((IConvertible) value).ToUInt64 (provider);
2166                 }               
2167                 
2168
2169                 // ========== Conversion / Helper Functions ========== //
2170
2171                 public static object ChangeType (object value, Type conversionType)
2172                 {
2173                         if ((value != null) && (conversionType == null))
2174                                 throw new ArgumentNullException ("conversionType");
2175                         CultureInfo ci = CultureInfo.CurrentCulture;
2176                         IFormatProvider provider;
2177                         if (conversionType == typeof(DateTime)) {
2178                                 provider = ci.DateTimeFormat;
2179                         }
2180                         else {
2181                                 provider = ci.NumberFormat;
2182                         }
2183                         return ToType (value, conversionType, provider, true);
2184                 }
2185                 
2186                 public static object ChangeType (object value, TypeCode typeCode)
2187                 {
2188                         CultureInfo ci = CultureInfo.CurrentCulture;
2189                         Type conversionType = conversionTable [(int) typeCode];
2190                         IFormatProvider provider;
2191                         if (conversionType == typeof(DateTime)) {
2192                                 provider = ci.DateTimeFormat;
2193                         }
2194                         else {
2195                                 provider = ci.NumberFormat;
2196                         }
2197                         return ToType (value, conversionType, provider, true);
2198                 }
2199
2200                 public static object ChangeType (object value, Type conversionType, IFormatProvider provider)
2201                 {
2202                         if ((value != null) && (conversionType == null))
2203                                 throw new ArgumentNullException ("conversionType");
2204                         return ToType (value, conversionType, provider, true);
2205                 }
2206                 
2207                 public static object ChangeType (object value, TypeCode typeCode, IFormatProvider provider)
2208                 {
2209                         Type conversionType = conversionTable [(int)typeCode];
2210                         return ToType (value, conversionType, provider, true);
2211                 }
2212
2213                 private static bool NotValidBase (int value)
2214                 {
2215                         if ((value == 2) || (value == 8) ||
2216                            (value == 10) || (value == 16))
2217                                 return false;
2218                         
2219                         return true;
2220                 }
2221
2222                 private static int ConvertFromBase (string value, int fromBase, bool unsigned)
2223                 {
2224                         if (NotValidBase (fromBase))
2225                                 throw new ArgumentException ("fromBase is not valid.");
2226                         if (value == null)
2227                                 return 0;
2228
2229                         int chars = 0;
2230                         int result = 0;
2231                         int digitValue;
2232
2233                         int i=0; 
2234                         int len = value.Length;
2235                         bool negative = false;
2236
2237                         // special processing for some bases
2238                         switch (fromBase) {
2239                                 case 10:
2240                                         if (value.Substring (i, 1) == "-") {
2241                                                 if (unsigned) {
2242                                                         throw new OverflowException (
2243                                                                 Locale.GetText ("The string was being parsed as"
2244                                                                 + " an unsigned number and could not have a"
2245                                                                 + " negative sign."));
2246                                                 }
2247                                                 negative = true;
2248                                                 i++;
2249                                         }
2250                                         break;
2251                                 case 16:
2252                                         if (value.Substring (i, 1) == "-") {
2253                                                 throw new ArgumentException ("String cannot contain a "
2254                                                         + "minus sign if the base is not 10.");
2255                                         }
2256                                         if (len >= i + 2) {
2257                                                 // 0x00 or 0X00
2258                                                 if ((value[i] == '0') && ((value [i+1] == 'x') || (value [i+1] == 'X'))) {
2259                                                         i+=2;
2260                                                 }
2261                                         }
2262                                         break;
2263                                 default:
2264                                         if (value.Substring (i, 1) == "-") {
2265                                                 throw new ArgumentException ("String cannot contain a "
2266                                                         + "minus sign if the base is not 10.");
2267                                         }
2268                                         break;
2269                         }
2270
2271                         if (len == i) {
2272                                 throw new FormatException ("Could not find any parsable digits.");
2273                         }
2274
2275                         if (value[i] == '+') {
2276                                 i++;
2277                         }
2278
2279                         while (i < len) {
2280                                 char c = value[i++];
2281                                 if (Char.IsNumber (c)) {
2282                                         digitValue = c - '0';
2283                                 } else if (Char.IsLetter (c)) {
2284                                         digitValue = Char.ToLowerInvariant (c) - 'a' + 10;
2285                                 } else {
2286                                         if (chars > 0) {
2287                                                 throw new FormatException ("Additional unparsable "
2288                                                         + "characters are at the end of the string.");
2289                                         } else {
2290                                                 throw new FormatException ("Could not find any parsable"
2291                                                         + " digits.");
2292                                         }
2293                                 }
2294
2295                                 if (digitValue >= fromBase) {
2296                                         if (chars > 0) {
2297                                                 throw new FormatException ("Additional unparsable "
2298                                                         + "characters are at the end of the string.");
2299                                         } else {
2300                                                 throw new FormatException ("Could not find any parsable"
2301                                                         + " digits.");
2302                                         }
2303                                 }
2304
2305                                 result = (fromBase) * result + digitValue;
2306                                 chars ++;
2307                         }
2308
2309                         if (chars == 0)
2310                                 throw new FormatException ("Could not find any parsable digits.");
2311
2312                         if (negative)
2313                                 return -result;
2314                         else
2315                                 return result;
2316                 }
2317
2318                 // note: this has nothing to do with base64 encoding (just base and Int64)
2319                 private static long ConvertFromBase64 (string value, int fromBase, bool unsigned)
2320                 {
2321                         if (NotValidBase (fromBase))
2322                                 throw new ArgumentException ("fromBase is not valid.");
2323                         if (value == null)
2324                                 return 0;
2325
2326                         int chars = 0;
2327                         int digitValue = -1;
2328                         long result = 0;
2329                         bool negative = false;
2330
2331                         int i = 0;
2332                         int len = value.Length;
2333
2334                         // special processing for some bases
2335                         switch (fromBase) {
2336                                 case 10:
2337                                         if (value.Substring(i, 1) == "-") {
2338                                                 if (unsigned) {
2339                                                         throw new OverflowException (
2340                                                                 Locale.GetText ("The string was being parsed as"
2341                                                                 + " an unsigned number and could not have a"
2342                                                                 + " negative sign."));
2343                                                 }
2344                                                 negative = true;
2345                                                 i++;
2346                                         }
2347                                         break;
2348                                 case 16:
2349                                         if (value.Substring (i, 1) == "-") {
2350                                                 throw new ArgumentException ("String cannot contain a "
2351                                                         + "minus sign if the base is not 10.");
2352                                         }
2353                                         if (len >= i + 2) {
2354                                                 // 0x00 or 0X00
2355                                                 if ((value[i] == '0') && ((value[i + 1] == 'x') || (value[i + 1] == 'X'))) {
2356                                                         i += 2;
2357                                                 }
2358                                         }
2359                                         break;
2360                                 default:
2361                                         if (value.Substring (i, 1) == "-") {
2362                                                 throw new ArgumentException ("String cannot contain a "
2363                                                         + "minus sign if the base is not 10.");
2364                                         }
2365                                         break;
2366                         }
2367
2368                         if (len == i) {
2369                                 throw new FormatException ("Could not find any parsable digits.");
2370                         }
2371
2372                         if (value[i] == '+') {
2373                                 i++;
2374                         }
2375
2376                         while (i < len) {
2377                                 char c = value[i++];
2378                                 if (Char.IsNumber (c)) {
2379                                         digitValue = c - '0';
2380                                 } else if (Char.IsLetter (c)) {
2381                                         digitValue = Char.ToLowerInvariant (c) - 'a' + 10;
2382                                 } else {
2383                                         if (chars > 0) {
2384                                                 throw new FormatException ("Additional unparsable "
2385                                                         + "characters are at the end of the string.");
2386                                         } else {
2387                                                 throw new FormatException ("Could not find any parsable"
2388                                                         + " digits.");
2389                                         }
2390                                 }
2391
2392                                 if (digitValue >= fromBase) {
2393                                         if (chars > 0) {
2394                                                 throw new FormatException ("Additional unparsable "
2395                                                         + "characters are at the end of the string.");
2396                                         } else {
2397                                                 throw new FormatException ("Could not find any parsable"
2398                                                         + " digits.");
2399                                         }
2400                                 }
2401
2402                                 result = (fromBase * result + digitValue);
2403                                 chars ++;
2404                         }
2405
2406                         if (chars == 0)
2407                                 throw new FormatException ("Could not find any parsable digits.");
2408
2409                         if (negative)
2410                                 return -1 * result;
2411                         else
2412                                 return result;
2413                 }
2414
2415                 private static void EndianSwap (ref byte[] value)
2416                 {
2417                         byte[] buf = new byte[value.Length];
2418                         for (int i = 0; i < value.Length; i++)
2419                                 buf[i] = value[value.Length-1-i];
2420                         value = buf;
2421                 }
2422
2423                 private static string ConvertToBase2 (byte[] value)
2424                 {
2425                         if (!BitConverter.IsLittleEndian)
2426                                 EndianSwap (ref value);
2427                         StringBuilder sb = new StringBuilder ();
2428                         for (int i = value.Length - 1; i >= 0; i--) {
2429                                 byte b = value [i];
2430                                 for (int j = 0; j < 8; j++) {
2431                                         if ((b & 0x80) == 0x80) {
2432                                                 sb.Append ('1');
2433                                         }
2434                                         else {
2435                                                 if (sb.Length > 0)
2436                                                         sb.Append ('0');
2437                                         }
2438                                         b <<= 1;
2439                                 }
2440                         }
2441                         return sb.ToString ();
2442                 }
2443
2444                 private static string ConvertToBase8 (byte[] value)
2445                 {
2446                         ulong l = 0;
2447                         switch (value.Length) {
2448                         case 1:
2449                                 l = (ulong) value [0];
2450                                 break;
2451                         case 2:
2452                                 l = (ulong) BitConverter.ToUInt16 (value, 0);
2453                                 break;
2454                         case 4:
2455                                 l = (ulong) BitConverter.ToUInt32 (value, 0);
2456                                 break;
2457                         case 8:
2458                                 l = BitConverter.ToUInt64 (value, 0);
2459                                 break;
2460                         default:
2461                                 throw new ArgumentException ("value");
2462                         }
2463
2464                         StringBuilder sb = new StringBuilder ();
2465                         for (int i = 21; i >= 0; i--) {
2466                                 // 3 bits at the time
2467                                 char val = (char) ((l >> i * 3) & 0x7);
2468                                 if ((val != 0) || (sb.Length > 0)) {
2469                                         val += '0';
2470                                         sb.Append (val);
2471                                 }
2472                         }
2473                         return sb.ToString ();
2474                 }
2475
2476                 private static string ConvertToBase16 (byte[] value)
2477                 {
2478                         if (!BitConverter.IsLittleEndian)
2479                                 EndianSwap (ref value);
2480                         StringBuilder sb = new StringBuilder ();
2481                         for (int i = value.Length - 1; i >= 0; i--) {
2482                                 char high = (char)((value[i] >> 4) & 0x0f);
2483                                 if ((high != 0) || (sb.Length > 0)) {
2484                                         if (high < 10) 
2485                                                 high += '0';
2486                                         else {
2487                                                 high -= (char) 10;
2488                                                 high += 'a';
2489                                         }
2490                                         sb.Append (high);
2491                                 }
2492
2493                                 char low = (char)(value[i] & 0x0f);
2494                                 if ((low != 0) || (sb.Length > 0)) {
2495                                         if (low < 10)
2496                                                 low += '0';
2497                                         else {
2498                                                 low -= (char) 10;
2499                                                 low += 'a';
2500                                         }
2501                                         sb.Append (low);
2502                                 }
2503                         }
2504                         return sb.ToString ();
2505                 }
2506
2507                 // Lookup table for the conversion ToType method. Order
2508                 // is important! Used by ToType for comparing the target
2509                 // type, and uses hardcoded array indexes.
2510                 private static readonly Type[] conversionTable = {
2511                         // Valid ICovnertible Types
2512                         null,               //  0 empty
2513                         typeof (object),   //  1 TypeCode.Object
2514                         typeof (DBNull),   //  2 TypeCode.DBNull
2515                         typeof (Boolean),  //  3 TypeCode.Boolean
2516                         typeof (Char),     //  4 TypeCode.Char
2517                         typeof (SByte),    //  5 TypeCode.SByte
2518                         typeof (Byte),     //  6 TypeCode.Byte
2519                         typeof (Int16),    //  7 TypeCode.Int16
2520                         typeof (UInt16),   //  8 TypeCode.UInt16
2521                         typeof (Int32),    //  9 TypeCode.Int32
2522                         typeof (UInt32),   // 10 TypeCode.UInt32
2523                         typeof (Int64),    // 11 TypeCode.Int64
2524                         typeof (UInt64),   // 12 TypeCode.UInt64
2525                         typeof (Single),   // 13 TypeCode.Single
2526                         typeof (Double),   // 14 TypeCode.Double
2527                         typeof (Decimal),  // 15 TypeCode.Decimal
2528                         typeof (DateTime), // 16 TypeCode.DateTime
2529                         null,               // 17 null.
2530                         typeof (String),   // 18 TypeCode.String
2531                 };
2532
2533                 // Function to convert an object to another type and return
2534                 // it as an object. In place for the core data types to use
2535                 // when implementing IConvertible. Uses hardcoded indexes in 
2536                 // the conversionTypes array, so if modify carefully.
2537         
2538                 //
2539                 // The `try_target_to_type' boolean indicates if the code
2540                 // should try to call the IConvertible.ToType method if everything
2541                 // else fails.
2542                 //
2543                 // This should be true for invocations from Convert.cs, and
2544                 // false from the mscorlib types that implement IConvertible that 
2545                 // all into this internal function.
2546                 //
2547                 // This was added to keep the fix for #481687 working and to avoid
2548                 // the regression that the simple fix introduced (485377)
2549                 internal static object ToType (object value, Type conversionType, IFormatProvider provider, bool try_target_to_type) 
2550                 {
2551                         if (value == null) {
2552                                 if ((conversionType != null) && conversionType.IsValueType){
2553                                         throw new InvalidCastException ("Null object can not be converted to a value type.");
2554                                 } else
2555                                         return null;
2556                         }
2557
2558                         if (conversionType == null)
2559                                 throw new InvalidCastException ("Cannot cast to destination type.");
2560
2561                         if (value.GetType () == conversionType)
2562                                 return value;
2563                         
2564                         if (value is IConvertible) {
2565                                 IConvertible convertValue = (IConvertible) value;
2566
2567                                 if (conversionType == conversionTable[0]) // 0 Empty
2568                                         throw new ArgumentNullException ();
2569                                 
2570                                 else if (conversionType == conversionTable[1]) // 1 TypeCode.Object
2571                                         return (object) value;
2572                                         
2573                                 else if (conversionType == conversionTable[2]) // 2 TypeCode.DBNull
2574                                         throw new InvalidCastException (
2575                                                 "Cannot cast to DBNull, it's not IConvertible");
2576                   
2577                                 else if (conversionType == conversionTable[3]) // 3 TypeCode.Boolean
2578                                         return (object) convertValue.ToBoolean (provider);
2579                                         
2580                                 else if (conversionType == conversionTable[4]) // 4 TypeCode.Char
2581                                         return (object) convertValue.ToChar (provider);
2582                   
2583                                 else if (conversionType == conversionTable[5]) // 5 TypeCode.SByte
2584                                         return (object) convertValue.ToSByte (provider);
2585
2586                                 else if (conversionType == conversionTable[6]) // 6 TypeCode.Byte
2587                                         return (object) convertValue.ToByte (provider);
2588                                 
2589                                 else if (conversionType == conversionTable[7]) // 7 TypeCode.Int16
2590                                         return (object) convertValue.ToInt16 (provider);
2591                                         
2592                                 else if (conversionType == conversionTable[8]) // 8 TypeCode.UInt16
2593                                         return (object) convertValue.ToUInt16 (provider);
2594                   
2595                                 else if (conversionType == conversionTable[9]) // 9 TypeCode.Int32
2596                                         return (object) convertValue.ToInt32 (provider);
2597                         
2598                                 else if (conversionType == conversionTable[10]) // 10 TypeCode.UInt32
2599                                         return (object) convertValue.ToUInt32 (provider);
2600                   
2601                                 else if (conversionType == conversionTable[11]) // 11 TypeCode.Int64
2602                                         return (object) convertValue.ToInt64 (provider);
2603                   
2604                                 else if (conversionType == conversionTable[12]) // 12 TypeCode.UInt64
2605                                         return (object) convertValue.ToUInt64 (provider);
2606                   
2607                                 else if (conversionType == conversionTable[13]) // 13 TypeCode.Single
2608                                         return (object) convertValue.ToSingle (provider);
2609                   
2610                                 else if (conversionType == conversionTable[14]) // 14 TypeCode.Double
2611                                         return (object) convertValue.ToDouble (provider);
2612
2613                                 else if (conversionType == conversionTable[15]) // 15 TypeCode.Decimal
2614                                         return (object) convertValue.ToDecimal (provider);
2615
2616                                 else if (conversionType == conversionTable[16]) // 16 TypeCode.DateTime
2617                                         return (object) convertValue.ToDateTime (provider);
2618                                 
2619                                 else if (conversionType == conversionTable[18]) // 18 TypeCode.String
2620                                         return (object) convertValue.ToString (provider);
2621                                 else {
2622                                         if (try_target_to_type)
2623                                                 return convertValue.ToType (conversionType, provider);
2624                                 }
2625                         } 
2626                         // Not in the conversion table
2627                         throw new InvalidCastException ((Locale.GetText (
2628                                                                  "Value is not a convertible object: " + value.GetType().ToString() + " to " + conversionType.FullName)));
2629                 }
2630         }
2631 }