Mark tests as not working under TARGET_JVM
[mono.git] / mcs / class / corlib / System.Collections.Generic / List.cs
index 6e8811f2d5dbf8ed23f9be6af1a9662ab874b734..a9d82d3539ec2f4c368cbbaddf9999ae85ac621c 100644 (file)
@@ -5,12 +5,10 @@
 //    Ben Maurer (bmaurer@ximian.com)
 //    Martin Baulig (martin@ximian.com)
 //    Carlos Alberto Cortez (calberto.cortez@gmail.com)
+//    David Waite (mass@akuma.org)
 //
-// (C) 2004 Novell, Inc.
-//
-
-//
-// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2005 David Waite
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 //
 
 #if NET_2_0
-using System;
-using System.Collections;
+
+using System.Collections.ObjectModel;
 using System.Runtime.InteropServices;
 
-namespace System.Collections.Generic
-{
-       [CLSCompliant(false)]
-       [ComVisible(false)]
-       public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable
-       {
-               T [] data;
-               int size;
-               int version;
-                       
+namespace System.Collections.Generic {
+       [Serializable]
+       public class List <T> : IList <T>, IList, ICollection {
+               T [] _items;
+               int _size;
+               int _version;
+               
+               static readonly T [] EmptyArray = new T [0]; 
                const int DefaultCapacity = 4;
                
                public List ()
                {
+                       _items = EmptyArray;
                }
                
                public List (IEnumerable <T> collection)
                {
-                       AddRange (collection);
+                       CheckCollection (collection);
+
+                       // initialize to needed size (if determinable)
+                       ICollection <T> c = collection as ICollection <T>;
+                       if (c == null)
+                       {
+                               _items = EmptyArray;
+                               AddEnumerable (collection);
+                       }
+                       else
+                       {
+                               _items = new T [c.Count];
+                               AddCollection (c);
+                       }
                }
                
                public List (int capacity)
                {
-                       data = new T [capacity];
+                       if (capacity < 0)
+                               throw new ArgumentOutOfRangeException ("capacity");
+                       _items = new T [capacity];
                }
                
+               internal List (T [] data, int size)
+               {
+                       _items = data;
+                       _size = size;
+               }
                public void Add (T item)
                {
-                       if (data == null)
-                               Capacity = DefaultCapacity;
-                       else if (size == data.Length)
-                               Capacity = Math.Max (Capacity * 2, DefaultCapacity);
-                       
-                       data [size ++] = item;
+                       GrowIfNeeded (1);
+                       _items [_size ++] = item;
+                       _version++;
                }
                
-               public void CheckRange (int idx, int count)
+               void GrowIfNeeded (int newCount)
                {
-                       if (idx < 0 || count < 0 || idx > size - count)
-                               throw new ArgumentOutOfRangeException ();
+                       int minimumSize = _size + newCount;
+                       if (minimumSize > _items.Length)
+                               Capacity = Math.Max (Math.Max (Capacity * 2, DefaultCapacity), minimumSize);
+               }
+               
+               void CheckRange (int idx, int count)
+               {
+                       if (idx < 0)
+                               throw new ArgumentOutOfRangeException ("index");
+                       
+                       if (count < 0)
+                               throw new ArgumentOutOfRangeException ("count");
+
+                       if ((uint) idx + (uint) count > (uint) _size)
+                               throw new ArgumentException ("index and count exceed length of list");
                }
                
-               [MonoTODO ("PERFORMANCE: fix if it is an IList <T>")]
-               public void AddRange(IEnumerable<T> collection)
+               void AddCollection (ICollection <T> collection)
                {
-                       foreach (T t in collection)
+                       int collectionCount = collection.Count;
+                       GrowIfNeeded (collectionCount);                  
+                       collection.CopyTo (_items, _size);
+                       _size += collectionCount;
+               }
+               void AddEnumerable (IEnumerable <T> enumerable)
+               {
+                       foreach (T t in enumerable)
+                       {
                                Add (t);
+                       }
+               }
+
+               public void AddRange (IEnumerable <T> collection)
+               {
+                       CheckCollection (collection);
+                       
+                       ICollection <T> c = collection as ICollection <T>;
+                       if (c != null)
+                               AddCollection (c);
+                       else
+                               AddEnumerable (collection);
+                       _version++;
                }
                
-               public IList<T> AsReadOnly ()
+               public ReadOnlyCollection <T> AsReadOnly ()
                {
-                       return new ReadOnlyList<T>(this);
+                       return new ReadOnlyCollection <T> (this);
                }
                
-               public int BinarySearch(T item)
+               public int BinarySearch (T item)
                {
-                       return BinarySearch (item, Comparer <T>.Default);
+                       return Array.BinarySearch <T> (_items, 0, _size, item);
                }
                
-               public int BinarySearch(T item, IComparer<T> comparer)
+               public int BinarySearch (T item, IComparer <T> comparer)
                {
-                       return BinarySearch (0, size, item, comparer);
+                       return Array.BinarySearch <T> (_items, 0, _size, item, comparer);
                }
                
-               public int BinarySearch(int index, int count, T item, IComparer<T> comparer)
+               public int BinarySearch (int index, int count, T item, IComparer <T> comparer)
                {
                        CheckRange (index, count);
-                       return Array.BinarySearch (data, index, size, item, comparer);
+                       return Array.BinarySearch <T> (_items, index, count, item, comparer);
                }
                
                public void Clear ()
                {
-                       if (data == null)
-                               return;
-                       
-                       Array.Clear (data, 0, data.Length);
+                       Array.Clear (_items, 0, _items.Length);
+                       _size = 0;
+                       _version++;
                }
                
                public bool Contains (T item)
                {
-                       return IndexOf (item) != -1;
+                       EqualityComparer<T> equalityComparer = EqualityComparer<T>.Default;
+                       for (int i = 0; i < _size; i++)
+                               if (equalityComparer.Equals (_items[i], item))
+                                       return true;
+                       return false;
                }
                
-               public List <U> ConvertAll <U> (Converter<T, U> converter)
+               public List <TOutput> ConvertAll <TOutput> (Converter <T, TOutput> converter)
                {
-                       List <U> u = new List <U> (size);
-                       int i = 0;
+                       if (converter == null)
+                               throw new ArgumentNullException ("converter");
+                       List <TOutput> u = new List <TOutput> (_size);
                        foreach (T t in this)
-                               u [i ++] = converter (t);
-                       
+                               u.Add (converter (t));
                        return u;
                }
                
                public void CopyTo (T [] array)
                {
-                       CopyTo (array, 0);
+                       Array.Copy (_items, 0, array, 0, _size);
                }
                
                public void CopyTo (T [] array, int arrayIndex)
                {
-                       CopyTo (0, array, arrayIndex, size);
+                       Array.Copy (_items, 0, array, arrayIndex, _size);
                }
                
-               public void CopyTo (int index, T[] array, int arrayIndex, int count)
+               public void CopyTo (int index, T [] array, int arrayIndex, int count)
                {
                        CheckRange (index, count);
-                       Array.Copy (data, index, array, arrayIndex, count);
+                       Array.Copy (_items, index, array, arrayIndex, count);
                }
 
-               public bool Exists (Predicate<T> match)
+               public bool Exists (Predicate <T> match)
                {
-                       foreach (T t in this)
-                               if (match (t))
-                                       return true;
-                       
-                       return false;
+                       return FindIndex (match) != -1;
                }
                
-               public T Find (Predicate<T> match)
+               public T Find (Predicate <T> match)
                {
-                       foreach (T t in this)
-                               if (match (t))
-                                       return t;
-                       
-                       return default (T);
+                       int i = FindIndex (match);
+                       return (i != -1) ? _items [i] : default (T);
+               }
+               void CheckMatch (Predicate <T> match)
+               {
+                       if (match == null)
+                               throw new ArgumentNullException ("match");
                }
                
                // Maybe we could make this faster. For example, you could
                // make a bit set with stackalloc for which elements to copy
                // then you could size the array correctly.
-               public List<T> FindAll (Predicate<T> match)
+               public List <T> FindAll (Predicate <T> match)
                {
+                       CheckMatch (match);
                        List <T> f = new List <T> ();
                        
                        foreach (T t in this)
@@ -180,20 +229,26 @@ namespace System.Collections.Generic
                
                public int FindIndex (Predicate <T> match)
                {
-                       return FindIndex (0, match);
+                       CheckMatch (match);
+                       return GetIndex (0, _size, match);
                }
                
                public int FindIndex (int startIndex, Predicate <T> match)
                {
-                       return FindIndex (startIndex, size - startIndex, match);
+                       CheckMatch (match);
+                       CheckIndex (startIndex);
+                       return GetIndex (startIndex, _size - startIndex, match);
                }
-               
                public int FindIndex (int startIndex, int count, Predicate <T> match)
                {
+                       CheckMatch (match);
                        CheckRange (startIndex, count);
-                       
+                       return GetIndex (startIndex, count, match);
+               }
+               int GetIndex (int startIndex, int count, Predicate <T> match)
+               {
                        for (int i = startIndex; i < startIndex + count; i ++)
-                               if (match (data [i]))
+                               if (match (_items [i]))
                                        return i;
                                
                        return -1;
@@ -201,32 +256,45 @@ namespace System.Collections.Generic
                
                public T FindLast (Predicate <T> match)
                {
-                       int i = FindLastIndex (match);
+                       CheckMatch (match);
+                       int i = GetLastIndex (0, _size, match);
                        return i == -1 ? default (T) : this [i];
                }
                
                public int FindLastIndex (Predicate <T> match)
                {
-                       return FindLastIndex (0, match);
+                       CheckMatch (match);
+                       return GetLastIndex (0, _size, match);
                }
                
                public int FindLastIndex (int startIndex, Predicate <T> match)
                {
-                       return FindLastIndex (startIndex, size - startIndex, match);
+                       CheckMatch (match);
+                       CheckIndex (startIndex);
+                       return GetLastIndex (0, startIndex + 1, match);
                }
                
                public int FindLastIndex (int startIndex, int count, Predicate <T> match)
                {
-                       CheckRange (startIndex, count);
+                       CheckMatch (match);
+                       int start = startIndex - count + 1;
+                       CheckRange (start, count);
+                       return GetLastIndex (start, count, match);
+               }
+
+               int GetLastIndex (int startIndex, int count, Predicate <T> match)
+               {
+                       // unlike FindLastIndex, takes regular params for search range
                        for (int i = startIndex + count; i != startIndex;)
-                               if (match (data [--i]))
+                               if (match (_items [--i]))
                                        return i;
-                               
                        return -1;      
                }
                
                public void ForEach (Action <T> action)
                {
+                       if (action == null)
+                               throw new ArgumentNullException ("action");
                        foreach (T t in this)
                                action (t);
                }
@@ -236,29 +304,37 @@ namespace System.Collections.Generic
                        return new Enumerator (this);
                }
                
-               [MonoTODO]
                public List <T> GetRange (int index, int count)
                {
-                       throw new NotImplementedException ();
+                       CheckRange (index, count);
+                       T [] tmpArray = new T [count];
+                       Array.Copy (_items, index, tmpArray, 0, count);
+                       return new List <T> (tmpArray, count);
                }
                
                public int IndexOf (T item)
                {
-                       return IndexOf (item, 0);
+                       return Array.IndexOf<T> (_items, item, 0, _size);
                }
                
                public int IndexOf (T item, int index)
                {
-                       return IndexOf (item, index, size - index);
+                       CheckIndex (index);
+                       return Array.IndexOf<T> (_items, item, index, _size - index);
                }
                
                public int IndexOf (T item, int index, int count)
                {
-                       CheckRange (index, count);
-                       if (data == null)
-                               return -1;
+                       if (index < 0)
+                               throw new ArgumentOutOfRangeException ("index");
                        
-                       return Array.IndexOf (data, item, index, count);
+                       if (count < 0)
+                               throw new ArgumentOutOfRangeException ("count");
+
+                       if ((uint) index + (uint) count > (uint) _size)
+                               throw new ArgumentOutOfRangeException ("index and count exceed length of list");
+
+                       return Array.IndexOf<T> (_items, item, index, count);
                }
                
                void Shift (int start, int delta)
@@ -266,44 +342,89 @@ namespace System.Collections.Generic
                        if (delta < 0)
                                start -= delta;
                        
-                       Array.Copy (data, start, data, start + delta, size - start);
+                       Array.Copy (_items, start, _items, start + delta, _size - start);
                        
-                       size += delta;
+                       _size += delta;
+               }
+
+               void CheckIndex (int index)
+               {
+                       if (index < 0 || (uint) index > (uint) _size)
+                               throw new ArgumentOutOfRangeException ("index");
                }
                
                public void Insert (int index, T item)
                {
-                       if ((uint) index < (uint) size)
-                               throw new ArgumentOutOfRangeException ();
-                       
+                       CheckIndex (index);                     
+                       GrowIfNeeded (1);
                        Shift (index, 1);
                        this [index] = item;
-                               
+                       _version++;
                }
-               [MonoTODO ("Performance for collection")]
-               public void InsertRange (int index, IEnumerable<T> collection)
+
+               void CheckCollection (IEnumerable <T> collection)
+               {
+                       if (collection == null)
+                               throw new ArgumentNullException ("collection");
+               }
+               
+               public void InsertRange (int index, IEnumerable <T> collection)
+               {
+                       CheckCollection (collection);
+                       CheckIndex (index);
+                       if (collection == this) {
+                               T[] buffer = new T[_size];
+                               CopyTo (buffer, 0);
+                               GrowIfNeeded (_size);
+                               Shift (index, buffer.Length);
+                               Array.Copy (buffer, 0, _items, index, buffer.Length);
+                       } else {
+                               ICollection <T> c = collection as ICollection <T>;
+                               if (c != null)
+                                       InsertCollection (index, c);
+                               else
+                                       InsertEnumeration (index, collection);
+                       }
+                       _version++;
+               }
+
+               void InsertCollection (int index, ICollection <T> collection)
                {
-                       foreach (T t in collection)
-                               Insert (index ++, t);
+                       int collectionCount = collection.Count;
+                       GrowIfNeeded (collectionCount);
+                       
+                       Shift (index, collectionCount);
+                       collection.CopyTo (_items, index);
                }
-               
+               void InsertEnumeration (int index, IEnumerable <T> enumerable)
+               {
+                       foreach (T t in enumerable)
+                               Insert (index++, t);            
+               }
+
                public int LastIndexOf (T item)
                {
-                       return LastIndexOf  (item, 0);
+                       return Array.LastIndexOf<T> (_items, item, _size - 1, _size);
                }
                
-               public int LastIndexOf  (T item, int index)
+               public int LastIndexOf (T item, int index)
                {
-                       return LastIndexOf  (item, index, size - index);
+                       CheckIndex (index);
+                       return Array.LastIndexOf<T> (_items, item, index, index + 1);
                }
                
                public int LastIndexOf (T item, int index, int count)
                {
-                       CheckRange (index, count);
-                       if (data == null)
-                               return -1;
-                       
-                       return Array.LastIndexOf (data, item, index, count);
+                       if (index < 0)
+                               throw new ArgumentOutOfRangeException ("index", index, "index is negative");
+
+                       if (count < 0)
+                               throw new ArgumentOutOfRangeException ("count", count, "count is negative");
+
+                       if (index - count + 1 < 0)
+                               throw new ArgumentOutOfRangeException ("cound", count, "count is too large");
+
+                       return Array.LastIndexOf<T> (_items, item, index, count);
                }
                
                public bool Remove (T item)
@@ -315,79 +436,93 @@ namespace System.Collections.Generic
                        return loc != -1;
                }
                
-               [MonoTODO ("I can make it faster than this...")]
-               public int RemoveAll (Predicate<T> match)
+               // FIXME: this could probably be made faster.
+               public int RemoveAll (Predicate <T> match)
                {
+                       CheckMatch (match);
+
                        int index = 0;
                        int c = 0;
-                       while ((index = FindIndex (index, match)) != -1) {
+                       while ((index = GetIndex (index, _size - index, match)) != -1) {
                                RemoveAt (index);
                                c ++;
                        }
                        
+                       Array.Clear (_items, _size, c);
                        return c;
                }
                
                public void RemoveAt (int index)
                {
-                       RemoveRange (index, 1);
+                       CheckIndex (index);
+                       Shift (index, -1);
+                       Array.Clear (_items, _size, 0);
+                       _version++;
                }
                
                public void RemoveRange (int index, int count)
                {
                        CheckRange (index, count);
-                       Shift (index, -count);
+                       if (count > 0) {
+                               Shift (index, -count);
+                               Array.Clear (_items, _size, count);
+                               _version++;
+                       }
                }
                
                public void Reverse ()
                {
-                       Reverse (0, size);
+                       Array.Reverse (_items, 0, _size);
+                       _version++;
                }
                public void Reverse (int index, int count)
                {
                        CheckRange (index, count);
-                       Array.Reverse (data, index, count);
+                       Array.Reverse (_items, index, count);
+                       _version++;
                }
                
                public void Sort ()
                {
-                       Sort (Comparer <T>.Default);
+                       Array.Sort<T> (_items, 0, _size, Comparer <T>.Default);
+                       _version++;
                }
-               public void Sort (IComparer<T> comparer)
+               public void Sort (IComparer <T> comparer)
                {
-                       Sort (0, size, comparer);
+                       Array.Sort<T> (_items, 0, _size, comparer);
+                       _version++;
                }
-               
-               // Waiting on Array
-               [MonoTODO]
-               public void Sort (Comparison<T> comparison)
+
+               public void Sort (Comparison <T> comparison)
                {
-                       throw new NotImplementedException ();
+                       Array.Sort<T> (_items, _size, comparison);
+                       _version++;
                }
                
-               [MonoTODO]
-               public void Sort (int index, int count, IComparer<T> comparer)
+               public void Sort (int index, int count, IComparer <T> comparer)
                {
                        CheckRange (index, count);
-                       throw new NotImplementedException ();
+                       Array.Sort<T> (_items, index, count, comparer);
+                       _version++;
                }
 
                public T [] ToArray ()
                {
-                       T [] t = new T [size];
-                       if (data != null)
-                               Array.Copy (data, t, size);
+                       T [] t = new T [_size];
+                       Array.Copy (_items, t, _size);
                        
                        return t;
                }
                
-               public void TrimToSize ()
+               public void TrimExcess ()
                {
-                       Capacity = size;
+                       Capacity = _size;
                }
                
                public bool TrueForAll (Predicate <T> match)
                {
+                       CheckMatch (match);
+
                        foreach (T t in this)
                                if (!match (t))
                                        return false;
@@ -397,75 +532,103 @@ namespace System.Collections.Generic
                
                public int Capacity {
                        get { 
-                               if (data == null)
-                                       return DefaultCapacity;
-                               return data.Length;
+                               return _items.Length;
                        }
                        set {
-                               if ((uint) value < (uint) size)
+                               if ((uint) value < (uint) _size)
                                        throw new ArgumentOutOfRangeException ();
                                
-                               Array.Resize (ref data, value);
+                               Array.Resize (ref _items, value);
                        }
                }
                
                public int Count {
-                       get { return size; }
+                       get { return _size; }
                }
                
                public T this [int index] {
                        get {
-                               if ((uint) index >= (uint) size)
-                                       throw new IndexOutOfRangeException ();
-                               return data [index];
+                               if ((uint) index >= (uint) _size)
+                                       throw new ArgumentOutOfRangeException ("index");
+                               return _items [index];
                        }
                        set {
-                               if ((uint) index >= (uint) size)
-                                       throw new IndexOutOfRangeException ();
-                               data [index] = value;
+                               CheckIndex (index);
+                               if ((uint) index == (uint) _size)
+                                       throw new ArgumentOutOfRangeException ("index");
+                               _items [index] = value;
                        }
                }
                
-#region Interface Crap
-               IEnumerator <T> IEnumerable <T>.GetEnumerator()
+#region Interface implementations.
+               IEnumerator <T> IEnumerable <T>.GetEnumerator ()
                {
                        return GetEnumerator ();
                }
                
                void ICollection.CopyTo (Array array, int arrayIndex)
                {
-                       Array.Copy (data, 0, data, arrayIndex, size);
+                       Array.Copy (_items, 0, array, arrayIndex, _size);
                }
                
-               IEnumerator IEnumerable.GetEnumerator()
+               IEnumerator IEnumerable.GetEnumerator ()
                {
                        return GetEnumerator ();
                }
                
                int IList.Add (object item)
                {
-                       Add ((T) item);
-                       return size - 1;
+                       try {
+                               Add ((T) item);
+                       } catch (InvalidCastException) {
+                               throw new ArgumentException("item");
+                       }
+                       return _size - 1;
                }
                
                bool IList.Contains (object item)
                {
-                       return Contains ((T) item);
+                       try {
+                               return Contains ((T) item);
+                       } catch (InvalidCastException) {
+                               return false;
+                       }
                }
                
                int IList.IndexOf (object item)
                {
-                       return IndexOf ((T) item);
+                       try {
+                               return IndexOf((T) item);
+                       } catch (InvalidCastException) {
+                               return -1;
+                       }
                }
                
                void IList.Insert (int index, object item)
                {
-                       Insert (index, (T) item);
+                       // We need to check this first because, even if the
+                       // item is null or not the correct type, we need to
+                       // return an ArgumentOutOfRange exception if the
+                       // index is out of range
+                       CheckIndex (index);
+                       try {
+                               Insert (index, (T) item);
+                       } catch (InvalidCastException) {
+                               throw new ArgumentException("item");
+                       }
                }
                
                void IList.Remove (object item)
                {
-                       Remove ((T) item);
+                       try {
+                               Remove ((T) item);
+                       } catch (InvalidCastException) {
+                               // Swallow the exception--if we
+                               // can't cast to the correct type
+                               // then we've already "succeeded"
+                               // in removing the item from the
+                               // List.
+                       }
                }
                
                bool ICollection <T>.IsReadOnly {
@@ -491,89 +654,8 @@ namespace System.Collections.Generic
                        set { this [index] = (T) value; }
                }
 #endregion
-               
-               [ComVisible (false)]
-               internal class ReadOnlyList<I> : IList<I>, ICollection<I>, IEnumerable<I>
-               {
-                       IList<I> list;
-               
-                       internal ReadOnlyList (IList<I> list)
-                       {
-                               this.list = list;
-                       }
-
-                       public void Add (I item)
-                       {
-                               throw new NotSupportedException ();
-                       }
-                       
-                       public void Clear ()
-                       {
-                               throw new NotSupportedException ();
-                       }
-
-                       public bool Contains (I item)
-                       {
-                               return list.Contains (item);
-                       }
-
-                       public void CopyTo (I [] array, int index)
-                       {
-                               list.CopyTo (array, index);
-                       }
-
-                       public IEnumerator<I> GetEnumerator ()
-                       {
-                               return list.GetEnumerator ();
-                       }
-
-                       IEnumerator IEnumerable.GetEnumerator ()
-                       {
-                               return ((IEnumerable) list).GetEnumerator ();
-                       }
-                       
-                       public int IndexOf (I item)
-                       {
-                               return list.IndexOf (item);
-                       }
-
-                       public void Insert (int index, I item)
-                       {
-                               throw new NotSupportedException ();
-                       }
-
-                       public bool Remove (I item)
-                       {
-                               throw new NotSupportedException ();
-                       }
-
-                       public void RemoveAt (int index)
-                       {
-                               throw new NotSupportedException ();
-                       }
-
-                       public int Count {
-                               get {
-                                       return list.Count;
-                               }
-                       }
-
-                       public bool IsReadOnly {
-                               get {
-                                       return true;
-                               }
-                       }
-
-                       public I this [int index] {
-                               get {
-                                       return list [index];
-                               }
-                               set {
-                                       throw new NotSupportedException ();
-                               }
-                       }
-               }
-               
+                               
+               [Serializable]
                public struct Enumerator : IEnumerator <T>, IDisposable {
                        const int NOT_STARTED = -2;
                        
@@ -589,7 +671,7 @@ namespace System.Collections.Generic
                        {
                                this.l = l;
                                idx = NOT_STARTED;
-                               ver = l.version;
+                               ver = l._version;
                        }
                        
                        // for some fucked up reason, MSFT added a useless dispose to this class
@@ -602,11 +684,12 @@ namespace System.Collections.Generic
                        
                        public bool MoveNext ()
                        {
-                               if (ver != l.version)
-                                       throw new InvalidOperationException ();
+                               if (ver != l._version)
+                                       throw new InvalidOperationException ("Collection was modified;"
+                                               + "enumeration operation may not execute.");
                                
                                if (idx == NOT_STARTED)
-                                       idx = l.size;
+                                       idx = l._size;
                                
                                return idx != FINISHED && -- idx != FINISHED;
                        }
@@ -616,14 +699,15 @@ namespace System.Collections.Generic
                                        if (idx < 0)
                                                throw new InvalidOperationException ();
                                        
-                                       return l.data [l.size - 1 - idx];
+                                       return l._items [l._size - 1 - idx];
                                }
                        }
                        
                        void IEnumerator.Reset ()
                        {
-                               if (ver != l.version)
-                                       throw new InvalidOperationException ();
+                               if (ver != l._version)
+                                       throw new InvalidOperationException ("Collection was modified;"
+                                               + "enumeration operation may not execute.");
                                
                                idx = NOT_STARTED;
                        }
@@ -631,7 +715,6 @@ namespace System.Collections.Generic
                        object IEnumerator.Current {
                                get { return Current; }
                        }
-                       
                }
        }
 }