Merge pull request #819 from brendanzagaeski/patch-1
[mono.git] / mcs / class / corlib / System / Convert.cs
index 6f3e9e17fc666e6b2fb4f5c0829c798bf697cf04..5533bb396821dc846c901c26d5b89e9c6d8a70f3 100644 (file)
@@ -1,12 +1,13 @@
 //
 // System.Convert.cs
 //
-// Author:
+// Authors:
 //   Derek Holden (dholden@draper.com)
 //   Duncan Mak (duncan@ximian.com)
+//   Marek Safar (marek.safar@gmail.com)
 //
 // (C) Ximian, Inc.  http://www.ximian.com
-//
+// Copyright (C) 2013 Xamarin Inc (http://www.xamarin.com)
 //
 // System.Convert class. This was written word for word off the 
 // Library specification for System.Convert in the ECMA TC39 TG2 
@@ -100,18 +101,10 @@ using System.Runtime.InteropServices;
 namespace System {
   
 //     [CLSCompliant(false)]
-#if NET_2_0
        public static class Convert {
-#else
-       public sealed class Convert {
-               private Convert ()
-               {
-               }
-#endif
 
                // Fields
                public static readonly object DBNull = System.DBNull.Value;
-               static ToBase64Transform toBase64Transform = new ToBase64Transform();
        
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                extern static byte [] InternalFromBase64String (string str, bool allowWhitespaceOnly);
@@ -140,14 +133,10 @@ namespace System {
                                throw new ArgumentNullException ("s");
 
                        if (s.Length == 0) {
-                               return new byte[0];
+                               return EmptyArray<byte>.Value;
                        }
 
-#if NET_2_0
                        return InternalFromBase64String (s, true);
-#else
-                       return InternalFromBase64String (s, false);
-#endif
                }
 
                public static TypeCode GetTypeCode (object value)
@@ -180,7 +169,7 @@ namespace System {
                                throw new ArgumentOutOfRangeException ("offsetIn + length > array.Length");
 
                        // note: normally ToBase64Transform doesn't support multiple block processing
-                       byte[] outArr = toBase64Transform.InternalTransformFinalBlock (inArray, offsetIn, length);
+                       byte[] outArr = Base64Helper.TransformFinalBlock (inArray, offsetIn, length);
                        
                        char[] cOutArr = new ASCIIEncoding ().GetChars (outArr);
                        
@@ -212,12 +201,11 @@ namespace System {
                                throw new ArgumentOutOfRangeException ("offset + length > array.Length");
                        
                        // note: normally ToBase64Transform doesn't support multiple block processing
-                       byte[] outArr = toBase64Transform.InternalTransformFinalBlock (inArray, offset, length);
+                       byte[] outArr = Base64Helper.TransformFinalBlock (inArray, offset, length);
                        
                        return (new ASCIIEncoding ().GetString (outArr));
                }
 
-#if NET_2_0
                [ComVisible (false)]
                public static string ToBase64String (byte[] inArray, Base64FormattingOptions options)
                {
@@ -237,10 +225,13 @@ namespace System {
                        if (offset > inArray.Length - length)
                                throw new ArgumentOutOfRangeException ("offset + length > array.Length");
 
+                       if (length == 0)
+                               return String.Empty;
+
                        if (options == Base64FormattingOptions.InsertLineBreaks)
                                return ToBase64StringBuilderWithLine (inArray, offset, length).ToString ();
                        else
-                               return Encoding.ASCII.GetString (toBase64Transform.InternalTransformFinalBlock (inArray, offset, length));
+                               return Encoding.ASCII.GetString (Base64Helper.TransformFinalBlock (inArray, offset, length));
                }
 
                [ComVisible (false)]
@@ -257,13 +248,16 @@ namespace System {
                        if (offsetIn > inArray.Length - length)
                                throw new ArgumentOutOfRangeException ("offsetIn + length > array.Length");
 
+                       if (length == 0)
+                               return 0;
+
                        // note: normally ToBase64Transform doesn't support multiple block processing
                        if (options == Base64FormattingOptions.InsertLineBreaks) {
                                StringBuilder sb = ToBase64StringBuilderWithLine (inArray, offsetIn, length);
                                sb.CopyTo (0, outArray, offsetOut, sb.Length);
                                return sb.Length;
                        } else {
-                               byte[] outArr = toBase64Transform.InternalTransformFinalBlock (inArray, offsetIn, length);
+                               byte[] outArr = Base64Helper.TransformFinalBlock (inArray, offsetIn, length);
                        
                                char[] cOutArr = Encoding.ASCII.GetChars (outArr);
                        
@@ -276,23 +270,29 @@ namespace System {
                        }
                }
 
+               private const int MaxBytesPerLine = 57;
+
                static StringBuilder ToBase64StringBuilderWithLine (byte [] inArray, int offset, int length)
                {
-                       BinaryReader reader = new BinaryReader (new MemoryStream (inArray, offset, length));
-                       byte[] b = null;
-
                        StringBuilder sb = new StringBuilder ();
-                       do {
-                               // 54 bytes of input makes for 72 bytes of output.
-                               b = reader.ReadBytes (54);
-                               if (b.Length > 0)
-                                       sb.AppendLine (Encoding.ASCII.GetString (toBase64Transform.InternalTransformFinalBlock (b, 0, b.Length)));
-                       } while (b.Length > 0);
+
+                       int remainder;
+                       int full = Math.DivRem (length, MaxBytesPerLine, out remainder);
+                       for (int i = 0; i < full; i ++) {
+                               byte[] data = Base64Helper.TransformFinalBlock (inArray, offset, MaxBytesPerLine);
+                               sb.AppendLine (Encoding.ASCII.GetString (data));
+                               offset += MaxBytesPerLine;
+                       }
+                       // we never complete (i.e. the last line) with a new line
+                       if (remainder == 0) {
+                               int nll = Environment.NewLine.Length;
+                               sb.Remove (sb.Length - nll, nll);
+                       } else {
+                               byte[] data = Base64Helper.TransformFinalBlock (inArray, offset, remainder);
+                               sb.Append (Encoding.ASCII.GetString (data));
+                       }
                        return sb;
                }
-#endif
-
-
                
                // ========== Boolean Conversions ========== //
        
@@ -414,11 +414,7 @@ namespace System {
 
                public static byte ToByte (char value) 
                { 
-                       if (value > Byte.MaxValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Byte.MaxValue"));
-
-                       return (byte)value;
+                       return checked ((byte) value);
                }
 
                public static byte ToByte (DateTime value)
@@ -428,82 +424,42 @@ namespace System {
        
                public static byte ToByte (decimal value)
                { 
-                       if (value > Byte.MaxValue || value < Byte.MinValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Byte.MaxValue or less than Byte.MinValue"));
-         
                        // Returned Even-Rounded
-                       return (byte)(Math.Round (value));
+                       return checked ((byte) Math.Round (value));
                }
        
                public static byte ToByte (double value) 
                { 
-                       if (value > Byte.MaxValue || value < Byte.MinValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Byte.MaxValue or less than Byte.MinValue"));
-         
-                       // This and the float version of ToByte are the only ones
-                       // the spec listed as checking for .NaN and Infinity overflow
-                       if (Double.IsNaN(value) || Double.IsInfinity(value))
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is equal to Double.NaN, Double.PositiveInfinity, or Double.NegativeInfinity"));
-
                        // Returned Even-Rounded
-                       return (byte)(Math.Round (value));
+                       return checked ((byte) Math.Round (value));
                }
 
                public static byte ToByte (float value) 
                { 
-                       if (value > Byte.MaxValue || value < Byte.MinValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Byte.MaxValue or less than Byte.Minalue"));
-
-                       // This and the double version of ToByte are the only ones
-                       // the spec listed as checking for .NaN and Infinity overflow
-                       if (Single.IsNaN(value) || Single.IsInfinity(value))
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is equal to Single.NaN, Single.PositiveInfinity, or Single.NegativeInfinity"));
-         
                        // Returned Even-Rounded, pass it as a double, could have this
                        // method just call Convert.ToByte ( (double)value)
-                       return (byte)(Math.Round ( (double)value));
+                       return checked ((byte) Math.Round (value));
                }
 
                public static byte ToByte (int value) 
                { 
-                       if (value > Byte.MaxValue || value < Byte.MinValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Byte.MaxValue or less than Byte.MinValue"));
-         
-                       return (byte)value; 
+                       return checked ((byte) value); 
                }
 
                public static byte ToByte (long value) 
                { 
-                       if (value > Byte.MaxValue || value < Byte.MinValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Byte.MaxValue or less than Byte.MinValue"));
-         
-                       return (byte)value;
+                       return checked ((byte) value);
                }
 
                [CLSCompliant (false)]
                public static byte ToByte (sbyte value) 
                { 
-                       if (value < Byte.MinValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is less than Byte.MinValue"));
-         
-                       return (byte)value;
+                       return checked ((byte) value);
                }
        
                public static byte ToByte (short value) 
                { 
-                       if (value > Byte.MaxValue || value < Byte.MinValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Byte.MaxValue or less than Byte.MinValue"));
-         
-                       return (byte)value; 
+                       return checked ((byte) value);
                }
 
                public static byte ToByte (string value) 
@@ -524,40 +480,25 @@ namespace System {
                {
                        int retVal = ConvertFromBase (value, fromBase, true);
 
-                       if (retVal < (int) Byte.MinValue || retVal > (int) Byte.MaxValue)
-                               throw new OverflowException ();
-                       else
-                               return (byte) retVal;
+                       return checked ((byte) retVal);
                }
 
                [CLSCompliant (false)]
                public static byte ToByte (uint value) 
                { 
-                       if (value > Byte.MaxValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Byte.MaxValue"));
-
-                       return (byte)value;
+                       return checked ((byte) value);
                }
 
                [CLSCompliant (false)]
                public static byte ToByte (ulong value) 
                { 
-                       if (value > Byte.MaxValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Byte.MaxValue"));
-
-                       return (byte)value;
+                       return checked ((byte) value);
                }
 
                [CLSCompliant (false)]
                public static byte ToByte (ushort value) 
                { 
-                       if (value > Byte.MaxValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Byte.MaxValue"));
-
-                       return (byte)value;
+                       return checked ((byte) value);
                }
 
                public static byte ToByte (object value)
@@ -608,20 +549,12 @@ namespace System {
                
                public static char ToChar (int value) 
                { 
-                       if (value > Char.MaxValue || value < Char.MinValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Char.MaxValue or less than Char.MinValue"));
-         
-                       return (char)value; 
+                       return checked ((char) value);
                }
 
                public static char ToChar (long value) 
                { 
-                       if (value > Char.MaxValue || value < Char.MinValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Char.MaxValue or less than Char.MinValue"));
-         
-                       return (char)value; 
+                       return checked ((char) value);
                }
 
                public static char ToChar (float value)
@@ -632,20 +565,12 @@ namespace System {
                [CLSCompliant (false)]
                public static char ToChar (sbyte value) 
                { 
-                       if (value < Char.MinValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is less than Char.MinValue"));
-         
-                       return (char)value; 
+                       return checked ((char) value);
                }
        
                public static char ToChar (short value) 
                { 
-                       if (value < Char.MinValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is less than Char.MinValue"));
-         
-                       return (char)value; 
+                       return checked ((char) value);
                }
 
                public static char ToChar (string value) 
@@ -661,21 +586,13 @@ namespace System {
                [CLSCompliant (false)]
                public static char ToChar (uint value) 
                { 
-                       if (value > Char.MaxValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Char.MaxValue"));
-         
-                       return (char)value; 
+                       return checked ((char) value);
                }
 
                [CLSCompliant (false)]
                public static char ToChar (ulong value) 
                { 
-                       if (value > Char.MaxValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Char.MaxValue"));
-         
-                       return (char)value; 
+                       return checked ((char) value);
                }
 
                [CLSCompliant (false)]
@@ -1024,11 +941,7 @@ namespace System {
 
                public static short ToInt16 (char value) 
                {
-                       if (value > Int16.MaxValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Int16.MaxValue"));
-
-                       return (short)value;
+                       return checked ((short) value);
                }
 
                public static short ToInt16 (DateTime value) 
@@ -1038,56 +951,36 @@ namespace System {
        
                public static short ToInt16 (decimal value) 
                { 
-                       if (value > Int16.MaxValue || value < Int16.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Int16.MaxValue or less than Int16.MinValue"));
-         
                        // Returned Even-Rounded
-                       return (short)(Math.Round (value));       
+                       return checked ((short) Math.Round (value));
                }
 
                public static short ToInt16 (double value) 
                { 
-                       if (value > Int16.MaxValue || value < Int16.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Int16.MaxValue or less than Int16.MinValue"));
-         
                        // Returned Even-Rounded
-                       return (short)(Math.Round (value));       
+                       return checked ((short) Math.Round (value));
                }
  
                public static short ToInt16 (float value) 
                { 
-                       if (value > Int16.MaxValue || value < Int16.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Int16.MaxValue or less than Int16.MinValue"));
-         
                        // Returned Even-Rounded, use Math.Round pass as a double.
-                       return (short)Math.Round ( (double)value);
+                       return checked ((short) Math.Round (value));
                }
 
                public static short ToInt16 (int value) 
                { 
-                       if (value > Int16.MaxValue || value < Int16.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Int16.MaxValue or less than Int16.MinValue"));
-
-                       return (short)value; 
+                       return checked ((short) value);
                }
        
                public static short ToInt16 (long value) 
                { 
-                       if (value > Int16.MaxValue || value < Int16.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Int16.MaxValue or less than Int16.MinValue"));
-
-                       return (short)value; 
+                       return checked ((short) value);
                }
 
                [CLSCompliant (false)]
                public static short ToInt16 (sbyte value) 
                { 
-                       return (short)value; 
+                       return value; 
                }
        
                public static short ToInt16 (short value) 
@@ -1129,30 +1022,19 @@ namespace System {
                [CLSCompliant (false)]
                public static short ToInt16 (uint value) 
                { 
-                       if (value > Int16.MaxValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Int16.MaxValue"));
-
-                       return (short)value; 
+                       return checked ((short) value);
                }
 
                [CLSCompliant (false)]
                public static short ToInt16 (ulong value) 
                { 
-                       if (value > (ulong)Int16.MaxValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Int16.MaxValue"));
-                       return (short)value; 
+                       return checked ((short) value);
                }
 
                [CLSCompliant (false)]
                public static short ToInt16 (ushort value) 
                { 
-                       if (value > Int16.MaxValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Int16.MaxValue"));
-
-                       return (short)value; 
+                       return checked ((short) value);
                }
 
                public static short ToInt16 (object value)
@@ -1193,22 +1075,16 @@ namespace System {
        
                public static int ToInt32 (decimal value) 
                { 
-                       if (value > Int32.MaxValue || value < Int32.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Int32.MaxValue or less than Int32.MinValue"));
-
                        // Returned Even-Rounded
-                       return (int)(Math.Round (value));         
+                       return checked ((int) Math.Round (value));
                }
 
                public static int ToInt32 (double value) 
                { 
-                       if (value > Int32.MaxValue || value < Int32.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Int32.MaxValue or less than Int32.MinValue"));
-         
                        // Returned Even-Rounded
-                       return (int)(Math.Round (value));         
+                       checked {
+                               return (int)(Math.Round (value));
+                       }
                }
  
                public static int ToInt32 (float value) 
@@ -1219,7 +1095,9 @@ namespace System {
          
                        // Returned Even-Rounded, pass as a double, could just call
                        // Convert.ToInt32 ( (double)value);
-                       return (int)(Math.Round ( (double)value));
+                       checked {
+                               return (int)(Math.Round ( (double)value));
+                       }
                }
 
                public static int ToInt32 (int value) 
@@ -1229,11 +1107,7 @@ namespace System {
        
                public static int ToInt32 (long value) 
                { 
-                       if (value > Int32.MaxValue || value < Int32.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Int32.MaxValue or less than Int32.MinValue"));
-
-                       return (int)value; 
+                       return checked ((int) value);
                }
 
                [CLSCompliant (false)]
@@ -1270,21 +1144,13 @@ namespace System {
                [CLSCompliant (false)]
                public static int ToInt32 (uint value) 
                { 
-                       if (value > Int32.MaxValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Int32.MaxValue"));
-
-                       return (int)value; 
+                       return checked ((int) value);
                }
 
                [CLSCompliant (false)]
                public static int ToInt32 (ulong value) 
                { 
-                       if (value > Int32.MaxValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Int32.MaxValue"));
-
-                       return (int)value; 
+                       return checked ((int) value);
                }
 
                [CLSCompliant (false)]
@@ -1331,33 +1197,21 @@ namespace System {
        
                public static long ToInt64 (decimal value) 
                { 
-                       if (value > Int64.MaxValue || value < Int64.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Int64.MaxValue or less than Int64.MinValue"));
-         
                        // Returned Even-Rounded
-                       return (long)(Math.Round (value));        
+                       return checked ((long) Math.Round (value));
                }
 
                public static long ToInt64 (double value) 
                { 
-                       if (value > Int64.MaxValue || value < Int64.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Int64.MaxValue or less than Int64.MinValue"));
-         
                        // Returned Even-Rounded
-                       return (long)(Math.Round (value));
+                       return checked ((long) Math.Round (value));
                }
  
                public static long ToInt64 (float value) 
                { 
-                       if (value > Int64.MaxValue || value < Int64.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Int64.MaxValue or less than Int64.MinValue"));
-         
                        // Returned Even-Rounded, pass to Math as a double, could
                        // just call Convert.ToInt64 ( (double)value);
-                       return (long)(Math.Round ( (double)value));
+                       return checked ((long) Math.Round (value));
                }
 
                public static long ToInt64 (int value) 
@@ -1409,11 +1263,7 @@ namespace System {
                [CLSCompliant (false)]
                public static long ToInt64 (ulong value) 
                { 
-                       if (value > Int64.MaxValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than Int64.MaxValue"));
-
-                       return (long)value; 
+                       return checked ((long) value);
                }
 
                [CLSCompliant (false)]
@@ -1447,21 +1297,13 @@ namespace System {
                [CLSCompliant (false)]
                public static sbyte ToSByte (byte value) 
                { 
-                       if (value > SByte.MaxValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than SByte.MaxValue"));
-
-                       return (sbyte)value; 
+                       return checked ((sbyte) value);
                }
 
                [CLSCompliant (false)]
                public static sbyte ToSByte (char value) 
                { 
-                       if (value > SByte.MaxValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than SByte.MaxValue"));
-
-                       return (sbyte)value;
+                       return checked ((sbyte) value);
                }
 
                [CLSCompliant (false)]
@@ -1473,54 +1315,34 @@ namespace System {
                [CLSCompliant (false)]  
                public static sbyte ToSByte (decimal value) 
                { 
-                       if (value > SByte.MaxValue || value < SByte.MinValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than SByte.MaxValue or less than SByte.MinValue"));
-         
                        // Returned Even-Rounded
-                       return (sbyte)(Math.Round (value));
+                       return checked ((sbyte) Math.Round (value));
                }
 
                [CLSCompliant (false)]
                public static sbyte ToSByte (double value) 
                { 
-                       if (value > SByte.MaxValue || value < SByte.MinValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than SByte.MaxValue or less than SByte.MinValue"));
-
                        // Returned Even-Rounded
-                       return (sbyte)(Math.Round (value));
+                       return checked ((sbyte) Math.Round (value));
                }
 
                [CLSCompliant (false)]
                public static sbyte ToSByte (float value) 
                { 
-                       if (value > SByte.MaxValue || value < SByte.MinValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than SByte.MaxValue or less than SByte.Minalue"));
-
                        // Returned Even-Rounded, pass as double to Math
-                       return (sbyte)(Math.Round ( (double)value));
+                       return checked ((sbyte) Math.Round (value));
                }
 
                [CLSCompliant (false)]
                public static sbyte ToSByte (int value) 
                { 
-                       if (value > SByte.MaxValue || value < SByte.MinValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than SByte.MaxValue or less than SByte.MinValue"));
-         
-                       return (sbyte)value; 
+                       return checked ((sbyte) value);
                }
 
                [CLSCompliant (false)]
                public static sbyte ToSByte (long value) 
                { 
-                       if (value > SByte.MaxValue || value < SByte.MinValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than SByte.MaxValue or less than SByte.MinValue"));
-         
-                       return (sbyte)value;
+                       return checked ((sbyte) value);
                }
 
                [CLSCompliant (false)]
@@ -1532,11 +1354,7 @@ namespace System {
                [CLSCompliant (false)]
                public static sbyte ToSByte (short value) 
                { 
-                       if (value > SByte.MaxValue || value < SByte.MinValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than SByte.MaxValue or less than SByte.MinValue"));
-         
-                       return (sbyte)value; 
+                       return checked ((sbyte) value);
                }
 
                [CLSCompliant (false)]
@@ -1572,31 +1390,19 @@ namespace System {
                [CLSCompliant (false)]
                public static sbyte ToSByte (uint value) 
                { 
-                       if (value > SByte.MaxValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than SByte.MaxValue"));
-
-                       return (sbyte)value;
+                       return checked ((sbyte) value);
                }
 
                [CLSCompliant (false)]
                public static sbyte ToSByte (ulong value) 
                { 
-                       if (value > (ulong)SByte.MaxValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than SByte.MaxValue"));
-
-                       return (sbyte)value;
+                       return checked ((sbyte) value);
                }
 
                [CLSCompliant (false)]
                public static sbyte ToSByte (ushort value) 
                { 
-                       if (value > SByte.MaxValue)
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than SByte.MaxValue"));
-
-                       return (sbyte)value;
+                       return checked ((sbyte) value);
                }
 
                [CLSCompliant (false)]
@@ -2007,74 +1813,46 @@ namespace System {
                [CLSCompliant (false)]
                public static ushort ToUInt16 (decimal value) 
                { 
-                       if (value > UInt16.MaxValue || value < UInt16.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than UInt16.MaxValue or less than UInt16.MinValue"));
-         
                        // Returned Even-Rounded
-                       return (ushort)(Math.Round (value));      
+                       return checked ((ushort) Math.Round (value));
                }
 
                [CLSCompliant (false)]
                public static ushort ToUInt16 (double value) 
                { 
-                       if (value > UInt16.MaxValue || value < UInt16.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than UInt16.MaxValue or less than UInt16.MinValue"));
-         
                        // Returned Even-Rounded
-                       return (ushort)(Math.Round (value));
+                       return checked ((ushort) Math.Round (value));
                }
 
                [CLSCompliant (false)]
                public static ushort ToUInt16 (float value) 
                { 
-                       if (value > UInt16.MaxValue || value < UInt16.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than UInt16.MaxValue or less than UInt16.MinValue"));
-         
                        // Returned Even-Rounded, pass as double to Math
-                       return (ushort)(Math.Round ( (double)value));
+                       return checked ((ushort) Math.Round (value));
                }
 
                [CLSCompliant (false)]
                public static ushort ToUInt16 (int value) 
                { 
-                       if (value > UInt16.MaxValue || value < UInt16.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than UInt16.MaxValue or less than UInt16.MinValue"));
-
-                       return (ushort)value; 
+                       return checked ((ushort) value);
                }
 
                [CLSCompliant (false)]
                public static ushort ToUInt16 (long value) 
                { 
-                       if (value > UInt16.MaxValue || value < UInt16.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than UInt16.MaxValue or less than UInt16.MinValue"));
-
-                       return (ushort)value; 
+                       return checked ((ushort) value);
                }
 
                [CLSCompliant (false)]
                public static ushort ToUInt16 (sbyte value) 
                { 
-                       if (value < UInt16.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is less than UInt16.MinValue"));
-
-                       return (ushort)value; 
+                       return checked ((ushort) value);
                }
 
                [CLSCompliant (false)]
                public static ushort ToUInt16 (short value) 
                { 
-                       if (value < UInt16.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is less than UInt16.MinValue"));
-
-                       return (ushort)value; 
+                       return checked ((ushort) value);
                }
                
                [CLSCompliant (false)]
@@ -2102,21 +1880,13 @@ namespace System {
                [CLSCompliant (false)]
                public static ushort ToUInt16 (uint value) 
                { 
-                       if (value > UInt16.MaxValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than UInt16.MaxValue"));
-
-                       return (ushort)value; 
+                       return checked ((ushort) value);
                }
 
                [CLSCompliant (false)]
                public static ushort ToUInt16 (ulong value) 
                { 
-                       if (value > (ulong)UInt16.MaxValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than UInt16.MaxValue"));
-
-                       return (ushort)value; 
+                       return checked ((ushort) value);
                }
 
                [CLSCompliant (false)]
@@ -2170,74 +1940,46 @@ namespace System {
                [CLSCompliant (false)]
                public static uint ToUInt32 (decimal value) 
                { 
-                       if (value > UInt32.MaxValue || value < UInt32.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than UInt32.MaxValue or less than UInt32.MinValue"));
-         
                        // Returned Even-Rounded
-                       return (uint)(Math.Round (value));        
+                       return checked ((uint) Math.Round (value));
                }
 
                [CLSCompliant (false)]
                public static uint ToUInt32 (double value) 
                { 
-                       if (value > UInt32.MaxValue || value < UInt32.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than UInt32.MaxValue or less than UInt32.MinValue"));
-         
                        // Returned Even-Rounded
-                       return (uint)(Math.Round (value));        
+                       return checked ((uint) Math.Round (value));
                }
 
                [CLSCompliant (false)]
                public static uint ToUInt32 (float value) 
                { 
-                       if (value > UInt32.MaxValue || value < UInt32.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than UInt32.MaxValue or less than UInt32.MinValue"));
-         
                        // Returned Even-Rounded, pass as double to Math
-                       return (uint)(Math.Round ( (double)value));
+                       return checked ((uint) Math.Round (value));
                }
 
                [CLSCompliant (false)]
                public static uint ToUInt32 (int value) 
                { 
-                       if (value < UInt32.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is less than UInt32.MinValue"));
-
-                       return (uint)value; 
+                       return checked ((uint) value);
                }
 
                [CLSCompliant (false)]
                public static uint ToUInt32 (long value) 
                { 
-                       if (value > UInt32.MaxValue || value < UInt32.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than UInt32.MaxValue or less than UInt32.MinValue"));
-
-                       return (uint)value; 
+                       return checked ((uint) value);
                }
 
                [CLSCompliant (false)]
                public static uint ToUInt32 (sbyte value) 
                { 
-                       if (value < UInt32.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is less than UInt32.MinValue"));
-
-                       return (uint)value; 
+                       return checked ((uint) value);
                }
 
                [CLSCompliant (false)]
                public static uint ToUInt32 (short value) 
                { 
-                       if (value < UInt32.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is less than UInt32.MinValue"));
-
-                       return (uint)value; 
+                       return checked ((uint) value);
                }
 
                [CLSCompliant (false)]
@@ -2271,11 +2013,7 @@ namespace System {
                [CLSCompliant (false)]
                public static uint ToUInt32 (ulong value) 
                { 
-                       if (value > UInt32.MaxValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than UInt32.MaxValue"));
-
-                       return (uint)value; 
+                       return checked ((uint) value);
                }
 
                [CLSCompliant (false)]
@@ -2330,74 +2068,46 @@ namespace System {
                [CLSCompliant (false)]
                public static ulong ToUInt64 (decimal value) 
                { 
-                       if (value > UInt64.MaxValue || value < UInt64.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than UInt64.MaxValue or less than UInt64.MinValue"));
-         
                        // Returned Even-Rounded
-                       return (ulong)(Math.Round (value));       
+                       return checked ((ulong) Math.Round (value));
                }
 
                [CLSCompliant (false)]
                public static ulong ToUInt64 (double value) 
                { 
-                       if (value > UInt64.MaxValue || value < UInt64.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than UInt64.MaxValue or less than UInt64.MinValue"));
-         
                        // Returned Even-Rounded
-                       return (ulong)(Math.Round (value));       
+                       return checked ((ulong) Math.Round (value));
                }
                
                [CLSCompliant (false)] 
                public static ulong ToUInt64 (float value) 
                { 
-                       if (value > UInt64.MaxValue || value < UInt64.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is greater than UInt64.MaxValue or less than UInt64.MinValue"));
-         
                        // Returned Even-Rounded, pass as a double to Math
-                       return (ulong)(Math.Round ( (double)value));
+                       return checked ((ulong) Math.Round (value));
                }
                
                [CLSCompliant (false)]
                public static ulong ToUInt64 (int value) 
                { 
-                       if (value < (int)UInt64.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is less than UInt64.MinValue"));
-
-                       return (ulong)value; 
+                       return checked ((ulong) value);
                }
                
                [CLSCompliant (false)]
                public static ulong ToUInt64 (long value) 
                { 
-                       if (value < (long)UInt64.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is less than UInt64.MinValue"));
-
-                       return (ulong)value; 
+                       return checked ((ulong) value);
                }
 
                [CLSCompliant (false)]
                public static ulong ToUInt64 (sbyte value) 
                { 
-                       if (value < (sbyte)UInt64.MinValue) 
-                               throw new OverflowException
-                               ("Value is less than UInt64.MinValue");
-
-                       return (ulong)value; 
+                       return checked ((ulong) value);
                }
                
                [CLSCompliant (false)]  
                public static ulong ToUInt64 (short value) 
                { 
-                       if (value < (short)UInt64.MinValue) 
-                               throw new OverflowException (Locale.GetText (
-                                       "Value is less than UInt64.MinValue"));
-
-                       return (ulong)value; 
+                       return checked ((ulong) value);
                }
 
                [CLSCompliant (false)]
@@ -2471,7 +2181,7 @@ namespace System {
                        else {
                                provider = ci.NumberFormat;
                        }
-                       return ToType (value, conversionType, provider);
+                       return ToType (value, conversionType, provider, true);
                }
                
                public static object ChangeType (object value, TypeCode typeCode)
@@ -2485,20 +2195,20 @@ namespace System {
                        else {
                                provider = ci.NumberFormat;
                        }
-                       return ToType (value, conversionType, provider);
+                       return ToType (value, conversionType, provider, true);
                }
 
                public static object ChangeType (object value, Type conversionType, IFormatProvider provider)
                {
                        if ((value != null) && (conversionType == null))
                                throw new ArgumentNullException ("conversionType");
-                       return ToType (value, conversionType, provider);
+                       return ToType (value, conversionType, provider, true);
                }
                
                public static object ChangeType (object value, TypeCode typeCode, IFormatProvider provider)
                {
                        Type conversionType = conversionTable [(int)typeCode];
-                       return ToType (value, conversionType, provider);
+                       return ToType (value, conversionType, provider, true);
                }
 
                private static bool NotValidBase (int value)
@@ -2690,7 +2400,7 @@ namespace System {
                                        }
                                }
 
-                               result = (fromBase * result + digitValue);
+                               result = fromBase * result + digitValue;
                                chars ++;
                        }
 
@@ -2819,25 +2529,30 @@ namespace System {
                        typeof (DateTime), // 16 TypeCode.DateTime
                        null,               // 17 null.
                        typeof (String),   // 18 TypeCode.String
+                       typeof (Enum)
                };
 
                // Function to convert an object to another type and return
                // it as an object. In place for the core data types to use
                // when implementing IConvertible. Uses hardcoded indexes in 
                // the conversionTypes array, so if modify carefully.
-               internal static object ToType (object value, Type conversionType, 
-                                              IFormatProvider provider) 
+       
+               //
+               // The `try_target_to_type' boolean indicates if the code
+               // should try to call the IConvertible.ToType method if everything
+               // else fails.
+               //
+               // This should be true for invocations from Convert.cs, and
+               // false from the mscorlib types that implement IConvertible that 
+               // all into this internal function.
+               //
+               // This was added to keep the fix for #481687 working and to avoid
+               // the regression that the simple fix introduced (485377)
+               internal static object ToType (object value, Type conversionType, IFormatProvider provider, bool try_target_to_type) 
                {
                        if (value == null) {
                                if ((conversionType != null) && conversionType.IsValueType){
-#if NET_2_0
                                        throw new InvalidCastException ("Null object can not be converted to a value type.");
-#else
-                                       //
-                                       // Bug compatibility with 1.0
-                                       //
-                                       throw new NullReferenceException ("Null object can not be converted to a value type.");
-#endif
                                } else
                                        return null;
                        }
@@ -2848,72 +2563,73 @@ namespace System {
                        if (value.GetType () == conversionType)
                                return value;
                        
-                       if (value is IConvertible) {
-                               IConvertible convertValue = (IConvertible) value;
+                       IConvertible convertValue = value as IConvertible;
+                       if (convertValue != null) {
 
                                if (conversionType == conversionTable[0]) // 0 Empty
                                        throw new ArgumentNullException ();
                                
-                               else if (conversionType == conversionTable[1]) // 1 TypeCode.Object
-                                       return (object) value;
+                               if (conversionType == conversionTable[1]) // 1 TypeCode.Object
+                                       return value;
                                        
-                               else if (conversionType == conversionTable[2]) // 2 TypeCode.DBNull
+                               if (conversionType == conversionTable[2]) // 2 TypeCode.DBNull
                                        throw new InvalidCastException (
                                                "Cannot cast to DBNull, it's not IConvertible");
                  
-                               else if (conversionType == conversionTable[3]) // 3 TypeCode.Boolean
-                                       return (object) convertValue.ToBoolean (provider);
+                               if (conversionType == conversionTable[3]) // 3 TypeCode.Boolean
+                                       return convertValue.ToBoolean (provider);
                                        
-                               else if (conversionType == conversionTable[4]) // 4 TypeCode.Char
-                                       return (object) convertValue.ToChar (provider);
+                               if (conversionType == conversionTable[4]) // 4 TypeCode.Char
+                                       return convertValue.ToChar (provider);
                  
-                               else if (conversionType == conversionTable[5]) // 5 TypeCode.SByte
-                                       return (object) convertValue.ToSByte (provider);
+                               if (conversionType == conversionTable[5]) // 5 TypeCode.SByte
+                                       return convertValue.ToSByte (provider);
 
-                               else if (conversionType == conversionTable[6]) // 6 TypeCode.Byte
-                                       return (object) convertValue.ToByte (provider);
+                               if (conversionType == conversionTable[6]) // 6 TypeCode.Byte
+                                       return convertValue.ToByte (provider);
                                
-                               else if (conversionType == conversionTable[7]) // 7 TypeCode.Int16
-                                       return (object) convertValue.ToInt16 (provider);
+                               if (conversionType == conversionTable[7]) // 7 TypeCode.Int16
+                                       return convertValue.ToInt16 (provider);
                                        
-                               else if (conversionType == conversionTable[8]) // 8 TypeCode.UInt16
-                                       return (object) convertValue.ToUInt16 (provider);
+                               if (conversionType == conversionTable[8]) // 8 TypeCode.UInt16
+                                       return convertValue.ToUInt16 (provider);
                  
-                               else if (conversionType == conversionTable[9]) // 9 TypeCode.Int32
-                                       return (object) convertValue.ToInt32 (provider);
+                               if (conversionType == conversionTable[9]) // 9 TypeCode.Int32
+                                       return convertValue.ToInt32 (provider);
                        
-                               else if (conversionType == conversionTable[10]) // 10 TypeCode.UInt32
-                                       return (object) convertValue.ToUInt32 (provider);
+                               if (conversionType == conversionTable[10]) // 10 TypeCode.UInt32
+                                       return convertValue.ToUInt32 (provider);
                  
-                               else if (conversionType == conversionTable[11]) // 11 TypeCode.Int64
-                                       return (object) convertValue.ToInt64 (provider);
+                               if (conversionType == conversionTable[11]) // 11 TypeCode.Int64
+                                       return convertValue.ToInt64 (provider);
                  
-                               else if (conversionType == conversionTable[12]) // 12 TypeCode.UInt64
-                                       return (object) convertValue.ToUInt64 (provider);
+                               if (conversionType == conversionTable[12]) // 12 TypeCode.UInt64
+                                       return convertValue.ToUInt64 (provider);
                  
-                               else if (conversionType == conversionTable[13]) // 13 TypeCode.Single
-                                       return (object) convertValue.ToSingle (provider);
+                               if (conversionType == conversionTable[13]) // 13 TypeCode.Single
+                                       return convertValue.ToSingle (provider);
                  
-                               else if (conversionType == conversionTable[14]) // 14 TypeCode.Double
-                                       return (object) convertValue.ToDouble (provider);
+                               if (conversionType == conversionTable[14]) // 14 TypeCode.Double
+                                       return convertValue.ToDouble (provider);
 
-                               else if (conversionType == conversionTable[15]) // 15 TypeCode.Decimal
-                                       return (object) convertValue.ToDecimal (provider);
+                               if (conversionType == conversionTable[15]) // 15 TypeCode.Decimal
+                                       return convertValue.ToDecimal (provider);
 
-                               else if (conversionType == conversionTable[16]) // 16 TypeCode.DateTime
-                                       return (object) convertValue.ToDateTime (provider);
+                               if (conversionType == conversionTable[16]) // 16 TypeCode.DateTime
+                                       return convertValue.ToDateTime (provider);
                                
-                               else if (conversionType == conversionTable[18]) // 18 TypeCode.String
-                                       return (object) convertValue.ToString (provider);
-                               else {
-                                       throw new InvalidCastException (
-                                               String.Format (Locale.GetText ("Unknown target convertion type from {0} to {1}"), 
-                                                              value.GetType (), conversionType));
-                               }
-                       } else
-                               // Not in the conversion table
-                               throw new InvalidCastException ((Locale.GetText (
-                                       "Value is not a convertible object: " + value.GetType().ToString() + " to " + conversionType.FullName)));
+                               if (conversionType == conversionTable[18]) // 18 TypeCode.String
+                                       return convertValue.ToString (provider);
+
+                               if (conversionType == conversionTable[19] && value is Enum) // System.Enum
+                                       return value;
+
+                               if (try_target_to_type)
+                                       return convertValue.ToType (conversionType, provider);
+                       } 
+                       // Not in the conversion table
+                       throw new InvalidCastException ((Locale.GetText (
+                                                                "Value is not a convertible object: " + value.GetType().ToString() + " to " + conversionType.FullName)));
                }
        }
 }