Merge pull request #1624 from esdrubal/getprocesstimes
[mono.git] / mcs / class / System.Data / Test / System.Data / DataRowTest2.cs
index d833753a65f0997447f106d98fcd713f95b022de..4a9e3ca2d47c26ffac2a40d6f2a460817ef5534e 100644 (file)
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-using NUnit.Framework;
 using System;
-using System.IO;
+using System.Collections;
 using System.ComponentModel;
 using System.Data;
+using System.Globalization;
+using System.IO;
+
 using MonoTests.System.Data.Utils;
 
+using NUnit.Framework;
+
 namespace MonoTests.System.Data
 {
        [TestFixture] public class DataRowTest2
        {
                bool _rowChanged;
+               ArrayList _eventsFired;
 
                [SetUp]
                public void SetUp ()
                {
                        _rowChanged = false;
+                       _eventsFired = new ArrayList ();
                }
 
                [Test] public void AcceptChanges()
@@ -733,6 +739,21 @@ namespace MonoTests.System.Data
                        Assert.AreEqual(true , dr.HasErrors , "DRW48");
                }
 
+               [Test] public void HasErrorsWithNullError()
+               {
+                       DataTable dt = new DataTable("myTable"); 
+                       DataRow dr = dt.NewRow();
+
+                       // HasErrors (default)
+                       Assert.AreEqual(false, dr.HasErrors, "DRW47.2");
+
+                       dr.RowError = null;
+
+                       // HasErrors (set/get)
+                       Assert.AreEqual(string.Empty , dr.RowError , "DRW48.2");
+                       Assert.AreEqual(false , dr.HasErrors , "DRW49.2");
+               }
+
                [Test] public void HasVersion_ByDataRowVersion()
                {
                        DataTable t = new DataTable("atable");
@@ -875,6 +896,1017 @@ namespace MonoTests.System.Data
                        Assert.AreEqual(false , r.HasVersion(DataRowVersion.Proposed) , "DRW84");
                }
 
+               [Test] // Object this [DataColumn]
+               public void Indexer1 ()
+               {
+                       EventInfo evt;
+                       DataColumnChangeEventArgs colChangeArgs;
+
+                       DataTable dt = new DataTable ();
+                       dt.ColumnChanged += new DataColumnChangeEventHandler (ColumnChanged);
+                       dt.ColumnChanging += new DataColumnChangeEventHandler (ColumnChanging);
+
+                       DataColumn dc0 = new DataColumn ("Col0", typeof (Address));
+                       dt.Columns.Add (dc0);
+                       DataColumn dc1 = new DataColumn ("Col1", typeof (Person));
+                       dt.Columns.Add (dc1);
+
+                       Person personA = new Person ("Miguel");
+                       Address addressA = new Address ("X", 5);
+                       Person personB = new Person ("Chris");
+                       Address addressB = new Address ("Y", 4);
+                       Person personC = new Person ("Jackson");
+                       Address addressC = new Address ("Z", 3);
+
+                       dt.Rows.Add (new object [] { addressA, personA });
+                       dt.Rows.Add (new object [] { addressB, personB });
+                       DataRow dr;
+
+                       dr = dt.Rows [0];
+                       Assert.AreEqual (addressA, dr [dc0], "#A1");
+                       Assert.AreSame (personA, dr [dc1], "#A2");
+
+                       dr = dt.Rows [1];
+                       Assert.AreEqual (addressB, dr [dc0], "#B1");
+                       Assert.AreSame (personB, dr [dc1], "#B2");
+
+                       dr = dt.Rows [0];
+                       Assert.AreEqual (0, _eventsFired.Count, "#C1");
+                       dr [dc0] = addressC;
+                       Assert.AreEqual (2, _eventsFired.Count, "#C2");
+                       Assert.AreEqual (addressC, dr [dc0], "#C3");
+                       Assert.AreSame (personA, dr [dc1], "#C4");
+
+                       dr = dt.Rows [1];
+                       dr.BeginEdit ();
+                       Assert.AreEqual (2, _eventsFired.Count, "#D1");
+                       dr [dc1] = personC;
+                       Assert.AreEqual (4, _eventsFired.Count, "#D2");
+                       Assert.AreEqual (addressB, dr [dc0], "#D3");
+                       Assert.AreSame (personC, dr [dc1], "#D4");
+                       dr.EndEdit ();
+                       Assert.AreEqual (4, _eventsFired.Count, "#D5");
+                       Assert.AreEqual (addressB, dr [dc0], "#D6");
+                       Assert.AreSame (personC, dr [dc1], "#D7");
+
+                       dr = dt.Rows [0];
+                       dr.BeginEdit ();
+                       Assert.AreEqual (4, _eventsFired.Count, "#E1");
+                       dr [dc0] = addressB;
+                       Assert.AreEqual (6, _eventsFired.Count, "#E2");
+                       Assert.AreEqual (addressB, dr [dc0], "#E3");
+                       Assert.AreSame (personA, dr [dc1], "#E4");
+                       dr.CancelEdit ();
+                       Assert.AreEqual (6, _eventsFired.Count, "#E5");
+                       Assert.AreEqual (addressC, dr [dc0], "#E6");
+                       Assert.AreSame (personA, dr [dc1], "#E7");
+
+                       evt = (EventInfo) _eventsFired [0];
+                       Assert.AreEqual ("ColumnChanging", evt.Name, "#F1");
+                       colChangeArgs = (DataColumnChangeEventArgs) evt.Args;
+                       Assert.AreSame (dc0, colChangeArgs.Column, "#F2");
+                       Assert.AreEqual (addressC, colChangeArgs.ProposedValue, "#F3");
+                       Assert.AreSame (dt.Rows [0], colChangeArgs.Row, "#F4");
+
+                       evt = (EventInfo) _eventsFired [1];
+                       Assert.AreEqual ("ColumnChanged", evt.Name, "#G1");
+                       colChangeArgs = (DataColumnChangeEventArgs) evt.Args;
+                       Assert.AreSame (dc0, colChangeArgs.Column, "#G2");
+                       Assert.AreEqual (addressC, colChangeArgs.ProposedValue, "#G3");
+                       Assert.AreSame (dt.Rows [0], colChangeArgs.Row, "#G4");
+
+                       evt = (EventInfo) _eventsFired [2];
+                       Assert.AreEqual ("ColumnChanging", evt.Name, "#H1");
+                       colChangeArgs = (DataColumnChangeEventArgs) evt.Args;
+                       Assert.AreSame (dc1, colChangeArgs.Column, "#H2");
+                       Assert.AreEqual (personC, colChangeArgs.ProposedValue, "#H3");
+                       Assert.AreSame (dt.Rows [1], colChangeArgs.Row, "#H4");
+
+                       evt = (EventInfo) _eventsFired [3];
+                       Assert.AreEqual ("ColumnChanged", evt.Name, "#I1");
+                       colChangeArgs = (DataColumnChangeEventArgs) evt.Args;
+                       Assert.AreSame (dc1, colChangeArgs.Column, "#I2");
+                       Assert.AreEqual (personC, colChangeArgs.ProposedValue, "#I3");
+                       Assert.AreSame (dt.Rows [1], colChangeArgs.Row, "#I4");
+
+                       evt = (EventInfo) _eventsFired [4];
+                       Assert.AreEqual ("ColumnChanging", evt.Name, "#J1");
+                       colChangeArgs = (DataColumnChangeEventArgs) evt.Args;
+                       Assert.AreSame (dc0, colChangeArgs.Column, "#J2");
+                       Assert.AreEqual (addressB, colChangeArgs.ProposedValue, "#J3");
+                       Assert.AreSame (dt.Rows [0], colChangeArgs.Row, "#J4");
+
+                       evt = (EventInfo) _eventsFired [5];
+                       Assert.AreEqual ("ColumnChanged", evt.Name, "#K1");
+                       colChangeArgs = (DataColumnChangeEventArgs) evt.Args;
+                       Assert.AreSame (dc0, colChangeArgs.Column, "#K2");
+                       Assert.AreEqual (addressB, colChangeArgs.ProposedValue, "#K3");
+                       Assert.AreSame (dt.Rows [0], colChangeArgs.Row, "#K4");
+               }
+
+               [Test] // Object this [DataColumn]
+               public void Indexer1_Column_NotInTable ()
+               {
+                       EventInfo evt;
+                       DataColumnChangeEventArgs colChangeArgs;
+
+                       DataTable dtA = new DataTable ("TableA");
+                       dtA.ColumnChanged += new DataColumnChangeEventHandler (ColumnChanged);
+                       dtA.ColumnChanging += new DataColumnChangeEventHandler (ColumnChanging);
+                       DataColumn dcA1 = new DataColumn ("Col0", typeof (Address));
+                       dtA.Columns.Add (dcA1);
+                       DataColumn dcA2 = new DataColumn ("Col1", typeof (Person));
+                       dtA.Columns.Add (dcA2);
+
+                       DataTable dtB = new DataTable ("TableB");
+                       dtB.ColumnChanged += new DataColumnChangeEventHandler (ColumnChanged);
+                       dtB.ColumnChanging += new DataColumnChangeEventHandler (ColumnChanging);
+                       DataColumn dcB1 = new DataColumn ("Col0", typeof (Address));
+                       dtB.Columns.Add (dcB1);
+                       DataColumn dcB2 = new DataColumn ("Col1", typeof (Person));
+                       dtB.Columns.Add (dcB2);
+
+                       Person personA = new Person ("Miguel");
+                       Address addressA = new Address ("X", 5);
+
+                       dtA.Rows.Add (new object [] { addressA, personA });
+                       DataRow dr = dtA.Rows [0];
+
+                       try {
+                               object value = dr [dcB1];
+                               Assert.Fail ("#A1:" + value);
+                       } catch (ArgumentException ex) {
+                               // Column 'Col0' does not belong to table TableA
+                               Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
+                               Assert.IsNull (ex.InnerException, "#A3");
+                               Assert.IsNotNull (ex.Message, "#A4");
+                               Assert.IsTrue (ex.Message.IndexOf ("'Col0'") != -1, "#A5");
+                               Assert.IsTrue (ex.Message.IndexOf ("TableA") != -1, "#A6");
+                       }
+
+                       try {
+                               object value = dr [new DataColumn ("ZZZ")];
+                               Assert.Fail ("#B1:" + value);
+                       } catch (ArgumentException ex) {
+                               // Column 'Col0' does not belong to table TableA
+                               Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
+                               Assert.IsNull (ex.InnerException, "#B3");
+                               Assert.IsNotNull (ex.Message, "#B4");
+                               Assert.IsTrue (ex.Message.IndexOf ("'ZZZ'") != -1, "#B5");
+                               Assert.IsTrue (ex.Message.IndexOf ("TableA") != -1, "#B6");
+                       }
+
+                       dtA.Columns.Remove (dcA2);
+
+                       try {
+                               object value = dr [dcA2];
+                               Assert.Fail ("#C1:" + value);
+                       } catch (ArgumentException ex) {
+                               // Column 'Col0' does not belong to table TableA
+                               Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#C2");
+                               Assert.IsNull (ex.InnerException, "#C3");
+                               Assert.IsNotNull (ex.Message, "#C4");
+                               Assert.IsTrue (ex.Message.IndexOf ("'Col1'") != -1, "#C5");
+                               Assert.IsTrue (ex.Message.IndexOf ("TableA") != -1, "#C6");
+                       }
+               }
+
+               [Test] // Object this [DataColumn]
+               public void Indexer1_Column_Null ()
+               {
+                       EventInfo evt;
+                       DataColumnChangeEventArgs colChangeArgs;
+
+                       DataTable dt = new DataTable ();
+                       dt.ColumnChanged += new DataColumnChangeEventHandler (ColumnChanged);
+                       dt.ColumnChanging += new DataColumnChangeEventHandler (ColumnChanging);
+                       DataColumn dc0 = new DataColumn ("Col0", typeof (Address));
+                       dt.Columns.Add (dc0);
+                       DataColumn dc1 = new DataColumn ("Col1", typeof (Person));
+                       dt.Columns.Add (dc1);
+
+                       Person personA = new Person ("Miguel");
+                       Address addressA = new Address ("X", 5);
+                       Person personB = new Person ("Chris");
+
+                       dt.Rows.Add (new object [] { addressA, personA });
+                       DataRow dr = dt.Rows [0];
+
+                       try {
+                               object value = dr [(DataColumn) null];
+                               Assert.Fail ("#A1:" + value);
+                       } catch (ArgumentNullException ex) {
+                               Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
+                               Assert.IsNull (ex.InnerException, "#A3");
+                               Assert.IsNotNull (ex.Message, "#A4");
+                               Assert.AreEqual ("column", ex.ParamName, "#A5");
+                       }
+
+                       try {
+                               dr [(DataColumn) null] = personB;
+                               Assert.Fail ("#B1");
+                       } catch (ArgumentNullException ex) {
+                               Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
+                               Assert.IsNull (ex.InnerException, "#B3");
+                               Assert.IsNotNull (ex.Message, "#B4");
+                               Assert.AreEqual ("column", ex.ParamName, "#B5");
+                       }
+
+                       Assert.AreEqual (0, _eventsFired.Count, "#C");
+               }
+
+               [Test] // Object this [DataColumn]
+               public void Indexer1_Value_Null ()
+               {
+                       EventInfo evt;
+                       DataColumnChangeEventArgs colChangeArgs;
+
+                       DataTable dt = new DataTable ();
+                       dt.ColumnChanged += new DataColumnChangeEventHandler (ColumnChanged);
+                       dt.ColumnChanging += new DataColumnChangeEventHandler (ColumnChanging);
+                       DataColumn dc0 = new DataColumn ("Col0", typeof (Address));
+                       dt.Columns.Add (dc0);
+                       DataColumn dc1 = new DataColumn ("Col1", typeof (Person));
+                       dt.Columns.Add (dc1);
+                       DataColumn dc2 = new DataColumn ("Col2", typeof (string));
+                       dt.Columns.Add (dc2);
+
+                       Person personA = new Person ("Miguel");
+                       Address addressA = new Address ("X", 5);
+                       string countryA = "U.S.";
+                       Person personB = new Person ("Chris");
+                       Address addressB = new Address ("Y", 4);
+                       string countryB = "Canada";
+                       Person personC = new Person ("Jackson");
+                       Address addressC = new Address ("Z", 3);
+
+                       dt.Rows.Add (new object [] { addressA, personA, countryA });
+                       dt.Rows.Add (new object [] { addressB, personB, countryB });
+
+                       DataRow dr = dt.Rows [0];
+
+                       try {
+                               dr [dc0] = null;
+                               Assert.Fail ("#A1");
+                       } catch (ArgumentException ex) {
+                               // Cannot set Column 'Col0' to be null.
+                               // Please use DBNull instead
+                               Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
+                               Assert.IsNull (ex.InnerException, "#A3");
+                               Assert.IsNotNull (ex.Message, "#A4");
+                               Assert.IsTrue (ex.Message.IndexOf ("'Col0'") != -1, "#A5");
+                               Assert.IsTrue (ex.Message.IndexOf ("DBNull") != -1, "#A6");
+                       }
+
+                       Assert.AreEqual (1, _eventsFired.Count, "#B1");
+                       Assert.AreEqual (addressA, dr [dc0], "#B2");
+                       Assert.IsFalse (dr.IsNull (dc0), "#B3");
+                       Assert.AreSame (personA, dr [dc1], "#B4");
+                       Assert.IsFalse (dr.IsNull (dc1), "#B5");
+                       Assert.AreEqual (1, _eventsFired.Count, "#B6");
+
+                       dr [dc1] = null;
+
+                       Assert.AreEqual (3, _eventsFired.Count, "#C1");
+                       Assert.AreEqual (addressA, dr [dc0], "#C2");
+                       Assert.IsFalse (dr.IsNull (dc0), "#C3");
+                       Assert.AreSame (DBNull.Value, dr [dc1], "#C4");
+                       Assert.IsTrue (dr.IsNull (dc1), "#C5");
+                       Assert.AreEqual (3, _eventsFired.Count, "#C6");
+
+                       dr [dc0] = DBNull.Value;
+                       Assert.AreEqual (5, _eventsFired.Count, "#D1");
+                       Assert.AreSame (DBNull.Value, dr [dc0], "#D2");
+                       Assert.IsTrue (dr.IsNull (dc0), "#D3");
+                       Assert.AreSame (DBNull.Value, dr [dc1], "#D4");
+                       Assert.IsTrue (dr.IsNull (dc1), "#D5");
+                       Assert.AreEqual (5, _eventsFired.Count, "#D6");
+
+                       dr.BeginEdit ();
+                       dr [dc1] = personC;
+                       Assert.AreEqual (7, _eventsFired.Count, "#E1");
+                       Assert.AreSame (DBNull.Value, dr [dc0], "#E2");
+                       Assert.IsTrue (dr.IsNull (dc0), "#E3");
+                       Assert.AreEqual (personC, dr [dc1], "#E4");
+                       Assert.IsFalse (dr.IsNull (dc1), "#E5");
+                       dr.EndEdit ();
+                       Assert.AreSame (DBNull.Value, dr [dc0], "#E6");
+                       Assert.IsTrue (dr.IsNull (dc0), "#E7");
+                       Assert.AreEqual (personC, dr [dc1], "#E8");
+                       Assert.IsFalse (dr.IsNull (dc1), "#E9");
+                       Assert.AreEqual (7, _eventsFired.Count, "#E10");
+
+                       dr [dc1] = DBNull.Value;
+                       Assert.AreEqual (9, _eventsFired.Count, "#F1");
+                       Assert.AreSame (DBNull.Value, dr [dc0], "#F2");
+                       Assert.IsTrue (dr.IsNull (dc0), "#F3");
+                       Assert.AreSame (DBNull.Value, dr [dc1], "#F4");
+                       Assert.IsTrue (dr.IsNull (dc1), "#F5");
+                       Assert.AreEqual (9, _eventsFired.Count, "#F6");
+
+                       dr [dc2] = null;
+                       Assert.AreEqual (11, _eventsFired.Count, "#G1");
+                       Assert.AreSame (DBNull.Value, dr [dc0], "#G2");
+                       Assert.IsTrue (dr.IsNull (dc0), "#G3");
+                       Assert.AreSame (DBNull.Value, dr [dc1], "#G4");
+                       Assert.IsTrue (dr.IsNull (dc1), "#G5");
+                       Assert.AreSame (DBNull.Value, dr [dc2], "#G6");
+                       Assert.IsTrue (dr.IsNull (dc2), "#G7");
+                       Assert.AreEqual (11, _eventsFired.Count, "#G8");
+
+                       dr [dc2] = DBNull.Value;
+                       Assert.AreEqual (13, _eventsFired.Count, "#H1");
+                       Assert.AreSame (DBNull.Value, dr [dc0], "#H2");
+                       Assert.IsTrue (dr.IsNull (dc0), "#H3");
+                       Assert.AreSame (DBNull.Value, dr [dc1], "#H4");
+                       Assert.IsTrue (dr.IsNull (dc1), "#H5");
+                       Assert.AreSame (DBNull.Value, dr [dc2], "#H6");
+                       Assert.IsTrue (dr.IsNull (dc2), "#H7");
+                       Assert.AreEqual (13, _eventsFired.Count, "#H8");
+
+                       int index = 0;
+
+                       evt = (EventInfo) _eventsFired [index++];
+                       Assert.AreEqual ("ColumnChanging", evt.Name, "#I1");
+                       colChangeArgs = (DataColumnChangeEventArgs) evt.Args;
+                       Assert.AreSame (dc0, colChangeArgs.Column, "#I2");
+                       Assert.IsNull (colChangeArgs.ProposedValue, "#I3");
+                       Assert.AreSame (dt.Rows [0], colChangeArgs.Row, "#I4");
+
+                       evt = (EventInfo) _eventsFired [index++];
+                       Assert.AreEqual ("ColumnChanging", evt.Name, "#J1");
+                       colChangeArgs = (DataColumnChangeEventArgs) evt.Args;
+                       Assert.AreSame (dc1, colChangeArgs.Column, "#J2");
+                       Assert.IsNull (colChangeArgs.ProposedValue, "#J3");
+                       Assert.AreSame (dt.Rows [0], colChangeArgs.Row, "#J4");
+
+
+                       evt = (EventInfo) _eventsFired [index++];
+                       Assert.AreEqual ("ColumnChanged", evt.Name, "#L1");
+                       colChangeArgs = (DataColumnChangeEventArgs) evt.Args;
+                       Assert.AreSame (dc1, colChangeArgs.Column, "#L2");
+                       Assert.IsNull (colChangeArgs.ProposedValue, "#L3");
+                       Assert.AreSame (dt.Rows [0], colChangeArgs.Row, "#L4");
+
+                       evt = (EventInfo) _eventsFired [index++];
+                       Assert.AreEqual ("ColumnChanging", evt.Name, "#M1");
+                       colChangeArgs = (DataColumnChangeEventArgs) evt.Args;
+                       Assert.AreSame (dc0, colChangeArgs.Column, "#M2");
+                       Assert.AreSame (DBNull.Value, colChangeArgs.ProposedValue, "#M3");
+                       Assert.AreSame (dt.Rows [0], colChangeArgs.Row, "#M4");
+
+                       evt = (EventInfo) _eventsFired [index++];
+                       Assert.AreEqual ("ColumnChanged", evt.Name, "#N1");
+                       colChangeArgs = (DataColumnChangeEventArgs) evt.Args;
+                       Assert.AreSame (dc0, colChangeArgs.Column, "#N2");
+                       Assert.AreSame (DBNull.Value, colChangeArgs.ProposedValue, "#N3");
+                       Assert.AreSame (dt.Rows [0], colChangeArgs.Row, "#N4");
+
+                       evt = (EventInfo) _eventsFired [index++];
+                       Assert.AreEqual ("ColumnChanging", evt.Name, "#O1");
+                       colChangeArgs = (DataColumnChangeEventArgs) evt.Args;
+                       Assert.AreSame (dc1, colChangeArgs.Column, "#O2");
+                       Assert.AreSame (personC, colChangeArgs.ProposedValue, "#O3");
+                       Assert.AreSame (dt.Rows [0], colChangeArgs.Row, "#O4");
+
+                       evt = (EventInfo) _eventsFired [index++];
+                       Assert.AreEqual ("ColumnChanged", evt.Name, "#P1");
+                       colChangeArgs = (DataColumnChangeEventArgs) evt.Args;
+                       Assert.AreSame (dc1, colChangeArgs.Column, "#P2");
+                       Assert.AreSame (personC, colChangeArgs.ProposedValue, "#P3");
+                       Assert.AreSame (dt.Rows [0], colChangeArgs.Row, "#P4");
+
+                       evt = (EventInfo) _eventsFired [index++];
+                       Assert.AreEqual ("ColumnChanging", evt.Name, "#Q1");
+                       colChangeArgs = (DataColumnChangeEventArgs) evt.Args;
+                       Assert.AreSame (dc1, colChangeArgs.Column, "#Q2");
+                       Assert.AreSame (DBNull.Value, colChangeArgs.ProposedValue, "#Q3");
+                       Assert.AreSame (dt.Rows [0], colChangeArgs.Row, "#Q4");
+
+                       evt = (EventInfo) _eventsFired [index++];
+                       Assert.AreEqual ("ColumnChanged", evt.Name, "#R1");
+                       colChangeArgs = (DataColumnChangeEventArgs) evt.Args;
+                       Assert.AreSame (dc1, colChangeArgs.Column, "#R2");
+                       Assert.AreSame (DBNull.Value, colChangeArgs.ProposedValue, "#R3");
+                       Assert.AreSame (dt.Rows [0], colChangeArgs.Row, "#R4");
+
+                       evt = (EventInfo) _eventsFired [index++];
+                       Assert.AreEqual ("ColumnChanging", evt.Name, "#S1");
+                       colChangeArgs = (DataColumnChangeEventArgs) evt.Args;
+                       Assert.AreSame (dc2, colChangeArgs.Column, "#S2");
+                       Assert.IsNull (colChangeArgs.ProposedValue, "#S3");
+                       Assert.AreSame (dt.Rows [0], colChangeArgs.Row, "#S4");
+
+                       evt = (EventInfo) _eventsFired [index++];
+                       Assert.AreEqual ("ColumnChanged", evt.Name, "#T1");
+                       colChangeArgs = (DataColumnChangeEventArgs) evt.Args;
+                       Assert.AreSame (dc2, colChangeArgs.Column, "#T2");
+                       Assert.IsNull (colChangeArgs.ProposedValue, "#T3");
+                       Assert.AreSame (dt.Rows [0], colChangeArgs.Row, "#T4");
+
+                       evt = (EventInfo) _eventsFired [index++];
+                       Assert.AreEqual ("ColumnChanging", evt.Name, "#U1");
+                       colChangeArgs = (DataColumnChangeEventArgs) evt.Args;
+                       Assert.AreSame (dc2, colChangeArgs.Column, "#U2");
+                       Assert.AreSame (DBNull.Value, colChangeArgs.ProposedValue, "#U3");
+                       Assert.AreSame (dt.Rows [0], colChangeArgs.Row, "#U4");
+
+                       evt = (EventInfo) _eventsFired [index++];
+                       Assert.AreEqual ("ColumnChanged", evt.Name, "#V1");
+                       colChangeArgs = (DataColumnChangeEventArgs) evt.Args;
+                       Assert.AreSame (dc2, colChangeArgs.Column, "#V2");
+                       Assert.AreSame (DBNull.Value, colChangeArgs.ProposedValue, "#V3");
+                       Assert.AreSame (dt.Rows [0], colChangeArgs.Row, "#V4");
+               }
+
+               [Test] // Object this [Int32]
+               public void Indexer2 ()
+               {
+                       DataTable dt = new DataTable ();
+                       DataColumn dc0 = new DataColumn ("Col0", typeof (Address));
+                       dt.Columns.Add (dc0);
+                       DataColumn dc1 = new DataColumn ("Col1", typeof (Person));
+                       dt.Columns.Add (dc1);
+
+                       Person personA = new Person ("Miguel");
+                       Address addressA = new Address ("X", 5);
+                       Person personB = new Person ("Chris");
+                       Address addressB = new Address ("Y", 4);
+                       Person personC = new Person ("Jackson");
+                       Address addressC = new Address ("Z", 3);
+
+                       dt.Rows.Add (new object [] { addressA, personA });
+                       dt.Rows.Add (new object [] { addressB, personB });
+                       DataRow dr;
+                       
+                       dr = dt.Rows [0];
+                       Assert.AreEqual (addressA, dr [0], "#A1");
+                       Assert.AreSame (personA, dr [1], "#A2");
+
+                       dr = dt.Rows [1];
+                       Assert.AreEqual (addressB, dr [0], "#B1");
+                       Assert.AreSame (personB, dr [1], "#B2");
+
+                       dr = dt.Rows [0];
+                       dr [0] = addressC;
+                       Assert.AreEqual (addressC, dr [0], "#C1");
+                       Assert.AreSame (personA, dr [1], "#C2");
+
+                       dr = dt.Rows [1];
+                       dr.BeginEdit ();
+                       dr [1] = personC;
+                       Assert.AreEqual (addressB, dr [0], "#D1");
+                       Assert.AreSame (personC, dr [1], "#D2");
+                       dr.EndEdit ();
+                       Assert.AreEqual (addressB, dr [0], "#D3");
+                       Assert.AreSame (personC, dr [1], "#D4");
+
+                       dr = dt.Rows [0];
+                       dr.BeginEdit ();
+                       dr [0] = addressB;
+                       Assert.AreEqual (addressB, dr [0], "#E1");
+                       Assert.AreSame (personA, dr [1], "#E2");
+                       dr.CancelEdit ();
+                       Assert.AreEqual (addressC, dr [0], "#E3");
+                       Assert.AreSame (personA, dr [1], "#E4");
+               }
+
+               [Test] // Object this [Int32]
+               public void Indexer2_Value_Null ()
+               {
+                       DataTable dt = new DataTable ();
+                       DataColumn dc0 = new DataColumn ("Col0", typeof (Address));
+                       dt.Columns.Add (dc0);
+                       DataColumn dc1 = new DataColumn ("Col1", typeof (Person));
+                       dt.Columns.Add (dc1);
+
+                       Person personA = new Person ("Miguel");
+                       Address addressA = new Address ("X", 5);
+                       Person personB = new Person ("Chris");
+                       Address addressB = new Address ("Y", 4);
+                       Person personC = new Person ("Jackson");
+                       Address addressC = new Address ("Z", 3);
+
+                       dt.Rows.Add (new object [] { addressA, personA });
+                       dt.Rows.Add (new object [] { addressB, personB });
+
+                       DataRow dr = dt.Rows [0];
+
+                       try {
+                               dr [0] = null;
+                               Assert.Fail ("#A1");
+                       } catch (ArgumentException ex) {
+                               // Cannot set Column 'Col0' to be null.
+                               // Please use DBNull instead
+                               Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
+                               Assert.IsNull (ex.InnerException, "#A3");
+                               Assert.IsNotNull (ex.Message, "#A4");
+                               Assert.IsTrue (ex.Message.IndexOf ("'Col0'") != -1, "#A5");
+                               Assert.IsTrue (ex.Message.IndexOf ("DBNull") != -1, "#A6");
+                       }
+
+                       Assert.AreEqual (addressA, dr [0], "#B1");
+                       Assert.IsFalse (dr.IsNull (0), "#B2");
+                       Assert.AreSame (personA, dr [1], "#B3");
+                       Assert.IsFalse (dr.IsNull (1), "#B4");
+
+                       dr [1] = null;
+
+                       Assert.AreEqual (addressA, dr [0], "#C1");
+                       Assert.IsFalse (dr.IsNull (0), "#C2");
+                       Assert.AreSame (DBNull.Value, dr [1], "#C3");
+                       Assert.IsTrue (dr.IsNull (1), "#C4");
+
+                       dr [0] = DBNull.Value;
+
+                       Assert.AreSame (DBNull.Value, dr [0], "#D1");
+                       Assert.IsTrue (dr.IsNull (0), "#D2");
+                       Assert.AreSame (DBNull.Value, dr [1], "#D3");
+                       Assert.IsTrue (dr.IsNull (1), "#D4");
+
+                       dr.BeginEdit ();
+                       dr [1] = personC;
+                       Assert.AreSame (DBNull.Value, dr [0], "#E1");
+                       Assert.IsTrue (dr.IsNull (0), "#E2");
+                       Assert.AreEqual (personC, dr [1], "#E3");
+                       Assert.IsFalse (dr.IsNull (1), "#E4");
+                       dr.EndEdit ();
+                       Assert.AreSame (DBNull.Value, dr [0], "#E5");
+                       Assert.IsTrue (dr.IsNull (0), "#E6");
+                       Assert.AreEqual (personC, dr [1], "#E7");
+                       Assert.IsFalse (dr.IsNull (1), "#E8");
+
+                       dr [1] = DBNull.Value;
+
+                       Assert.AreSame (DBNull.Value, dr [0], "#F1");
+                       Assert.IsTrue (dr.IsNull (0), "#F2");
+                       Assert.AreSame (DBNull.Value, dr [1], "#F3");
+                       Assert.IsTrue (dr.IsNull (1), "#F4");
+               }
+
+               [Test] // Object this [String]
+               public void Indexer3 ()
+               {
+                       DataTable dt = new DataTable ();
+                       DataColumn dc0 = new DataColumn ("Col0", typeof (Address));
+                       dt.Columns.Add (dc0);
+                       DataColumn dc1 = new DataColumn ("Col1", typeof (Person));
+                       dt.Columns.Add (dc1);
+
+                       Person personA = new Person ("Miguel");
+                       Address addressA = new Address ("X", 5);
+                       Person personB = new Person ("Chris");
+                       Address addressB = new Address ("Y", 4);
+                       Person personC = new Person ("Jackson");
+                       Address addressC = new Address ("Z", 3);
+
+                       dt.Rows.Add (new object [] { addressA, personA });
+                       dt.Rows.Add (new object [] { addressB, personB });
+                       DataRow dr;
+
+                       dr = dt.Rows [0];
+                       Assert.AreEqual (addressA, dr ["Col0"], "#A1");
+                       Assert.AreSame (personA, dr ["Col1"], "#A2");
+
+                       dr = dt.Rows [1];
+                       Assert.AreEqual (addressB, dr ["Col0"], "#B1");
+                       Assert.AreSame (personB, dr ["Col1"], "#B2");
+
+                       dr = dt.Rows [0];
+                       dr ["Col0"] = addressC;
+                       Assert.AreEqual (addressC, dr ["Col0"], "#C1");
+                       Assert.AreSame (personA, dr ["Col1"], "#C2");
+
+                       dr = dt.Rows [1];
+                       dr.BeginEdit ();
+                       dr ["Col1"] = personC;
+                       Assert.AreEqual (addressB, dr ["Col0"], "#D1");
+                       Assert.AreSame (personC, dr ["Col1"], "#D2");
+                       dr.EndEdit ();
+                       Assert.AreEqual (addressB, dr ["Col0"], "#D3");
+                       Assert.AreSame (personC, dr ["Col1"], "#D4");
+
+                       dr = dt.Rows [0];
+                       dr.BeginEdit ();
+                       dr ["Col0"] = addressB;
+                       Assert.AreEqual (addressB, dr ["Col0"], "#E1");
+                       Assert.AreSame (personA, dr ["Col1"], "#E2");
+                       dr.CancelEdit ();
+                       Assert.AreEqual (addressC, dr ["Col0"], "#E3");
+                       Assert.AreSame (personA, dr ["Col1"], "#E4");
+               }
+
+               [Test] // Object this [String]
+               public void Indexer3_ColumnName_Empty ()
+               {
+                       DataTable dt = new DataTable ("Persons");
+                       DataColumn dc0 = new DataColumn ("Col0", typeof (Address));
+                       dt.Columns.Add (dc0);
+                       DataColumn dc1 = new DataColumn (string.Empty, typeof (Person));
+                       dt.Columns.Add (dc1);
+
+                       Person personA = new Person ("Miguel");
+                       Address addressA = new Address ("X", 5);
+                       Person personB = new Person ("Chris");
+
+                       dt.Rows.Add (new object [] { addressA, personA });
+
+                       DataRow dr = dt.Rows [0];
+
+                       try {
+                               object value = dr [string.Empty];
+                               Assert.Fail ("#A1:" + value);
+                       } catch (ArgumentException ex) {
+                               //  Column '' does not belong to table Persons
+                               Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
+                               Assert.IsNull (ex.InnerException, "#A3");
+                               Assert.IsNotNull (ex.Message, "#A4");
+                               Assert.IsTrue (ex.Message.IndexOf ("''") != -1, "#A5");
+                               Assert.IsTrue (ex.Message.IndexOf ("Persons") != -1, "#A6");
+                               Assert.IsNull (ex.ParamName, "#A7");
+                       }
+
+                       try {
+                               dr [string.Empty] = personB;
+                               Assert.Fail ("#B1");
+                       } catch (ArgumentException ex) {
+                               // Column '' does not belong to table Persons
+                               Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
+                               Assert.IsNull (ex.InnerException, "#B3");
+                               Assert.IsNotNull (ex.Message, "#B4");
+                               Assert.IsTrue (ex.Message.IndexOf ("''") != -1, "#B5");
+                               Assert.IsTrue (ex.Message.IndexOf ("Persons") != -1, "#B6");
+                               Assert.IsNull (ex.ParamName, "#B7");
+                       }
+               }
+
+               [Test] // Object this [String]
+               public void Indexer3_ColumnName_Null ()
+               {
+                       DataTable dt = new DataTable ();
+                       DataColumn dc0 = new DataColumn ("Col0", typeof (Address));
+                       dt.Columns.Add (dc0);
+                       DataColumn dc1 = new DataColumn ("Col1", typeof (Person));
+                       dt.Columns.Add (dc1);
+
+                       Person personA = new Person ("Miguel");
+                       Address addressA = new Address ("X", 5);
+                       Person personB = new Person ("Chris");
+
+                       dt.Rows.Add (new object [] { addressA, personA });
+
+                       DataRow dr = dt.Rows [0];
+
+                       try {
+                               object value = dr [(string) null];
+                               Assert.Fail ("#A1:" + value);
+                       } catch (ArgumentNullException ex) {
+                               Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
+                               Assert.IsNull (ex.InnerException, "#A3");
+                               Assert.IsNotNull (ex.Message, "#A4");
+                               Assert.AreEqual ("name", ex.ParamName, "#A5");
+                       }
+
+                       try {
+                               dr [(string) null] = personB;
+                               Assert.Fail ("#B1");
+                       } catch (ArgumentNullException ex) {
+                               Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
+                               Assert.IsNull (ex.InnerException, "#B3");
+                               Assert.IsNotNull (ex.Message, "#B4");
+                               Assert.AreEqual ("name", ex.ParamName, "#B5");
+                       }
+               }
+
+               [Test] // Object this [String]
+               public void Indexer3_Value_Null ()
+               {
+                       DataTable dt = new DataTable ();
+                       DataColumn dc0 = new DataColumn ("Col0", typeof (Address));
+                       dt.Columns.Add (dc0);
+                       DataColumn dc1 = new DataColumn ("Col1", typeof (Person));
+                       dt.Columns.Add (dc1);
+
+                       Person personA = new Person ("Miguel");
+                       Address addressA = new Address ("X", 5);
+                       Person personB = new Person ("Chris");
+                       Address addressB = new Address ("Y", 4);
+                       Person personC = new Person ("Jackson");
+                       Address addressC = new Address ("Z", 3);
+
+                       dt.Rows.Add (new object [] { addressA, personA });
+                       dt.Rows.Add (new object [] { addressB, personB });
+
+                       DataRow dr = dt.Rows [0];
+
+                       try {
+                               dr ["Col0"] = null;
+                               Assert.Fail ("#A1");
+                       } catch (ArgumentException ex) {
+                               // Cannot set Column 'Col0' to be null.
+                               // Please use DBNull instead
+                               Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
+                               Assert.IsNull (ex.InnerException, "#A3");
+                               Assert.IsNotNull (ex.Message, "#A4");
+                               Assert.IsTrue (ex.Message.IndexOf ("'Col0'") != -1, "#A5");
+                               Assert.IsTrue (ex.Message.IndexOf ("DBNull") != -1, "#A6");
+                       }
+
+                       Assert.AreEqual (addressA, dr ["Col0"], "#B1");
+                       Assert.IsFalse (dr.IsNull ("Col0"), "#B2");
+                       Assert.AreSame (personA, dr ["Col1"], "#B3");
+                       Assert.IsFalse (dr.IsNull ("Col1"), "#B4");
+
+                       dr ["Col1"] = null;
+
+                       Assert.AreEqual (addressA, dr ["Col0"], "#C1");
+                       Assert.IsFalse (dr.IsNull ("Col0"), "#C2");
+                       Assert.AreSame (DBNull.Value, dr ["Col1"], "#C3");
+                       Assert.IsTrue (dr.IsNull ("Col1"), "#C4");
+
+                       dr ["Col0"] = DBNull.Value;
+
+                       Assert.AreSame (DBNull.Value, dr ["Col0"], "#D1");
+                       Assert.IsTrue (dr.IsNull ("Col0"), "#D2");
+                       Assert.AreSame (DBNull.Value, dr ["Col1"], "#D3");
+                       Assert.IsTrue (dr.IsNull ("Col1"), "#D4");
+
+                       dr ["Col1"] = personC;
+                       dr.BeginEdit ();
+                       Assert.AreSame (DBNull.Value, dr ["Col0"], "#E1");
+                       Assert.IsTrue (dr.IsNull ("Col0"), "#E2");
+                       Assert.AreEqual (personC, dr ["Col1"], "#E3");
+                       Assert.IsFalse (dr.IsNull ("Col1"), "#E4");
+                       dr.EndEdit ();
+
+                       dr ["Col1"] = DBNull.Value;
+
+                       Assert.AreSame (DBNull.Value, dr ["Col0"], "#F1");
+                       Assert.IsTrue (dr.IsNull ("Col0"), "#F2");
+                       Assert.AreSame (DBNull.Value, dr ["Col1"], "#F3");
+                       Assert.IsTrue (dr.IsNull ("Col1"), "#F4");
+               }
+
+               [Test] // Object this [DataColumn, DataRowVersion]
+               public void Indexer4 ()
+               {
+                       DataTable dt = new DataTable ();
+                       DataColumn dc0 = new DataColumn ("Col0", typeof (Address));
+                       dt.Columns.Add (dc0);
+                       DataColumn dc1 = new DataColumn ("Col1", typeof (Person));
+                       dt.Columns.Add (dc1);
+
+                       Person personA = new Person ("Miguel");
+                       Address addressA = new Address ("X", 5);
+                       Person personB = new Person ("Chris");
+                       Address addressB = new Address ("Y", 4);
+                       Person personC = new Person ("Jackson");
+                       Address addressC = new Address ("Z", 3);
+
+                       dt.Rows.Add (new object [] { addressA, personA });
+                       dt.Rows.Add (new object [] { addressB, personB });
+                       DataRow dr;
+
+                       dr = dt.Rows [0];
+                       Assert.AreEqual (addressA, dr [dc0, DataRowVersion.Current], "#A1");
+                       Assert.AreEqual (addressA, dr [dc0, DataRowVersion.Default], "#A2");
+                       Assert.IsTrue (AssertNotFound (dr, dc0, DataRowVersion.Original), "#A3");
+                       Assert.IsTrue (AssertNotFound (dr, dc0, DataRowVersion.Proposed), "#A4");
+                       Assert.AreSame (personA, dr [dc1, DataRowVersion.Current], "#A5");
+                       Assert.AreSame (personA, dr [dc1, DataRowVersion.Default], "#A6");
+                       Assert.IsTrue (AssertNotFound (dr, dc1, DataRowVersion.Original), "#A7");
+                       Assert.IsTrue (AssertNotFound (dr, dc1, DataRowVersion.Proposed), "#A8");
+
+                       dr = dt.Rows [1];
+                       Assert.AreEqual (addressB, dr [dc0, DataRowVersion.Current], "#B1");
+                       Assert.AreEqual (addressB, dr [dc0, DataRowVersion.Default], "#B2");
+                       Assert.IsTrue (AssertNotFound (dr, dc0, DataRowVersion.Original), "#B3");
+                       Assert.IsTrue (AssertNotFound (dr, dc0, DataRowVersion.Proposed), "#B4");
+                       Assert.AreSame (personB, dr [dc1, DataRowVersion.Current], "#B5");
+                       Assert.AreSame (personB, dr [dc1, DataRowVersion.Default], "#B6");
+                       Assert.IsTrue (AssertNotFound (dr, dc1, DataRowVersion.Original), "#B7");
+                       Assert.IsTrue (AssertNotFound (dr, dc1, DataRowVersion.Proposed), "#B8");
+
+                       dr = dt.Rows [0];
+                       dr [dc0] = addressC;
+                       Assert.AreEqual (addressC, dr [dc0, DataRowVersion.Current], "#C1");
+                       Assert.AreEqual (addressC, dr [dc0, DataRowVersion.Default], "#C2");
+                       Assert.IsTrue (AssertNotFound (dr, dc0, DataRowVersion.Original), "#C3");
+                       Assert.IsTrue (AssertNotFound (dr, dc0, DataRowVersion.Proposed), "#C4");
+                       Assert.AreSame (personA, dr [dc1, DataRowVersion.Current], "#C5");
+                       Assert.AreSame (personA, dr [dc1, DataRowVersion.Default], "#C6");
+                       Assert.IsTrue (AssertNotFound (dr, dc1, DataRowVersion.Original), "#C7");
+                       Assert.IsTrue (AssertNotFound (dr, dc1, DataRowVersion.Proposed), "#C8");
+
+                       dr = dt.Rows [1];
+                       dr.BeginEdit ();
+                       dr [dc1] = personC;
+                       Assert.AreEqual (addressB, dr [dc0, DataRowVersion.Current], "#D1");
+                       Assert.AreEqual (addressB, dr [dc0, DataRowVersion.Default], "#D2");
+                       Assert.IsTrue (AssertNotFound (dr, dc0, DataRowVersion.Original), "#D3");
+                       Assert.AreEqual (addressB, dr [dc0, DataRowVersion.Proposed], "#D4");
+                       Assert.AreSame (personB, dr [dc1, DataRowVersion.Current], "#D5");
+                       Assert.AreSame (personC, dr [dc1, DataRowVersion.Default], "#D6");
+                       Assert.IsTrue (AssertNotFound (dr, dc1, DataRowVersion.Original), "#D7");
+                       Assert.AreSame (personC, dr [dc1, DataRowVersion.Proposed], "#D8");
+                       dr.EndEdit ();
+                       Assert.AreEqual (addressB, dr [dc0, DataRowVersion.Current], "#D9");
+                       Assert.AreEqual (addressB, dr [dc0, DataRowVersion.Default], "#D10");
+                       Assert.IsTrue (AssertNotFound (dr, dc0, DataRowVersion.Original), "#D11");
+                       Assert.IsTrue (AssertNotFound (dr, dc0, DataRowVersion.Proposed), "#D12");
+                       Assert.AreSame (personC, dr [dc1, DataRowVersion.Current], "#D13");
+                       Assert.AreSame (personC, dr [dc1, DataRowVersion.Default], "#D14");
+                       Assert.IsTrue (AssertNotFound (dr, dc1, DataRowVersion.Original), "#D15");
+                       Assert.IsTrue (AssertNotFound (dr, dc1, DataRowVersion.Proposed), "#D16");
+                       dr.AcceptChanges ();
+                       Assert.AreEqual (addressB, dr [dc0, DataRowVersion.Current], "#D17");
+                       Assert.AreEqual (addressB, dr [dc0, DataRowVersion.Default], "#D18");
+                       Assert.AreEqual (addressB, dr [dc0, DataRowVersion.Original], "#D19");
+                       Assert.IsTrue (AssertNotFound (dr, dc0, DataRowVersion.Proposed), "#D20");
+                       Assert.AreSame (personC, dr [dc1, DataRowVersion.Current], "#D21");
+                       Assert.AreSame (personC, dr [dc1, DataRowVersion.Default], "#D22");
+                       Assert.AreEqual (personC, dr [dc1, DataRowVersion.Original], "#D23");
+                       Assert.IsTrue (AssertNotFound (dr, dc1, DataRowVersion.Proposed), "#D24");
+
+                       dr = dt.Rows [0];
+                       dr.BeginEdit ();
+                       dr [dc0] = addressA;
+                       Assert.AreEqual (addressC, dr [dc0, DataRowVersion.Current], "#E1");
+                       Assert.AreEqual (addressA, dr [dc0, DataRowVersion.Default], "#E2");
+                       Assert.IsTrue (AssertNotFound (dr, dc0, DataRowVersion.Original), "#E3");
+                       Assert.AreEqual (addressA, dr [dc0, DataRowVersion.Proposed], "#E4");
+                       Assert.AreSame (personA, dr [dc1, DataRowVersion.Current], "#E5");
+                       Assert.AreSame (personA, dr [dc1, DataRowVersion.Default], "#E6");
+                       Assert.IsTrue (AssertNotFound (dr, dc1, DataRowVersion.Original), "#E7");
+                       Assert.AreSame (personA, dr [dc1, DataRowVersion.Proposed], "#E8");
+                       dr.CancelEdit ();
+                       Assert.AreEqual (addressC, dr [dc0, DataRowVersion.Current], "#E9");
+                       Assert.AreEqual (addressC, dr [dc0, DataRowVersion.Default], "#E10");
+                       Assert.IsTrue (AssertNotFound (dr, dc0, DataRowVersion.Original), "#E11");
+                       Assert.IsTrue (AssertNotFound (dr, dc0, DataRowVersion.Proposed), "#E12");
+                       Assert.AreSame (personA, dr [dc1, DataRowVersion.Current], "#E13");
+                       Assert.AreSame (personA, dr [dc1, DataRowVersion.Default], "#E14");
+                       Assert.IsTrue (AssertNotFound (dr, dc1, DataRowVersion.Original), "#E15");
+                       Assert.IsTrue (AssertNotFound (dr, dc1, DataRowVersion.Proposed), "#E16");
+               }
+
+               [Test]
+               public void Indexer4_Column_NotInTable ()
+               {
+                       DataTable dtA = new DataTable ("TableA");
+                       DataColumn dcA1 = new DataColumn ("Col0", typeof (Address));
+                       dtA.Columns.Add (dcA1);
+                       DataColumn dcA2 = new DataColumn ("Col1", typeof (Person));
+                       dtA.Columns.Add (dcA2);
+
+                       DataTable dtB = new DataTable ("TableB");
+                       DataColumn dcB1 = new DataColumn ("Col0", typeof (Address));
+                       dtB.Columns.Add (dcB1);
+                       DataColumn dcB2 = new DataColumn ("Col1", typeof (Person));
+                       dtB.Columns.Add (dcB2);
+
+                       Person personA = new Person ("Miguel");
+                       Address addressA = new Address ("X", 5);
+
+                       dtA.Rows.Add (new object [] { addressA, personA });
+                       DataRow dr = dtA.Rows [0];
+
+                       try {
+                               object value = dr [dcB1, DataRowVersion.Default];
+                               Assert.Fail ("#A1:" + value);
+                       } catch (ArgumentException ex) {
+                               // Column 'Col0' does not belong to table TableA
+                               Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
+                               Assert.IsNull (ex.InnerException, "#A3");
+                               Assert.IsNotNull (ex.Message, "#A4");
+                               Assert.IsTrue (ex.Message.IndexOf ("'Col0'") != -1, "#A5");
+                               Assert.IsTrue (ex.Message.IndexOf ("TableA") != -1, "#A6");
+                       }
+
+                       try {
+                               object value = dr [new DataColumn ("ZZZ"), DataRowVersion.Default];
+                               Assert.Fail ("#B1:" + value);
+                       } catch (ArgumentException ex) {
+                               // Column 'Col0' does not belong to table TableA
+                               Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
+                               Assert.IsNull (ex.InnerException, "#B3");
+                               Assert.IsNotNull (ex.Message, "#B4");
+                               Assert.IsTrue (ex.Message.IndexOf ("'ZZZ'") != -1, "#B5");
+                               Assert.IsTrue (ex.Message.IndexOf ("TableA") != -1, "#B6");
+                       }
+
+                       dtA.Columns.Remove (dcA2);
+
+                       try {
+                               object value = dr [dcA2, DataRowVersion.Default];
+                               Assert.Fail ("#C1:" + value);
+                       } catch (ArgumentException ex) {
+                               // Column 'Col0' does not belong to table TableA
+                               Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#C2");
+                               Assert.IsNull (ex.InnerException, "#C3");
+                               Assert.IsNotNull (ex.Message, "#C4");
+                               Assert.IsTrue (ex.Message.IndexOf ("'Col1'") != -1, "#C5");
+                               Assert.IsTrue (ex.Message.IndexOf ("TableA") != -1, "#C6");
+                       }
+               }
+
+               [Test] // Object this [DataColumn, DataRowVersion]
+               public void Indexer4_Column_Null ()
+               {
+                       DataTable dt = new DataTable ();
+                       DataColumn dc0 = new DataColumn ("Col0", typeof (Address));
+                       dt.Columns.Add (dc0);
+                       DataColumn dc1 = new DataColumn ("Col1", typeof (Person));
+                       dt.Columns.Add (dc1);
+
+                       Person personA = new Person ("Miguel");
+                       Address addressA = new Address ("X", 5);
+                       Person personB = new Person ("Chris");
+
+                       dt.Rows.Add (new object [] { addressA, personA });
+                       DataRow dr = dt.Rows [0];
+
+                       try {
+                               object value = dr [(DataColumn) null, DataRowVersion.Default];
+                               Assert.Fail ("#1:" + value);
+                       } catch (ArgumentNullException ex) {
+                               Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
+                               Assert.IsNull (ex.InnerException, "#3");
+                               Assert.IsNotNull (ex.Message, "#4");
+                               Assert.AreEqual ("column", ex.ParamName, "#5");
+                       }
+               }
+
+               [Test] // Object this [DataColumn, DataRowVersion]
+               public void Indexer4_Version_Invalid ()
+               {
+                       DataTable dt = new DataTable ();
+                       DataColumn dc0 = new DataColumn ("Col0", typeof (Address));
+                       dt.Columns.Add (dc0);
+                       DataColumn dc1 = new DataColumn ("Col1", typeof (Person));
+                       dt.Columns.Add (dc1);
+
+                       Person personA = new Person ("Miguel");
+                       Address addressA = new Address ("X", 5);
+                       Person personB = new Person ("Chris");
+
+                       dt.Rows.Add (new object [] { addressA, personA });
+                       DataRow dr = dt.Rows [0];
+
+                       try {
+                               object value = dr [dc0, (DataRowVersion) 666];
+                               Assert.Fail ("#1:" + value);
+                       } catch (DataException ex) {
+                               // Version must be Original, Current, or Proposed
+                               Assert.AreEqual (typeof (DataException), ex.GetType (), "#2");
+                               Assert.IsNull (ex.InnerException, "#3");
+                               Assert.IsNotNull (ex.Message, "#4");
+                               Assert.IsTrue (ex.Message.IndexOf ("Original") != -1, "#5");
+                               Assert.IsTrue (ex.Message.IndexOf ("Current") != -1, "#6");
+                               Assert.IsTrue (ex.Message.IndexOf ("Proposed") != -1, "#7");
+                               Assert.IsFalse (ex.Message.IndexOf ("Default") != -1, "#8");
+                       }
+               }
+
+               [Test] // Object this [DataColumn, DataRowVersion]
+               public void Indexer4_Version_NotFound ()
+               {
+                       DataTable dt = new DataTable ();
+                       DataColumn dc0 = new DataColumn ("Col0", typeof (Address));
+                       dt.Columns.Add (dc0);
+                       DataColumn dc1 = new DataColumn ("Col1", typeof (Person));
+                       dt.Columns.Add (dc1);
+
+                       Person personA = new Person ("Miguel");
+                       Address addressA = new Address ("X", 5);
+                       Person personB = new Person ("Chris");
+
+                       dt.Rows.Add (new object [] { addressA, personA });
+                       DataRow dr = dt.Rows [0];
+
+                       try {
+                               object value = dr [dc0, DataRowVersion.Original];
+                               Assert.Fail ("#A1:" + value);
+                       } catch (VersionNotFoundException ex) {
+                               // There is no Original data to access
+                               Assert.AreEqual (typeof (VersionNotFoundException), ex.GetType (), "#A2");
+                               Assert.IsNull (ex.InnerException, "#A3");
+                               Assert.IsNotNull (ex.Message, "#A4");
+                               Assert.IsTrue (ex.Message.IndexOf ("Original") != -1, "#A5");
+                       }
+
+                       try {
+                               object value = dr [dc0, DataRowVersion.Proposed];
+                               Assert.Fail ("#B1:" + value);
+                       } catch (VersionNotFoundException ex) {
+                               // There is no Proposed data to access
+                               Assert.AreEqual (typeof (VersionNotFoundException), ex.GetType (), "#B2");
+                               Assert.IsNull (ex.InnerException, "#B3");
+                               Assert.IsNotNull (ex.Message, "#B4");
+                               Assert.IsTrue (ex.Message.IndexOf ("Proposed") != -1, "#B5");
+                       }
+               }
+
                [Test] public void IsNull_ByDataColumn()
                {
                        DataTable dt = new DataTable(); 
@@ -945,7 +1977,8 @@ namespace MonoTests.System.Data
                        Assert.AreEqual(true , dr.IsNull(1) , "DRW95");
                }
 
-               [Test] public void IsNull_ByName()
+               [Test]
+               public void IsNull_ByName()
                {
                        DataTable dt = new DataTable(); 
                        DataColumn dc0 = new DataColumn("Col0",typeof(int));
@@ -980,7 +2013,7 @@ namespace MonoTests.System.Data
 
                        foreach( DataRow row in ds.Tables[0].Rows )
                        {
-                               // Console.WriteLine(row["ValueListValueMember"].ToString() + " " );
+                               Console.WriteLine(row["ValueListValueMember"].ToString() + " " );
                                if( row.IsNull("ValueListValueMember") == true )
                                        Assert.AreEqual("Failed", "SubTest", "DRW98");
                                else
@@ -990,6 +2023,59 @@ namespace MonoTests.System.Data
 #endregion
                }
 
+               [Test]
+               public void IsNull_BeforeGetValue ()
+               {
+                       DataTable table = new DataTable ();
+
+                       // add the row, with the value in the column
+                       DataColumn staticColumn = table.Columns.Add ("static", typeof(string), null); // static
+                       DataRow row = table.Rows.Add ("the value");
+                       Assert.IsFalse (row.IsNull ("static"), "static null check failed");
+                       Assert.AreEqual ("the value", row ["static"], "static value check failed");
+
+                       // add the first derived column
+                       DataColumn firstColumn = table.Columns.Add ("first", typeof(string), "static"); // first -> static
+                       Assert.IsFalse (row.IsNull ("first"), "first level null check failed");
+                       Assert.AreEqual ("the value", row ["first"], "first level value check failed");
+
+                       // add the second level of related
+                       DataColumn secondColumn = table.Columns.Add ("second", typeof(string), "first"); // second -> first -> static
+                       Assert.IsFalse (row.IsNull ("second"), "second level null check failed");
+                       Assert.AreEqual ("the value", row ["second"], "second level value check failed");
+               }
+
+               [Test]
+               public void IsNull_NullValueArguments ()
+               {
+                       DataTable table = new DataTable ();
+
+                       // add the row, with the value in the column
+                       DataColumn staticColumn = table.Columns.Add ("static", typeof(string), null);
+                       DataRow row = table.Rows.Add ("the value");
+
+                       try {
+                               row.IsNull ((string)null);
+                               Assert.Fail ("expected an arg null exception for passing a null string");
+                       } catch (ArgumentNullException) {
+                               // do nothing as null columns aren't allowed
+                       }
+
+                       try {
+                               row.IsNull ("");
+                               Assert.Fail ("expected an arg exception for passing an empty string");
+                       } catch (ArgumentException) {
+                               // do nothing as we can't find a col with no name
+                       }
+
+                       try {
+                               row.IsNull (null, DataRowVersion.Default);
+                               Assert.Fail ("null column with version check failed");
+                       } catch (ArgumentNullException) {
+                               // do nothing as null columns aren't allowed
+                       }
+               }
+
                [Test] public void Item()
                {
                        // init table with columns
@@ -1492,7 +2578,7 @@ namespace MonoTests.System.Data
                                drChild.GetParentRows(drl,DataRowVersion.Current); 
                                Assert.Fail("DRW129: failed to throw ArgumentException");
                        }
-                       catch (ArgumentException) {}
+                       catch (InvalidConstraintException) {}
                        catch (AssertionException exc) {throw  exc;}
                        catch (Exception exc)
                        {
@@ -1664,8 +2750,6 @@ namespace MonoTests.System.Data
                        _rowChanged = true;
                }
 
-#if NET_2_0
-               string SetAddedModified_ErrMsg = "SetAdded and SetModified can only be called on DataRows with Unchanged DataRowState.";
                [Test]
                public void SetAdded_test()
                {
@@ -1676,7 +2760,6 @@ namespace MonoTests.System.Data
                                row.SetAdded();
                                Assert.Fail ("#1");
                        } catch (InvalidOperationException e) {
-                               Assert.AreEqual (SetAddedModified_ErrMsg, e.Message, "#2");
                        }
 
                        table.Columns.Add("col1", typeof(int));
@@ -1689,7 +2772,6 @@ namespace MonoTests.System.Data
                                row.SetAdded();
                                Assert.Fail ("#2");
                        } catch (InvalidOperationException e) {
-                               Assert.AreEqual (SetAddedModified_ErrMsg, e.Message, "#2");
                        }
                        Assert.AreEqual(DataRowState.Added, row.RowState, "#2");
 
@@ -1700,7 +2782,6 @@ namespace MonoTests.System.Data
                                row.SetAdded();
                                Assert.Fail ("#3");
                        } catch (InvalidOperationException e) {
-                               Assert.AreEqual (SetAddedModified_ErrMsg, e.Message, "#2");
                        }
 
                        row.AcceptChanges();
