2004-08-18 Umadevi S <sumadevi@novell.com>
authorUmadevi S <uma@mono-cvs.ximian.com>
Wed, 18 Aug 2004 03:44:21 +0000 (03:44 -0000)
committerUmadevi S <uma@mono-cvs.ximian.com>
Wed, 18 Aug 2004 03:44:21 +0000 (03:44 -0000)
        * DataView.cs - Completed most of the event handling.
        * DataTable.cs - Changed Access modifiers of class/methods since it was used by DataView

svn path=/trunk/mcs/; revision=32475

mcs/class/System.Data/System.Data/ChangeLog
mcs/class/System.Data/System.Data/DataTable.cs
mcs/class/System.Data/System.Data/DataView.cs

index 78cc45ac10114a7bfdcf04f4038c4e11c223d3af..5d5b4fe096a79e3dc469c773d2a700c126a419c7 100644 (file)
@@ -1,3 +1,9 @@
+2004-08-18 Umadevi S <sumadevi@novell.com>
+       * DataView.cs - Completed most of the event handling. 
+       Thanks to Punit Todi <punit_todi@da-iict.org> for implementing most of it.
+       Thanks to Boris Kirzner <borisk@mainsoft.com> for commenting and suggesting changes to the implementation.
+       * DataTable.cs - Changed Access modifiers of class/methods since it was used by DataView.
+
 2004-08-06  Atsushi Enomoto  <atsushi@ximian.com>
 
        * DataSet.cs : DataSet's ExtendedProperties were not XmlConverted.
