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