Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / mscorlib / system / collections / arraylist.cs
1 // ==++==
2 // 
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6 /*============================================================
7 **
8 ** Class:  ArrayList
9 ** 
10 ** <OWNER>Microsoft</OWNER>
11 **
12 **
13 ** Purpose: Implements a dynamically sized List as an array,
14 **          and provides many convenience methods for treating
15 **          an array as an IList.
16 **
17 ** 
18 ===========================================================*/
19 namespace System.Collections {
20     using System;
21     using System.Runtime;
22     using System.Security;
23     using System.Security.Permissions;
24     using System.Diagnostics;
25     using System.Runtime.CompilerServices;
26     using System.Runtime.Serialization;
27     using System.Diagnostics.CodeAnalysis;
28     using System.Diagnostics.Contracts;
29
30     // Implements a variable-size List that uses an array of objects to store the
31     // elements. A ArrayList has a capacity, which is the allocated length
32     // of the internal array. As elements are added to a ArrayList, the capacity
33     // of the ArrayList is automatically increased as required by reallocating the
34     // internal array.
35     // 
36 #if FEATURE_CORECLR
37     [FriendAccessAllowed]
38 #endif
39     [DebuggerTypeProxy(typeof(System.Collections.ArrayList.ArrayListDebugView))]   
40     [DebuggerDisplay("Count = {Count}")]
41     [Serializable]
42     [System.Runtime.InteropServices.ComVisible(true)]
43     public class ArrayList : IList, ICloneable
44     {
45         private Object[] _items;
46         [ContractPublicPropertyName("Count")]
47         private int _size;
48         private int _version;
49         [NonSerialized]
50         private Object _syncRoot;
51         
52         private const int _defaultCapacity = 4;
53         private static readonly Object[] emptyArray = EmptyArray<Object>.Value; 
54     
55         // Note: this constructor is a bogus constructor that does nothing
56         // and is for use only with SyncArrayList.
57         internal ArrayList( bool trash )
58         {
59         }
60
61         // Constructs a ArrayList. The list is initially empty and has a capacity
62         // of zero. Upon adding the first element to the list the capacity is
63         // increased to _defaultCapacity, and then increased in multiples of two as required.
64         public ArrayList() {
65             _items = emptyArray;  
66         }
67     
68         // Constructs a ArrayList with a given initial capacity. The list is
69         // initially empty, but will have room for the given number of elements
70         // before any reallocations are required.
71         // 
72          public ArrayList(int capacity) {
73              if (capacity < 0) throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_MustBeNonNegNum", "capacity"));
74              Contract.EndContractBlock();
75
76              if (capacity == 0)
77                  _items = emptyArray;
78              else
79                  _items = new Object[capacity];
80         }
81     
82         // Constructs a ArrayList, copying the contents of the given collection. The
83         // size and capacity of the new list will both be equal to the size of the
84         // given collection.
85         // 
86         public ArrayList(ICollection c) {
87             if (c==null)
88                 throw new ArgumentNullException("c", Environment.GetResourceString("ArgumentNull_Collection"));
89             Contract.EndContractBlock();
90
91             int count = c.Count;
92             if (count == 0)
93             {
94                 _items = emptyArray;
95             }
96             else {
97                 _items = new Object[count];
98                 AddRange(c);
99             }
100         }
101     
102         // Gets and sets the capacity of this list.  The capacity is the size of
103         // the internal array used to hold items.  When set, the internal 
104         // array of the list is reallocated to the given capacity.
105         // 
106          public virtual int Capacity {
107             get {
108                 Contract.Ensures(Contract.Result<int>() >= Count);
109                 return _items.Length;
110             }
111             set {
112                 if (value < _size) {
113                     throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
114                 }
115                 Contract.Ensures(Capacity >= 0);
116                 Contract.EndContractBlock();
117                 // We don't want to update the version number when we change the capacity.
118                 // Some existing applications have dependency on this.
119                 if (value != _items.Length) {
120                     if (value > 0) {
121                         Object[] newItems = new Object[value];
122                         if (_size > 0) { 
123                             Array.Copy(_items, 0, newItems, 0, _size);
124                         }
125                         _items = newItems;
126                     }
127                     else {
128                         _items = new Object[_defaultCapacity];
129                     }
130                 }            
131             }
132         }
133
134         // Read-only property describing how many elements are in the List.
135         public virtual int Count {
136             get {
137                 Contract.Ensures(Contract.Result<int>() >= 0);
138                 return _size;
139             }
140         }
141
142         public virtual bool IsFixedSize {
143             get { return false; }
144         }
145
146             
147         // Is this ArrayList read-only?
148         public virtual bool IsReadOnly {
149             get { return false; }
150         }
151
152         // Is this ArrayList synchronized (thread-safe)?
153         public virtual bool IsSynchronized {
154             get { return false; }
155         }
156     
157         // Synchronization root for this object.
158         public virtual Object SyncRoot {
159             get { 
160                 if( _syncRoot == null) {
161                     System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);    
162                 }
163                 return _syncRoot; 
164             }
165         }
166     
167         // Sets or Gets the element at the given index.
168         // 
169         public virtual Object this[int index] {
170             get {
171                 if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
172                 Contract.EndContractBlock();
173                 return _items[index];
174             }
175             set {
176                 if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
177                 Contract.EndContractBlock();
178                 _items[index] = value;
179                 _version++;
180             }
181         }
182     
183         // Creates a ArrayList wrapper for a particular IList.  This does not
184         // copy the contents of the IList, but only wraps the ILIst.  So any
185         // changes to the underlying list will affect the ArrayList.  This would
186         // be useful if you want to Reverse a subrange of an IList, or want to
187         // use a generic BinarySearch or Sort method without implementing one yourself.
188         // However, since these methods are generic, the performance may not be
189         // nearly as good for some operations as they would be on the IList itself.
190         //
191         public static ArrayList Adapter(IList list) {
192             if (list==null)
193                 throw new ArgumentNullException("list");
194             Contract.Ensures(Contract.Result<ArrayList>() != null);
195             Contract.EndContractBlock();
196             return new IListWrapper(list);
197         }
198         
199         // Adds the given object to the end of this list. The size of the list is
200         // increased by one. If required, the capacity of the list is doubled
201         // before adding the new element.
202         //
203         public virtual int Add(Object value) {
204             Contract.Ensures(Contract.Result<int>() >= 0);
205             if (_size == _items.Length) EnsureCapacity(_size + 1);
206             _items[_size] = value;
207             _version++;
208             return _size++;
209         }
210     
211         // Adds the elements of the given collection to the end of this list. If
212         // required, the capacity of the list is increased to twice the previous
213         // capacity or the new size, whichever is larger.
214         //
215         public virtual void AddRange(ICollection c) {
216             InsertRange(_size, c);
217         }
218     
219         // Searches a section of the list for a given element using a binary search
220         // algorithm. Elements of the list are compared to the search value using
221         // the given IComparer interface. If comparer is null, elements of
222         // the list are compared to the search value using the IComparable
223         // interface, which in that case must be implemented by all elements of the
224         // list and the given search value. This method assumes that the given
225         // section of the list is already sorted; if this is not the case, the
226         // result will be incorrect.
227         //
228         // The method returns the index of the given value in the list. If the
229         // list does not contain the given value, the method returns a negative
230         // integer. The bitwise complement operator (~) can be applied to a
231         // negative result to produce the index of the first element (if any) that
232         // is larger than the given search value. This is also the index at which
233         // the search value should be inserted into the list in order for the list
234         // to remain sorted.
235         // 
236         // The method uses the Array.BinarySearch method to perform the
237         // search.
238         // 
239         public virtual int BinarySearch(int index, int count, Object value, IComparer comparer) {
240             if (index < 0)
241                 throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
242             if (count < 0)
243                 throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
244             if (_size - index < count)
245                 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
246             Contract.Ensures(Contract.Result<int>() < Count);
247             Contract.Ensures(Contract.Result<int>() < index + count);
248             Contract.EndContractBlock();
249     
250             return Array.BinarySearch((Array)_items, index, count, value, comparer);
251         }
252     
253         public virtual int BinarySearch(Object value)
254         {
255             Contract.Ensures(Contract.Result<int>() < Count);
256             return BinarySearch(0, Count, value, null);
257         }
258
259         public virtual int BinarySearch(Object value, IComparer comparer)
260         {
261             Contract.Ensures(Contract.Result<int>() < Count);
262             return BinarySearch(0, Count, value, comparer);
263         }
264
265     
266         // Clears the contents of ArrayList.
267         public virtual void Clear() {
268             if (_size > 0)
269             {
270             Array.Clear(_items, 0, _size); // Don't need to doc this but we clear the elements so that the gc can reclaim the references.
271             _size = 0;
272             }
273             _version++;
274         }
275     
276         // Clones this ArrayList, doing a shallow copy.  (A copy is made of all
277         // Object references in the ArrayList, but the Objects pointed to 
278         // are not cloned).
279         public virtual Object Clone()
280         {
281             Contract.Ensures(Contract.Result<Object>() != null);
282             ArrayList la = new ArrayList(_size);
283             la._size = _size;
284             la._version = _version;
285             Array.Copy(_items, 0, la._items, 0, _size);
286             return la;
287         }
288     
289     
290         // Contains returns true if the specified element is in the ArrayList.
291         // It does a linear, O(n) search.  Equality is determined by calling
292         // item.Equals().
293         //
294         public virtual bool Contains(Object item) {
295             if (item==null) {
296                 for(int i=0; i<_size; i++)
297                     if (_items[i]==null)
298                         return true;
299                 return false;
300             }
301             else {
302                 for(int i=0; i<_size; i++)
303                     if ( (_items[i] != null) && (_items[i].Equals(item)) )
304                         return true;
305                 return false;
306             }
307         }
308     
309         // Copies this ArrayList into array, which must be of a 
310         // compatible array type.  
311         //
312         public virtual void CopyTo(Array array) {
313             CopyTo(array, 0);
314         }
315
316         // Copies this ArrayList into array, which must be of a 
317         // compatible array type.  
318         //
319         public virtual void CopyTo(Array array, int arrayIndex) {
320             if ((array != null) && (array.Rank != 1))
321                 throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
322             Contract.EndContractBlock();
323             // Delegate rest of error checking to Array.Copy.
324             Array.Copy(_items, 0, array, arrayIndex, _size);
325         }
326     
327         // Copies a section of this list to the given array at the given index.
328         // 
329         // The method uses the Array.Copy method to copy the elements.
330         // 
331         public virtual void CopyTo(int index, Array array, int arrayIndex, int count) {
332             if (_size - index < count)
333                 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
334             if ((array != null) && (array.Rank != 1))
335                 throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
336             Contract.EndContractBlock();
337             // Delegate rest of error checking to Array.Copy.
338             Array.Copy(_items, index, array, arrayIndex, count);
339         }
340
341         // Ensures that the capacity of this list is at least the given minimum
342         // value. If the currect capacity of the list is less than min, the
343         // capacity is increased to twice the current capacity or to min,
344         // whichever is larger.
345         private void EnsureCapacity(int min) {
346             if (_items.Length < min) {
347                 int newCapacity = _items.Length == 0? _defaultCapacity: _items.Length * 2;
348                 // Allow the list to grow to maximum possible capacity (~2G elements) before encountering overflow.
349                 // Note that this check works even when _items.Length overflowed thanks to the (uint) cast
350                 if ((uint)newCapacity > Array_ReferenceSources.MaxArrayLength) newCapacity = Array_ReferenceSources.MaxArrayLength;
351                 if (newCapacity < min) newCapacity = min;
352                 Capacity = newCapacity;
353             }
354         }
355     
356         // Returns a list wrapper that is fixed at the current size.  Operations
357         // that add or remove items will fail, however, replacing items is allowed.
358         //
359         public static IList FixedSize(IList list) {
360             if (list==null)
361                 throw new ArgumentNullException("list");
362             Contract.Ensures(Contract.Result<IList>() != null);
363             Contract.EndContractBlock();
364             return new FixedSizeList(list);
365         }
366
367         // Returns a list wrapper that is fixed at the current size.  Operations
368         // that add or remove items will fail, however, replacing items is allowed.
369         //
370         public static ArrayList FixedSize(ArrayList list) {
371             if (list==null)
372                 throw new ArgumentNullException("list");
373             Contract.Ensures(Contract.Result<ArrayList>() != null);
374             Contract.EndContractBlock();
375             return new FixedSizeArrayList(list);
376         }
377     
378         // Returns an enumerator for this list with the given
379         // permission for removal of elements. If modifications made to the list 
380         // while an enumeration is in progress, the MoveNext and 
381         // GetObject methods of the enumerator will throw an exception.
382         //
383         public virtual IEnumerator GetEnumerator() {
384             Contract.Ensures(Contract.Result<IEnumerator>() != null);
385             return new ArrayListEnumeratorSimple(this);
386         }
387     
388         // Returns an enumerator for a section of this list with the given
389         // permission for removal of elements. If modifications made to the list 
390         // while an enumeration is in progress, the MoveNext and 
391         // GetObject methods of the enumerator will throw an exception.
392         //
393         public virtual IEnumerator GetEnumerator(int index, int count) {
394             if (index < 0)
395                 throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
396             if (count < 0)
397                 throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
398             if (_size - index < count)
399                 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
400             Contract.Ensures(Contract.Result<IEnumerator>() != null);
401             Contract.EndContractBlock();
402     
403             return new ArrayListEnumerator(this, index, count);
404         }
405     
406         // Returns the index of the first occurrence of a given value in a range of
407         // this list. The list is searched forwards from beginning to end.
408         // The elements of the list are compared to the given value using the
409         // Object.Equals method.
410         // 
411         // This method uses the Array.IndexOf method to perform the
412         // search.
413         // 
414         public virtual int IndexOf(Object value) {
415             Contract.Ensures(Contract.Result<int>() < Count);
416             return Array.IndexOf((Array)_items, value, 0, _size);
417         }
418     
419         // Returns the index of the first occurrence of a given value in a range of
420         // this list. The list is searched forwards, starting at index
421         // startIndex and ending at count number of elements. The
422         // elements of the list are compared to the given value using the
423         // Object.Equals method.
424         // 
425         // This method uses the Array.IndexOf method to perform the
426         // search.
427         // 
428         public virtual int IndexOf(Object value, int startIndex) {
429             if (startIndex > _size)
430                 throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
431             Contract.Ensures(Contract.Result<int>() < Count);
432             Contract.EndContractBlock();
433             return Array.IndexOf((Array)_items, value, startIndex, _size - startIndex);
434         }
435
436         // Returns the index of the first occurrence of a given value in a range of
437         // this list. The list is searched forwards, starting at index
438         // startIndex and upto count number of elements. The
439         // elements of the list are compared to the given value using the
440         // Object.Equals method.
441         // 
442         // This method uses the Array.IndexOf method to perform the
443         // search.
444         // 
445         public virtual int IndexOf(Object value, int startIndex, int count) {
446             if (startIndex > _size)
447                 throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
448             if (count <0 || startIndex > _size - count) throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count"));
449             Contract.Ensures(Contract.Result<int>() < Count);
450             Contract.EndContractBlock();
451             return Array.IndexOf((Array)_items, value, startIndex, count);
452         }
453     
454         // Inserts an element into this list at a given index. The size of the list
455         // is increased by one. If required, the capacity of the list is doubled
456         // before inserting the new element.
457         // 
458         public virtual void Insert(int index, Object value) {
459             // Note that insertions at the end are legal.
460             if (index < 0 || index > _size) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_ArrayListInsert"));
461             //Contract.Ensures(Count == Contract.OldValue(Count) + 1);
462             Contract.EndContractBlock();
463
464             if (_size == _items.Length) EnsureCapacity(_size + 1);
465             if (index < _size) {
466                 Array.Copy(_items, index, _items, index + 1, _size - index);
467             }
468             _items[index] = value;
469             _size++;
470             _version++;
471         }
472     
473         // Inserts the elements of the given collection at a given index. If
474         // required, the capacity of the list is increased to twice the previous
475         // capacity or the new size, whichever is larger.  Ranges may be added
476         // to the end of the list by setting index to the ArrayList's size.
477         //
478         public virtual void InsertRange(int index, ICollection c) {
479             if (c==null)
480                 throw new ArgumentNullException("c", Environment.GetResourceString("ArgumentNull_Collection"));
481             if (index < 0 || index > _size) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
482             //Contract.Ensures(Count == Contract.OldValue(Count) + c.Count);
483             Contract.EndContractBlock();
484
485             int count = c.Count;
486             if (count > 0) {
487                 EnsureCapacity(_size + count);                
488                 // shift existing items
489                 if (index < _size) {
490                     Array.Copy(_items, index, _items, index + count, _size - index);
491                 }
492
493                 Object[] itemsToInsert = new Object[count];
494                 c.CopyTo(itemsToInsert, 0);
495                 itemsToInsert.CopyTo(_items, index);
496                 _size += count;
497                 _version++;
498             }
499         }
500     
501         // Returns the index of the last occurrence of a given value in a range of
502         // this list. The list is searched backwards, starting at the end 
503         // and ending at the first element in the list. The elements of the list 
504         // are compared to the given value using the Object.Equals method.
505         // 
506         // This method uses the Array.LastIndexOf method to perform the
507         // search.
508         // 
509         public virtual int LastIndexOf(Object value)
510         {
511             Contract.Ensures(Contract.Result<int>() < _size);
512             return LastIndexOf(value, _size - 1, _size);
513         }
514
515         // Returns the index of the last occurrence of a given value in a range of
516         // this list. The list is searched backwards, starting at index
517         // startIndex and ending at the first element in the list. The 
518         // elements of the list are compared to the given value using the 
519         // Object.Equals method.
520         // 
521         // This method uses the Array.LastIndexOf method to perform the
522         // search.
523         // 
524         public virtual int LastIndexOf(Object value, int startIndex)
525         {
526             if (startIndex >= _size)
527                 throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
528             Contract.Ensures(Contract.Result<int>() < Count);
529             Contract.EndContractBlock();
530             return LastIndexOf(value, startIndex, startIndex + 1);
531         }
532
533         // Returns the index of the last occurrence of a given value in a range of
534         // this list. The list is searched backwards, starting at index
535         // startIndex and upto count elements. The elements of
536         // the list are compared to the given value using the Object.Equals
537         // method.
538         // 
539         // This method uses the Array.LastIndexOf method to perform the
540         // search.
541         // 
542         public virtual int LastIndexOf(Object value, int startIndex, int count) {
543             if (Count != 0 && (startIndex < 0 || count < 0))
544                 throw new ArgumentOutOfRangeException((startIndex<0 ? "startIndex" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
545             Contract.Ensures(Contract.Result<int>() < Count);
546             Contract.EndContractBlock();
547
548             if (_size == 0)  // Special case for an empty list
549                 return -1;
550
551             if (startIndex >= _size || count > startIndex + 1) 
552                 throw new ArgumentOutOfRangeException((startIndex>=_size ? "startIndex" : "count"), Environment.GetResourceString("ArgumentOutOfRange_BiggerThanCollection"));
553
554             return Array.LastIndexOf((Array)_items, value, startIndex, count);
555         }
556     
557         // Returns a read-only IList wrapper for the given IList.
558         //
559 #if FEATURE_CORECLR
560         [FriendAccessAllowed]
561 #endif
562         public static IList ReadOnly(IList list) {
563             if (list==null)
564                 throw new ArgumentNullException("list");
565             Contract.Ensures(Contract.Result<IList>() != null);
566             Contract.EndContractBlock();
567             return new ReadOnlyList(list);
568         }
569
570         // Returns a read-only ArrayList wrapper for the given ArrayList.
571         //
572         public static ArrayList ReadOnly(ArrayList list) {
573             if (list==null)
574                 throw new ArgumentNullException("list");
575             Contract.Ensures(Contract.Result<ArrayList>() != null);
576             Contract.EndContractBlock();
577             return new ReadOnlyArrayList(list);
578         }
579     
580         // Removes the element at the given index. The size of the list is
581         // decreased by one.
582         // 
583         public virtual void Remove(Object obj) {
584             Contract.Ensures(Count >= 0);
585
586             int index = IndexOf(obj);
587             BCLDebug.Correctness(index >= 0 || !(obj is Int32), "You passed an Int32 to Remove that wasn't in the ArrayList." + Environment.NewLine + "Did you mean RemoveAt?  int: "+obj+"  Count: "+Count);
588             if (index >=0) 
589                 RemoveAt(index);
590         }
591     
592         // Removes the element at the given index. The size of the list is
593         // decreased by one.
594         // 
595         public virtual void RemoveAt(int index) {
596             if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
597             Contract.Ensures(Count >= 0);
598             //Contract.Ensures(Count == Contract.OldValue(Count) - 1);
599             Contract.EndContractBlock();
600
601             _size--;
602             if (index < _size) {
603                 Array.Copy(_items, index + 1, _items, index, _size - index);
604             }
605             _items[_size] = null;
606             _version++;
607         }
608     
609         // Removes a range of elements from this list.
610         // 
611         public virtual void RemoveRange(int index, int count) {
612             if (index < 0)
613                 throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
614             if (count < 0)
615                 throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
616             if (_size - index < count)
617                 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
618             Contract.Ensures(Count >= 0);
619             //Contract.Ensures(Count == Contract.OldValue(Count) - count);
620             Contract.EndContractBlock();
621     
622             if (count > 0) {
623                 int i = _size;
624                 _size -= count;
625                 if (index < _size) {
626                     Array.Copy(_items, index + count, _items, index, _size - index);
627                 }
628                 while (i > _size) _items[--i] = null;
629                 _version++;
630             }
631         }
632     
633         // Returns an IList that contains count copies of value.
634         //
635         public static ArrayList Repeat(Object value, int count) {
636             if (count < 0)
637                 throw new ArgumentOutOfRangeException("count",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
638             Contract.Ensures(Contract.Result<ArrayList>() != null);
639             Contract.EndContractBlock();
640
641             ArrayList list = new ArrayList((count>_defaultCapacity)?count:_defaultCapacity);
642             for(int i=0; i<count; i++)
643                 list.Add(value);
644             return list;
645         }
646
647         // Reverses the elements in this list.
648         public virtual void Reverse() {
649             Reverse(0, Count);
650         }
651     
652         // Reverses the elements in a range of this list. Following a call to this
653         // method, an element in the range given by index and count
654         // which was previously located at index i will now be located at
655         // index index + (index + count - i - 1).
656         // 
657         // This method uses the Array.Reverse method to reverse the
658         // elements.
659         // 
660         public virtual void Reverse(int index, int count) {
661             if (index < 0)
662                 throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
663             if (count < 0)
664                 throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
665             if (_size - index < count)
666                 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
667             Contract.EndContractBlock();
668             Array.Reverse(_items, index, count);
669             _version++;
670         }
671     
672         // Sets the elements starting at the given index to the elements of the
673         // given collection.
674         //
675         public virtual void SetRange(int index, ICollection c) {
676             if (c==null) throw new ArgumentNullException("c", Environment.GetResourceString("ArgumentNull_Collection"));
677             Contract.EndContractBlock();
678             int count = c.Count;
679             if (index < 0 || index > _size - count) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
680             
681             if (count > 0) {
682                 c.CopyTo(_items, index);
683                 _version++;
684             }
685         }
686     
687         public virtual ArrayList GetRange(int index, int count) {
688             if (index < 0 || count < 0)
689                 throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
690             if (_size - index < count)
691                 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
692             Contract.Ensures(Contract.Result<ArrayList>() != null);
693             Contract.EndContractBlock();
694             return new Range(this,index, count);
695         }
696
697         // Sorts the elements in this list.  Uses the default comparer and 
698         // Array.Sort.
699         public virtual void Sort()
700         {
701             Sort(0, Count, Comparer.Default);
702         }
703
704         // Sorts the elements in this list.  Uses Array.Sort with the
705         // provided comparer.
706         public virtual void Sort(IComparer comparer)
707         {
708             Sort(0, Count, comparer);
709         }
710
711         // Sorts the elements in a section of this list. The sort compares the
712         // elements to each other using the given IComparer interface. If
713         // comparer is null, the elements are compared to each other using
714         // the IComparable interface, which in that case must be implemented by all
715         // elements of the list.
716         // 
717         // This method uses the Array.Sort method to sort the elements.
718         // 
719         public virtual void Sort(int index, int count, IComparer comparer) {
720             if (index < 0)
721                 throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
722             if (count < 0)
723                 throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
724             if (_size - index < count)
725                 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
726             Contract.EndContractBlock();
727             
728             Array.Sort(_items, index, count, comparer);
729             _version++;
730         }
731     
732         // Returns a thread-safe wrapper around an IList.
733         //
734         [HostProtection(Synchronization=true)]
735         public static IList Synchronized(IList list) {
736             if (list==null)
737                 throw new ArgumentNullException("list");
738             Contract.Ensures(Contract.Result<IList>() != null);
739             Contract.EndContractBlock();
740             return new SyncIList(list);
741         }
742     
743         // Returns a thread-safe wrapper around a ArrayList.
744         //
745         [HostProtection(Synchronization=true)]
746         public static ArrayList Synchronized(ArrayList list) {
747             if (list==null)
748                 throw new ArgumentNullException("list");
749             Contract.Ensures(Contract.Result<ArrayList>() != null);
750             Contract.EndContractBlock();
751             return new SyncArrayList(list);
752         }
753     
754         // ToArray returns a new Object array containing the contents of the ArrayList.
755         // This requires copying the ArrayList, which is an O(n) operation.
756         public virtual Object[] ToArray() {
757             Contract.Ensures(Contract.Result<Object[]>() != null);
758
759             Object[] array = new Object[_size];
760             Array.Copy(_items, 0, array, 0, _size);
761             return array;
762         }
763     
764         // ToArray returns a new array of a particular type containing the contents 
765         // of the ArrayList.  This requires copying the ArrayList and potentially
766         // downcasting all elements.  This copy may fail and is an O(n) operation.
767         // Internally, this implementation calls Array.Copy.
768         //
769         [SecuritySafeCritical]
770         public virtual Array ToArray(Type type) {
771             if (type==null)
772                 throw new ArgumentNullException("type");
773             Contract.Ensures(Contract.Result<Array>() != null);
774             Contract.EndContractBlock();
775             Array array = Array.UnsafeCreateInstance(type, _size);
776             Array.Copy(_items, 0, array, 0, _size);
777             return array;
778         }
779     
780         // Sets the capacity of this list to the size of the list. This method can
781         // be used to minimize a list's memory overhead once it is known that no
782         // new elements will be added to the list. To completely clear a list and
783         // release all memory referenced by the list, execute the following
784         // statements:
785         // 
786         // list.Clear();
787         // list.TrimToSize();
788         // 
789         public virtual void TrimToSize() {
790             Capacity = _size;
791         }
792     
793     
794         // This class wraps an IList, exposing it as a ArrayList
795         // Note this requires reimplementing half of ArrayList...
796         [Serializable]
797         private class IListWrapper : ArrayList
798         {
799             private IList _list;
800             
801             internal IListWrapper(IList list) {
802                 _list = list;
803                 _version = 0; // list doesn't not contain a version number
804             }
805     
806              public override int Capacity {
807                 get { return _list.Count; }
808                 set {
809                     if (value < Count) throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
810                     Contract.EndContractBlock();
811                 }
812             }
813     
814             public override int Count { 
815                 get { return _list.Count; }
816             }
817     
818             public override bool IsReadOnly { 
819                 get { return _list.IsReadOnly; }
820             }
821
822             public override bool IsFixedSize {
823                 get { return _list.IsFixedSize; }
824             }
825
826         
827             public override bool IsSynchronized { 
828                 get { return _list.IsSynchronized; }
829             }
830             
831              public override Object this[int index] {
832                 get {
833                     return _list[index];
834                 }
835                 set {
836                     _list[index] = value;
837                     _version++;
838                 }
839             }
840     
841             public override Object SyncRoot {
842                 get { return _list.SyncRoot; }
843             }
844             
845             public override int Add(Object obj) {
846                 int i = _list.Add(obj);
847                 _version++;
848                 return i;
849             }
850         
851             public override void AddRange(ICollection c) {
852                 InsertRange(Count, c);
853             }
854     
855             // Other overloads with automatically work
856             public override int BinarySearch(int index, int count, Object value, IComparer comparer) 
857             {
858                 if (index < 0 || count < 0)
859                     throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
860                 if (this.Count - index < count)
861                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
862                 Contract.EndContractBlock();
863                 if (comparer == null)
864                     comparer = Comparer.Default;
865                 
866                 int lo = index;
867                 int hi = index + count - 1;
868                 int mid;
869                 while (lo <= hi) {
870                     mid = (lo+hi)/2;
871                     int r = comparer.Compare(value, _list[mid]);
872                     if (r == 0)
873                         return mid;
874                     if (r < 0)
875                         hi = mid-1;
876                     else 
877                         lo = mid+1;
878                 }
879                 // return bitwise complement of the first element greater than value.
880                 // Since hi is less than lo now, ~lo is the correct item.
881                 return ~lo;
882             }
883     
884             public override void Clear() {
885                 // If _list is an array, it will support Clear method.
886                 // We shouldn't allow clear operation on a FixedSized ArrayList
887                 if(_list.IsFixedSize) {
888                     throw new NotSupportedException(Environment.GetResourceString("NotSupported_FixedSizeCollection"));
889                 }
890
891                 _list.Clear();
892                 _version++;
893             }
894     
895             public override Object Clone() {
896                 // This does not do a shallow copy of _list into a ArrayList!
897                 // This clones the IListWrapper, creating another wrapper class!
898                 return new IListWrapper(_list);
899             }
900     
901             public override bool Contains(Object obj) {
902                 return _list.Contains(obj);
903             }
904     
905             public override void CopyTo(Array array, int index) {
906                 _list.CopyTo(array, index);
907             }
908     
909             public override void CopyTo(int index, Array array, int arrayIndex, int count) {
910                 if (array==null)
911                     throw new ArgumentNullException("array");
912                 if (index < 0 || arrayIndex < 0)
913                     throw new ArgumentOutOfRangeException((index < 0) ? "index" : "arrayIndex", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
914                 if( count < 0)
915                     throw new ArgumentOutOfRangeException( "count" , Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));                 
916                 if (array.Length - arrayIndex < count)
917                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
918                 if (array.Rank != 1)
919                     throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
920                 Contract.EndContractBlock();
921
922                 if (_list.Count - index < count)
923                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
924                 
925                 for(int i=index; i<index+count; i++)
926                     array.SetValue(_list[i], arrayIndex++);
927             }
928     
929             public override IEnumerator GetEnumerator() {
930                 return _list.GetEnumerator();
931             }
932     
933             public override IEnumerator GetEnumerator(int index, int count) {
934                 if (index < 0 || count < 0)
935                     throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
936                 Contract.EndContractBlock();
937                 if (_list.Count - index < count)
938                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
939     
940                 return new IListWrapperEnumWrapper(this, index, count);
941             }
942     
943             public override int IndexOf(Object value) {
944                 return _list.IndexOf(value);
945             }
946
947             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
948             public override int IndexOf(Object value, int startIndex) {
949                 return IndexOf(value, startIndex, _list.Count - startIndex);
950             }
951     
952             public override int IndexOf(Object value, int startIndex, int count) {
953                 if (startIndex < 0 || startIndex > this.Count) throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
954                 if (count < 0 || startIndex > this.Count - count) throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count"));
955                 Contract.EndContractBlock();
956
957                 int endIndex = startIndex + count;
958                 if (value == null) {
959                     for(int i=startIndex; i<endIndex; i++)
960                         if (_list[i] == null)
961                             return i;
962                     return -1;
963                 } else {
964                     for(int i=startIndex; i<endIndex; i++)
965                         if (_list[i] != null && _list[i].Equals(value))
966                             return i;
967                     return -1;
968                 }
969             }
970     
971             public override void Insert(int index, Object obj) {
972                 _list.Insert(index, obj);
973                 _version++;
974             }
975     
976             public override void InsertRange(int index, ICollection c) {
977                 if (c==null)
978                     throw new ArgumentNullException("c", Environment.GetResourceString("ArgumentNull_Collection"));
979                 if (index < 0 || index > this.Count) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
980                 Contract.EndContractBlock();
981
982                 if( c.Count > 0) {
983                     ArrayList al = _list as ArrayList;
984                     if( al != null) { 
985                         // We need to special case ArrayList. 
986                         // When c is a range of _list, we need to handle this in a special way.
987                         // See ArrayList.InsertRange for details.
988                         al.InsertRange(index, c);    
989                     }
990                     else {
991                         IEnumerator en = c.GetEnumerator();
992                         while(en.MoveNext()) {
993                             _list.Insert(index++, en.Current);
994                         }                   
995                     }
996                     _version++;
997                 }
998             }
999     
1000             public override int LastIndexOf(Object value) {
1001                  return LastIndexOf(value,_list.Count - 1, _list.Count);
1002             }
1003
1004             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1005             public override int LastIndexOf(Object value, int startIndex) {
1006                 return LastIndexOf(value, startIndex, startIndex + 1);
1007             }
1008
1009             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1010             public override int LastIndexOf(Object value, int startIndex, int count) {
1011                 if (_list.Count == 0)
1012                     return -1;
1013    
1014                 if (startIndex < 0 || startIndex >= _list.Count) throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
1015                 if (count < 0 || count > startIndex + 1) throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count"));
1016
1017                 int endIndex = startIndex - count + 1;
1018                 if (value == null) {
1019                     for(int i=startIndex; i >= endIndex; i--)
1020                         if (_list[i] == null)
1021                             return i;
1022                     return -1;
1023                 } else {
1024                     for(int i=startIndex; i >= endIndex; i--)
1025                         if (_list[i] != null && _list[i].Equals(value))
1026                             return i;
1027                     return -1;
1028                 }
1029             }
1030     
1031             public override void Remove(Object value) {
1032                 int index = IndexOf(value);                
1033                 if (index >=0) 
1034                     RemoveAt(index);
1035             }
1036     
1037             public override void RemoveAt(int index) {
1038                 _list.RemoveAt(index);
1039                 _version++;
1040             }
1041     
1042             public override void RemoveRange(int index, int count) {
1043                 if (index < 0 || count < 0)
1044                     throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
1045                 Contract.EndContractBlock();
1046                 if (_list.Count - index < count)
1047                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
1048                 
1049                 if( count > 0)    // be consistent with ArrayList
1050                     _version++;
1051
1052                 while(count > 0) {
1053                     _list.RemoveAt(index);
1054                     count--;
1055                 }
1056             }
1057     
1058             public override void Reverse(int index, int count) {
1059                 if (index < 0 || count < 0)
1060                     throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
1061                 Contract.EndContractBlock();
1062                 if (_list.Count - index < count)
1063                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
1064     
1065                 int i = index;
1066                 int j = index + count - 1;
1067                 while (i < j)
1068                 {
1069                     Object tmp = _list[i];
1070                     _list[i++] = _list[j];
1071                     _list[j--] = tmp;
1072                 }
1073                 _version++;
1074             }
1075     
1076             public override void SetRange(int index, ICollection c) {
1077                 if (c==null) {
1078                     throw new ArgumentNullException("c", Environment.GetResourceString("ArgumentNull_Collection"));
1079                 }
1080                 Contract.EndContractBlock();
1081
1082                 if (index < 0 || index > _list.Count - c.Count) {
1083                     throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));            
1084                 }
1085                    
1086                 if( c.Count > 0) {                                     
1087                     IEnumerator en = c.GetEnumerator();
1088                     while(en.MoveNext()) {
1089                         _list[index++] = en.Current;
1090                     }
1091                     _version++;
1092                 }
1093             }
1094     
1095             public override ArrayList GetRange(int index, int count) {
1096                 if (index < 0 || count < 0)
1097                     throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
1098                 Contract.EndContractBlock();
1099                 if (_list.Count - index < count)
1100                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
1101                 return new Range(this,index, count);
1102             }
1103
1104             public override void Sort(int index, int count, IComparer comparer) {
1105                 if (index < 0 || count < 0)
1106                     throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
1107                 Contract.EndContractBlock();
1108                 if (_list.Count - index < count)
1109                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
1110                 
1111                 Object [] array = new Object[count];
1112                 CopyTo(index, array, 0, count);
1113                 Array.Sort(array, 0, count, comparer);
1114                 for(int i=0; i<count; i++)
1115                     _list[i+index] = array[i];
1116
1117                 _version++;
1118             }
1119
1120
1121             public override Object[] ToArray() {
1122                 Object[] array = new Object[Count];
1123                 _list.CopyTo(array, 0);
1124                 return array;
1125             }
1126
1127             [SecuritySafeCritical]
1128             public override Array ToArray(Type type)
1129             {
1130                 if (type==null)
1131                     throw new ArgumentNullException("type");
1132                 Contract.EndContractBlock();
1133                 Array array = Array.UnsafeCreateInstance(type, _list.Count);
1134                 _list.CopyTo(array, 0);
1135                 return array;
1136             }
1137
1138             public override void TrimToSize()
1139             {
1140                 // Can't really do much here...
1141             }
1142     
1143             // This is the enumerator for an IList that's been wrapped in another
1144             // class that implements all of ArrayList's methods.
1145             [Serializable]
1146             private sealed class IListWrapperEnumWrapper : IEnumerator, ICloneable
1147             {
1148                 private IEnumerator _en;
1149                 private int _remaining;
1150                 private int _initialStartIndex;   // for reset
1151                 private int _initialCount;        // for reset
1152                 private bool _firstCall;       // firstCall to MoveNext
1153     
1154                 private IListWrapperEnumWrapper()
1155                 {
1156                 }
1157
1158                 internal IListWrapperEnumWrapper(IListWrapper listWrapper, int startIndex, int count) 
1159                 {
1160                     _en = listWrapper.GetEnumerator();
1161                     _initialStartIndex = startIndex;
1162                     _initialCount = count;
1163                     while(startIndex-- > 0 && _en.MoveNext());
1164                     _remaining = count;
1165                     _firstCall = true;
1166                 }
1167
1168                 public Object Clone() {
1169                     // We must clone the underlying enumerator, I think.
1170                     IListWrapperEnumWrapper clone = new IListWrapperEnumWrapper();
1171                     clone._en = (IEnumerator) ((ICloneable)_en).Clone();
1172                     clone._initialStartIndex = _initialStartIndex;
1173                     clone._initialCount = _initialCount;
1174                     clone._remaining = _remaining;
1175                     clone._firstCall = _firstCall;
1176                     return clone;
1177                 }
1178
1179                 public bool MoveNext() {
1180                     if (_firstCall) {
1181                         _firstCall = false;
1182                         return _remaining-- > 0 && _en.MoveNext();
1183                     }
1184                     if (_remaining < 0)
1185                         return false;
1186                     bool r = _en.MoveNext();
1187                     return r && _remaining-- > 0;
1188                 }
1189                 
1190                 public Object Current {
1191                     get {
1192                         if (_firstCall)
1193                             throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumNotStarted));
1194                         if (_remaining < 0)
1195                             throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumEnded));
1196                         return _en.Current;
1197                     }
1198                 }
1199     
1200                 public void Reset() {
1201                     _en.Reset();
1202                     int startIndex = _initialStartIndex;
1203                     while(startIndex-- > 0 && _en.MoveNext());
1204                     _remaining = _initialCount;
1205                     _firstCall = true;
1206                 }
1207             }
1208         }
1209     
1210     
1211         [Serializable]
1212         private class SyncArrayList : ArrayList
1213         {
1214             private ArrayList _list;
1215             private Object _root;
1216
1217             internal SyncArrayList(ArrayList list)
1218                 : base( false )
1219             {
1220                 _list = list;
1221                 _root = list.SyncRoot;
1222             }
1223     
1224             public override int Capacity {
1225                 get {
1226                     lock(_root) {
1227                         return _list.Capacity;
1228                     }
1229                 }
1230                 [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1231                 set {
1232                     lock(_root) {
1233                         _list.Capacity = value;
1234                     }
1235                 }
1236             }
1237     
1238             public override int Count { 
1239                 get { lock(_root) { return _list.Count; } }
1240             }
1241     
1242             public override bool IsReadOnly {
1243                 get { return _list.IsReadOnly; }
1244             }
1245
1246             public override bool IsFixedSize {
1247                 get { return _list.IsFixedSize; }
1248             }
1249
1250                     
1251             public override bool IsSynchronized { 
1252                 get { return true; }
1253             }
1254             
1255              public override Object this[int index] {
1256                 get {
1257                     lock(_root) {
1258                         return _list[index];
1259                     }
1260                 }
1261                 set {
1262                     lock(_root) {
1263                         _list[index] = value;
1264                     }
1265                 }
1266             }
1267     
1268             public override Object SyncRoot {
1269                 get { return _root; }
1270             }
1271     
1272             public override int Add(Object value) {
1273                 lock(_root) {
1274                     return _list.Add(value);
1275                 }
1276             }
1277     
1278             public override void AddRange(ICollection c) {
1279                 lock(_root) {
1280                     _list.AddRange(c);
1281                 }
1282             }
1283
1284             public override int BinarySearch(Object value) {
1285                 lock(_root) {
1286                     return _list.BinarySearch(value);
1287                 }
1288             }
1289
1290             public override int BinarySearch(Object value, IComparer comparer) {
1291                 lock(_root) {
1292                     return _list.BinarySearch(value, comparer);
1293                 }
1294             }
1295
1296             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1297             public override int BinarySearch(int index, int count, Object value, IComparer comparer) {
1298                 lock(_root) {
1299                     return _list.BinarySearch(index, count, value, comparer);
1300                 }
1301             }
1302
1303             public override void Clear() {
1304                 lock(_root) {
1305                     _list.Clear();
1306                 }
1307             }
1308
1309             public override Object Clone() {
1310                 lock(_root) {
1311                     return new SyncArrayList((ArrayList)_list.Clone());
1312                 }
1313             }
1314     
1315             public override bool Contains(Object item) {
1316                 lock(_root) {
1317                     return _list.Contains(item);
1318                 }
1319             }
1320     
1321             public override void CopyTo(Array array) {
1322                 lock(_root) {
1323                     _list.CopyTo(array);
1324                 }
1325             }
1326
1327             public override void CopyTo(Array array, int index) {
1328                 lock(_root) {
1329                     _list.CopyTo(array, index);
1330                 }
1331             }
1332
1333             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1334             public override void CopyTo(int index, Array array, int arrayIndex, int count) {
1335                 lock(_root) {
1336                     _list.CopyTo(index, array, arrayIndex, count);
1337                 }
1338             }
1339     
1340             public override IEnumerator GetEnumerator() {
1341                 lock(_root) {
1342                     return _list.GetEnumerator();
1343                 }
1344             }
1345
1346             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1347             public override IEnumerator GetEnumerator(int index, int count) {
1348                 lock(_root) {
1349                     return _list.GetEnumerator(index, count);
1350                 }
1351             }
1352     
1353             public override int IndexOf(Object value) {
1354                 lock(_root) {
1355                     return _list.IndexOf(value);
1356                 }
1357             }
1358
1359             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1360             public override int IndexOf(Object value, int startIndex) {
1361                 lock(_root) {
1362                     return _list.IndexOf(value, startIndex);
1363                 }
1364             }
1365
1366             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1367             public override int IndexOf(Object value, int startIndex, int count) {
1368                 lock(_root) {
1369                     return _list.IndexOf(value, startIndex, count);
1370                 }
1371             }
1372     
1373             public override void Insert(int index, Object value) {
1374                 lock(_root) {
1375                     _list.Insert(index, value);
1376                 }
1377             }
1378
1379             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1380             public override void InsertRange(int index, ICollection c) {
1381                 lock(_root) {
1382                     _list.InsertRange(index, c);
1383                 }
1384             }
1385     
1386             public override int LastIndexOf(Object value) {
1387                 lock(_root) {
1388                     return _list.LastIndexOf(value);
1389                 }
1390             }
1391
1392             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1393             public override int LastIndexOf(Object value, int startIndex) {
1394                 lock(_root) {
1395                     return _list.LastIndexOf(value, startIndex);
1396                 }
1397             }
1398
1399             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1400             public override int LastIndexOf(Object value, int startIndex, int count) {
1401                 lock(_root) {
1402                     return _list.LastIndexOf(value, startIndex, count);
1403                 }
1404             }
1405     
1406             public override void Remove(Object value) {
1407                 lock(_root) {
1408                     _list.Remove(value);
1409                 }
1410             }
1411     
1412             public override void RemoveAt(int index) {
1413                 lock(_root) {
1414                     _list.RemoveAt(index);
1415                 }
1416             }
1417
1418             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1419             public override void RemoveRange(int index, int count) {
1420                 lock(_root) {
1421                     _list.RemoveRange(index, count);
1422                 }
1423             }
1424
1425             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1426             public override void Reverse(int index, int count) {
1427                 lock(_root) {
1428                     _list.Reverse(index, count);
1429                 }
1430             }
1431
1432             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1433             public override void SetRange(int index, ICollection c) {
1434                 lock(_root) {
1435                     _list.SetRange(index, c);
1436                 }
1437             }
1438
1439             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1440             public override ArrayList GetRange(int index, int count) {
1441                 lock(_root) {
1442                     return _list.GetRange(index, count);
1443                 }
1444             }
1445
1446             public override void Sort() {
1447                 lock(_root) {
1448                     _list.Sort();
1449                 }
1450             }
1451     
1452             public override void Sort(IComparer comparer) {
1453                 lock(_root) {
1454                     _list.Sort(comparer);
1455                 }
1456             }
1457
1458             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1459             public override void Sort(int index, int count, IComparer comparer) {
1460                 lock(_root) {
1461                     _list.Sort(index, count, comparer);
1462                 }
1463             }
1464     
1465             public override Object[] ToArray() {
1466                 lock(_root) {
1467                     return _list.ToArray();
1468                 }
1469             }
1470
1471             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1472             public override Array ToArray(Type type) {
1473                 lock(_root) {
1474                     return _list.ToArray(type);
1475                 }
1476             }
1477     
1478             public override void TrimToSize() {
1479                 lock(_root) {
1480                     _list.TrimToSize();
1481                 }
1482             }
1483         }
1484     
1485     
1486         [Serializable]
1487         private class SyncIList : IList
1488         {
1489             private IList _list;
1490             private Object _root;
1491     
1492             internal SyncIList(IList list) {
1493                 _list = list;
1494                 _root = list.SyncRoot;
1495             }
1496     
1497             public virtual int Count { 
1498                 get { lock(_root) { return _list.Count; } }
1499             }
1500     
1501             public virtual bool IsReadOnly {
1502                 get { return _list.IsReadOnly; }
1503             }
1504
1505             public virtual bool IsFixedSize {
1506                 get { return _list.IsFixedSize; }
1507             }
1508
1509             
1510             public virtual bool IsSynchronized { 
1511                 get { return true; }
1512             }
1513             
1514              public virtual Object this[int index] {
1515                 get {
1516                     lock(_root) {
1517                         return _list[index];
1518                     }
1519                 }
1520                 set {
1521                     lock(_root) {
1522                         _list[index] = value;
1523                     }
1524                 }
1525             }
1526     
1527             public virtual Object SyncRoot {
1528                 get { return _root; }
1529             }
1530     
1531             public virtual int Add(Object value) {
1532                 lock(_root) {
1533                     return _list.Add(value);
1534                 }
1535             }
1536                  
1537     
1538             public virtual void Clear() {
1539                 lock(_root) {
1540                     _list.Clear();
1541                 }
1542             }
1543     
1544             public virtual bool Contains(Object item) {
1545                 lock(_root) {
1546                     return _list.Contains(item);
1547                 }
1548             }
1549     
1550             public virtual void CopyTo(Array array, int index) {
1551                 lock(_root) {
1552                     _list.CopyTo(array, index);
1553                 }
1554             }
1555     
1556             public virtual IEnumerator GetEnumerator() {
1557                 lock(_root) {
1558                     return _list.GetEnumerator();
1559                 }
1560             }
1561     
1562             public virtual int IndexOf(Object value) {
1563                 lock(_root) {
1564                     return _list.IndexOf(value);
1565                 }
1566             }
1567     
1568             public virtual void Insert(int index, Object value) {
1569                 lock(_root) {
1570                     _list.Insert(index, value);
1571                 }
1572             }
1573     
1574             public virtual void Remove(Object value) {
1575                 lock(_root) {
1576                     _list.Remove(value);
1577                 }
1578             }
1579     
1580             public virtual void RemoveAt(int index) {
1581                 lock(_root) {
1582                     _list.RemoveAt(index);
1583                 }
1584             }
1585         }
1586     
1587         [Serializable]
1588         private class FixedSizeList : IList
1589         {
1590             private IList _list;
1591     
1592             internal FixedSizeList(IList l) {
1593                 _list = l;
1594             }
1595     
1596             public virtual int Count { 
1597                 get { return _list.Count; }
1598             }
1599     
1600             public virtual bool IsReadOnly {
1601                 get { return _list.IsReadOnly; }
1602             }
1603
1604             public virtual bool IsFixedSize {
1605                 get { return true; }
1606             }
1607
1608             public virtual bool IsSynchronized { 
1609                 get { return _list.IsSynchronized; }
1610             }
1611             
1612              public virtual Object this[int index] {
1613                 get {
1614                     return _list[index];
1615                 }
1616                 set {
1617                     _list[index] = value;
1618                 }
1619             }
1620     
1621             public virtual Object SyncRoot {
1622                 get { return _list.SyncRoot; }
1623             }
1624             
1625             public virtual int Add(Object obj) {
1626                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_FixedSizeCollection"));
1627             }
1628     
1629             public virtual void Clear() {
1630                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_FixedSizeCollection"));
1631             }
1632     
1633             public virtual bool Contains(Object obj) {
1634                 return _list.Contains(obj);
1635             }
1636     
1637             public virtual void CopyTo(Array array, int index) {
1638                 _list.CopyTo(array, index);
1639             }
1640     
1641             public virtual IEnumerator GetEnumerator() {
1642                 return _list.GetEnumerator();
1643             }
1644     
1645             public virtual int IndexOf(Object value) {
1646                 return _list.IndexOf(value);
1647             }
1648     
1649             public virtual void Insert(int index, Object obj) {
1650                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_FixedSizeCollection"));
1651             }
1652     
1653             public virtual void Remove(Object value) {
1654                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_FixedSizeCollection"));
1655             }
1656     
1657             public virtual void RemoveAt(int index) {
1658                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_FixedSizeCollection"));
1659             }
1660         }
1661
1662         [Serializable]
1663         private class FixedSizeArrayList : ArrayList
1664         {
1665             private ArrayList _list;
1666     
1667             internal FixedSizeArrayList(ArrayList l) {
1668                 _list = l;
1669                 _version = _list._version;
1670             }
1671     
1672             public override int Count { 
1673                 get { return _list.Count; }
1674             }
1675     
1676             public override bool IsReadOnly {
1677                 get { return _list.IsReadOnly; }
1678             }
1679
1680             public override bool IsFixedSize {
1681                 get { return true; }
1682             }
1683
1684             public override bool IsSynchronized { 
1685                 get { return _list.IsSynchronized; }
1686             }
1687             
1688              public override Object this[int index] {
1689                 get {
1690                     return _list[index];
1691                 }
1692                 set {
1693                     _list[index] = value;
1694                     _version = _list._version;
1695                 }
1696             }
1697     
1698             public override Object SyncRoot {
1699                 get { return _list.SyncRoot; }
1700             }
1701             
1702             public override int Add(Object obj) {
1703                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_FixedSizeCollection"));
1704             }
1705     
1706             public override void AddRange(ICollection c) {
1707                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_FixedSizeCollection"));
1708             }
1709
1710             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1711             public override int BinarySearch(int index, int count, Object value, IComparer comparer) {
1712                 return _list.BinarySearch(index, count, value, comparer);
1713             }
1714
1715             public override int Capacity {
1716                 get { return _list.Capacity; }
1717                 [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1718                 set { throw new NotSupportedException(Environment.GetResourceString("NotSupported_FixedSizeCollection")); }
1719             }
1720
1721             public override void Clear() {
1722                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_FixedSizeCollection"));
1723             }
1724     
1725             public override Object Clone() {
1726                 FixedSizeArrayList arrayList = new FixedSizeArrayList(_list);
1727                 arrayList._list = (ArrayList)_list.Clone();
1728                 return arrayList;
1729             }
1730
1731             public override bool Contains(Object obj) {
1732                 return _list.Contains(obj);
1733             }
1734     
1735             public override void CopyTo(Array array, int index) {
1736                 _list.CopyTo(array, index);
1737             }
1738
1739             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1740             public override void CopyTo(int index, Array array, int arrayIndex, int count) {
1741                 _list.CopyTo(index, array, arrayIndex, count);
1742             }
1743
1744             public override IEnumerator GetEnumerator() {
1745                 return _list.GetEnumerator();
1746             }
1747
1748             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1749             public override IEnumerator GetEnumerator(int index, int count) {
1750                 return _list.GetEnumerator(index, count);
1751             }
1752
1753             public override int IndexOf(Object value) {
1754                 return _list.IndexOf(value);
1755             }
1756
1757             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1758             public override int IndexOf(Object value, int startIndex) {
1759                 return _list.IndexOf(value, startIndex);
1760             }
1761
1762             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1763             public override int IndexOf(Object value, int startIndex, int count) {
1764                 return _list.IndexOf(value, startIndex, count);
1765             }
1766     
1767             public override void Insert(int index, Object obj) {
1768                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_FixedSizeCollection"));
1769             }
1770
1771             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1772             public override void InsertRange(int index, ICollection c) {
1773                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_FixedSizeCollection"));
1774             }
1775
1776             public override int LastIndexOf(Object value) {
1777                 return _list.LastIndexOf(value);
1778             }
1779
1780             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1781             public override int LastIndexOf(Object value, int startIndex) {
1782                 return _list.LastIndexOf(value, startIndex);
1783             }
1784
1785             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1786             public override int LastIndexOf(Object value, int startIndex, int count) {
1787                 return _list.LastIndexOf(value, startIndex, count);
1788             }
1789
1790             public override void Remove(Object value) {
1791                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_FixedSizeCollection"));
1792             }
1793     
1794             public override void RemoveAt(int index) {
1795                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_FixedSizeCollection"));
1796             }
1797
1798             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1799             public override void RemoveRange(int index, int count) {
1800                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_FixedSizeCollection"));
1801             }
1802
1803             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1804             public override void SetRange(int index, ICollection c) {
1805                 _list.SetRange(index, c);
1806                 _version = _list._version;
1807             }
1808
1809             public override ArrayList GetRange(int index, int count) {
1810                 if (index < 0 || count < 0)
1811                     throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
1812                 if (Count - index < count)
1813                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
1814                 Contract.EndContractBlock();
1815
1816                 return new Range(this,index, count);
1817             }
1818
1819             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1820             public override void Reverse(int index, int count) {
1821                 _list.Reverse(index, count);
1822                 _version = _list._version;
1823             }
1824
1825             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1826             public override void Sort(int index, int count, IComparer comparer) {
1827                 _list.Sort(index, count, comparer);
1828                 _version = _list._version;
1829             }
1830
1831             public override Object[] ToArray() {
1832                 return _list.ToArray();
1833             }
1834
1835             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1836             public override Array ToArray(Type type) {
1837                 return _list.ToArray(type);
1838             }
1839     
1840             public override void TrimToSize() {
1841                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_FixedSizeCollection"));
1842             }
1843         }
1844     
1845         [Serializable]
1846         private class ReadOnlyList : IList
1847         {
1848             private IList _list;
1849     
1850             internal ReadOnlyList(IList l) {
1851                 _list = l;
1852             }
1853     
1854             public virtual int Count { 
1855                 get { return _list.Count; }
1856             }
1857     
1858             public virtual bool IsReadOnly {
1859                 get { return true; }
1860             }
1861
1862             public virtual bool IsFixedSize {
1863                 get { return true; }
1864             }
1865
1866             public virtual bool IsSynchronized { 
1867                 get { return _list.IsSynchronized; }
1868             }
1869             
1870              public virtual Object this[int index] {
1871                 get {
1872                     return _list[index];
1873                 }
1874                 set {
1875                     throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
1876                 }
1877             }
1878     
1879             public virtual Object SyncRoot {
1880                 get { return _list.SyncRoot; }
1881             }
1882             
1883             public virtual int Add(Object obj) {
1884                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
1885             }
1886     
1887             public virtual void Clear() {
1888                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
1889             }
1890     
1891             public virtual bool Contains(Object obj) {
1892                 return _list.Contains(obj);
1893             }
1894             
1895             public virtual void CopyTo(Array array, int index) {
1896                 _list.CopyTo(array, index);
1897             }
1898     
1899             public virtual IEnumerator GetEnumerator() {
1900                 return _list.GetEnumerator();
1901             }
1902     
1903             public virtual int IndexOf(Object value) {
1904                 return _list.IndexOf(value);
1905             }
1906     
1907             public virtual void Insert(int index, Object obj) {
1908                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
1909             }
1910
1911             public virtual void Remove(Object value) {
1912                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
1913             }
1914     
1915             public virtual void RemoveAt(int index) {
1916                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
1917             }
1918         }
1919
1920         [Serializable]
1921         private class ReadOnlyArrayList : ArrayList
1922         {
1923             private ArrayList _list;
1924     
1925             internal ReadOnlyArrayList(ArrayList l) {
1926                 _list = l;
1927             }
1928     
1929             public override int Count { 
1930                 get { return _list.Count; }
1931             }
1932     
1933             public override bool IsReadOnly {
1934                 get { return true; }
1935             }
1936
1937             public override bool IsFixedSize {
1938                 get { return true; }
1939             }
1940
1941             public override bool IsSynchronized { 
1942                 get { return _list.IsSynchronized; }
1943             }
1944             
1945              public override Object this[int index] {
1946                 get {
1947                     return _list[index];
1948                 }
1949                 set {
1950                     throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
1951                 }
1952             }
1953     
1954             public override Object SyncRoot {
1955                 get { return _list.SyncRoot; }
1956             }
1957             
1958             public override int Add(Object obj) {
1959                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
1960             }
1961     
1962             public override void AddRange(ICollection c) {
1963                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
1964             }
1965
1966             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1967             public override int BinarySearch(int index, int count, Object value, IComparer comparer) {
1968                 return _list.BinarySearch(index, count, value, comparer);
1969             }
1970
1971
1972             public override int Capacity {
1973                 get { return _list.Capacity; }
1974                 [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1975                 set { throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection")); }
1976             }
1977
1978             public override void Clear() {
1979                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
1980             }
1981
1982             public override Object Clone() {
1983                 ReadOnlyArrayList arrayList = new ReadOnlyArrayList(_list);
1984                 arrayList._list = (ArrayList)_list.Clone();
1985                 return arrayList;
1986             }
1987     
1988             public override bool Contains(Object obj) {
1989                 return _list.Contains(obj);
1990             }
1991     
1992             public override void CopyTo(Array array, int index) {
1993                 _list.CopyTo(array, index);
1994             }
1995
1996             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
1997             public override void CopyTo(int index, Array array, int arrayIndex, int count) {
1998                 _list.CopyTo(index, array, arrayIndex, count);
1999             }
2000
2001             public override IEnumerator GetEnumerator() {
2002                 return _list.GetEnumerator();
2003             }
2004
2005             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
2006             public override IEnumerator GetEnumerator(int index, int count) {
2007                 return _list.GetEnumerator(index, count);
2008             }
2009
2010             public override int IndexOf(Object value) {
2011                 return _list.IndexOf(value);
2012             }
2013
2014             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
2015             public override int IndexOf(Object value, int startIndex) {
2016                 return _list.IndexOf(value, startIndex);
2017             }
2018
2019             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
2020             public override int IndexOf(Object value, int startIndex, int count) {
2021                 return _list.IndexOf(value, startIndex, count);
2022             }
2023     
2024             public override void Insert(int index, Object obj) {
2025                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
2026             }
2027
2028             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
2029             public override void InsertRange(int index, ICollection c) {
2030                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
2031             }
2032
2033             public override int LastIndexOf(Object value) {
2034                 return _list.LastIndexOf(value);
2035             }
2036
2037             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
2038             public override int LastIndexOf(Object value, int startIndex) {
2039                 return _list.LastIndexOf(value, startIndex);
2040             }
2041
2042             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
2043             public override int LastIndexOf(Object value, int startIndex, int count) {
2044                 return _list.LastIndexOf(value, startIndex, count);
2045             }
2046
2047             public override void Remove(Object value) {
2048                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
2049             }
2050     
2051             public override void RemoveAt(int index) {
2052                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
2053             }
2054
2055             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
2056             public override void RemoveRange(int index, int count) {
2057                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
2058             }
2059
2060             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
2061             public override void SetRange(int index, ICollection c) {
2062                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
2063             }
2064     
2065             public override ArrayList GetRange(int index, int count) {
2066                 if (index < 0 || count < 0)
2067                     throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
2068                 if (Count - index < count)
2069                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
2070                 Contract.EndContractBlock();
2071
2072                 return new Range(this,index, count);
2073             }
2074
2075             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
2076             public override void Reverse(int index, int count) {
2077                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
2078             }
2079
2080             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
2081             public override void Sort(int index, int count, IComparer comparer) {
2082                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
2083             }
2084
2085             public override Object[] ToArray() {
2086                 return _list.ToArray();
2087             }
2088
2089             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
2090             public override Array ToArray(Type type) {
2091                 return _list.ToArray(type);
2092             }
2093     
2094             public override void TrimToSize() {
2095                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
2096             }
2097         }
2098
2099     
2100         // Implements an enumerator for a ArrayList. The enumerator uses the
2101         // internal version number of the list to ensure that no modifications are
2102         // made to the list while an enumeration is in progress.
2103         [Serializable]
2104         private sealed class ArrayListEnumerator : IEnumerator, ICloneable
2105         {
2106             private ArrayList list;
2107             private int index;
2108             private int endIndex;       // Where to stop.
2109             private int version;
2110             private Object currentElement;
2111             private int startIndex;     // Save this for Reset.
2112     
2113             internal ArrayListEnumerator(ArrayList list, int index, int count) {
2114                 this.list = list;
2115                 startIndex = index;
2116                 this.index = index - 1;
2117                 endIndex = this.index + count;  // last valid index
2118                 version = list._version;
2119                 currentElement = null;
2120             }
2121
2122             public Object Clone() {
2123                 return MemberwiseClone();
2124             }
2125     
2126             public bool MoveNext() {
2127                 if (version != list._version) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));
2128                 if (index < endIndex) {
2129                     currentElement = list[++index];
2130                     return true;
2131                 }
2132                 else {
2133                     index = endIndex + 1;
2134                 }
2135                 
2136                 return false;
2137             }
2138     
2139             public Object Current {
2140                 get {
2141                     if (index < startIndex) 
2142                         throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumNotStarted));
2143                     else if (index > endIndex) {
2144                         throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumEnded));
2145                     }
2146                     return currentElement;
2147                 }
2148             }
2149        
2150             public void Reset() {
2151                 if (version != list._version) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));
2152                 index = startIndex - 1;                
2153             }
2154         }
2155
2156         // Implementation of a generic list subrange. An instance of this class
2157         // is returned by the default implementation of List.GetRange.
2158         [Serializable]
2159         private class Range: ArrayList
2160         {
2161             private ArrayList _baseList;
2162             private int _baseIndex;
2163             [ContractPublicPropertyName("Count")]
2164             private int _baseSize;
2165             private int _baseVersion;
2166                         
2167             internal Range(ArrayList list, int index, int count) : base(false) {
2168                 _baseList = list;
2169                 _baseIndex = index;
2170                 _baseSize = count;
2171                 _baseVersion = list._version;
2172                 // we also need to update _version field to make Range of Range work
2173                 _version = list._version;                
2174             }
2175
2176             private void InternalUpdateRange()
2177             {
2178                 if (_baseVersion != _baseList._version)
2179                     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_UnderlyingArrayListChanged"));
2180             }
2181
2182             private void InternalUpdateVersion() {
2183                 _baseVersion++;
2184                 _version++;                
2185             }
2186             
2187             public override int Add(Object value) {
2188                 InternalUpdateRange();
2189                 _baseList.Insert(_baseIndex + _baseSize, value);
2190                 InternalUpdateVersion();
2191                 return _baseSize++;
2192             }
2193
2194             public override void AddRange(ICollection c) {
2195                 if( c ==  null ) {
2196                     throw new ArgumentNullException("c");
2197                 }
2198                 Contract.EndContractBlock();
2199
2200                 InternalUpdateRange();
2201                 int count = c.Count;
2202                 if( count > 0) {
2203                     _baseList.InsertRange(_baseIndex + _baseSize, c);
2204                     InternalUpdateVersion();
2205                     _baseSize += count;
2206                 }
2207             }
2208
2209             // Other overloads with automatically work 
2210             public override int BinarySearch(int index, int count, Object value, IComparer comparer) {
2211                 if (index < 0 || count < 0)
2212                     throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
2213                 if (_baseSize - index < count)
2214                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
2215                 Contract.EndContractBlock();
2216                 InternalUpdateRange();
2217
2218                 int i = _baseList.BinarySearch(_baseIndex + index, count, value, comparer);
2219                 if (i >= 0) return i - _baseIndex;
2220                 return i + _baseIndex;
2221             }
2222
2223             public override int Capacity {
2224                 get {
2225                     return _baseList.Capacity;
2226                 }
2227              
2228                 set {
2229                     if (value < Count) throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
2230                     Contract.EndContractBlock();
2231                 }
2232             }
2233     
2234
2235             public override void Clear() {
2236                 InternalUpdateRange();
2237                 if (_baseSize != 0)
2238                 {
2239                     _baseList.RemoveRange(_baseIndex, _baseSize);
2240                     InternalUpdateVersion();
2241                     _baseSize = 0;
2242                 }
2243             }
2244
2245             public override Object Clone() {
2246                 InternalUpdateRange();
2247                 Range arrayList = new Range(_baseList,_baseIndex,_baseSize);
2248                 arrayList._baseList = (ArrayList)_baseList.Clone();
2249                 return arrayList;
2250             }
2251
2252             public override bool Contains(Object item) {
2253               InternalUpdateRange();
2254               if (item==null) {
2255                     for(int i=0; i<_baseSize; i++)
2256                         if (_baseList[_baseIndex + i]==null)
2257                             return true;
2258                     return false;
2259                 }
2260                 else {
2261                     for(int i=0; i<_baseSize; i++)
2262                         if (_baseList[_baseIndex + i] != null && _baseList[_baseIndex + i].Equals(item))
2263                             return true;
2264                     return false;
2265                 }
2266             }
2267     
2268             public override void CopyTo(Array array, int index) {
2269                 if (array==null)
2270                     throw new ArgumentNullException("array");
2271                 if (array.Rank != 1)
2272                     throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
2273                 if (index < 0)
2274                     throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
2275                 if (array.Length - index < _baseSize)
2276                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
2277                 Contract.EndContractBlock();
2278
2279                 InternalUpdateRange();
2280                 _baseList.CopyTo(_baseIndex, array, index, _baseSize);
2281             }
2282
2283             public override void CopyTo(int index, Array array, int arrayIndex, int count) {
2284                 if (array==null)
2285                     throw new ArgumentNullException("array");
2286                 if (array.Rank != 1)
2287                     throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
2288                 if (index < 0 || count < 0)
2289                     throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
2290                 if (array.Length - arrayIndex < count)
2291                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
2292                 if (_baseSize - index < count)
2293                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
2294                 Contract.EndContractBlock();
2295
2296                 InternalUpdateRange();
2297                 _baseList.CopyTo(_baseIndex + index, array, arrayIndex, count);
2298             }
2299
2300             public override int Count {
2301                 get {
2302                  InternalUpdateRange();
2303                  return _baseSize; 
2304                 }
2305             }
2306
2307             public override bool IsReadOnly {
2308                 get { return _baseList.IsReadOnly; }
2309             }
2310
2311             public override bool IsFixedSize {
2312                 get { return _baseList.IsFixedSize; }
2313             }
2314
2315             public override bool IsSynchronized {
2316                 get { return _baseList.IsSynchronized; }
2317             }
2318                                 
2319             public override IEnumerator GetEnumerator() {
2320                 return GetEnumerator(0,_baseSize);
2321             }
2322
2323             public override IEnumerator GetEnumerator(int index, int count) {
2324                 if (index < 0 || count < 0)
2325                     throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
2326                 if (_baseSize - index < count)
2327                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
2328                 Contract.EndContractBlock();
2329
2330                 InternalUpdateRange();
2331                 return _baseList.GetEnumerator(_baseIndex + index, count);
2332             }
2333
2334             public override ArrayList GetRange(int index, int count) {
2335                 if (index < 0 || count < 0)
2336                     throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
2337                 if (_baseSize - index < count)
2338                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
2339                 Contract.EndContractBlock();
2340
2341                 InternalUpdateRange();
2342                 return new Range(this, index, count);
2343             }
2344
2345             public override Object SyncRoot {
2346                 get {
2347                     return _baseList.SyncRoot;
2348                 }
2349             }
2350         
2351
2352             public override int IndexOf(Object value) {
2353                 InternalUpdateRange();
2354                 int i = _baseList.IndexOf(value, _baseIndex, _baseSize);
2355                 if (i >= 0) return i - _baseIndex;
2356                 return -1;
2357             }
2358
2359             public override int IndexOf(Object value, int startIndex) {
2360                 if (startIndex < 0)
2361                     throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
2362                 if (startIndex > _baseSize)
2363                     throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
2364                 Contract.EndContractBlock();
2365
2366                 InternalUpdateRange();
2367                 int i = _baseList.IndexOf(value, _baseIndex + startIndex, _baseSize - startIndex);
2368                 if (i >= 0) return i - _baseIndex;
2369                 return -1;
2370             }
2371             
2372             public override int IndexOf(Object value, int startIndex, int count) {
2373                 if (startIndex < 0 || startIndex > _baseSize)
2374                     throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
2375                     
2376                 if (count < 0 || (startIndex > _baseSize - count))
2377                     throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count"));
2378                 Contract.EndContractBlock();
2379
2380                 InternalUpdateRange();
2381                 int i = _baseList.IndexOf(value, _baseIndex + startIndex, count);
2382                 if (i >= 0) return i - _baseIndex;
2383                 return -1;
2384             }
2385
2386             public override void Insert(int index, Object value) {
2387                 if (index < 0 || index > _baseSize) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
2388                 Contract.EndContractBlock();
2389
2390                 InternalUpdateRange();
2391                 _baseList.Insert(_baseIndex + index, value);
2392                 InternalUpdateVersion();
2393                 _baseSize++;
2394             }
2395
2396             public override void InsertRange(int index, ICollection c) {
2397                 if (index < 0 || index > _baseSize) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
2398                 if( c == null) {
2399                     throw new ArgumentNullException("c");
2400                 }
2401                 Contract.EndContractBlock();
2402
2403                 InternalUpdateRange();                
2404                 int count = c.Count;
2405                 if( count > 0) {
2406                     _baseList.InsertRange(_baseIndex + index, c);
2407                     _baseSize += count;                    
2408                     InternalUpdateVersion();
2409                 }
2410             }
2411
2412             public override int LastIndexOf(Object value) {
2413                 InternalUpdateRange();
2414                 int i = _baseList.LastIndexOf(value, _baseIndex + _baseSize - 1, _baseSize);
2415                 if (i >= 0) return i - _baseIndex;
2416                 return -1;
2417             }
2418
2419             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
2420             public override int LastIndexOf(Object value, int startIndex) {
2421                 return LastIndexOf(value, startIndex, startIndex + 1);
2422             }
2423
2424             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
2425             public override int LastIndexOf(Object value, int startIndex, int count) {
2426                 InternalUpdateRange();
2427                 if (_baseSize == 0)
2428                     return -1;
2429    
2430                 if (startIndex >= _baseSize)
2431                     throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
2432                 if (startIndex < 0)
2433                     throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
2434                 
2435                 int i = _baseList.LastIndexOf(value, _baseIndex + startIndex, count);
2436                 if (i >= 0) return i - _baseIndex;
2437                 return -1;
2438             }
2439
2440             // Don't need to override Remove
2441
2442             public override void RemoveAt(int index) {
2443                 if (index < 0 || index >= _baseSize) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
2444                 Contract.EndContractBlock();
2445
2446                 InternalUpdateRange();
2447                 _baseList.RemoveAt(_baseIndex + index);
2448                 InternalUpdateVersion();
2449                 _baseSize--;
2450             }
2451
2452             public override void RemoveRange(int index, int count) {            
2453                 if (index < 0 || count < 0)
2454                     throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
2455                 if (_baseSize - index < count)
2456                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
2457                 Contract.EndContractBlock();
2458
2459                 InternalUpdateRange();
2460                 // No need to call _bastList.RemoveRange if count is 0.
2461                 // In addition, _baseList won't change the vresion number if count is 0. 
2462                 if( count > 0) {
2463                     _baseList.RemoveRange(_baseIndex + index, count);
2464                     InternalUpdateVersion();
2465                     _baseSize -= count;
2466                 }
2467             }
2468
2469             public override void Reverse(int index, int count) {
2470                 if (index < 0 || count < 0)
2471                     throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
2472                 if (_baseSize - index < count)
2473                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
2474                 Contract.EndContractBlock();
2475
2476                 InternalUpdateRange();
2477                 _baseList.Reverse(_baseIndex + index, count);
2478                 InternalUpdateVersion();
2479             }
2480
2481             [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
2482             public override void SetRange(int index, ICollection c) {
2483                 InternalUpdateRange();
2484                 if (index < 0 || index >= _baseSize) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
2485                 _baseList.SetRange(_baseIndex + index, c);
2486                 if( c.Count > 0) {
2487                     InternalUpdateVersion();
2488                 }
2489             }
2490
2491             public override void Sort(int index, int count, IComparer comparer) {
2492                 if (index < 0 || count < 0)
2493                     throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
2494                 if (_baseSize - index < count)
2495                     throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
2496                 Contract.EndContractBlock();
2497
2498                 InternalUpdateRange();
2499                 _baseList.Sort(_baseIndex + index, count, comparer);
2500                 InternalUpdateVersion();
2501             }
2502
2503             public override Object this[int index] {
2504                 get {
2505                     InternalUpdateRange();
2506                     if (index < 0 || index >= _baseSize) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
2507                     return _baseList[_baseIndex + index];
2508                 }
2509                 set {
2510                     InternalUpdateRange();
2511                     if (index < 0 || index >= _baseSize) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
2512                     _baseList[_baseIndex + index] = value;
2513                     InternalUpdateVersion();
2514                 }
2515             }
2516
2517             public override Object[] ToArray() {
2518                 InternalUpdateRange();
2519                 Object[] array = new Object[_baseSize];
2520                 Array.Copy(_baseList._items, _baseIndex, array, 0, _baseSize);
2521                 return array;
2522             }
2523
2524             [SecuritySafeCritical]
2525             public override Array ToArray(Type type) {
2526                 if (type==null)
2527                     throw new ArgumentNullException("type");
2528                 Contract.EndContractBlock();
2529
2530                 InternalUpdateRange();
2531                 Array array = Array.UnsafeCreateInstance(type, _baseSize);
2532                 _baseList.CopyTo(_baseIndex, array, 0, _baseSize);
2533                 return array;
2534             }
2535
2536             public override void TrimToSize() {
2537                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_RangeCollection"));
2538             }
2539         }
2540
2541         [Serializable]
2542         private sealed class ArrayListEnumeratorSimple : IEnumerator, ICloneable {
2543             private ArrayList list;
2544             private int index;
2545             private int version;
2546             private Object currentElement;
2547             [NonSerialized]
2548             private bool isArrayList;
2549             // this object is used to indicate enumeration has not started or has terminated
2550             static Object dummyObject = new Object();  
2551                             
2552             internal ArrayListEnumeratorSimple(ArrayList list) {
2553                 this.list = list;
2554                 this.index = -1;
2555                 version = list._version;
2556                 isArrayList = (list.GetType() == typeof(ArrayList));
2557                 currentElement = dummyObject;                
2558             }
2559             
2560             public Object Clone() {
2561                 return MemberwiseClone();
2562             }
2563     
2564             public bool MoveNext() {
2565                 if (version != list._version) {
2566                     throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));
2567                 }
2568
2569                 if( isArrayList) {  // avoid calling virtual methods if we are operating on ArrayList to improve performance
2570                     if (index < list._size - 1) {
2571                         currentElement = list._items[++index];
2572                         return true;
2573                     }
2574                     else {
2575                         currentElement = dummyObject;
2576                         index =list._size;
2577                         return false;
2578                     }                    
2579                 }
2580                 else {                    
2581                     if (index < list.Count - 1) {
2582                         currentElement = list[++index];
2583                         return true;
2584                     }
2585                     else {
2586                         index = list.Count;
2587                         currentElement = dummyObject;
2588                         return false;
2589                     }
2590                 }
2591             }
2592     
2593             public Object Current {
2594                 get {
2595                     object temp = currentElement;
2596                     if(dummyObject == temp) { // check if enumeration has not started or has terminated
2597                         if (index == -1) {
2598                             throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumNotStarted));
2599                         }
2600                         else {                    
2601                             throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumEnded));                        
2602                         }
2603                     }
2604
2605                     return temp;
2606                 }
2607             }
2608     
2609             public void Reset() {
2610                 if (version != list._version) {
2611                     throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));
2612                 }    
2613                 
2614                 currentElement = dummyObject;
2615                 index = -1;
2616             }
2617         }
2618
2619         internal class ArrayListDebugView {
2620             private ArrayList arrayList; 
2621         
2622             public ArrayListDebugView( ArrayList arrayList) {
2623                 if( arrayList == null)
2624                     throw new ArgumentNullException("arrayList");
2625
2626                 this.arrayList = arrayList;
2627             }
2628
2629             [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
2630             public Object[] Items { 
2631                 get {
2632                     return arrayList.ToArray();
2633                 }
2634             }
2635         }
2636     }    
2637 }