@@ -1744,7 +2825,8 @@ namespace MonoTests.System.Data
                                row.SetModified();
                                Assert.Fail ("#1");
                        } catch (InvalidOperationException e) {
-                               Assert.AreEqual (SetAddedModified_ErrMsg, e.Message, "#2");
+                               // Never premise English.
+                               //Assert.AreEqual (SetAddedModified_ErrMsg, e.Message, "#2");
                        }
 
                        row.AcceptChanges();
@@ -1754,7 +2836,8 @@ namespace MonoTests.System.Data
                                row.SetModified ();
                                Assert.Fail ("#2");
                        } catch (InvalidOperationException e) {
-                               Assert.AreEqual (SetAddedModified_ErrMsg, e.Message, "#2");
+                               // Never premise English.
+                               //Assert.AreEqual (SetAddedModified_ErrMsg, e.Message, "#2");
                        }
 
                        row.AcceptChanges();
@@ -1780,6 +2863,126 @@ namespace MonoTests.System.Data
                        table.RejectChanges ();
                        Assert.AreEqual(row.RowState, DataRowState.Unchanged, "#3");
                }
-#endif
+               [Test]
+               public void DataRowExpressionDefaultValueTest ()
+               {
+                       DataSet ds = new DataSet ();
+                       DataTable custTable = ds.Tables.Add ("CustTable");
+
+                       DataColumn column = new DataColumn ("units", typeof (int));
+                       column.AllowDBNull = false;
+                       column.Caption = "Units";
+                       column.DefaultValue = 1;
+                       custTable.Columns.Add (column);
+
+                       column = new DataColumn ("price", typeof (decimal));
+                       column.AllowDBNull = false;
+                       column.Caption = "Price";
+                       column.DefaultValue = 25;
+                       custTable.Columns.Add (column);
+
+                       column = new DataColumn ("total", typeof (string));
+                       column.Caption = "Total";
+                       column.Expression = "price*units";
+                       custTable.Columns.Add (column);
+
+                       DataRow row = custTable.NewRow ();
+
+                       Assert.AreEqual (DBNull.Value, row["Total"] , "#1 Should be System.DBNull");
+                       custTable.Rows.Add (row);
+
+                       Assert.AreEqual ("25", row["Total"] , "#2 Should not be emptry string");
+               }
+
+               void ColumnChanged (object sender, DataColumnChangeEventArgs e)
+               {
+                       _eventsFired.Add (new EventInfo ("ColumnChanged", e));
+               }
+
+               void ColumnChanging (object sender, DataColumnChangeEventArgs e)
+               {
+                       _eventsFired.Add (new EventInfo ("ColumnChanging", e));
+               }
+
+               class EventInfo
+               {
+                       public EventInfo (string name, EventArgs args)
+                       {
+                               this.name = name;
+                               this.args = args;
+                       }
+
+                       public string Name {
+                               get { return name; }
+                       }
+
+                       public EventArgs Args {
+                               get { return args; }
+                       }
+
+                       private readonly string name;
+                       private readonly EventArgs args;
+               }
+
+               static bool AssertNotFound (DataRow rc, DataColumn dc, DataRowVersion version)
+               {
+                       try {
+                               object value = rc [dc, version];
+                               return false;
+                       } catch (VersionNotFoundException) {
+                               return true;
+                       }
+               }
+
+               class Person
+               {
+                       public Person (string name)
+                       {
+                               this.Name = name;
+                       }
+
+                       public string Name;
+                       public Address HomeAddress;
+               }
+
+               struct Address
+               {
+                       public Address (string street, int houseNumber)
+                       {
+                               Street = street;
+                               HouseNumber = houseNumber;
+                       }
+
+                       public override bool Equals (object o)
+                       {
+                               if (!(o is Address))
+                                       return false;
+
+                               Address address = (Address) o;
+                               if (address.HouseNumber != HouseNumber)
+                                       return false;
+                               if (address.Street != Street)
+                                       return false;
+                               return true;
+                       }
+
+                       public override int GetHashCode ()
+                       {
+                               if (Street == null)
+                                       return HouseNumber.GetHashCode ();
+                               return (Street.GetHashCode () ^ HouseNumber.GetHashCode ());
+                       }
+
+                       public override string ToString ()
+                       {
+                               if (Street == null)
+                                       return HouseNumber.ToString (CultureInfo.InvariantCulture);
+
+                               return string.Concat (Street, HouseNumber.ToString (CultureInfo.InvariantCulture));
+                       }
+
+                       public string Street;
+                       public int HouseNumber;
+               }
        }
 }