index c8f06e7ec0bd6f00383bb1d1d3f8f70a9e64cfaf..410a15ecc2e8ae1e15f42497973e5da4e59188b7 100644 (file)
@@ -1699,7 +1699,7 @@ namespace System.Data {
                // to parse the sort string for DataTable:Select(expression,sort)
                // into sortable columns (think ORDER BY, 
                // such as, "customer ASC, price DESC" )
-               private SortableColumn[] ParseTheSortString (string sort) 
+               internal SortableColumn[] ParseTheSortString (string sort) 
                {
                        SortableColumn[] sortColumns = null;
                        ArrayList columns = null;
@@ -1747,7 +1747,7 @@ namespace System.Data {
                        return sortColumns;
                }
        
-               private class SortableColumn 
+               internal class SortableColumn 
                {
                        private DataColumn col;
                        private ListSortDirection dir;
index d25bfc5bf67091a76a0b50b4c4df45bffd16116c..e4912d307db625204a6825200f1056d3b205e7e6 100644 (file)
-//
-// System.Data.DataView.cs
-//
-// Author:
-//    Daniel Morgan <danmorg@sc.rr.com>
-//    Tim Coleman (tim@timcoleman.com)
-//
-// Copyright (C) Daniel Morgan, 2002, 2003
-// (C) Ximian, Inc 2002
-// Copyright (C) Tim Coleman, 2002-2003
-//
-
-//
-// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System;
-using System.Collections;
-using System.ComponentModel;
-using System.Reflection;
-
-namespace System.Data 
-{
-       /// <summary>
-       /// A DataView is used in the binding of data between
-       /// a DataTable and Windows Forms or Web Forms allowing
-       /// a view of a DataTable for editing, filtering,
-       /// navigation, searching, and sorting.
-       /// </summary>
-       //[Designer]
-       [Editor]
-       [DefaultEvent ("PositionChanged")]
-       [DefaultProperty ("Table")]
-       [DesignerAttribute ("Microsoft.VSDesigner.Data.VS.DataViewDesigner, "+ Consts.AssemblyMicrosoft_VSDesigner, "System.ComponentModel.Design.IDesigner")]
-       public class DataView : MarshalByValueComponent, IBindingList, IList, ICollection, IEnumerable, ITypedList, ISupportInitialize
-       {
-               DataTable dataTable = null;
-               string rowFilter = "";
-               string sort = "";
-               DataViewRowState rowState;
-               DataRowView[] rowCache = null;
-               
-               // FIXME: what are the default values?
-               bool allowNew = true; 
-               bool allowEdit = true;
-               bool allowDelete = true;
-               bool applyDefaultSort = false;
-               bool isSorted = false;
-
-               bool isOpen = false;
-
-               bool bInit = false;
-               
-               internal DataViewManager dataViewManager = null;
-
-               public DataView () 
-               {
-                       dataTable = new DataTable ();
-                       rowState = DataViewRowState.CurrentRows;
-                       Open ();
-               }
-
-               public DataView (DataTable table) 
-               {
-                       dataTable = table;
-                       rowState = DataViewRowState.CurrentRows;
-                       Open ();
-               }
-
-               public DataView (DataTable table, string RowFilter,
-                               string Sort, DataViewRowState RowState) 
-               {
-                       dataTable = table;
-                       rowState = DataViewRowState.CurrentRows;
-                       rowFilter = RowFilter;
-                       sort = Sort;
-                       rowState = RowState;
-                       Open();
-               }
-
-               [DataCategory ("Data")]
-               [DataSysDescription ("Indicates whether this DataView and the user interface associated with it allows deletes.")]
-               [DefaultValue (true)]
-               public bool AllowDelete {
-                       get {
-                               return allowDelete;
-                       }
-                       set {
-                               allowDelete = value;
-                       }
-               }
-
-               [DataCategory ("Data")]
-               [DataSysDescription ("Indicates whether this DataView and the user interface associated with it allows edits.")]
-               [DefaultValue (true)]
-               public bool AllowEdit {
-                       get {
-                               return allowEdit;
-                       }
-                       set {
-                               allowEdit = value;
-                       }
-               }
-
-               [DataCategory ("Data")]
-               [DataSysDescription ("Indicates whether this DataView and the user interface associated with it allows new rows to be added.")]
-               [DefaultValue (true)]
-               public bool AllowNew {
-                       get {
-                               return allowNew;
-                       }
-                       
-                       set {
-                               allowNew = value;
-                       }
-               }
-
-               [DataCategory ("Data")]
-               [DataSysDescription ("Indicates whether to use the default sort if the Sort property is not set.")]
-               [DefaultValue (false)]
-               [RefreshProperties (RefreshProperties.All)]
-               public bool ApplyDefaultSort {
-                       [MonoTODO]
-                       get {                           
-                               return applyDefaultSort;
-                       }
-                       
-                       [MonoTODO]
-                       set {
-                               applyDefaultSort = value;
-                               // FIXME: update the index cache to the DataTable, and 
-                               //        only refresh the index when the DataTable
-                               //        has changes via column, row, or constraint
-                               //        changed events
-                               UpdateIndex ();
-                       }
-               }
-
-               // get the count of rows in the DataView after RowFilter 
-               // and RowStateFilter have been applied
-               [Browsable (false)]
-               [DataSysDescription ("Returns the number of items currently in this view.")]
-               public int Count {
-                       [MonoTODO]
-                       get {
-                               // FIXME: remove this line once collection change
-                               //        events from the DataTable are handled
-                               UpdateIndex ();
-
-                               return rowCache.Length;;
-                       }
-               }
-
-               [Browsable (false)]
-               [DataSysDescription ("This returns a pointer to back to the DataViewManager that owns this DataSet (if any).")]
-               public DataViewManager DataViewManager {
-                       [MonoTODO]
-                       get {
-                               return dataViewManager;
-                       }
-               }
-
-               // Item indexer
-               // the compiler creates a DefaultMemeberAttribute from
-               // this IndexerNameAttribute
-               [System.Runtime.CompilerServices.IndexerName("Item")]
-               public DataRowView this[int recordIndex] {
-                       [MonoTODO]
-                       get {
-                               // FIXME: use index cache to the DataTable, and 
-                               //        only refresh the index when the DataTable
-                               //        has changes via column, row, or constraint
-                               //        changed events
-                               // Remove this line once changed events are handled
-                               UpdateIndex ();
-                               
-                               return rowCache[recordIndex];
-                       }
-               }
-
-               [DataCategory ("Data")]
-               [DataSysDescription ("Indicates an expression used to filter the data returned by this DataView.")]
-               [DefaultValue ("")]
-               public virtual string RowFilter {
-                       [MonoTODO]
-                       get {
-                               return rowFilter;
-                       }
-                       
-                       [MonoTODO]
-                       set {
-                               rowFilter = value;
-                               // FIXME: update the index cache to the DataTable, and 
-                               //        only refresh the index when the DataTable
-                               //        has changes via column, row, or constraint
-                               //        changed events
-                               UpdateIndex ();
-                       }
-               }
-
-               [DataCategory ("Data")]
-               [DataSysDescription ("Indicates the versions of data returned by this DataView.")]
-               [DefaultValue (DataViewRowState.CurrentRows)]
-               public DataViewRowState RowStateFilter {
-                       [MonoTODO]
-                       get {
-                               return rowState;
-                       }
-                       
-                       [MonoTODO]
-                       set {
-                               rowState = value;
-                               // FIXME: update the index cache to the DataTable, and 
-                               //        only refresh the index when the DataTable
-                               //        has changes via column, row, or constraint
-                               //        changed events
-                               UpdateIndex ();
-                       }
-               }
-
-               [DataCategory ("Data")]
-               [DataSysDescription ("Indicates the order in which data is returned by this DataView.")]
-               [DefaultValue ("")]
-               public string Sort {
-                       [MonoTODO]
-                       get {
-                               return sort;
-                       }
-                       
-                       [MonoTODO]
-                       set {
-                               sort = value;
-                               // FIXME: update the index cache to the DataTable, and 
-                               //        only refresh the index when the DataTable
-                               //        has changes via column, row, or constraint
-                               //        changed events
-                               UpdateIndex ();
-                               OnListChanged (new ListChangedEventArgs (ListChangedType.Reset, - 1, -1));
-                       }
-               }
-
-               [DataCategory ("Data")]
-               [DataSysDescription ("Indicates the table this DataView uses to get data.")]
-               [DefaultValue (null)]
-               [RefreshProperties (RefreshProperties.All)]
-               [TypeConverter (typeof(DataTableTypeConverter))]
-               public DataTable Table {
-                       [MonoTODO]
-                       get {
-                               return dataTable;
-                       }
-                       
-                       [MonoTODO]
-                       set {
-                               dataTable = value;
-                               // FIXME: update the index cache to the DataTable, and 
-                               //        only refresh the index when the DataTable
-                               //        has changes via column, row, or constraint
-                               //        changed events
-                               UpdateIndex ();
-                       }
-               }
-
-               [MonoTODO]
-               public virtual DataRowView AddNew() 
-               {
-                       if (!IsOpen)
-                               throw new DataException ("DataView is not open.");
-                       if (!AllowNew)
-                               throw new DataException ("Cannot call AddNew on a DataView where AllowNew is false.");
-                       
-                       DataRow row = dataTable.NewRow ();
-                       DataRowView rowView = new DataRowView (this, row, true);
-                       
-                       dataTable.Rows.Add (row);
-
-                       UpdateIndex ();
-                       OnListChanged (new ListChangedEventArgs (ListChangedType.ItemAdded, rowCache.Length - 1,-1));
-                       return rowView;
-               }
-
-               [MonoTODO]
-               public void BeginInit() 
-               {
-                       bInit = true; 
-                       // FIXME:
-               }
-
-               [MonoTODO]
-               public void CopyTo (Array array, int index) 
-               {
-                       // FIXME: use index cache to the DataTable, and 
-                       //        only refresh the index when the DataTable
-                       //        has changes via column, row, or constraint
-                       //        changed events
-                       UpdateIndex ();
-                       
-                       int row = 0;
-                       for (; row < rowCache.Length && row < array.Length; row++) {
-                               array.SetValue (rowCache[row], index + row);
-                       }
-                       if (row < array.Length) {
-                               for (int r = 0; r < array.Length; r++) {
-                                       array.SetValue (null, index + r);
-                               }
-                       }
-               }
-
-               public void Delete(int index) 
-               {
-                       if (!IsOpen)
-                               throw new DataException ("DataView is not open.");
-                       if (!AllowDelete)
-                               throw new DataException ("Cannot delete on a DataSource where AllowDelete is false.");
-                       
-                       UpdateIndex ();
-
-                       if (index > rowCache.Length)
-                               throw new IndexOutOfRangeException ("There is no row at " +
-                                               "position: " + index + ".");
-                       
-                       DataRowView row = rowCache [index];
-                       row.Row.Delete ();
-
-                       OnListChanged (new ListChangedEventArgs (ListChangedType.ItemDeleted, index));
-               }
-
-#if NET_2_0
-               [MonoTODO]
-               public virtual bool Equals (DataView dv)
-               {
-                       throw new NotImplementedException ();
-               }
-#endif
-
-               [MonoTODO]
-               public void EndInit() 
-               {
-                       bInit = false;
-                       // FIXME:
-               }
-
-               [MonoTODO]
-               public int Find(object key) 
-               {
-                       // FIXME: use index cache to the DataTable, and 
-                       //        only refresh the index when the DataTable
-                       //        has changes via column, row, or constraint
-                       //        changed events
-
-                       throw new NotImplementedException ();
-               }
-
-               [MonoTODO]
-               public int Find(object[] key) 
-               {
-                       // FIXME: use an index cache to the DataTable, and 
-                       //        only refresh the index when the DataTable
-                       //        has changes via column, row, or constraint
-                       //        changed events
-
-                       throw new NotImplementedException ();
-               }
-
-               [MonoTODO]
-               public DataRowView[] FindRows(object key) 
-               {
-                       // FIXME: use an index cache to the DataTable, and 
-                       //        only refresh the index when the DataTable
-                       //        has changes via column, row, or constraint
-                       //        changed events
-
-                       throw new NotImplementedException ();
-               }
-
-               [MonoTODO]
-               public DataRowView[] FindRows(object[] key) 
-               {
-                       // FIXME: use an index cache to the DataTable, and 
-                       //        only refresh the index when the DataTable
-                       //        has changes via column, row, or constraint
-                       //        changed events
-                       
-                       throw new NotImplementedException ();
-               }
-
-               [MonoTODO]
-               public IEnumerator GetEnumerator() 
-               {
-                       // FIXME: use an index cache to the DataTable, and 
-                       //        only refresh the index when the DataTable
-                       //        has changes via column, row, or constraint
-                       //        changed events
-                       UpdateIndex ();                                 
-
-                       return new DataViewEnumerator (rowCache);
-               }
-               
-               [MonoTODO]
-               [DataCategory ("Data")]
-               [DataSysDescription ("Indicates the data returned by this DataView has somehow changed.")]
-               public event ListChangedEventHandler ListChanged;
-
-               [Browsable (false)]
-               [DataSysDescription ("DataViewIsOpenDescr")]
-               protected bool IsOpen {
-                       [MonoTODO]
-                       get {
-                               return isOpen;
-                       }
-               }
-
-               [MonoTODO]
-               protected void Close() 
-               {
-                       // FIXME:
-                       isOpen = false;
-               }
-
-               [MonoTODO]
-               protected virtual void ColumnCollectionChanged (object sender, 
-                                                       CollectionChangeEventArgs e) 
-               {
-                       throw new NotImplementedException ();
-               }
-
-               protected override void Dispose (bool disposing) 
-               {
-                       if (disposing)
-                               Close ();
-
-                       base.Dispose (disposing);
-               }
-
-               [MonoTODO]
-               protected virtual void IndexListChanged(object sender, ListChangedEventArgs e) 
-               {
-                       throw new NotImplementedException ();
-               }
-
-               [MonoTODO]
-               protected virtual void OnListChanged(ListChangedEventArgs e) 
-               {
-                       try {
-                               if (ListChanged != null)
-                                       ListChanged (this, e);
-                       } catch {
-                       }
-               }
-
-               internal void ChangedList(ListChangedType listChangedType, int newIndex,int oldIndex)
-               {
-                       ListChangedEventArgs e = new ListChangedEventArgs(listChangedType,newIndex,oldIndex);
-                       OnListChanged(e);
-               }
-
-               [MonoTODO]
-               protected void Open() 
-               {
-                       // FIXME: create the initial index cache to the DataTable, and 
-                       //        only refresh the index when the DataTable
-                       //        has changes via column, row, or constraint
-                       //        changed events. the index cache is generally
-                       //        a DataViewRow array that points to the actual
-                       //        DataRows in the this DataTable's DataRowCollection;
-                       //        this index is really a cache that gets 
-                       //        created during Open(), gets Updated 
-                       //        when various properties of this view
-                       //        changes, gets Updated when this DataTable's 
-                       //        row, column, or constraint collections have changed.
-                       //        I'm not sure what else.
-                       //        The data view will know one of the DataTable's
-                       //        collections have changed via one of 
-                       //        its changed events.
-                       //        Otherwise, if getting a/the DataRowView(s),
-                       //        Count, or other properties, then just use the
-                       //        index cache.
-                       UpdateIndex (true);
-                       isOpen = true;
-               }
-
-               // internal use by Mono
-               protected void Reset() 
-               {
-                       // TODO: what really happens?
-                       Close ();
-                       rowCache = null;
-                       Open ();
-                       OnListChanged (new ListChangedEventArgs (ListChangedType.Reset, -1));
-               }
-
-#if NET_2_0
-               [MonoTODO]
-               public DataTable ToTable ()
-               {
-                       throw new NotImplementedException ();
-               }
-
-               [MonoTODO]
-               public DataTable ToTable (bool isDistinct, string[] columnNames)
-               {
-                       throw new NotImplementedException ();
-               }
-#endif
-
-               // internal use by Mono
-               protected virtual void UpdateIndex () 
-               {
-                       UpdateIndex (false);
-               }
-
-               // This is method is internal to 
-               // the Mono implementation of DataView; it
-               // is not to be used from your code.
-               //
-               // Update the DataRowView array which is an index cache
-               // into the DataTable's DataRowCollection.
-               //
-               // I assume this is what UpdateIndex is used for
-               protected virtual void UpdateIndex(bool force) 
-               {
-                       DataRowView[] newRowCache = null;
-                       DataRow[] rows = null;
-                       
-                       rows = dataTable.Select (RowFilter, Sort, RowStateFilter);
-
-                       newRowCache = new DataRowView[rows.Length];
-                       for (int r = 0; r < rows.Length; r++) {
-                               newRowCache[r] = new DataRowView (this, rows[r]);
-                       }
-                       rowCache = newRowCache;
-               }
-
-               [MonoTODO]
-               PropertyDescriptorCollection ITypedList.GetItemProperties (PropertyDescriptor[] listAccessors) 
-               {
-                       // FIXME: use listAccessors somehow
-
-                       DataColumnPropertyDescriptor[] descriptors = 
-                               new DataColumnPropertyDescriptor[dataTable.Columns.Count];
-
-                       DataColumnPropertyDescriptor descriptor;
-                       DataColumn dataColumn;
-                       for (int col = 0; col < dataTable.Columns.Count; col ++)
-                       {
-                               dataColumn = dataTable.Columns[col];
-                               
-                               descriptor = new DataColumnPropertyDescriptor(
-                                       dataColumn.ColumnName, col, null);
-                               descriptor.SetComponentType (typeof (System.Data.DataRowView));
-                               descriptor.SetPropertyType (dataColumn.DataType);
-                               descriptor.SetReadOnly (dataColumn.ReadOnly);
-
-                               descriptors[col] = descriptor;
-                       }
-
-                       return new PropertyDescriptorCollection (descriptors);
-               }
-
-               [MonoTODO]
-               string ITypedList.GetListName (PropertyDescriptor[] listAccessors) 
-               {
-                       return "";
-               }
-
-               //int ICollection.Count { 
-               //      get {
-               //              return Count;
-               //      } 
-               //}
-
-               bool ICollection.IsSynchronized { 
-                       [MonoTODO]
-                       get {
-                               return false;
-                       } 
-               }
-
-               object ICollection.SyncRoot { 
-                       [MonoTODO]
-                       get {
-                               // FIXME:
-                               return this;
-                       }
-               }
-
-               //void ICollection.CopyTo (Array array, int index) 
-               //{
-               //      CopyTo (array, index);
-               //}
-
-               bool IList.IsFixedSize {
-                       [MonoTODO]
-                       get {
-                               return false;
-                       }
-               }
-               
-               bool IList.IsReadOnly {
-                       [MonoTODO]
-                       get {
-                               return false;
-                       }
-               }
-
-               object IList.this[int recordIndex] {
-                       [MonoTODO]
-                       get {
-                               return this[recordIndex];
-                       }
-
-                       [MonoTODO]
-                       set{
-                               throw new InvalidOperationException();
-                       }
-               }
-
-               [MonoTODO]
-               int IList.Add (object value) 
-               {
-                       throw new NotImplementedException ();
-               }
-
-               [MonoTODO]
-               void IList.Clear () 
-               {
-                       throw new NotImplementedException ();
-               }
-
-               [MonoTODO]
-               bool IList.Contains (object value) 
-               {
-                       throw new NotImplementedException ();
-               }
-
-               [MonoTODO]
-               int IList.IndexOf (object value) 
-               {
-                       throw new NotImplementedException ();
-               }
-                       
-               [MonoTODO]
-               void IList.Insert(int index,object value) 
-               {
-                       throw new NotImplementedException ();
-               }
-
-               [MonoTODO]
-               void IList.Remove(object value) 
-               {
-                       throw new NotImplementedException ();
-               }
-
-               [MonoTODO]
-               void IList.RemoveAt(int index) 
-               {
-                       throw new NotImplementedException ();
-               }
-
-               #region IBindingList implementation
-
-               [MonoTODO]
-               void IBindingList.AddIndex (PropertyDescriptor property) 
-               {
-                       throw new NotImplementedException ();
-               }
-
-               [MonoTODO]
-               object IBindingList.AddNew () 
-               {
-                       throw new NotImplementedException ();
-               }
-
-               [MonoTODO]
-               void IBindingList.ApplySort (PropertyDescriptor property, ListSortDirection direction) 
-               {
-                       throw new NotImplementedException ();
-               }
-
-               [MonoTODO]
-               int IBindingList.Find (PropertyDescriptor property, object key) 
-               {
-                       throw new NotImplementedException ();
-               }
-
-               [MonoTODO]
-               void IBindingList.RemoveIndex (PropertyDescriptor property) 
-               {
-                       throw new NotImplementedException ();
-               }
-
-               [MonoTODO]
-               void IBindingList.RemoveSort () 
-               {
-                       throw new NotImplementedException ();
-               }
-               
-               bool IBindingList.AllowEdit {
-                       [MonoTODO]
-                       get {
-                               return AllowEdit;
-                       }
-               }
-
-               bool IBindingList.AllowNew {
-                       [MonoTODO]
-                       get {
-                               return AllowNew;
-                       }
-               }
-
-               bool IBindingList.AllowRemove {
-                       [MonoTODO]
-                       get {
-                               return AllowDelete;
-                       }
-               }
-
-               bool IBindingList.IsSorted {
-                       [MonoTODO]
-                       get {
-                               return isSorted;
-                       }
-               }
-
-               ListSortDirection IBindingList.SortDirection {
-                       [MonoTODO]
-                       get {
-                               // FIXME: 
-                               return ListSortDirection.Ascending;
-                       }
-               }
-
-               PropertyDescriptor IBindingList.SortProperty {
-                       [MonoTODO]
-                       get {
-                               // FIXME:
-                               return null;
-                       }
-               }
-
-               bool IBindingList.SupportsChangeNotification {
-                       [MonoTODO]
-                       get {
-                               return false;
-                       }
-               }
-
-               bool IBindingList.SupportsSearching {
-                       [MonoTODO]
-                       get {
-                               return false;
-                       }
-               }
-
-               bool IBindingList.SupportsSorting {
-                       [MonoTODO]
-                       get {
-                               return false;
-                       }
-               }
-
-               #endregion // IBindingList implementation
-
-               private class DataViewEnumerator : IEnumerator 
-               {
-                       private DataRowView[] rows;
-                       int on = -1;
-
-                       internal DataViewEnumerator (DataRowView[] dataRowViews) 
-                       {
-                               rows = dataRowViews;
-                       }
-
-                       public object Current {
-                               get {
-                                       if (on == -1 || on >= rows.Length)
-                                               throw new InvalidOperationException ();
-                                       return rows[on];
-                               }
-                       }
-
-                       public bool MoveNext () 
-                       {
-                               // TODO: how do you determine
-                               // if a collection has been
-                               // changed?
-                               if (on < rows.Length - 1) {
-                                       on++;
-                                       return true;
-                               }
-
-                               return false; // EOF
-                       }
-
-                       public void Reset () {
-                               on = -1;
-                       }
-               }
-       }
-}
-
+//\r
+// System.Data.DataView.cs\r
+//\r
+// Author:\r
+//    Daniel Morgan <danmorg@sc.rr.com>\r
+//    Tim Coleman (tim@timcoleman.com)\r
+//    Punit Todi (punits_mailbox@yahoo.com)\r
+// Copyright (C) Daniel Morgan, 2002, 2003\r
+// (C) Ximian, Inc 2002\r
+// Copyright (C) Tim Coleman, 2002-2003                \r
+\r
+using System;\r
+using System.Collections;\r
+using System.ComponentModel;\r
+using System.Reflection;\r
+\r
+namespace System.Data \r
+{\r
+       /// <summary>\r
+       /// A DataView is used in the binding of data between\r
+       /// a DataTable and Windows Forms or Web Forms allowing\r
+       /// a view of a DataTable for editing, filtering,\r
+       /// navigation, searching, and sorting.\r
+       /// </summary>\r
+       //[Designer]\r
+       [Editor]\r
+       [DefaultEvent ("PositionChanged")]\r
+       [DefaultProperty ("Table")]\r
+       [DesignerAttribute ("Microsoft.VSDesigner.Data.VS.DataViewDesigner, "+ Consts.AssemblyMicrosoft_VSDesigner, "System.ComponentModel.Design.IDesigner")]\r
+       public class DataView : MarshalByValueComponent, IBindingList, IList, ICollection, IEnumerable, ITypedList, ISupportInitialize\r
+       {\r
+               DataTable dataTable = null;\r
+               string rowFilter = "";\r
+               string sort = "";\r
+               DataViewRowState rowState;\r
+               DataRowView[] rowCache = null;\r
+               \r
+               \r
+               bool allowNew = true; \r
+               bool allowEdit = true;\r
+               bool allowDelete = true;\r
+               bool applyDefaultSort = false;\r
+               bool isSorted = false;\r
+\r
+               bool isOpen = false;\r
+\r
+               bool bInit = false;\r
+               bool useDefaultSort = true;\r
+               \r
+               internal DataViewManager dataViewManager = null;\r
+               #region Constructors\r
+               public DataView () \r
+               {\r
+                       rowState = DataViewRowState.CurrentRows;\r
+                       Open ();\r
+               }\r
+\r
+               public DataView (DataTable table) \r
+               {\r
+                       dataTable = table;\r
+                       rowState = DataViewRowState.CurrentRows;\r
+                       Open ();\r
+               }\r
+\r
+               public DataView (DataTable table, string RowFilter,\r
+                               string Sort, DataViewRowState RowState) \r
+               {\r
+                       dataTable = table;\r
+                       rowState = DataViewRowState.CurrentRows;\r
+                       rowFilter = RowFilter;\r
+                       sort = Sort;\r
+                       rowState = RowState;\r
+                       Open();\r
+               }\r
+               #endregion // Constructors\r
+               #region PublicProperties\r
+               [DataCategory ("Data")]\r
+               [DataSysDescription ("Indicates whether this DataView and the user interface associated with it allows deletes.")]\r
+               [DefaultValue (true)]\r
+               public bool AllowDelete {\r
+                       get {\r
+                               return allowDelete;\r
+                       }\r
+                       set {\r
+                               allowDelete = value;\r
+                       }\r
+               }\r
+\r
+               [DataCategory ("Data")]\r
+               [DataSysDescription ("Indicates whether this DataView and the user interface associated with it allows edits.")]\r
+               [DefaultValue (true)]\r
+               public bool AllowEdit {\r
+                       get {\r
+                               return allowEdit;\r
+                       }\r
+                       set {\r
+                               allowEdit = value;\r
+                       }\r
+               }\r
+\r
+               [DataCategory ("Data")]\r
+               [DataSysDescription ("Indicates whether this DataView and the user interface associated with it allows new rows to be added.")]\r
+               [DefaultValue (true)]\r
+               public bool AllowNew {\r
+                       get {\r
+                               return allowNew;\r
+                       }\r
+                       \r
+                       set {\r
+                               allowNew = value;\r
+                       }\r
+               }\r
+\r
+               [DataCategory ("Data")]\r
+               [DataSysDescription ("Indicates whether to use the default sort if the Sort property is not set.")]\r
+               [DefaultValue (false)]\r
+               [RefreshProperties (RefreshProperties.All)]\r
+               public bool ApplyDefaultSort {\r
+                       [MonoTODO]\r
+                       get {                           \r
+                               return applyDefaultSort;\r
+                       }\r
+                       \r
+                       [MonoTODO]\r
+                       set {\r
+                               applyDefaultSort = value;\r
+                               if (applyDefaultSort == true && (sort == null || sort == string.Empty)) {\r
+                                       foreach (Constraint c in dataTable.Constraints) {\r
+                                               if (c is UniqueConstraint) {\r
+                                                       sort = GetSortString ((UniqueConstraint) c);\r
+                                                       break;\r
+                                               }\r
+                                       }\r
+                               }\r
+                               UpdateIndex ();\r
+                               OnListChanged (new ListChangedEventArgs (ListChangedType.Reset,-1,-1));\r
+                       }\r
+               }\r
+               // get the count of rows in the DataView after RowFilter \r
+               // and RowStateFilter have been applied\r
+               [Browsable (false)]\r
+               [DataSysDescription ("Returns the number of items currently in this view.")]\r
+               public int Count {\r
+                       [MonoTODO]\r
+                       get {\r
+                               return rowCache.Length;\r
+                       }\r
+               }\r
+\r
+               [Browsable (false)]\r
+               [DataSysDescription ("This returns a pointer to back to the DataViewManager that owns this DataSet (if any).")]\r
+               public DataViewManager DataViewManager {\r
+                       [MonoTODO]\r
+                       get {\r
+                               return dataViewManager;\r
+                       }\r
+               }\r
+\r
+               // Item indexer\r
+               // the compiler creates a DefaultMemeberAttribute from\r
+               // this IndexerNameAttribute\r
+               [System.Runtime.CompilerServices.IndexerName("Item")]\r
+               public DataRowView this[int recordIndex] {\r
+                       [MonoTODO]\r
+                       get {\r
+                               return rowCache [recordIndex];\r
+                       }\r
+               }\r
+\r
+               [DataCategory ("Data")]\r
+               [DataSysDescription ("Indicates an expression used to filter the data returned by this DataView.")]\r
+               [DefaultValue ("")]\r
+               public virtual string RowFilter {\r
+                       [MonoTODO]\r
+                       get {\r
+                               return rowFilter;\r
+                       }\r
+                       \r
+                       [MonoTODO]\r
+                       set {\r
+                               rowFilter = value;\r
+                               UpdateIndex ();\r
+                               OnListChanged (new ListChangedEventArgs (ListChangedType.Reset, - 1, -1));\r
+                       }\r
+               }\r
+\r
+               [DataCategory ("Data")]\r
+               [DataSysDescription ("Indicates the versions of data returned by this DataView.")]\r
+               [DefaultValue (DataViewRowState.CurrentRows)]\r
+               public DataViewRowState RowStateFilter {\r
+                       [MonoTODO]\r
+                       get {\r
+                               return rowState;\r
+                       }\r
+                       \r
+                       [MonoTODO]\r
+                       set {\r
+                               rowState = value;\r
+                               UpdateIndex ();\r
+                               OnListChanged (new ListChangedEventArgs (ListChangedType.Reset, - 1, -1));\r
+                       }\r
+               }\r
+\r
+               [DataCategory ("Data")]\r
+               [DataSysDescription ("Indicates the order in which data is returned by this DataView.")]\r
+               [DefaultValue ("")]\r
+               public string Sort {\r
+                       [MonoTODO]\r
+                       get {\r
+                               return sort;\r
+                       }\r
+                       \r
+                       [MonoTODO]\r
+                       set {\r
+                               if (value == null) {    \r
+                               /* if given value is null useDefaultSort */\r
+                                       useDefaultSort = true;\r
+                                       /* if ApplyDefault sort is true try appling it */\r
+                                       if (ApplyDefaultSort == true) {\r
+                                               foreach (Constraint c in dataTable.Constraints) {\r
+                                                       if (c is UniqueConstraint) {\r
+                                                               sort = GetSortString ((UniqueConstraint)c);\r
+                                                               break;\r
+                                                       }\r
+                                               }\r
+                                               \r
+                                       }\r
+                               }\r
+                               else {  \r
+                                       /* else donot useDefaultSort. set it as false */\r
+                                       /* sort is set to value specified */\r
+                                       useDefaultSort = false;\r
+                                       sort = value;\r
+                               }\r
+                               UpdateIndex ();\r
+                               OnListChanged (new ListChangedEventArgs (ListChangedType.Reset, - 1, -1));\r
+                       }\r
+               }\r
+\r
+               [DataCategory ("Data")]\r
+               [DataSysDescription ("Indicates the table this DataView uses to get data.")]\r
+               [DefaultValue (null)]\r
+               [RefreshProperties (RefreshProperties.All)]\r
+               public DataTable Table {\r
+                       [MonoTODO]\r
+                       get {\r
+                               return dataTable;\r
+                       }\r
+                       \r
+                       [MonoTODO]\r
+                       set {\r
+                               if (value != null && value.TableName.Equals("")) {\r
+                                       throw new DataException("Cannot bind to DataTable with no name.");\r
+                               }\r
+\r
+                               if (dataTable != null) {\r
+                                       UnregisterEventHandlers();\r
+                               }\r
+\r
+                               dataTable = value;\r
+\r
+                               if (dataTable != null) {\r
+                                       RegisterEventHandlers();\r
+                                       UpdateIndex ();\r
+                                       OnListChanged (new ListChangedEventArgs (ListChangedType.Reset, - 1, -1));\r
+                               }\r
+                       }\r
+               }\r
+               #endregion // PublicProperties\r
+               \r
+               #region PublicMethods\r
+               [MonoTODO]\r
+               public virtual DataRowView AddNew() \r
+               {\r
+                       if (!IsOpen)\r
+                               throw new DataException ("DataView is not open.");\r
+                       if (!AllowNew)\r
+                               throw new DataException ("Cannot call AddNew on a DataView where AllowNew is false.");\r
+                       \r
+                       DataRow row = dataTable.NewRow ();\r
+                       if (row == null)\r
+                               throw new Exception ("Row not created");\r
+                       DataRowView rowView = new DataRowView (this, row, true);\r
+                       \r
+                       dataTable.Rows.Add (row);\r
+                       return rowView;\r
+               }\r
+\r
+               [MonoTODO]\r
+               public void BeginInit() \r
+               {\r
+                       bInit = true; \r
+                       // FIXME:\r
+               }\r
+\r
+               [MonoTODO]\r
+               public void CopyTo (Array array, int index) \r
+               {\r
+                       int row = 0;\r
+                       for (; row < rowCache.Length && row < array.Length; row++) {\r
+                               array.SetValue (rowCache[row], index + row);\r
+                       }\r
+               }\r
+\r
+               public void Delete(int index) \r
+               {\r
+                       if (!IsOpen)\r
+                               throw new DataException ("DataView is not open.");\r
+                       if (!AllowDelete)\r
+                               throw new DataException ("Cannot delete on a DataSource where AllowDelete is false.");\r
+                       \r
+                       if (index > rowCache.Length)\r
+                               throw new IndexOutOfRangeException ("There is no row at " +\r
+                                               "position: " + index + ".");\r
+                       DataRowView row = rowCache [index];\r
+                       row.Row.Delete ();\r
+               }\r
+\r
+#if NET_2_0\r
+               [MonoTODO]\r
+               public virtual bool Equals (DataView dv)\r
+               {\r
+                       throw new NotImplementedException ();\r
+               }\r
+#endif\r
+\r
+               [MonoTODO]\r
+               public void EndInit() \r
+               {\r
+                       bInit = false;\r
+                       // FIXME:\r
+               }\r
+\r
+               public int Find(object key) \r
+               {\r
+                       object [] keys = new object[1];\r
+                       keys[0] = key;\r
+                       return Find(keys);\r
+               }\r
+               \r
+               public int Find(object[] key) \r
+               {\r
+                       int index; \r
+                       if (sort == null || sort == string.Empty)\r
+                               throw new ArgumentException ("Find finds a row based on a Sort order, and no Sort order is specified");\r
+                       else {\r
+                               DataTable.SortableColumn [] sortedColumns = null;\r
+                               sortedColumns = dataTable.ParseTheSortString (sort);\r
+                               if (sortedColumns == null)\r
+                                       throw new Exception ("sort expression result is null");\r
+                               if (sortedColumns.Length == 0)\r
+                                       throw new Exception ("sort expression result is 0");\r
+                               if (sortedColumns.Length != key.Length)\r
+                                       throw new ArgumentException ("Expecting " + sortedColumns.Length +\r
+                                               " value(s) from the key being indexed, but recieved "+\r
+                                               key.Length+" value(s).");\r
+                               RowComparer rowComparer = new RowComparer (dataTable,sortedColumns);\r
+                               int searchResult = Array.BinarySearch (rowCache,key,rowComparer);\r
+                               if (searchResult < 0)\r
+                                       return -1;\r
+                               else\r
+                                       return searchResult;\r
+                       }\r
+               }\r
+               \r
+               [MonoTODO]\r
+               public DataRowView[] FindRows(object key) \r
+               {\r
+                       // FIXME: use an index cache to the DataTable, and \r
+                       //        only refresh the index when the DataTable\r
+                       //        has changes via column, row, or constraint\r
+                       //        changed events\r
+\r
+                       throw new NotImplementedException ();\r
+               }\r
+\r
+               [MonoTODO]\r
+               public DataRowView[] FindRows(object[] key) \r
+               {\r
+                       // FIXME: use an index cache to the DataTable, and \r
+                       //        only refresh the index when the DataTable\r
+                       //        has changes via column, row, or constraint\r
+                       //        changed events\r
+                       \r
+                       throw new NotImplementedException ();\r
+               }\r
+\r
+               [MonoTODO]\r
+               public IEnumerator GetEnumerator() \r
+               {\r
+                       return new DataViewEnumerator (rowCache);\r
+               }\r
+               #endregion // PublicMethods\r
+               \r
+               [MonoTODO]\r
+               [DataCategory ("Data")]\r
+               [DataSysDescription ("Indicates the data returned by this DataView has somehow changed.")]\r
+               public event ListChangedEventHandler ListChanged;\r
+\r
+               protected bool IsOpen {\r
+                       [MonoTODO]\r
+                       get {\r
+                               return isOpen;\r
+                       }\r
+               }\r
+\r
+               [MonoTODO]\r
+               protected void Close() \r
+               {\r
+                       // FIXME:\r
+                       isOpen = false;\r
+               }\r
+\r
+               [MonoTODO]\r
+               protected virtual void ColumnCollectionChanged (object sender, \r
+                                                       CollectionChangeEventArgs e) \r
+               {\r
+                       throw new NotImplementedException ();\r
+               }\r
+\r
+               protected override void Dispose (bool disposing) \r
+               {\r
+                       if (disposing)\r
+                               Close ();\r
+\r
+                       base.Dispose (disposing);\r
+               }\r
+\r
+               [MonoTODO]\r
+               protected virtual void IndexListChanged(object sender, ListChangedEventArgs e) \r
+               {\r
+                       throw new NotImplementedException ();\r
+               }\r
+\r
+               [MonoTODO]\r
+               protected virtual void OnListChanged(ListChangedEventArgs e) \r
+               {\r
+                       try {\r
+                               if (ListChanged != null)\r
+                                       ListChanged (this, e);\r
+                       } catch {\r
+                       }\r
+               }\r
+\r
+               internal void ChangedList(ListChangedType listChangedType, int newIndex,int oldIndex)\r
+               {\r
+                       ListChangedEventArgs e = new ListChangedEventArgs(listChangedType,newIndex,oldIndex);\r
+                       OnListChanged(e);\r
+               }\r
+\r
+               [MonoTODO]\r
+               protected void Open() \r
+               {\r
+                       // FIXME: create the initial index cache to the DataTable, and \r
+                       //        only refresh the index when the DataTable\r
+                       //        has changes via column, row, or constraint\r
+                       //        changed events. the index cache is generally\r
+                       //        a DataViewRow array that points to the actual\r
+                       //        DataRows in the this DataTable's DataRowCollection;\r
+                       //        this index is really a cache that gets \r
+                       //        created during Open(), gets Updated \r
+                       //        when various properties of this view\r
+                       //        changes, gets Updated when this DataTable's \r
+                       //        row, column, or constraint collections have changed.\r
+                       //        I'm not sure what else.\r
+                       //        The data view will know one of the DataTable's\r
+                       //        collections have changed via one of \r
+                       //        its changed events.\r
+                       //        Otherwise, if getting a/the DataRowView(s),\r
+                       //        Count, or other properties, then just use the\r
+                       //        index cache.\r
+                       //              dataTable.ColumnChanged  += new DataColumnChangeEventHandler(OnColumnChanged);\r
+                       if (dataTable != null) {\r
+                               RegisterEventHandlers();\r
+                               UpdateIndex (true);\r
+                       }\r
+                       isOpen = true;\r
+               }\r
+               \r
+               private void RegisterEventHandlers()\r
+               {\r
+                       dataTable.RowChanged     += new DataRowChangeEventHandler(OnRowChanged);\r
+                       dataTable.RowDeleted     += new DataRowChangeEventHandler(OnRowDeleted);\r
+                       dataTable.Columns.CollectionChanged += new CollectionChangeEventHandler(OnColumnCollectionChanged);\r
+                       dataTable.Constraints.CollectionChanged += new CollectionChangeEventHandler(OnConstraintCollectionChanged);\r
+               }\r
+\r
+               private void UnregisterEventHandlers()\r
+               {\r
+                       dataTable.RowChanged     -= new DataRowChangeEventHandler(OnRowChanged);\r
+                       dataTable.RowDeleted     -= new DataRowChangeEventHandler(OnRowDeleted);\r
+                       dataTable.Columns.CollectionChanged -= new CollectionChangeEventHandler(OnColumnCollectionChanged);\r
+                       dataTable.Constraints.CollectionChanged -= new CollectionChangeEventHandler(OnConstraintCollectionChanged);\r
+               }\r
+               \r
+               private void OnColumnChanged(object sender, DataColumnChangeEventArgs args)\r
+               {       /* not used */\r
+                       UpdateIndex(true);\r
+               }\r
+               \r
+               private void OnRowChanged(object sender, DataRowChangeEventArgs args)\r
+               {\r
+                       int oldIndex,newIndex;\r
+                       oldIndex = newIndex = -1;\r
+                       oldIndex = IndexOf (args.Row);\r
+                       UpdateIndex (true);\r
+                       newIndex = IndexOf (args.Row);\r
+\r
+                       /* ItemAdded */\r
+                       if(args.Action == DataRowAction.Add)\r
+                       {       \r
+                               OnListChanged (new ListChangedEventArgs (ListChangedType.ItemAdded, newIndex, -1));\r
+                       }\r
+                               \r
+                       /* ItemChanged or ItemMoved */\r
+                       if (args.Action == DataRowAction.Change) { \r
+                               if (oldIndex == newIndex)\r
+                               OnListChanged (new ListChangedEventArgs (ListChangedType.ItemChanged, newIndex, -1)); \r
+                               else\r
+                               OnListChanged (new ListChangedEventArgs (ListChangedType.ItemMoved, newIndex, oldIndex)); \r
+                       }\r
+               }\r
+               \r
+               private void OnRowDeleted (object sender, DataRowChangeEventArgs args)\r
+               {\r
+                       /* ItemDeleted */\r
+                       int newIndex;\r
+                       newIndex = IndexOf (args.Row);\r
+                       UpdateIndex (true);\r
+                       OnListChanged (new ListChangedEventArgs (ListChangedType.ItemDeleted, newIndex, -1));\r
+               }\r
+               \r
+               private void OnColumnCollectionChanged (object sender, CollectionChangeEventArgs args)\r
+               {\r
+                       UpdateIndex (true);\r
+                       /* PropertyDescriptor Add */\r
+                       if (args.Action == CollectionChangeAction.Add)\r
+                               OnListChanged (new ListChangedEventArgs (ListChangedType.PropertyDescriptorAdded,0,0));\r
+                       /* PropertyDescriptor Removed */\r
+                       if (args.Action == CollectionChangeAction.Remove)\r
+                               OnListChanged (new ListChangedEventArgs (ListChangedType.PropertyDescriptorDeleted,0,0));\r
+                       /* FIXME: PropertyDescriptor Changed ???*/\r
+                       if (args.Action == CollectionChangeAction.Refresh)\r
+                               OnListChanged (new ListChangedEventArgs (ListChangedType.PropertyDescriptorChanged,0,0));\r
+               }\r
+               private void OnConstraintCollectionChanged(object sender, CollectionChangeEventArgs args)\r
+               {\r
+                       //      The Sort variable is set to the UniqueConstraint column.\r
+                       //  if ApplyDefault Sort is true and Sort is null or is not set Explicitly\r
+                       \r
+                       // FIXME: The interal cache may change as result of change in Constraint collection\r
+                       // one such scenerio is taken care.\r
+                       // There may be more. I dont know what else can be done.\r
+                       /* useDefaultSort is set to false when Sort is set explicitly */\r
+                       if (args.Action == CollectionChangeAction.Add && args.Element is UniqueConstraint) {\r
+                               if (ApplyDefaultSort == true && useDefaultSort == true)\r
+                                               Sort = GetSortString ((UniqueConstraint) args.Element);\r
+                       }\r
+                       UpdateIndex (true);\r
+                       /* ItemReset */\r
+                       OnListChanged (new ListChangedEventArgs (ListChangedType.Reset,-1,-1));\r
+               }\r
+\r
+               // internal use by Mono\r
+               protected void Reset() \r
+               {\r
+                       // TODO: what really happens?\r
+                       Close ();\r
+                       rowCache = null;\r
+                       Open ();\r
+                       OnListChanged (new ListChangedEventArgs (ListChangedType.Reset, -1 ));\r
+               }\r
+\r
+#if NET_2_0\r
+               [MonoTODO]\r
+               public DataTable ToTable ()\r
+               {\r
+                       throw new NotImplementedException ();\r
+               }\r
+\r
+               [MonoTODO]\r
+               public DataTable ToTable (bool isDistinct, string[] columnNames)\r
+               {\r
+                       throw new NotImplementedException ();\r
+               }\r
+#endif\r
+\r
+               // internal use by Mono\r
+               protected virtual void UpdateIndex () \r
+               {\r
+                       UpdateIndex (false);\r
+               }\r
+\r
+               // This is method is internal to \r
+               // the Mono implementation of DataView; it\r
+               // is not to be used from your code.\r
+               //\r
+               // Update the DataRowView array which is an index cache\r
+               // into the DataTable's DataRowCollection.\r
+               //\r
+               // I assume this is what UpdateIndex is used for\r
+               protected virtual void UpdateIndex(bool force) \r
+               {\r
+                       DataRowView[] newRowCache = null;\r
+                       DataRow[] rows = null;\r
+                       \r
+                       rows = dataTable.Select (RowFilter, Sort, RowStateFilter);\r
+\r
+                       newRowCache = new DataRowView[rows.Length];\r
+                       for (int r = 0; r < rows.Length; r++) {\r
+                               newRowCache[r] = new DataRowView (this, rows[r]);\r
+                       }\r
+                       rowCache = newRowCache;\r
+               }\r
+\r
+               [MonoTODO]\r
+               PropertyDescriptorCollection ITypedList.GetItemProperties (PropertyDescriptor[] listAccessors) \r
+               {\r
+                       // FIXME: use listAccessors somehow\r
+                       DataColumnPropertyDescriptor [] descriptors = \r
+                               new DataColumnPropertyDescriptor [dataTable.Columns.Count];\r
+\r
+                       DataColumnPropertyDescriptor descriptor;\r
+                       DataColumn dataColumn;\r
+                       for (int col = 0; col < dataTable.Columns.Count; col ++) {\r
+                               dataColumn = dataTable.Columns[col];\r
+                               descriptor = new DataColumnPropertyDescriptor(\r
+                                       dataColumn.ColumnName, col, null);\r
+                               descriptor.SetComponentType (typeof (System.Data.DataRowView));\r
+                               descriptor.SetPropertyType (dataColumn.DataType);\r
+                               descriptor.SetReadOnly (dataColumn.ReadOnly);\r
+                               descriptors [col] = descriptor;\r
+                       }\r
+                       return new PropertyDescriptorCollection (descriptors);\r
+               }\r
+\r
+               [MonoTODO]\r
+               string ITypedList.GetListName (PropertyDescriptor[] listAccessors) \r
+               {\r
+                       return "";\r
+               }\r
+\r
+               //int ICollection.Count { \r
+               //      get {\r
+               //              return Count;\r
+               //      } \r
+               //}\r
+\r
+               bool ICollection.IsSynchronized { \r
+                       [MonoTODO]\r
+                       get {\r
+                               return false;\r
+                       } \r
+               }\r
+\r
+               object ICollection.SyncRoot { \r
+                       [MonoTODO]\r
+                       get {\r
+                               // FIXME:\r
+                               return this;\r
+                       }\r
+               }\r
+\r
+               //void ICollection.CopyTo (Array array, int index) \r
+               //{\r
+               //      CopyTo (array, index);\r
+               //}\r
+\r
+               bool IList.IsFixedSize {\r
+                       [MonoTODO]\r
+                       get {\r
+                               return false;\r
+                       }\r
+               }\r
+               \r
+               bool IList.IsReadOnly {\r
+                       [MonoTODO]\r
+                       get {\r
+                               return false;\r
+                       }\r
+               }\r
+\r
+               object IList.this[int recordIndex] {\r
+                       [MonoTODO]\r
+                       get {\r
+                               return this[recordIndex];\r
+                       }\r
+\r
+                       [MonoTODO]\r
+                       set{\r
+                               throw new InvalidOperationException();\r
+                       }\r
+               }\r
+\r
+               [MonoTODO]\r
+               int IList.Add (object value) \r
+               {\r
+                       throw new NotImplementedException ();\r
+               }\r
+\r
+               [MonoTODO]\r
+               void IList.Clear () \r
+               {\r
+                       throw new NotImplementedException ();\r
+               }\r
+\r
+               [MonoTODO]\r
+               bool IList.Contains (object value) \r
+               {\r
+                       throw new NotImplementedException ();\r
+               }\r
+\r
+               [MonoTODO]\r
+               int IList.IndexOf (object value) \r
+               {\r
+                       throw new NotImplementedException ();\r
+               }\r
+                       \r
+               [MonoTODO]\r
+               void IList.Insert(int index,object value) \r
+               {\r
+                       throw new NotImplementedException ();\r
+               }\r
+\r
+               [MonoTODO]\r
+               void IList.Remove(object value) \r
+               {\r
+                       throw new NotImplementedException ();\r
+               }\r
+\r
+               [MonoTODO]\r
+               void IList.RemoveAt(int index) \r
+               {\r
+                       throw new NotImplementedException ();\r
+               }\r
+\r
+               #region IBindingList implementation\r
+\r
+               [MonoTODO]\r
+               void IBindingList.AddIndex (PropertyDescriptor property) \r
+               {\r
+                       throw new NotImplementedException ();\r
+               }\r
+\r
+               [MonoTODO]\r
+               object IBindingList.AddNew () \r
+               {\r
+                       throw new NotImplementedException ();\r
+               }\r
+\r
+               [MonoTODO]\r
+               void IBindingList.ApplySort (PropertyDescriptor property, ListSortDirection direction) \r
+               {\r
+                       throw new NotImplementedException ();\r
+               }\r
+\r
+               [MonoTODO]\r
+               int IBindingList.Find (PropertyDescriptor property, object key) \r
+               {\r
+                       throw new NotImplementedException ();\r
+               }\r
+\r
+               [MonoTODO]\r
+               void IBindingList.RemoveIndex (PropertyDescriptor property) \r
+               {\r
+                       throw new NotImplementedException ();\r
+               }\r
+\r
+               [MonoTODO]\r
+               void IBindingList.RemoveSort () \r
+               {\r
+                       throw new NotImplementedException ();\r
+               }\r
+               \r
+               bool IBindingList.AllowEdit {\r
+                       [MonoTODO]\r
+                       get {\r
+                               return AllowEdit;\r
+                       }\r
+               }\r
+\r
+               bool IBindingList.AllowNew {\r
+                       [MonoTODO]\r
+                       get {\r
+                               return AllowNew;\r
+                       }\r
+               }\r
+\r
+               bool IBindingList.AllowRemove {\r
+                       [MonoTODO]\r
+                       get {\r
+                               return AllowDelete;\r
+                       }\r
+               }\r
+\r
+               bool IBindingList.IsSorted {\r
+                       [MonoTODO]\r
+                       get {\r
+                               return isSorted;\r
+                       }\r
+               }\r
+\r
+               ListSortDirection IBindingList.SortDirection {\r
+                       [MonoTODO]\r
+                       get {\r
+                               // FIXME: \r
+                               return ListSortDirection.Ascending;\r
+                       }\r
+               }\r
+\r
+               PropertyDescriptor IBindingList.SortProperty {\r
+                       [MonoTODO]\r
+                       get {\r
+                               // FIXME:\r
+                               return null;\r
+                       }\r
+               }\r
+\r
+               bool IBindingList.SupportsChangeNotification {\r
+                       [MonoTODO]\r
+                       get {\r
+                               return false;\r
+                       }\r
+               }\r
+\r
+               bool IBindingList.SupportsSearching {\r
+                       [MonoTODO]\r
+                       get {\r
+                               return false;\r
+                       }\r
+               }\r
+\r
+               bool IBindingList.SupportsSorting {\r
+                       [MonoTODO]\r
+                       get {\r
+                               return false;\r
+                       }\r
+               }\r
+\r
+               #endregion // IBindingList implementation\r
+               private int IndexOf(DataRow dr)\r
+               {\r
+                       for (int i=0; i < rowCache.Length; i++)\r
+                               if (dr.Equals (rowCache [i].Row))\r
+                                       return i;\r
+                       return -1;\r
+               }\r
+               \r
+               private string GetSortString (UniqueConstraint uc)\r
+               {\r
+                       string sortKey = null;\r
+                       foreach (DataColumn dc in uc.Columns)\r
+                               sortKey += dc.ColumnName + ", ";\r
+                       sortKey = sortKey.Substring (0,sortKey.Length - 2);\r
+                       return sortKey;\r
+               }\r
+               \r
+               private object [] GetSearchKey (DataRow dr)\r
+               {\r
+                       DataTable.SortableColumn [] sortedColumns = null;\r
+                       sortedColumns = dataTable.ParseTheSortString (sort);\r
+                       if (sortedColumns == null) \r
+                               return null;\r
+                       object [] keys = new object [sortedColumns.Length];\r
+                       int i = 0;\r
+                       foreach (DataTable.SortableColumn sc in sortedColumns) {\r
+                               keys [i] = dr [sc.Column];\r
+                               i++;\r
+                       }\r
+                       return keys;\r
+               }\r
+\r
+               private class DataViewEnumerator : IEnumerator \r
+               {\r
+                       private DataRowView [] rows;\r
+                       int on = -1;\r
+\r
+                       internal DataViewEnumerator (DataRowView [] dataRowViews) \r
+                       {\r
+                               rows = dataRowViews;\r
+                       }\r
+\r
+                       public object Current {\r
+                               get {\r
+                                       if (on == -1 || on >= rows.Length)\r
+                                               throw new InvalidOperationException ();\r
+                                       return rows [on];\r
+                               }\r
+                       }\r
+\r
+                       public bool MoveNext () \r
+                       {\r
+                               // TODO: how do you determine\r
+                               // if a collection has been\r
+                               // changed?\r
+                               if (on < rows.Length - 1) {\r
+                                       on++;\r
+                                       return true;\r
+                               }\r
+\r
+                               return false; // EOF\r
+                       }\r
+\r
+                       public void Reset () {\r
+                               on = -1;\r
+                       }\r
+               }\r
+               \r
+               private class RowComparer : IComparer \r
+               {\r
+                       private DataTable.SortableColumn [] sortColumns;\r
+                       private DataTable table;\r
+                       public RowComparer(DataTable table, DataTable.SortableColumn[] sortColumns) \r
+                       {\r
+                               this.table = table;                     \r
+                               this.sortColumns = sortColumns;\r
+                       }\r
+\r
+                       public DataTable.SortableColumn[] SortedColumns {\r
+                               get {\r
+                                       return sortColumns;\r
+                               }\r
+                       }\r
+                       \r
+                       int IComparer.Compare (object x, object y) \r
+                       {\r
+                               if(x == null)\r
+                                       throw new Exception ("Object to compare is null: x");\r
+                               if(y == null)\r
+                                       throw new Exception ("Object to compare is null: y");\r
+                               DataRowView rowView = (DataRowView) y;\r
+                               object [] keys = (object [])x;\r
+                               for(int i = 0; i < sortColumns.Length; i++) {\r
+                                       DataTable.SortableColumn sortColumn = sortColumns [i];\r
+                                       DataColumn dc = sortColumn.Column;\r
+\r
+                                       IComparable row = (IComparable) rowView.Row [dc];\r
+                                       object key = keys [i];\r
+                                       \r
+                                       int result = CompareObjects (key,row);\r
+                                       if (result != 0) {\r
+                                               if (sortColumn.SortDirection == ListSortDirection.Ascending)\r
+                                                       return result;\r
+                                               else \r
+                                                       return -result;\r
+                                       }\r
+                               }\r
+                               return 0;\r
+                       }\r
+\r
+                       private int CompareObjects (object a, object b) \r
+                       {\r
+                               if (a == b)\r
+                                       return 0;\r
+                               else if (a == null)\r
+                                       return -1;\r
+                               else if (a == DBNull.Value)\r
+                                       return -1;\r
+                               else if (b == null)\r
+                                       return 1;\r
+                               else if (b == DBNull.Value)\r
+                                       return 1;\r
+\r
+                               if((a is string) && (b is string)) {\r
+                                       a = ((string) a).ToUpper (table.Locale);\r
+                                       b = ((string) b).ToUpper (table.Locale);                        \r
+                               }\r
+\r
+                               if (a is IComparable)\r
+                                       return ((a as IComparable).CompareTo (b));\r
+                               else if (b is IComparable)\r
+                                       return -((b as IComparable).CompareTo (a));\r
+\r
+                               throw new ArgumentException ("Neither a nor b IComparable");\r
+                       }\r
+               }\r
+\r
+       }\r
+}\r