context: // EnumTest.cs - NUnit Test Cases for the System.Enum class
  //
  // David Brandt (bucky@keystreams.com)
  // Gert Driesen (drieseng@users.sourceforge.net)
  //
  // (C) Ximian, Inc.  http://www.ximian.com
  // 
  
  using System;
  using System.IO;
  using System.Reflection;
  
  using NUnit.Framework;
  
  namespace MonoTests.System
  {
  	[TestFixture]
  	public class EnumTest
  	{
  		[Test]
  		public void TestCompareTo ()
  		{
  			Enum e1 = new TestingEnum ();
  			Enum e2 = new TestingEnum ();
  			Enum e3 = new TestingEnum2 ();
  
  			Assert.AreEqual (0, e1.CompareTo (e1), "#A1");
  			Assert.AreEqual (0, e1.CompareTo (e2), "#A2");
  
  			TestingEnum x = TestingEnum.This;
  			TestingEnum y = TestingEnum.Is;
  			Assert.AreEqual (0, x.CompareTo (x), "#B1");
  			Assert.AreEqual (-1, x.CompareTo (y), "#B2");
  			Assert.AreEqual (1, y.CompareTo (x), "#B3");
  
  			try {
  				e1.CompareTo (e3);
  				Assert.Fail ("#C1");
  			} catch (ArgumentException ex) {
  				// Object must be the same type as the enum.
  				// The type passed in was MonoTests.System.EnumTest+TestingEnum2;
  				// the enum type was MonoTests.System.EnumTest+TestingEnum
  				Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
  				Assert.IsNull (ex.InnerException, "#A3");
  				Assert.IsNotNull (ex.Message, "#A4");
  				Assert.IsTrue (ex.Message.IndexOf (typeof (TestingEnum).FullName) != -1, "#A5");
  				Assert.IsTrue (ex.Message.IndexOf (typeof (TestingEnum2).FullName) != -1, "#A6");
  				Assert.IsNull (ex.ParamName, "#A7");
  			}
  
  			try {
  				((Enum) e1).CompareTo ((Enum) e3);
  				Assert.Fail ("#D1");
  			} catch (ArgumentException ex) {
  				// Object must be the same type as the enum.
  				// The type passed in was MonoTests.System.EnumTest+TestingEnum2;
  				// the enum type was MonoTests.System.EnumTest+TestingEnum
  				Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#D2");
  				Assert.IsNull (ex.InnerException, "#D3");
  				Assert.IsNotNull (ex.Message, "#D4");
  				Assert.IsTrue (ex.Message.IndexOf (typeof (TestingEnum).FullName) != -1, "#D5");
  				Assert.IsTrue (ex.Message.IndexOf (typeof (TestingEnum2).FullName) != -1, "#D6");
  				Assert.IsNull (ex.ParamName, "#D7");
  			}
  		}
  
  		[Test]
  		public void TestEquals ()
  		{
  			Enum e1 = new TestingEnum ();
  			Enum e2 = new TestingEnum ();
  			Enum e3 = new TestingEnum2 ();
  
  			Assert.IsTrue (e1.Equals (e1), "#1");
  			Assert.IsTrue (e1.Equals (e2), "#2");
  			Assert.IsFalse (e1.Equals (e3), "#3");
  			Assert.IsFalse (e1.Equals (null), "#4");
  		}
  
  		[Test]
  		public void TestFormat_Args ()
  		{
  			try {
  				TestingEnum x = TestingEnum.Test;
  				Enum.Format (null, x, "G");
  				Assert.Fail ("#A1");
  			} catch (ArgumentNullException ex) {
  				Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
  				Assert.IsNull (ex.InnerException, "#A3");
  				Assert.IsNotNull (ex.Message, "#A4");
  				Assert.IsNotNull (ex.ParamName, "#A5");
  				Assert.AreEqual ("enumType", ex.ParamName, "#A6");
  			}
  
  			try {
  				Enum.Format (typeof (TestingEnum), null, "G");
  				Assert.Fail ("#B1");
  			} catch (ArgumentNullException ex) {
  				Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
  				Assert.IsNull (ex.InnerException, "#B3");
  				Assert.IsNotNull (ex.Message, "#B4");
  				Assert.IsNotNull (ex.ParamName, "#B5");
  				Assert.AreEqual ("value", ex.ParamName, "#B6");
  			}
  
  			try {
  				TestingEnum x = TestingEnum.Test;
  				Enum.Format (x.GetType (), x, null);
  				Assert.Fail ("#C1");
  			} catch (ArgumentNullException ex) {
  				Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#C2");
  				Assert.IsNull (ex.InnerException, "#C3");
  				Assert.IsNotNull (ex.Message, "#C4");
  				Assert.IsNotNull (ex.ParamName, "#C5");
  				Assert.AreEqual ("format", ex.ParamName, "#C6");
  			}
  
  			try {
  				TestingEnum x = TestingEnum.Test;
  				Enum.Format (typeof (string), x, "G");
  				Assert.Fail ("#D1");
  			} catch (ArgumentException ex) {
  				// Type provided must be an Enum
  				Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
  				Assert.IsNull (ex.InnerException, "#A3");
  				Assert.IsNotNull (ex.Message, "#A4");
  				Assert.IsNotNull (ex.ParamName, "#A5");
  				Assert.AreEqual ("enumType", ex.ParamName, "#A6");
  			}
  
  			try {
  				TestingEnum x = TestingEnum.Test;
  				TestingEnum2 y = TestingEnum2.Test;
  				Enum.Format (y.GetType (), x, "G");
  				Assert.Fail ("#E1");
  			} catch (ArgumentException ex) {
  				// Object must be the same type as the enum. The type passed in was
  				// MonoTests.System.EnumTest.TestingEnum2; the enum type was
  				// MonoTests.System.EnumTest.TestingEnum
  				Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#E2");
  				Assert.IsNull (ex.InnerException, "#E3");
  				Assert.IsNotNull (ex.Message, "#E4");
  				Assert.IsTrue (ex.Message.IndexOf (typeof (TestingEnum2).FullName) != -1, "#E5");
  				Assert.IsTrue (ex.Message.IndexOf (typeof (TestingEnum).FullName) != -1, "#E6");
  				Assert.IsNull (ex.ParamName, "#A7");
  			}
  
  			try {
  				String bad = "huh?";
  				TestingEnum x = TestingEnum.Test;
  				Enum.Format (x.GetType (), bad, "G");
  				Assert.Fail ("#F1");
  			} catch (ArgumentException ex) {
  				// Enum underlying type and the object must be the same type or
  				// object. Type passed in was String.String; the enum underlying
  				// was System.Int32
  				Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#F2");
  				Assert.IsNull (ex.InnerException, "#F3");
  				Assert.IsNotNull (ex.Message, "#F4");
  				Assert.IsTrue (ex.Message.IndexOf (typeof (string).FullName) != -1, "#F5");
  				Assert.IsTrue (ex.Message.IndexOf (typeof (int).FullName) != -1, "#F6");
  				Assert.IsNull (ex.ParamName, "#F7");
  			}
  
  			string [] codes = {"a", "b", "c", "ad", "e", "af", "ag", "h", 
  				  "i", "j", "k", "l", "m", "n", "o", "p", 
  				  "q", "r", "s", "t", "u", "v", "w", "ax", 
  				  "y", "z"};
  			foreach (string code in codes) {
  				try {
  					TestingEnum x = TestingEnum.Test;
  					Enum.Format (x.GetType (), x, code);
  					Assert.Fail ("#G1:" + code);
  				} catch (FormatException ex) {
  					// Format String can be only "G","g","X","x","F","f","D" or "d"
  					Assert.AreEqual (typeof (FormatException), ex.GetType (), "#G2");
  					Assert.IsNull (ex.InnerException, "#G3");
  					Assert.IsNotNull (ex.Message, "#G4");
  				}
  			}
  
  			TestingEnum test = TestingEnum.Test;
  			Assert.AreEqual ("3", Enum.Format (test.GetType (), test, "d"), "#H1");
  			Assert.AreEqual ("18446744073709551615", Enum.Format (typeof (TestingEnum3), TestingEnum3.Test, "d"), "#H2");
  			Assert.AreEqual ("Test", Enum.Format (test.GetType (), test, "g"), "#H3");
  			Assert.AreEqual ("00000003", Enum.Format (test.GetType (), test, "x"), "#H4");
  			Assert.AreEqual ("Test", Enum.Format (test.GetType (), test, "f"), "#H5");
  		}
  
  		[Test]
  		public void TestFormat_FormatSpecifier ()
  		{
  			ParameterAttributes pa =
  				ParameterAttributes.In | ParameterAttributes.HasDefault;
  			const string fFormatOutput = "In, HasDefault";
  			const string xFormatOutput = "00001001";
  			string fOutput = Enum.Format (pa.GetType (), pa, "f");
  			Assert.AreEqual (fFormatOutput, fOutput, "#A1");
  			string xOutput = Enum.Format (pa.GetType (), pa, "x");
  			Assert.AreEqual (xFormatOutput, xOutput, "#A2");
  
  			Assert.AreEqual ("00", TestingEnum4.This.ToString ("x"), "#B1");
  			Assert.AreEqual ("00", TestingEnum4.This.ToString ("X"), "#B2");
  			Assert.AreEqual ("FF", TestingEnum4.Test.ToString ("x"), "#B3");
  			Assert.AreEqual ("FF", TestingEnum4.Test.ToString ("X"), "#B4");
  
  			Assert.AreEqual ("0000", TestingEnum5.This.ToString ("x"), "#C1");
  			Assert.AreEqual ("0000", TestingEnum5.This.ToString ("X"), "#C2");
  			Assert.AreEqual ("7FFF", TestingEnum5.Test.ToString ("x"), "#C3");
  			Assert.AreEqual ("7FFF", TestingEnum5.Test.ToString ("X"), "#C4");
  
  			Assert.AreEqual ("00000000", TestingEnum6.This.ToString ("x"), "#D1");
  			Assert.AreEqual ("00000000", TestingEnum6.This.ToString ("X"), "#D2");
  			Assert.AreEqual ("7FFFFFFF", TestingEnum6.Test.ToString ("x"), "#D3");
  			Assert.AreEqual ("7FFFFFFF", TestingEnum6.Test.ToString ("X"), "#D4");
  
  			Assert.AreEqual ("0000000000000000", TestingEnum3.This.ToString ("x"), "#E1");
  			Assert.AreEqual ("0000000000000000", TestingEnum3.This.ToString ("X"), "#E2");
  			Assert.AreEqual ("FFFFFFFFFFFFFFFF", TestingEnum3.Test.ToString ("x"), "#E3");
  			Assert.AreEqual ("FFFFFFFFFFFFFFFF", TestingEnum3.Test.ToString ("X"), "#E4");
  		}
  
  		[Test]
  		public void TestGetHashCode ()
  		{
  			Enum e1 = new TestingEnum ();
  			Enum e2 = new TestingEnum2 ();
  
  			Assert.AreEqual (e1.GetHashCode (), e1.GetHashCode ());
  		}
  
  		[Test]
  		public void GetName ()
  		{
  			try {
  				TestingEnum x = TestingEnum.Test;
  				Enum.GetName (null, x);
  				Assert.Fail ("#A1");
  			} catch (ArgumentNullException ex) {
  				Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
  				Assert.IsNull (ex.InnerException, "#A3");
  				Assert.IsNotNull (ex.Message, "#A4");
  				Assert.IsNotNull (ex.ParamName, "#A5");
  				Assert.AreEqual ("enumType", ex.ParamName, "#A6");
  			}
  
  			try {
  				TestingEnum x = TestingEnum.Test;
  				Enum.GetName (x.GetType (), null);
  				Assert.Fail ("#B1");
  			} catch (ArgumentNullException ex) {
  				Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
  				Assert.IsNull (ex.InnerException, "#B3");
  				Assert.IsNotNull (ex.Message, "#B4");
  				Assert.IsNotNull (ex.ParamName, "#B5");
  				Assert.AreEqual ("value", ex.ParamName, "#B6");
  			}
  
  			try {
  				String bad = "huh?";
  				TestingEnum x = TestingEnum.Test;
  				Enum.GetName (bad.GetType (), x);
  				Assert.Fail ("#C1");
  			} catch (ArgumentException ex) {
  				// Type provided must be an Enum
  				Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#C2");
  				Assert.IsNull (ex.InnerException, "#C3");
  				Assert.IsNotNull (ex.Message, "#C4");
  				Assert.IsNotNull (ex.ParamName, "#C5");
  				Assert.AreEqual ("enumType", ex.ParamName, "#C6");
  			}
  
  			try {
  				String bad = "huh?";
  				TestingEnum x = TestingEnum.Test;
  				Enum.GetName (x.GetType (), bad);
  				Assert.Fail ("#D1");
  			} catch (ArgumentException ex) {
  				Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#D2");
  				Assert.IsNull (ex.InnerException, "#D3");
  				Assert.IsNotNull (ex.Message, "#D4");
  				Assert.IsNotNull (ex.ParamName, "#D5");
  				Assert.AreEqual ("value", ex.ParamName, "#D6");
  			}
  
  			TestingEnum a = TestingEnum.This;
  			TestingEnum b = TestingEnum.Is;
  			TestingEnum c = TestingEnum.A;
  			TestingEnum2 d = TestingEnum2.Test;
  
  			Assert.AreEqual ("This", Enum.GetName (a.GetType (), a), "#E1");
  			Assert.AreEqual ("Is", Enum.GetName (b.GetType (), b), "#E2");
  			Assert.AreEqual ("A", Enum.GetName (c.GetType (), c), "#E3");
  			Assert.AreEqual ("Test", Enum.GetName (c.GetType (), d), "#E4");
  		}
  
  		[Test]
  		public void GetNameIdenticalToGetEnumName ()
  		{
  			Assert.AreEqual (typeof (EnumOverlap).GetEnumName (0), Enum.GetName (typeof(EnumOverlap), 0), "#1");
  			Assert.AreEqual ("First", Enum.GetName (typeof(EnumOverlap), 0), "#2");
  		}
  
  		[Test]
  		public void TestGetNames ()
  		{
  			try {
  				Enum.GetNames (null);
  				Assert.Fail ("#A1");
  			} catch (ArgumentNullException ex) {
  				Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
  				Assert.IsNull (ex.InnerException, "#A3");
  				Assert.IsNotNull (ex.Message, "#A4");
  				Assert.IsNotNull (ex.ParamName, "#A5");
  				Assert.AreEqual ("enumType", ex.ParamName, "#A6");
  			}
  
  			TestingEnum x = TestingEnum.This;
  			string [] match = { "This", "Is", "A", "Test" };
  			string [] names = Enum.GetNames (x.GetType ());
  			Assert.IsNotNull (names, "#B1");
  			Assert.AreEqual (match.Length, names.Length, "#B2");
  			for (int i = 0; i < names.Length; i++)
  				Assert.AreEqual (match [i], names [i], "#B3");
  		}
  
  		[Test]
  		public void TestGetTypeCode ()
  		{
  			TestingEnum x = TestingEnum.This;
  			TestingEnum y = new TestingEnum ();
  			Assert.AreEqual (TypeCode.Int32, x.GetTypeCode (), "#1");
  			Assert.AreEqual (TypeCode.Int32, y.GetTypeCode (), "#2");
  		}
  
  		[Test]
  		public void TestGetUnderlyingType ()
  		{
  			try {
  				Enum.GetUnderlyingType (null);
  				Assert.Fail ("#A1");
  			} catch (ArgumentNullException ex) {
  				Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
  				Assert.IsNull (ex.InnerException, "#A3");
  				Assert.IsNotNull (ex.Message, "#A4");
  				Assert.IsNotNull (ex.ParamName, "#A5");
  				Assert.AreEqual ("enumType", ex.ParamName, "#A6");
  			}
  
  			try {
  				String bad = "huh?";
  				Enum.GetUnderlyingType (bad.GetType ());
  				Assert.Fail ("#B1");
  			} catch (ArgumentException ex) {
  				// Type provided must be an Enum
  				Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
  				Assert.IsNull (ex.InnerException, "#B3");
  				Assert.IsNotNull (ex.Message, "#B4");
  				Assert.IsNotNull (ex.ParamName, "#B5");
  				Assert.AreEqual ("enumType", ex.ParamName, "#B6");
  			}
  
  			short sh = 5;
  			int i = 5;
  			Enum t1 = new TestingEnum ();
  			Enum t2 = new TestShortEnum ();
  			Assert.AreEqual (i.GetType (), Enum.GetUnderlyingType (t1.GetType ()), "#C1");
  			Assert.AreEqual (sh.GetType (), Enum.GetUnderlyingType (t2.GetType ()), "#C2");
  		}
  
  		[Test]
  		public void TestGetValues ()
  		{
  			try {
  				Enum.GetValues (null);
  				Assert.Fail ("#A1");
  			} catch (ArgumentNullException ex) {
  				Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
  				Assert.IsNull (ex.InnerException, "#A3");
  				Assert.IsNotNull (ex.Message, "#A4");
  				Assert.IsNotNull (ex.ParamName, "#A5");
  				Assert.AreEqual ("enumType", ex.ParamName, "#A6");
  			}
  
  			try {
  				String bad = "huh?";
  				Enum.GetValues (bad.GetType ());
  				Assert.Fail ("#B1");
  			} catch (ArgumentException ex) {
  				// Type provided must be an Enum
  				Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
  				Assert.IsNull (ex.InnerException, "#B3");
  				Assert.IsNotNull (ex.Message, "#B4");
  				Assert.IsNotNull (ex.ParamName, "#B5");
  				Assert.AreEqual ("enumType", ex.ParamName, "#B6");
  			}
  
  			Enum t1 = new TestingEnum ();
  			Array a1 = Enum.GetValues (t1.GetType ());
  			for (int i = 0; i < a1.Length; i++)
  				Assert.AreEqual ((TestingEnum) i, a1.GetValue (i), "#C1");
  
  			Enum t2 = new TestShortEnum ();
  			Array a2 = Enum.GetValues (t2.GetType ());
  			for (short i = 0; i < a1.Length; i++)
  				Assert.AreEqual ((TestShortEnum) i, a2.GetValue (i), "#C2");
  		}
  
  		[Test]
  		public void TestIsDefined ()
  		{
  			try {
  				Enum.IsDefined (null, 1);
  				Assert.Fail ("#A1");
  			} catch (ArgumentNullException ex) {
  				Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
  				Assert.IsNull (ex.InnerException, "#A3");
  				Assert.IsNotNull (ex.Message, "#A4");
  				Assert.IsNotNull (ex.ParamName, "#A5");
  				Assert.AreEqual ("enumType", ex.ParamName, "#A6");
  			}
  
  			try {
  				TestingEnum x = TestingEnum.Test;
  				Enum.IsDefined (x.GetType (), null);
  				Assert.Fail ("#B1");
  			} catch (ArgumentNullException ex) {
  				Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
  				Assert.IsNull (ex.InnerException, "#B3");
  				Assert.IsNotNull (ex.Message, "#B4");
  				Assert.IsNotNull (ex.ParamName, "#B5");
  				Assert.AreEqual ("value", ex.ParamName, "#B6");
  			}
  
  			try {
  				String bad = "huh?";
  				int i = 4;
  				Enum.IsDefined (bad.GetType (), i);
  				Assert.Fail ("#C1");
  			} catch (ArgumentException ex) {
  				// Type provided must be an Enum
  				Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#C2");
  				Assert.IsNull (ex.InnerException, "#C3");
  				Assert.IsNotNull (ex.Message, "#C4");
  				Assert.IsNotNull (ex.ParamName, "#C5");
  				Assert.AreEqual ("enumType", ex.ParamName, "#C6");
  			}
  
  			try {
  				TestingEnum x = TestingEnum.Test;
  				short i = 4;
  				Enum.IsDefined (x.GetType (), i);
  				Assert.Fail ("#D1");
  			} catch (ArgumentException ex) {
  				Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#D2");
  				Assert.IsNull (ex.InnerException, "#D3");
  				Assert.IsNotNull (ex.Message, "#D4");
  				Assert.IsNull (ex.ParamName, "#D5");
  			}
  
  			Enum t1 = new TestingEnum ();
  			int valCount = Enum.GetValues (t1.GetType ()).Length;
  			for (int i = 0; i < valCount; i++)
  				Assert.IsTrue (Enum.IsDefined (t1.GetType (), i), "#F1:" + i);
  			Assert.IsFalse (Enum.IsDefined (t1.GetType (), valCount), "#F2");
  			Assert.IsFalse (Enum.IsDefined (typeof (TestingEnum), "huh?"), "#F3");
  		}
  
  		[Test]
  		public void TestParse1 ()
  		{
  			try {
  				String name = "huh?";
  				Enum.Parse (null, name);
  				Assert.Fail ("#A1");
  			} catch (ArgumentNullException ex) {
  				Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
  				Assert.IsNull (ex.InnerException, "#A3");
  				Assert.IsNotNull (ex.Message, "#A4");
  				Assert.IsNotNull (ex.ParamName, "#A5");
  				Assert.AreEqual ("enumType", ex.ParamName, "#A6");
  			}
  
  			try {
  				TestingEnum x = TestingEnum.Test;
  				Enum.Parse (x.GetType (), null);
  				Assert.Fail ("#B1");
  			} catch (ArgumentNullException ex) {
  				Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
  				Assert.IsNull (ex.InnerException, "#B3");
  				Assert.IsNotNull (ex.Message, "#B4");
  				Assert.IsNotNull (ex.ParamName, "#B5");
  				Assert.AreEqual ("value", ex.ParamName, "#B6");
  			}
  
  			try {
  				String bad = "huh?";
  				Enum.Parse (bad.GetType (), bad);
  				Assert.Fail ("#C1");
  			} catch (ArgumentException ex) {
  				// Type provided must be an Enum
  				Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#C2");
  				Assert.IsNull (ex.InnerException, "#C3");
  				Assert.IsNotNull (ex.Message, "#C4");
  				Assert.IsNotNull (ex.ParamName, "#C5");
  				Assert.AreEqual ("enumType", ex.ParamName, "#C6");
  			}
  
  			try {
  				TestingEnum x = TestingEnum.Test;
  				String bad = "";
  				Enum.Parse (x.GetType (), bad);
  				Assert.Fail ("#D1");
  			} catch (ArgumentException ex) {
  				// Must specify valid information for parsing
  				// in the string
  				Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#D2");
  				Assert.IsNull (ex.InnerException, "#D3");
  				Assert.IsNotNull (ex.Message, "#D4");
  				Assert.IsNull (ex.ParamName, "#D5");
  			}
  
  			try {
  				TestingEnum x = TestingEnum.Test;
  				String bad = " ";
  				Enum.Parse (x.GetType (), bad);
  				Assert.Fail ("#E1");
  			} catch (ArgumentException ex) {
  				Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#E2");
  				Assert.IsNull (ex.InnerException, "#E3");
  				Assert.IsNotNull (ex.Message, "#E4");
  				Assert.IsNull (ex.ParamName, "#E5");
  			}
  
  			try {
  				String bad = "huh?";
  				TestingEnum x = TestingEnum.Test;
  				Enum.Parse (x.GetType (), bad);
  				Assert.Fail ("#F1");
  			} catch (ArgumentException ex) {
  				Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#F2");
  				Assert.IsNull (ex.InnerException, "#F3");
  				Assert.IsNotNull (ex.Message, "#F4");
  				Assert.IsNull (ex.ParamName, "#F5");
  			}
  
  			TestingEnum t1 = new TestingEnum ();
  			Assert.AreEqual (TestingEnum.This, Enum.Parse (t1.GetType (), "This"), "#G1");
  			Assert.AreEqual (TestingEnum.Is, Enum.Parse (t1.GetType (), "Is"), "#G2");
  			Assert.AreEqual (TestingEnum.A, Enum.Parse (t1.GetType (), "A"), "#G3");
  			Assert.AreEqual (TestingEnum.Test, Enum.Parse (t1.GetType (), "Test"), "#G4");
  			Assert.AreEqual (TestingEnum.Test, Enum.Parse (t1.GetType (), "    \n\nTest\t"), "#G5");
  			Assert.AreEqual (TestingEnum.Is, Enum.Parse (t1.GetType (), "This,Is"), "#G6");
  			Assert.AreEqual (TestingEnum.Test, Enum.Parse (t1.GetType (), "This,Test"), "#G7");
  			Assert.AreEqual (TestingEnum.Test, Enum.Parse (t1.GetType (), "This,Is,A"), "#G8");
  			Assert.AreEqual (TestingEnum.Test, Enum.Parse (t1.GetType (), "   \n\tThis \t\n,    Is,A \n"), "#G9");
  		}
  
  		[Test]
  		public void TestParse2 ()
  		{
  			try {
  				String name = "huh?";
  				Enum.Parse (null, name, true);
  				Assert.Fail ("#A1");
  			} catch (ArgumentNullException ex) {
  				Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
  				Assert.IsNull (ex.InnerException, "#A3");
  				Assert.IsNotNull (ex.Message, "#A4");
  				Assert.IsNotNull (ex.ParamName, "#A5");
  				Assert.AreEqual ("enumType", ex.ParamName, "#A6");
  			}
  
  			try {
  				TestingEnum x = TestingEnum.Test;
  				Enum.Parse (x.GetType (), null, true);
  				Assert.Fail ("#B1");
  			} catch (ArgumentNullException ex) {
  				Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
  				Assert.IsNull (ex.InnerException, "#B3");
  				Assert.IsNotNull (ex.Message, "#B4");
  				Assert.IsNotNull (ex.ParamName, "#B5");
  				Assert.AreEqual ("value", ex.ParamName, "#B6");
  			}
  
  			try {
  				String bad = "huh?";
  				Enum.Parse (bad.GetType (), bad, true);
  				Assert.Fail ("#C1");
  			} catch (ArgumentException ex) {
  				// Type provided must be an Enum
  				Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#D2");
  				Assert.IsNull (ex.InnerException, "#D3");
  				Assert.IsNotNull (ex.Message, "#D4");
  				Assert.IsNotNull (ex.ParamName, "#D5");
  				Assert.AreEqual ("enumType", ex.ParamName, "#D6");
  			}
  
  			try {
  				TestingEnum x = TestingEnum.Test;
  				String bad = "";
  				Enum.Parse (x.GetType (), bad, true);
  				Assert.Fail ("#E1");
  			} catch (ArgumentException ex) {
  				// Must specify valid information for parsing
  				// in the string
  				Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#E2");
  				Assert.IsNull (ex.InnerException, "#E3");
  				Assert.IsNotNull (ex.Message, "#E4");
  				Assert.IsNull (ex.ParamName, "#E5");
  			}
  
  			try {
  				TestingEnum x = TestingEnum.Test;
  				String bad = " ";
  				Enum.Parse (x.GetType (), bad, true);
  				Assert.Fail ("#F1");
  			} catch (ArgumentException ex) {
  				// Must specify valid information for parsing
  				// in the string
  				Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#F2");
  				Assert.IsNull (ex.InnerException, "#F3");
  				Assert.IsNotNull (ex.Message, "#F4");
  				Assert.IsFalse (ex.Message.IndexOf ("' '") != -1, "#F5");
  				Assert.IsNull (ex.ParamName, "#F6");
  			}
  
  			try {
  				String bad = "huh?";
  				TestingEnum x = TestingEnum.Test;
  				Enum.Parse (x.GetType (), bad, true);
  				Assert.Fail ("#G1");
  			} catch (ArgumentException ex) {
  				// Requested value 'huh?' was not found
  				Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#G2");
  				Assert.IsNull (ex.InnerException, "#G3");
  				Assert.IsNotNull (ex.Message, "#G4");
  				Assert.IsTrue (ex.Message.IndexOf ("'huh?'") != -1, "#G5");
  				Assert.IsNull (ex.ParamName, "#G6");
  			}
  
  			try {
  				String bad = "test";
  				TestingEnum x = TestingEnum.Test;
  				Enum.Parse (x.GetType (), bad, false);
  				Assert.Fail ("#H1");
  			} catch (ArgumentException ex) {
  				// Requested value 'test' was not found
  				Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#H2");
  				Assert.IsNull (ex.InnerException, "#H3");
  				Assert.IsNotNull (ex.Message, "#H4");
  				Assert.IsTrue (ex.Message.IndexOf ("'test'") != -1, "#H5");
  				Assert.IsNull (ex.ParamName, "#H6");
  			}
  
  			TestingEnum t1 = new TestingEnum ();
  			Assert.AreEqual (TestingEnum.This, Enum.Parse (t1.GetType (), "this", true), "#I1");
  			Assert.AreEqual (TestingEnum.Is, Enum.Parse (t1.GetType (), "is", true), "#I2");
  			Assert.AreEqual (TestingEnum.A, Enum.Parse (t1.GetType (), "a", true), "#I3");
  			Assert.AreEqual (TestingEnum.Test, Enum.Parse (t1.GetType (), "test", true), "#I4");
  			Assert.AreEqual (TestingEnum.Test, Enum.Parse (t1.GetType (), "    \n\ntest\t", true), "#I5");
  
  			Assert.AreEqual (TestingEnum.Is, Enum.Parse (t1.GetType (), "This,is", true), "#J1");
  			Assert.AreEqual (TestingEnum.Test, Enum.Parse (t1.GetType (), "This,test", true), "#J2");
  			Assert.AreEqual (TestingEnum.Test, Enum.Parse (t1.GetType (), "This,is,A", true), "#J3");
  			Assert.AreEqual (TestingEnum.Test, Enum.Parse (t1.GetType (), "   \n\tThis \t\n,    is,a \n", true), "#J4");
  		}
  
  		[Test]
  		public void ParseValue ()
  		{
  			TestingEnum3 t1 = new TestingEnum3 ();
  			Assert.AreEqual (TestingEnum3.Test, Enum.Parse (t1.GetType (), "18446744073709551615", false));
  		}
  
  #if NET_4_0
  		[Test]
  		public void TryParseErrors ()
  		{
  			TestingEnum result;
  			bool success;
  
  			success = Enum.TryParse<TestingEnum> (null, out result);
  			Assert.AreEqual (false, success, "#A1");
  			Assert.AreEqual (TestingEnum.This, result, "#A2");
  
  			success = Enum.TryParse<TestingEnum> ("WrongValue", out result);
  			Assert.AreEqual (false, success, "#B1");
  			Assert.AreEqual (TestingEnum.This, result, "#B2");
  
  			success = Enum.TryParse<TestingEnum> (String.Empty, out result);
  			Assert.AreEqual (false, success, "#C1");
  			Assert.AreEqual (TestingEnum.This, result, "#C2");
  
  			success = Enum.TryParse<TestingEnum> (" ", out result);
  			Assert.AreEqual (false, success, "#D1");
  			Assert.AreEqual (TestingEnum.This, result, "#D2");
  
  			// TryParse throws ArgumentException if TEnum is not an enumeration type
  			try {
  				int n;
  				Enum.TryParse<int> ("31416", out n);
  				Assert.Fail ("#E1");
  			} catch (ArgumentException ex) {
  				Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#E2");
  				Assert.IsNull (ex.InnerException, "#E3");
  				Assert.IsNotNull (ex.Message, "#E4");
  				Assert.IsNotNull (ex.ParamName, "#E5");
  				Assert.AreEqual ("enumType", ex.ParamName, "#E6");
  			}
  		}
  
  		[Test]
  		public void TryParse ()
  		{
  			TestingEnum result;
  			bool success;
  
  			success = Enum.TryParse<TestingEnum> ("Is", out result);
  			Assert.AreEqual (true, success, "#A1");
  			Assert.AreEqual (TestingEnum.Is, result, "#A2");
  
  			success = Enum.TryParse<TestingEnum> ("100", out result);
  			Assert.AreEqual (true, success, "#C1");
  			Assert.AreEqual (((TestingEnum)100), result, "#C2");
  
  			success = Enum.TryParse<TestingEnum> ("is", out result);
  			Assert.AreEqual (false, success, "#D1");
  			Assert.AreEqual (TestingEnum.This, result, "#D2");
  
  			success = Enum.TryParse<TestingEnum> ("is", true, out result);
  			Assert.AreEqual (true, success, "#D1");
  			Assert.AreEqual (TestingEnum.Is, result, "#D2");
  
  			success = Enum.TryParse<TestingEnum> ("  Is  ", out result);
  			Assert.AreEqual (true, success, "#E1");
  			Assert.AreEqual (TestingEnum.Is, result, "#E2");
  		}
  #endif
  
  		[Test]
  		public void ToObject_EnumType_Int32 ()
  		{
  			object value = Enum.ToObject (typeof (TestingEnum), 0);
  			Assert.AreEqual (TestingEnum.This, value, "#1");
  			value = Enum.ToObject (typeof (TestingEnum), 2);
  			Assert.AreEqual (TestingEnum.A, value, "#2");
  		}
  
  		[Test]
  		public void ToObject_EnumType_UInt64 ()
  		{
  			object value = Enum.ToObject (typeof (TestingEnum3), 0);
  			Assert.AreEqual (TestingEnum3.This, value, "#1");
  			value = Enum.ToObject (typeof (TestingEnum3), 1);
  			Assert.AreEqual (TestingEnum3.Is, value, "#2");
  
gt: 			value = Enum.ToObject (typeof (TestingEnum3), ulong.MaxValue);