New tests.
[mono.git] / mcs / class / corlib / System.Collections / ArrayList.cs
1 // ArrayList.cs
2 // 
3 // Implementation of the ECMA ArrayList.
4 //
5 // Copyright (c) 2003 Thong (Tum) Nguyen [tum@veridicus.com]
6 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining
9 // a copy of this software and associated documentation files (the
10 // "Software"), to deal in the Software without restriction, including
11 // without limitation the rights to use, copy, modify, merge, publish,
12 // distribute, sublicense, and/or sell copies of the Software, and to
13 // permit persons to whom the Software is furnished to do so, subject to
14 // the following conditions:
15 // 
16 // The above copyright notice and this permission notice shall be
17 // included in all copies or substantial portions of the Software.
18 // 
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 //
27
28 using System.Runtime.InteropServices;
29
30 namespace System.Collections 
31 {
32 #if NET_2_0
33         [ComVisible(true)]
34 #endif
35         [Serializable]
36 #if INSIDE_CORLIB
37         public
38 #else
39         internal
40 #endif
41         class ArrayList
42                 : IList, ICloneable, ICollection, IEnumerable 
43         {
44                 #region Enumerator
45
46                 private sealed class ArrayListEnumerator
47                         : IEnumerator, ICloneable 
48                 {                       
49                         private int m_Pos;
50                         private int m_Index;
51                         private int m_Count;
52                         private object m_Current;
53                         private ArrayList m_List;
54                         private int m_ExpectedStateChanges;
55
56                         public ArrayListEnumerator(ArrayList list)
57                                 : this(list, 0, list.Count) 
58                         {                               
59                         }
60
61                         public object Clone() 
62                         {
63                                 return this.MemberwiseClone();
64                         }
65
66                         public ArrayListEnumerator(ArrayList list, int index, int count) 
67                         {
68                                 m_List = list;
69                                 m_Index = index;
70                                 m_Count = count;
71                                 m_Pos = m_Index - 1;
72                                 m_Current = null;
73                                 m_ExpectedStateChanges = list._version;
74                         }
75
76                         public object Current 
77                         {
78                                 get 
79                                 {
80                                         if (m_Pos == m_Index - 1) {
81                                                 throw new InvalidOperationException("Enumerator unusable (Reset pending, or past end of array.");
82                                         }
83
84                                         return m_Current;
85                                 }
86                         }
87
88                         public bool MoveNext() 
89                         {
90                                 if (m_List._version != m_ExpectedStateChanges) 
91                                 {
92                                         throw new InvalidOperationException("List has changed.");
93                                 }
94
95                                 m_Pos++;
96
97                                 if (m_Pos - m_Index < m_Count) 
98                                 {
99                                         m_Current = m_List[m_Pos];
100
101                                         return true;
102                                 }
103
104                                 return false;
105                         }
106
107                         public void Reset() 
108                         {
109                                 m_Current = null;
110                                 m_Pos = m_Index - 1;
111                         }
112                 }
113                 
114                 sealed class SimpleEnumerator : IEnumerator, ICloneable
115                 {
116                         ArrayList list;
117                         int index;
118                         int version;
119                         object currentElement;
120                         static object endFlag = new object ();
121                                                         
122                         public SimpleEnumerator (ArrayList list)
123                         {
124                                 this.list = list;
125                                 index = -1;
126                                 version = list._version;
127                                 currentElement = endFlag;
128                         }
129
130                         public object Clone ()
131                         {
132                                 return MemberwiseClone ();
133                         }
134         
135                         public bool MoveNext ()
136                         {
137                                 if (version != list._version)
138                                         throw new InvalidOperationException("List has changed.");
139                                 
140                                 if (++index < list.Count) {
141                                         currentElement = list [index];
142                                         return true;
143                                 } else {
144                                         currentElement = endFlag;
145                                         return false;
146                                 }
147                         }
148         
149                         public object Current {
150                                 get {
151                                         if (currentElement == endFlag) {
152                                                 if (index == -1)
153                                                         throw new InvalidOperationException ("Enumerator not started");
154                                                 else
155                                                         throw new InvalidOperationException ("Enumerator ended");                                                
156                                         }
157                                         
158                                         return currentElement;
159                                 }
160                         }
161         
162                         public void Reset ()
163                         {
164                                 if (version != list._version)
165                                         throw new InvalidOperationException ("List has changed.");
166                                 
167                                 currentElement = endFlag;
168                                 index = -1;
169                         }
170                 }
171
172                 #endregion
173
174                 #region ArrayListAdapter
175
176                 /// <summary>
177                 /// Adapts various ILists into an ArrayList.
178                 /// </summary>
179                 [Serializable]
180                 private sealed class ArrayListAdapter
181                         : ArrayList 
182                 {
183                         private sealed class EnumeratorWithRange
184                                 : IEnumerator, ICloneable 
185                         {
186                                 private int m_StartIndex;
187                                 private int m_Count;
188                                 private int m_MaxCount;
189                                 private IEnumerator m_Enumerator;
190
191                                 public EnumeratorWithRange(IEnumerator enumerator, int index, int count) 
192                                 {
193                                         m_Count = 0;
194                                         m_StartIndex = index;
195                                         m_MaxCount = count;
196                                         m_Enumerator = enumerator;
197
198                                         Reset();
199                                 }
200
201                                 public object Clone() 
202                                 {
203                                         return this.MemberwiseClone();
204                                 }
205
206                                 public object Current 
207                                 {
208                                         get 
209                                         {
210                                                 return m_Enumerator.Current;
211                                         }
212                                 }
213
214                                 public bool MoveNext() 
215                                 {
216                                         if (m_Count >= m_MaxCount) 
217                                         {
218                                                 return false;
219                                         }
220                                         
221                                         m_Count++;
222
223                                         return m_Enumerator.MoveNext();
224                                 }
225
226                                 public void Reset() 
227                                 {
228                                         m_Count = 0;                            
229                                         m_Enumerator.Reset();
230
231                                         for (int i = 0; i < m_StartIndex; i++) 
232                                         {
233                                                 m_Enumerator.MoveNext();
234                                         }
235                                 }
236                         }
237
238                         private IList m_Adaptee;
239
240                         public ArrayListAdapter(IList adaptee)
241                                 : base(0, true) 
242                         {
243                                 m_Adaptee = adaptee;
244                         }
245
246                         public override object this[int index] 
247                         {
248                                 get 
249                                 {
250                                         return m_Adaptee[index];
251                                 }
252
253                                 set 
254                                 {
255                                         m_Adaptee[index] = value;
256                                 }
257                         }       
258
259                         public override int Count 
260                         {
261                                 get 
262                                 {
263                                         return m_Adaptee.Count;
264                                 }
265                         }
266
267                         public override int Capacity 
268                         {
269                                 get 
270                                 {
271                                         return m_Adaptee.Count;
272                                 }
273
274                                 set 
275                                 {
276                                         if (value < m_Adaptee.Count) 
277                                         {
278                                                 throw new ArgumentException("capacity");
279                                         }
280                                 }
281                         }
282
283                         public override bool IsFixedSize 
284                         {
285                                 get 
286                                 {
287                                         return m_Adaptee.IsFixedSize;
288                                 }
289                         }
290
291                         public override bool IsReadOnly 
292                         {
293                                 get 
294                                 {
295                                         return m_Adaptee.IsReadOnly;
296                                 }
297                         }
298
299                         public override object SyncRoot 
300                         {
301                                 get 
302                                 {
303                                         return m_Adaptee.SyncRoot;
304                                 }
305                         }
306
307                         public override int Add(object value) 
308                         {
309                                 return m_Adaptee.Add(value);
310                         }
311
312                         public override void Clear() 
313                         {
314                                 m_Adaptee.Clear();
315                         }
316
317                         public override bool Contains(object value) 
318                         {
319                                 return m_Adaptee.Contains(value);
320                         }
321
322                         public override int IndexOf(object value) 
323                         {
324                                 return m_Adaptee.IndexOf(value);
325                         }
326
327                         public override int IndexOf(object value, int startIndex) 
328                         {
329                                 return IndexOf(value, startIndex, m_Adaptee.Count - startIndex);
330                         }
331
332                         public override int IndexOf(object value, int startIndex, int count) 
333                         {
334                                 if (startIndex < 0 || startIndex > m_Adaptee.Count) 
335                                 {
336                                         ThrowNewArgumentOutOfRangeException ("startIndex", startIndex,
337                                                 "Does not specify valid index.");
338                                 }
339
340                                 if (count < 0) 
341                                 {
342                                         ThrowNewArgumentOutOfRangeException ("count", count,
343                                                 "Can't be less than 0.");
344                                 }
345
346                                 // re-ordered to avoid possible integer overflow
347                                 if (startIndex > m_Adaptee.Count - count) {
348                                         // LAMESPEC: Every other method throws ArgumentException
349                                         throw new ArgumentOutOfRangeException("count",
350                                                 "Start index and count do not specify a valid range.");
351                                 }
352
353                                 if (value == null) 
354                                 {
355                                         for (int i = startIndex; i < startIndex + count; i++) 
356                                         {
357                                                 if (m_Adaptee[i] == null) 
358                                                 {
359                                                         return i;
360                                                 }
361                                         }
362                                 }
363                                 else 
364                                 {
365                                         for (int i = startIndex; i < startIndex + count; i++) 
366                                         {
367                                                 if (value.Equals(m_Adaptee[i])) 
368                                                 {
369                                                         return i;
370                                                 }
371                                         }
372                                 }
373
374                                 return -1;
375                         }
376
377                         public override int LastIndexOf(object value) 
378                         {
379                                 return LastIndexOf(value, m_Adaptee.Count - 1);
380                         }
381
382                         public override int LastIndexOf(object value, int startIndex) 
383                         {
384                                 return LastIndexOf(value, startIndex, startIndex + 1);
385                         }
386
387                         public override int LastIndexOf(object value, int startIndex, int count) 
388                         {
389                                 if (startIndex < 0) 
390                                 {
391                                         ThrowNewArgumentOutOfRangeException ("startIndex", startIndex, "< 0");
392                                 }
393
394                                 if (count < 0) 
395                                 {
396                                         ThrowNewArgumentOutOfRangeException ("count", count, "count is negative.");
397                                 }
398
399                                 if (startIndex - count  + 1 < 0) 
400                                 {
401                                         ThrowNewArgumentOutOfRangeException ("count", count, "count is too large.");
402                                 }
403
404                                 if (value == null) 
405                                 {
406                                         for (int i = startIndex; i > startIndex - count; i--) 
407                                         {
408                                                 if (m_Adaptee[i] == null) 
409                                                 {
410                                                         return i;
411                                                 }
412                                         }
413                                 }
414                                 else 
415                                 {
416                                         for (int i = startIndex; i > startIndex - count; i--) 
417                                         {
418                                                 if (value.Equals(m_Adaptee[i])) 
419                                                 {
420                                                         return i;
421                                                 }
422                                         }
423                                 }
424
425                                 return -1;
426                         }
427
428                         public override void Insert(int index, object value) 
429                         {
430                                 m_Adaptee.Insert(index, value);
431                         }
432
433                         public override void InsertRange(int index, ICollection c) 
434                         {
435                                 if (c == null) 
436                                 {
437                                         throw new ArgumentNullException("c");
438                                 }
439
440                                 if (index > m_Adaptee.Count) 
441                                 {
442                                         ThrowNewArgumentOutOfRangeException ("index", index,
443                                                 "Index must be >= 0 and <= Count.");
444                                 }
445
446                                 foreach (object value in c) 
447                                 {
448                                         m_Adaptee.Insert(index++, value);
449                                 }
450                         }
451
452                         public override void Remove(object value) 
453                         {
454                                 m_Adaptee.Remove(value);
455                         }
456
457                         public override void RemoveAt(int index) 
458                         {
459                                 m_Adaptee.RemoveAt(index);
460                         }
461
462                         public override void RemoveRange(int index, int count) 
463                         {
464                                 CheckRange(index, count, m_Adaptee.Count);
465
466                                 for (int i = 0; i < count; i++) 
467                                 {
468                                         m_Adaptee.RemoveAt(index);
469                                 }                       
470                         }
471
472                         public override void Reverse() 
473                         {
474                                 Reverse(0, m_Adaptee.Count);
475                         }
476
477                         public override void Reverse(int index, int count) 
478                         {
479                                 object tmp;
480
481                                 CheckRange(index, count, m_Adaptee.Count);
482                         
483                                 for (int i = 0; i < count / 2; i++) 
484                                 {
485                                         tmp = m_Adaptee[i + index];
486                                         m_Adaptee[i + index] = m_Adaptee[(index + count) - i + index - 1];
487                                         m_Adaptee[(index + count) - i + index - 1] = tmp;                               
488                                 }
489                         }
490
491                         public override void SetRange(int index, ICollection c) 
492                         {
493                                 if (c == null) 
494                                 {
495                                         throw new ArgumentNullException("c");
496                                 }
497
498                                 if (index < 0 || index + c.Count > m_Adaptee.Count) 
499                                 {
500                                         throw new ArgumentOutOfRangeException("index");
501                                 }
502
503                                 int x = index;
504
505                                 foreach (object value in c) 
506                                 {
507                                         m_Adaptee[x++] = value;
508                                 }
509                         }
510
511                         public override void CopyTo(System.Array array) 
512                         {
513                                 m_Adaptee.CopyTo(array, 0);
514                         }
515
516                         public override void CopyTo(System.Array array, int index) 
517                         {
518                                 m_Adaptee.CopyTo(array, index);
519                         }
520
521                         public override void CopyTo(int index, System.Array array, int arrayIndex, int count) 
522                         {
523                                 if (index < 0) 
524                                 {
525                                         ThrowNewArgumentOutOfRangeException ("index", index,
526                                                 "Can't be less than zero.");
527                                 }
528
529                                 if (arrayIndex < 0) 
530                                 {
531                                         ThrowNewArgumentOutOfRangeException ("arrayIndex", arrayIndex,
532                                                 "Can't be less than zero.");
533                                 }
534
535                                 if (count < 0) 
536                                 {
537                                         ThrowNewArgumentOutOfRangeException ("index", index,
538                                                 "Can't be less than zero.");
539                                 }
540
541                                 if (index >= m_Adaptee.Count) 
542                                 {
543                                         throw new ArgumentException("Can't be more or equal to list count.",
544                                                 "index");
545                                 }
546
547                                 if (array.Rank > 1) 
548                                 {
549                                         throw new ArgumentException("Can't copy into multi-dimensional array.");
550                                 }
551
552                                 if (arrayIndex >= array.Length) 
553                                 {
554                                         throw new ArgumentException("arrayIndex can't be greater than array.Length - 1.");
555                                 }
556
557                                 if (array.Length - arrayIndex + 1 < count) 
558                                 {
559                                         throw new ArgumentException("Destination array is too small.");
560                                 }
561
562                                 // re-ordered to avoid possible integer overflow
563                                 if (index > m_Adaptee.Count - count) {
564                                         throw new ArgumentException("Index and count do not denote a valid range of elements.", "index");
565                                 }
566
567                                 for (int i = 0; i < count; i++) 
568                                 {
569                                         array.SetValue(m_Adaptee[index + i], arrayIndex + i); 
570                                 }
571                         }
572
573                         public override bool IsSynchronized 
574                         {
575                                 get 
576                                 {
577                                         return m_Adaptee.IsSynchronized;
578                                 }
579                         }
580
581                         public override IEnumerator GetEnumerator() 
582                         {
583                                 return m_Adaptee.GetEnumerator();
584                         }
585                         
586                         public override IEnumerator GetEnumerator(int index, int count) 
587                         {
588                                 CheckRange(index, count, m_Adaptee.Count);
589
590                                 return new EnumeratorWithRange(m_Adaptee.GetEnumerator(), index, count);
591                         }
592
593                         public override void AddRange(ICollection c) 
594                         {
595                                 foreach (object value in c) 
596                                 {
597                                         m_Adaptee.Add(value);
598                                 }
599                         }
600
601                         public override int BinarySearch(object value) 
602                         {
603                                 return BinarySearch(value, null);
604                         }
605
606                         public override int BinarySearch(object value, IComparer comparer) 
607                         {
608                                 return BinarySearch(0, m_Adaptee.Count, value, comparer);
609                         }
610
611                         public override int BinarySearch(int index, int count, object value, IComparer comparer) 
612                         {
613                                 int r, x, y, z;
614
615                                 // Doing a direct BinarySearch on the adaptee will perform poorly if the adaptee is a linked-list.
616                                 // Alternatives include copying the adaptee to a temporary array first.
617
618                                 CheckRange(index, count, m_Adaptee.Count);
619
620                                 if (comparer == null) 
621                                 {
622                                         comparer = Comparer.Default;
623                                 }
624
625                                 x = index;
626                                 y = index + count - 1;
627
628                                 while (x <= y) 
629                                 {
630                                         // Be careful with overflows
631                                         z = x + ((y - x) / 2);
632                                 
633                                         r = comparer.Compare(value, m_Adaptee[z]);
634                                 
635                                         if (r < 0) 
636                                         {
637                                                 y = z - 1;
638                                         }
639                                         else if (r > 0) 
640                                         {
641                                                 x = z + 1;
642                                         }       
643                                         else 
644                                         {
645                                                 return z;
646                                         }
647                                 }
648
649                                 return ~x;
650                         }
651
652                         public override object Clone() 
653                         {
654                                 return new ArrayList.ArrayListAdapter(m_Adaptee);
655                         }
656
657                         public override ArrayList GetRange(int index, int count) 
658                         {
659                                 CheckRange(index, count, m_Adaptee.Count);
660                                 
661                                 return new RangedArrayList(this, index, count);
662                         }
663
664                         public override void TrimToSize() 
665                         {
666                                 // N/A
667                         }
668
669                         public override void Sort() 
670                         {
671                                 Sort(Comparer.Default);
672                         }
673
674                         public override void Sort(IComparer comparer) 
675                         {
676                                 Sort(0, m_Adaptee.Count, comparer);
677                         }
678
679                         public override void Sort(int index, int count, IComparer comparer) 
680                         {
681                                 CheckRange(index, count, m_Adaptee.Count);
682
683                                 if (comparer == null) 
684                                 {
685                                         comparer = Comparer.Default;
686                                 }
687
688                                 // Doing a direct sort on the adaptee will perform poorly if the adaptee is a linked-list.
689                                 // Alternatives include copying the adaptee into a temporary array first.
690
691                                 QuickSort(m_Adaptee, index, index + count - 1, comparer);
692                         }
693
694
695                         /// <summary>
696                         /// Swaps two items in a list at the specified indexes.
697                         /// </summary>
698                         private static void Swap(IList list, int x, int y) 
699                         {
700                                 object tmp;
701                                 
702                                 tmp = list[x];
703                                 list[x] = list[y];
704                                 list[y] = tmp;
705                         }
706
707                         /// <summary>
708                         /// Quicksort for lists.
709                         /// </summary>
710                         /// <remarks>
711                         /// This function acts as both qsort() and partition().
712                         /// </remarks>
713                         internal static void QuickSort(IList list, int left, int right, IComparer comparer) 
714                         {
715                                 int i, j, middle;
716                                 object pivot;
717                                         
718                                 if (left >= right) 
719                                 {
720                                         return;
721                                 }
722
723                                 // Pick the pivot using the median-of-three strategy.
724
725                                 // Be careful with overflows
726                                 middle = left + ((right - left) / 2);
727
728                                 if (comparer.Compare(list[middle], list[left]) < 0) 
729                                 {
730                                         Swap(list, middle, left);
731                                 }
732
733                                 if (comparer.Compare(list[right], list[left]) < 0) 
734                                 {
735                                         Swap(list, right, left);
736                                 }
737
738                                 if (comparer.Compare(list[right], list[middle]) < 0) 
739                                 {
740                                         Swap(list, right, middle);
741                                 }
742                 
743                                 if (right - left + 1 <= 3) 
744                                 {
745                                         return;
746                                 }
747                 
748                                 // Put the pivot in right - 1.
749                                 Swap(list, right - 1, middle);
750
751                                 // List should look like:
752                                 //
753                                 // [Small] ..Numbers.. [Middle] ..Numbers.. [Pivot][Large]
754
755                                 pivot = list[right - 1];
756
757                                 // Sort from (left + 1) to (right - 2).
758
759                                 i = left;
760                                 j = right - 1;                  
761                 
762                                 for (;;) 
763                                 {
764                                         while (comparer.Compare(list[++i], pivot) < 0);
765                                         while (comparer.Compare(list[--j], pivot) > 0);
766                         
767                                         if (i < j) 
768                                         {
769                                                 Swap(list, i, j);
770                                         }
771                                         else 
772                                         {
773                                                 break;
774                                         }
775                                 }
776
777                                 // Put pivot into the right position (real middle).
778
779                                 Swap(list, right - 1, i);
780
781                                 // Recursively sort the left and right sub lists.
782
783                                 QuickSort(list, left, i - 1, comparer);
784                                 QuickSort(list, i + 1, right, comparer);                
785                         }
786
787                         public override object[] ToArray() 
788                         {
789                                 object[] retval;
790
791                                 retval = new object[m_Adaptee.Count];
792
793                                 m_Adaptee.CopyTo(retval, 0);
794                         
795                                 return retval;
796                         }
797
798                         public override Array ToArray(Type elementType) 
799                         {
800                                 Array retval;
801
802                                 retval = Array.CreateInstance(elementType, m_Adaptee.Count);
803
804                                 m_Adaptee.CopyTo(retval, 0);
805                         
806                                 return retval;
807                         }
808                 }
809
810                 #endregion // ArrayListAdapter
811
812                 //
813                 // ArrayList wrappers
814                 //
815
816                 #region ArrayListWrapper
817
818                 /// <summary>
819                 /// Base wrapper/decorator for ArrayLists.  Simply delegates all methods to
820                 /// the underlying wrappee.
821                 /// </summary>
822                 [Serializable]
823                 private class ArrayListWrapper
824                         : ArrayList 
825                 {               
826                         protected ArrayList m_InnerArrayList;
827
828                         #region Constructors
829
830                         public ArrayListWrapper(ArrayList innerArrayList) 
831                         {                       
832                                 m_InnerArrayList = innerArrayList;
833                         }               
834
835                         #endregion
836
837                         #region Indexers
838
839                         public override object this[int index] 
840                         {
841                                 get 
842                                 {
843                                         return m_InnerArrayList[index];
844                                 }
845
846                                 set 
847                                 {
848                                         m_InnerArrayList[index] = value;
849                                 }
850                         }
851
852                         #endregion
853
854                         #region Properties
855
856                         public override int Count 
857                         {
858                                 get 
859                                 {
860                                         return m_InnerArrayList.Count;
861                                 }
862                         }
863
864                         public override int Capacity 
865                         {
866                                 get 
867                                 {
868                                         return m_InnerArrayList.Capacity;
869                                 }
870
871                                 set 
872                                 {
873                                         m_InnerArrayList.Capacity = value;
874                                 }
875                         }
876
877                         public override bool IsFixedSize 
878                         {
879                                 get 
880                                 {
881                                         return m_InnerArrayList.IsFixedSize;
882                                 }
883                         }
884
885                         public override bool IsReadOnly 
886                         {
887                                 get 
888                                 {
889                                         return m_InnerArrayList.IsReadOnly;
890                                 }
891                         }
892
893                         public override bool IsSynchronized 
894                         {
895                                 get 
896                                 {
897                                         return m_InnerArrayList.IsSynchronized;
898                                 }
899                         }
900
901                         public override object SyncRoot 
902                         {
903                                 get 
904                                 {
905                                         return m_InnerArrayList.SyncRoot;
906                                 }
907                         }
908
909                         #endregion
910
911                         #region Methods
912
913                         public override int Add(object value) 
914                         {
915                                 return m_InnerArrayList.Add(value);
916                         }
917
918                         public override void Clear() 
919                         {
920                                 m_InnerArrayList.Clear();
921                         }
922
923                         public override bool Contains(object value) 
924                         {
925                                 return m_InnerArrayList.Contains(value);
926                         }
927
928                         public override int IndexOf(object value) 
929                         {
930                                 return m_InnerArrayList.IndexOf(value);
931                         }
932
933                         public override int IndexOf(object value, int startIndex) 
934                         {
935                                 return m_InnerArrayList.IndexOf(value, startIndex);
936                         }
937
938                         public override int IndexOf(object value, int startIndex, int count) 
939                         {
940                                 return m_InnerArrayList.IndexOf(value, startIndex, count);
941                         }
942
943                         public override int LastIndexOf(object value) 
944                         {
945                                 return m_InnerArrayList.LastIndexOf(value);
946                         }
947
948                         public override int LastIndexOf(object value, int startIndex) 
949                         {
950                                 return m_InnerArrayList.LastIndexOf(value, startIndex);
951                         }
952
953                         public override int LastIndexOf(object value, int startIndex, int count) 
954                         {
955                                 return m_InnerArrayList.LastIndexOf(value, startIndex, count);
956                         }
957
958                         public override void Insert(int index, object value) 
959                         {
960                                 m_InnerArrayList.Insert(index, value);
961                         }
962
963                         public override void InsertRange(int index, ICollection c) 
964                         {
965                                 m_InnerArrayList.InsertRange(index, c);
966                         }
967
968                         public override void Remove(object value) 
969                         {
970                                 m_InnerArrayList.Remove(value);
971                         }
972
973                         public override void RemoveAt(int index) 
974                         {
975                                 m_InnerArrayList.RemoveAt(index);
976                         }
977
978                         public override void RemoveRange(int index, int count) 
979                         {
980                                 m_InnerArrayList.RemoveRange(index, count);
981                         }
982
983                         public override void Reverse() 
984                         {
985                                 m_InnerArrayList.Reverse();
986                         }
987
988                         public override void Reverse(int index, int count) 
989                         {
990                                 m_InnerArrayList.Reverse(index, count);
991                         }
992
993                         public override void SetRange(int index, ICollection c) 
994                         {
995                                 m_InnerArrayList.SetRange(index, c);
996                         }
997
998                         public override void CopyTo(System.Array array) 
999                         {
1000                                 m_InnerArrayList.CopyTo(array);
1001                         }
1002
1003                         public override void CopyTo(System.Array array, int index) 
1004                         {
1005                                 m_InnerArrayList.CopyTo(array, index);
1006                         }
1007
1008                         public override void CopyTo(int index, System.Array array, int arrayIndex, int count) 
1009                         {
1010                                 m_InnerArrayList.CopyTo(index, array, arrayIndex, count);
1011                         }
1012
1013                         public override IEnumerator GetEnumerator() 
1014                         {
1015                                 return m_InnerArrayList.GetEnumerator();
1016                         }
1017
1018                         public override IEnumerator GetEnumerator(int index, int count) 
1019                         {
1020                                 return m_InnerArrayList.GetEnumerator(index, count);
1021                         }
1022
1023                         public override void AddRange(ICollection c) 
1024                         {
1025                                 m_InnerArrayList.AddRange(c);
1026                         }
1027
1028                         public override int BinarySearch(object value) 
1029                         {
1030                                 return m_InnerArrayList.BinarySearch(value);
1031                         }
1032
1033                         public override int BinarySearch(object value, IComparer comparer) 
1034                         {
1035                                 return m_InnerArrayList.BinarySearch(value, comparer);
1036                         }
1037
1038                         public override int BinarySearch(int index, int count, object value, IComparer comparer) 
1039                         {
1040                                 return m_InnerArrayList.BinarySearch(index, count, value, comparer);
1041                         }
1042
1043                         public override object Clone() 
1044                         {
1045                                 return m_InnerArrayList.Clone();
1046                         }
1047
1048                         public override ArrayList GetRange(int index, int count) 
1049                         {
1050                                 return m_InnerArrayList.GetRange(index, count);
1051                         }
1052
1053                         public override void TrimToSize() 
1054                         {
1055                                 m_InnerArrayList.TrimToSize();
1056                         }
1057
1058                         public override void Sort() 
1059                         {
1060                                 m_InnerArrayList.Sort();
1061                         }
1062
1063                         public override void Sort(IComparer comparer) 
1064                         {
1065                                 m_InnerArrayList.Sort(comparer);
1066                         }
1067
1068                         public override void Sort(int index, int count, IComparer comparer) 
1069                         {
1070                                 m_InnerArrayList.Sort(index, count, comparer);
1071                         }
1072
1073                         public override object[] ToArray() 
1074                         {
1075                                 return m_InnerArrayList.ToArray();
1076                         }
1077
1078                         public override Array ToArray(Type elementType) 
1079                         {
1080                                 return m_InnerArrayList.ToArray(elementType);
1081                         }
1082
1083                         #endregion
1084                 }
1085
1086                 #endregion
1087
1088                 #region SynchronizedArrayListWrapper
1089
1090                 /// <summary>
1091                 /// ArrayListWrapper that synchronizes calls to all methods/properties.
1092                 /// </summary>
1093                 /// <remarks>
1094                 /// Works by just synchronizing all method calls.  In the future careful optimisation
1095                 /// could give better performance...
1096                 /// </remarks>
1097                 [Serializable]
1098                 private sealed class SynchronizedArrayListWrapper
1099                         : ArrayListWrapper 
1100                 {
1101                         private object m_SyncRoot;
1102
1103                         #region Constructors
1104
1105                         /// <summary>
1106                         /// Creates a new synchronized wrapper for the given <see cref="ArrayList"/>.
1107                         /// </summary>
1108                         /// <param name="innerArrayList"></param>
1109                         internal SynchronizedArrayListWrapper(ArrayList innerArrayList)
1110                                 : base(innerArrayList) 
1111                         {
1112                                 m_SyncRoot = innerArrayList.SyncRoot;
1113                         }               
1114
1115                         #endregion
1116
1117                         #region Indexers
1118
1119                         public override object this[int index] 
1120                         {
1121                                 get 
1122                                 {
1123                                         lock (m_SyncRoot) 
1124                                         {
1125                                                 return m_InnerArrayList[index];
1126                                         }
1127                                 }
1128
1129                                 set 
1130                                 {
1131                                         lock (m_SyncRoot) 
1132                                         {
1133                                                 m_InnerArrayList[index] = value;
1134                                         }
1135                                 }
1136                         }       
1137         
1138                         #endregion
1139
1140                         #region Properties
1141                         
1142                         // Some of these properties may be calculated so it's best to synchronize 
1143                         // them even though it might cause a performance hit.
1144                         // Better safe than sorry ;D.
1145
1146                         public override int Count 
1147                         {
1148                                 get 
1149                                 {
1150                                         lock (m_SyncRoot) 
1151                                         {
1152                                                 return m_InnerArrayList.Count;
1153                                         }
1154                                 }
1155                         }
1156
1157                         public override int Capacity 
1158                         {
1159                                 get 
1160                                 {
1161                                         lock (m_SyncRoot) 
1162                                         {
1163                                                 return m_InnerArrayList.Capacity;
1164                                         }
1165                                 }
1166
1167                                 set 
1168                                 {
1169                                         lock (m_SyncRoot) 
1170                                         {
1171                                                 m_InnerArrayList.Capacity = value;
1172                                         }
1173                                 }
1174                         }
1175
1176                         public override bool IsFixedSize 
1177                         {
1178                                 get 
1179                                 {
1180                                         lock (m_SyncRoot) 
1181                                         {
1182                                                 return m_InnerArrayList.IsFixedSize;
1183                                         }
1184                                 }
1185                         }
1186
1187                         public override bool IsReadOnly 
1188                         {
1189                                 get 
1190                                 {
1191                                         lock (m_SyncRoot) 
1192                                         {
1193                                                 return m_InnerArrayList.IsReadOnly;
1194                                         }
1195                                 }
1196                         }
1197
1198                         public override bool IsSynchronized 
1199                         {
1200                                 get 
1201                                 {
1202                                         return true;
1203                                 }
1204                         }
1205
1206                         public override object SyncRoot 
1207                         {
1208                                 get 
1209                                 {
1210                                         return m_SyncRoot;
1211                                 }
1212                         }
1213
1214                         #endregion
1215
1216                         #region Methods
1217
1218                         public override int Add(object value) 
1219                         {
1220                                 lock (m_SyncRoot) 
1221                                 {
1222                                         return m_InnerArrayList.Add(value);
1223                                 }
1224                         }
1225
1226                         public override void Clear() 
1227                         {
1228                                 lock (m_SyncRoot) 
1229                                 {
1230                                         m_InnerArrayList.Clear();
1231                                 }
1232                         }
1233
1234                         public override bool Contains(object value) 
1235                         {
1236                                 lock (m_SyncRoot) 
1237                                 {
1238                                         return m_InnerArrayList.Contains(value);
1239                                 }
1240                         }
1241
1242                         public override int IndexOf(object value) 
1243                         {
1244                                 lock (m_SyncRoot) 
1245                                 {
1246                                         return m_InnerArrayList.IndexOf(value);
1247                                 }
1248                         }
1249
1250                         public override int IndexOf(object value, int startIndex) 
1251                         {
1252                                 lock (m_SyncRoot) 
1253                                 {
1254                                         return m_InnerArrayList.IndexOf(value, startIndex);
1255                                 }
1256                         }
1257
1258                         public override int IndexOf(object value, int startIndex, int count) 
1259                         {
1260                                 lock (m_SyncRoot) 
1261                                 {
1262                                         return m_InnerArrayList.IndexOf(value, startIndex, count);
1263                                 }
1264                         }
1265
1266                         public override int LastIndexOf(object value) 
1267                         {
1268                                 lock (m_SyncRoot) 
1269                                 {
1270                                         return m_InnerArrayList.LastIndexOf(value);                     
1271                                 }
1272                         }
1273
1274                         public override int LastIndexOf(object value, int startIndex) 
1275                         {
1276                                 lock (m_SyncRoot) 
1277                                 {
1278                                         return m_InnerArrayList.LastIndexOf(value, startIndex);
1279                                 }
1280                         }
1281
1282                         public override int LastIndexOf(object value, int startIndex, int count) 
1283                         {
1284                                 lock (m_SyncRoot) 
1285                                 {
1286                                         return m_InnerArrayList.LastIndexOf(value, startIndex, count);
1287                                 }
1288                         }
1289
1290                         public override void Insert(int index, object value) 
1291                         {
1292                                 lock (m_SyncRoot) 
1293                                 {
1294                                         m_InnerArrayList.Insert(index, value);
1295                                 }
1296                         }
1297
1298                         public override void InsertRange(int index, ICollection c) 
1299                         {
1300                                 lock (m_SyncRoot) 
1301                                 {
1302                                         m_InnerArrayList.InsertRange(index, c);
1303                                 }
1304                         }
1305
1306                         public override void Remove(object value) 
1307                         {
1308                                 lock (m_SyncRoot) 
1309                                 {
1310                                         m_InnerArrayList.Remove(value);
1311                                 }
1312                         }
1313
1314                         public override void RemoveAt(int index) 
1315                         {
1316                                 lock (m_SyncRoot) 
1317                                 {
1318                                         m_InnerArrayList.RemoveAt(index);
1319                                 }
1320                         }
1321
1322                         public override void RemoveRange(int index, int count) 
1323                         {
1324                                 lock (m_SyncRoot) 
1325                                 {
1326                                         m_InnerArrayList.RemoveRange(index, count);
1327                                 }
1328                         }
1329
1330                         public override void Reverse() 
1331                         {
1332                                 lock (m_SyncRoot) 
1333                                 {
1334                                         m_InnerArrayList.Reverse();
1335                                 }
1336                         }
1337
1338                         public override void Reverse(int index, int count) 
1339                         {
1340                                 lock (m_SyncRoot) 
1341                                 {
1342                                         m_InnerArrayList.Reverse(index, count);
1343                                 }
1344                         }
1345
1346                         public override void CopyTo(System.Array array) 
1347                         {
1348                                 lock (m_SyncRoot) 
1349                                 {
1350                                         m_InnerArrayList.CopyTo(array);
1351                                 }
1352                         }
1353
1354                         public override void CopyTo(System.Array array, int index) 
1355                         {
1356                                 lock (m_SyncRoot) 
1357                                 {
1358                                         m_InnerArrayList.CopyTo(array, index);
1359                                 }
1360                         }
1361
1362                         public override void CopyTo(int index, System.Array array, int arrayIndex, int count) 
1363                         {
1364                                 lock (m_SyncRoot) 
1365                                 {
1366                                         m_InnerArrayList.CopyTo(index, array, arrayIndex, count);
1367                                 }
1368                         }
1369
1370                         public override IEnumerator GetEnumerator() 
1371                         {
1372                                 lock (m_SyncRoot) 
1373                                 {
1374                                         return m_InnerArrayList.GetEnumerator();
1375                                 }
1376                         }
1377
1378                         public override IEnumerator GetEnumerator(int index, int count) 
1379                         {
1380                                 lock (m_SyncRoot) 
1381                                 {                               
1382                                         return m_InnerArrayList.GetEnumerator(index, count);
1383                                 }
1384                         }
1385
1386                         public override void AddRange(ICollection c) 
1387                         {
1388                                 lock (m_SyncRoot) 
1389                                 {
1390                                         m_InnerArrayList.AddRange(c);
1391                                 }
1392                         }
1393
1394                         public override int BinarySearch(object value) 
1395                         {
1396                                 lock (m_SyncRoot) 
1397                                 {
1398                                         return m_InnerArrayList.BinarySearch(value);
1399                                 }
1400                         }
1401
1402                         public override int BinarySearch(object value, IComparer comparer) 
1403                         {
1404                                 lock (m_SyncRoot) 
1405                                 {
1406                                         return m_InnerArrayList.BinarySearch(value, comparer);
1407                                 }
1408                         }
1409
1410                         public override int BinarySearch(int index, int count, object value, IComparer comparer) 
1411                         {
1412                                 lock (m_SyncRoot) 
1413                                 {
1414                                         return m_InnerArrayList.BinarySearch(index, count, value, comparer);
1415                                 }
1416                         }
1417
1418                         public override object Clone() 
1419                         {
1420                                 lock (m_SyncRoot) 
1421                                 {
1422                                         return m_InnerArrayList.Clone();
1423                                 }
1424                         }
1425
1426                         public override ArrayList GetRange(int index, int count) 
1427                         {
1428                                 lock (m_SyncRoot) 
1429                                 {
1430                                         return m_InnerArrayList.GetRange(index, count);
1431                                 }
1432                         }
1433
1434                         public override void TrimToSize() 
1435                         {
1436                                 lock (m_SyncRoot) 
1437                                 {
1438                                         m_InnerArrayList.TrimToSize();
1439                                 }
1440                         }
1441
1442                         public override void Sort() 
1443                         {
1444                                 lock (m_SyncRoot) 
1445                                 {
1446                                         m_InnerArrayList.Sort();
1447                                 }
1448                         }
1449
1450                         public override void Sort(IComparer comparer) 
1451                         {
1452                                 lock (m_SyncRoot) 
1453                                 {
1454                                         m_InnerArrayList.Sort(comparer);
1455                                 }
1456                         }
1457
1458                         public override void Sort(int index, int count, IComparer comparer) 
1459                         {
1460                                 lock (m_SyncRoot) 
1461                                 {
1462                                         m_InnerArrayList.Sort(index, count, comparer);
1463                                 }
1464                         }
1465
1466                         public override object[] ToArray() 
1467                         {
1468                                 lock (m_SyncRoot) 
1469                                 {
1470                                         return m_InnerArrayList.ToArray();
1471                                 }
1472                         }
1473
1474                         public override Array ToArray(Type elementType) 
1475                         {
1476                                 lock (m_SyncRoot) 
1477                                 {
1478                                         return m_InnerArrayList.ToArray(elementType);
1479                                 }
1480                         }
1481
1482                         #endregion
1483                 }
1484
1485                 #endregion
1486
1487                 #region FixedSizeArrayListWrapper
1488
1489                 [Serializable]
1490                 private class FixedSizeArrayListWrapper
1491                         : ArrayListWrapper 
1492                 {
1493                         #region Constructors
1494
1495                         public FixedSizeArrayListWrapper(ArrayList innerList)
1496                                 : base(innerList) 
1497                         {
1498                         }
1499
1500                         #endregion
1501
1502                         #region Properties
1503                 
1504                         /// <summary>
1505                         /// Gets the error message to display when an readonly/fixedsize related exception is
1506                         /// thrown.
1507                         /// </summary>
1508                         protected virtual string ErrorMessage 
1509                         {
1510                                 get 
1511                                 {
1512                                         return "Can't add or remove from a fixed-size list.";
1513                                 }
1514                         }
1515
1516                         public override int Capacity 
1517                         {
1518                                 get 
1519                                 {
1520                                         return base.Capacity;
1521                                 }
1522
1523                                 set 
1524                                 {
1525                                         throw new NotSupportedException(this.ErrorMessage);
1526                                 }
1527                         }
1528
1529                         public override bool IsFixedSize 
1530                         {
1531                                 get 
1532                                 {
1533                                         return true;
1534                                 }
1535                         }
1536
1537                         #endregion
1538
1539                         #region Methods
1540
1541                         public override int Add(object value) 
1542                         {
1543                                 throw new NotSupportedException(this.ErrorMessage);
1544                         }
1545
1546                         public override void AddRange(ICollection c) 
1547                         {
1548                                 throw new NotSupportedException(this.ErrorMessage);
1549                         }
1550
1551                         public override void Clear() 
1552                         {
1553                                 throw new NotSupportedException(this.ErrorMessage);
1554                         }
1555
1556                         public override void Insert(int index, object value) 
1557                         {
1558                                 throw new NotSupportedException(this.ErrorMessage);
1559                         }
1560
1561                         public override void InsertRange(int index, ICollection c) 
1562                         {
1563                                 throw new NotSupportedException(this.ErrorMessage);
1564                         }
1565
1566                         public override void Remove(object value) 
1567                         {
1568                                 throw new NotSupportedException(this.ErrorMessage);
1569                         }
1570
1571                         public override void RemoveAt(int index) 
1572                         {
1573                                 throw new NotSupportedException(this.ErrorMessage);
1574                         }
1575
1576                         public override void RemoveRange(int index, int count) 
1577                         {
1578                                 throw new NotSupportedException(this.ErrorMessage);
1579                         }
1580                                 
1581                         public override void TrimToSize() 
1582                         {
1583                                 throw new NotSupportedException(this.ErrorMessage);
1584                         }
1585
1586                         #endregion
1587                 }
1588
1589                 #endregion              
1590
1591                 #region ReadOnlyArrayListWrapper
1592
1593                 [Serializable]
1594                 private sealed class ReadOnlyArrayListWrapper
1595                         : FixedSizeArrayListWrapper 
1596                 {
1597                         protected override string ErrorMessage 
1598                         {
1599                                 get 
1600                                 {
1601                                         return "Can't modify a readonly list.";
1602                                 }
1603                         }
1604
1605                         public override bool IsReadOnly 
1606                         {
1607                                 get 
1608                                 {
1609                                         return true;
1610                                 }
1611                         }
1612
1613                         public ReadOnlyArrayListWrapper(ArrayList innerArrayList)
1614                                 : base(innerArrayList) 
1615                         {
1616                         }
1617
1618                         public override object this[int index] 
1619                         {
1620                                 get 
1621                                 {
1622                                         return m_InnerArrayList[index];
1623                                 }
1624
1625                                 set 
1626                                 {
1627                                         throw new NotSupportedException(this.ErrorMessage);
1628                                 }
1629                         }
1630
1631                         public override void Reverse() 
1632                         {
1633                                 throw new NotSupportedException(this.ErrorMessage);
1634                         }
1635
1636                         public override void Reverse(int index, int count) 
1637                         {
1638                                 throw new NotSupportedException(this.ErrorMessage);
1639                         }
1640
1641                         public override void SetRange(int index, ICollection c) 
1642                         {
1643                                 throw new NotSupportedException(this.ErrorMessage);
1644                         }
1645
1646                         public override void Sort() 
1647                         {
1648                                 throw new NotSupportedException(this.ErrorMessage);
1649                         }
1650
1651                         public override void Sort(IComparer comparer) 
1652                         {
1653                                 throw new NotSupportedException(this.ErrorMessage);
1654                         }
1655
1656                         public override void Sort(int index, int count, IComparer comparer) 
1657                         {
1658                                 throw new NotSupportedException(this.ErrorMessage);
1659                         }
1660                 }
1661
1662                 #endregion
1663
1664                 #region RangedArrayList
1665
1666                 [Serializable]
1667                 private sealed class RangedArrayList
1668                         : ArrayListWrapper 
1669                 {
1670                         private int m_InnerIndex;
1671                         private int m_InnerCount;
1672                         private int m_InnerStateChanges;
1673
1674                         public RangedArrayList(ArrayList innerList, int index, int count)
1675                                 : base(innerList) 
1676                         {
1677                                 m_InnerIndex = index;
1678                                 m_InnerCount = count;
1679                                 m_InnerStateChanges = innerList._version;
1680                         }
1681
1682                         #region Indexers
1683
1684                         public override bool IsSynchronized
1685                         {
1686                                 get
1687                                 {
1688                                         return false;
1689                                 }
1690                         }
1691
1692                         public override object this[int index] 
1693                         {
1694                                 get 
1695                                 {
1696                                         if (index < 0 || index > m_InnerCount) 
1697                                         {
1698                                                 throw new ArgumentOutOfRangeException("index");
1699                                         }
1700
1701                                         return m_InnerArrayList[m_InnerIndex + index];
1702                                 }
1703
1704                                 set 
1705                                 {
1706                                         if (index < 0 || index > m_InnerCount) 
1707                                         {
1708                                                 throw new ArgumentOutOfRangeException("index");
1709                                         }
1710
1711                                         m_InnerArrayList[m_InnerIndex + index] = value;
1712                                 }
1713                         }
1714
1715                         #endregion
1716
1717                         #region Properties
1718
1719                         public override int Count 
1720                         {
1721                                 get 
1722                                 {
1723                                         VerifyStateChanges();
1724
1725                                         return m_InnerCount;
1726                                 }
1727                         }
1728
1729                         public override int Capacity 
1730                         {
1731                                 get 
1732                                 {
1733                                         return m_InnerArrayList.Capacity;
1734                                 }
1735
1736                                 set 
1737                                 {
1738                                         if (value < m_InnerCount) 
1739                                         {
1740                                                 throw new ArgumentOutOfRangeException();
1741                                         }
1742                                 }
1743                         }
1744
1745                         #endregion
1746
1747                         #region Methods
1748
1749                         private void VerifyStateChanges() 
1750                         {
1751                                 if (m_InnerStateChanges != m_InnerArrayList._version) 
1752                                 {
1753                                         throw new InvalidOperationException
1754                                                 ("ArrayList view is invalid because the underlying ArrayList was modified.");
1755                                 }
1756                         }
1757
1758                         public override int Add(object value) 
1759                         {
1760                                 VerifyStateChanges();
1761
1762                                 m_InnerArrayList.Insert(m_InnerIndex + m_InnerCount, value);
1763
1764                                 m_InnerStateChanges = m_InnerArrayList._version;
1765
1766                                 return ++m_InnerCount;
1767                         }
1768
1769                         public override void Clear() 
1770                         {
1771                                 VerifyStateChanges();
1772
1773                                 m_InnerArrayList.RemoveRange(m_InnerIndex, m_InnerCount);
1774                                 m_InnerCount = 0;
1775
1776                                 m_InnerStateChanges = m_InnerArrayList._version;
1777                         }
1778
1779                         public override bool Contains(object value) 
1780                         {
1781                                 return m_InnerArrayList.Contains(value, m_InnerIndex, m_InnerCount);
1782                         }
1783
1784                         public override int IndexOf(object value) 
1785                         {
1786                                 return IndexOf(value, 0);
1787                         }
1788
1789                         public override int IndexOf(object value, int startIndex) 
1790                         {
1791                                 return IndexOf(value, startIndex, m_InnerCount - startIndex);
1792                         }
1793
1794                         public override int IndexOf(object value, int startIndex, int count) 
1795                         {
1796                                 if (startIndex < 0 || startIndex > m_InnerCount) 
1797                                 {
1798                                         ThrowNewArgumentOutOfRangeException ("startIndex", startIndex,
1799                                                 "Does not specify valid index.");
1800                                 }
1801
1802                                 if (count < 0) 
1803                                 {
1804                                         ThrowNewArgumentOutOfRangeException ("count", count,
1805                                                 "Can't be less than 0.");
1806                                 }
1807
1808                                 // re-ordered to avoid possible integer overflow
1809                                 if (startIndex > m_InnerCount - count) 
1810                                 {
1811                                         // LAMESPEC: Every other method throws ArgumentException
1812
1813                                         throw new ArgumentOutOfRangeException("count",
1814                                                 "Start index and count do not specify a valid range.");
1815                                 }
1816
1817                                 int retval = m_InnerArrayList.IndexOf(value, m_InnerIndex + startIndex, count);
1818
1819                                 if (retval == -1) 
1820                                 {
1821                                         return -1;
1822                                 }
1823                                 else 
1824                                 {
1825                                         return retval - m_InnerIndex;
1826                                 }
1827                         }
1828
1829                         public override int LastIndexOf(object value) 
1830                         {
1831                                 return LastIndexOf(value, m_InnerCount - 1);
1832                         }
1833
1834                         public override int LastIndexOf(object value, int startIndex) 
1835                         {
1836                                 return LastIndexOf(value, startIndex, startIndex + 1);
1837                         }
1838
1839                         public override int LastIndexOf(object value, int startIndex, int count) 
1840                         {
1841                                 if (startIndex < 0) 
1842                                 {
1843                                         ThrowNewArgumentOutOfRangeException ("startIndex", startIndex,  "< 0");
1844                                 }
1845
1846                                 if (count < 0) 
1847                                 {
1848                                         ThrowNewArgumentOutOfRangeException ("count", count, "count is negative.");
1849                                 }
1850
1851                                 int retval = m_InnerArrayList.LastIndexOf(value, m_InnerIndex + startIndex, count);
1852
1853                                 if (retval == -1) 
1854                                 {
1855                                         return -1;
1856                                 }
1857                                 else 
1858                                 {
1859                                         return retval - m_InnerIndex;
1860                                 }
1861                         }
1862
1863                         public override void Insert(int index, object value) 
1864                         {
1865                                 VerifyStateChanges();
1866                                 
1867                                 if (index < 0 || index > m_InnerCount) 
1868                                 {
1869                                         ThrowNewArgumentOutOfRangeException ("index", index,
1870                                                 "Index must be >= 0 and <= Count.");
1871                                 }
1872
1873                                 m_InnerArrayList.Insert(m_InnerIndex + index, value);
1874
1875                                 m_InnerCount++;
1876
1877                                 m_InnerStateChanges = m_InnerArrayList._version;
1878                         }
1879
1880                         public override void InsertRange(int index, ICollection c) 
1881                         {
1882                                 VerifyStateChanges();
1883
1884                                 if (index < 0 || index > m_InnerCount) 
1885                                 {
1886                                         ThrowNewArgumentOutOfRangeException ("index", index,
1887                                                 "Index must be >= 0 and <= Count.");
1888                                 }
1889
1890                                 m_InnerArrayList.InsertRange(m_InnerIndex + index, c);
1891
1892                                 m_InnerCount += c.Count;
1893
1894                                 m_InnerStateChanges = m_InnerArrayList._version;
1895                         }
1896
1897                         public override void Remove(object value) 
1898                         {
1899                                 VerifyStateChanges();
1900
1901                                 int x = IndexOf(value);
1902
1903                                 if (x > -1) 
1904                                 {
1905                                         RemoveAt(x);
1906                                 }
1907
1908                                 m_InnerStateChanges = m_InnerArrayList._version;
1909                         }
1910
1911                         public override void RemoveAt(int index) 
1912                         {
1913                                 VerifyStateChanges();
1914
1915                                 if (index < 0 || index > m_InnerCount) 
1916                                 {
1917                                         ThrowNewArgumentOutOfRangeException ("index", index,
1918                                                 "Index must be >= 0 and <= Count.");
1919                                 }
1920
1921                                 m_InnerArrayList.RemoveAt(m_InnerIndex + index);
1922
1923                                 m_InnerCount--;
1924                                 m_InnerStateChanges = m_InnerArrayList._version;
1925                         }
1926
1927                         public override void RemoveRange(int index, int count) 
1928                         {
1929                                 VerifyStateChanges();
1930
1931                                 CheckRange(index, count, m_InnerCount);                         
1932
1933                                 m_InnerArrayList.RemoveRange(m_InnerIndex + index, count);
1934
1935                                 m_InnerCount -= count;
1936
1937                                 m_InnerStateChanges = m_InnerArrayList._version;
1938                         }
1939
1940                         public override void Reverse() 
1941                         {
1942                                 Reverse(0, m_InnerCount);
1943                         }
1944
1945                         public override void Reverse(int index, int count) 
1946                         {
1947                                 VerifyStateChanges();
1948
1949                                 CheckRange(index, count, m_InnerCount);                         
1950
1951                                 m_InnerArrayList.Reverse(m_InnerIndex + index, count);
1952
1953                                 m_InnerStateChanges = m_InnerArrayList._version;
1954                         }
1955
1956                         public override void SetRange(int index, ICollection c) 
1957                         {
1958                                 VerifyStateChanges();
1959
1960                                 if (index < 0 || index > m_InnerCount) 
1961                                 {
1962                                         ThrowNewArgumentOutOfRangeException ("index", index,
1963                                                 "Index must be >= 0 and <= Count.");
1964                                 }
1965
1966                                 m_InnerArrayList.SetRange(m_InnerIndex + index, c);
1967
1968                                 m_InnerStateChanges = m_InnerArrayList._version;
1969                         }
1970
1971                         public override void CopyTo(System.Array array) 
1972                         {
1973                                 CopyTo(array, 0);
1974                         }
1975
1976                         public override void CopyTo(System.Array array, int index) 
1977                         {
1978                                 CopyTo(0, array, index, m_InnerCount);
1979                         }
1980
1981                         public override void CopyTo(int index, System.Array array, int arrayIndex, int count) 
1982                         {
1983                                 CheckRange(index, count, m_InnerCount);                         
1984
1985                                 m_InnerArrayList.CopyTo(m_InnerIndex + index, array, arrayIndex, count);
1986                         }
1987
1988                         public override IEnumerator GetEnumerator() 
1989                         {
1990                                 return GetEnumerator(0, m_InnerCount);
1991                         }
1992
1993                         public override IEnumerator GetEnumerator(int index, int count) 
1994                         {
1995                                 CheckRange(index, count, m_InnerCount);
1996
1997                                 return m_InnerArrayList.GetEnumerator(m_InnerIndex + index, count);
1998                         }
1999
2000                         public override void AddRange(ICollection c) 
2001                         {
2002                                 VerifyStateChanges();
2003
2004                                 m_InnerArrayList.InsertRange(m_InnerCount, c);
2005
2006                                 m_InnerCount += c.Count;
2007
2008                                 m_InnerStateChanges = m_InnerArrayList._version;
2009                         }
2010
2011                         public override int BinarySearch(object value) 
2012                         {
2013                                 return BinarySearch(0, m_InnerCount, value, Comparer.Default);
2014                         }
2015
2016                         public override int BinarySearch(object value, IComparer comparer) 
2017                         {
2018                                 return BinarySearch(0, m_InnerCount, value, comparer);
2019                         }
2020
2021                         public override int BinarySearch(int index, int count, object value, IComparer comparer) 
2022                         {
2023                                 CheckRange(index, count, m_InnerCount);
2024
2025                                 return m_InnerArrayList.BinarySearch(m_InnerIndex + index, count, value, comparer);
2026                         }
2027
2028                         public override object Clone() 
2029                         {
2030                                 return new RangedArrayList((ArrayList)m_InnerArrayList.Clone(), m_InnerIndex, m_InnerCount);
2031                         }
2032
2033                         public override ArrayList GetRange(int index, int count) 
2034                         {
2035                                 CheckRange(index, count, m_InnerCount);
2036
2037                                 return new RangedArrayList(this, index, count);
2038                         }
2039
2040                         public override void TrimToSize() 
2041                         {
2042                                 throw new NotSupportedException();
2043                         }
2044
2045                         public override void Sort() 
2046                         {
2047                                 Sort(Comparer.Default);
2048                         }
2049
2050                         public override void Sort(IComparer comparer) 
2051                         {
2052                                 Sort(0, m_InnerCount, comparer);
2053                         }
2054
2055                         public override void Sort(int index, int count, IComparer comparer) 
2056                         {
2057                                 VerifyStateChanges();
2058
2059                                 CheckRange(index, count, m_InnerCount);
2060
2061                                 m_InnerArrayList.Sort(m_InnerIndex + index, count, comparer);
2062
2063                                 m_InnerStateChanges = m_InnerArrayList._version;
2064                         }
2065
2066                         public override object[] ToArray() 
2067                         {
2068                                 object[] array;
2069
2070                                 array = new object[m_InnerCount];
2071
2072                                 m_InnerArrayList.CopyTo (m_InnerIndex, array, 0, m_InnerCount);
2073
2074                                 return array;
2075                         }
2076
2077                         public override Array ToArray(Type elementType) 
2078                         {
2079                                 Array array;
2080
2081                                 array = Array.CreateInstance(elementType, m_InnerCount);
2082
2083                                 m_InnerArrayList.CopyTo(m_InnerIndex, array, 0, m_InnerCount);
2084
2085                                 return array;
2086                         }
2087
2088                         #endregion
2089                 }
2090
2091                 #endregion
2092
2093                 //
2094                 // List wrappers
2095                 //
2096
2097                 #region SynchronizedListWrapper
2098
2099                 [Serializable]
2100                 private sealed class SynchronizedListWrapper
2101                         : ListWrapper 
2102                 {
2103                         private object m_SyncRoot;
2104
2105                         public SynchronizedListWrapper(IList innerList)
2106                                 : base(innerList) 
2107                         {
2108                                 m_SyncRoot = innerList.SyncRoot;
2109                         }
2110
2111                         public override int Count 
2112                         {
2113                                 get 
2114                                 {
2115                                         lock (m_SyncRoot) 
2116                                         {
2117                                                 return m_InnerList.Count;
2118                                         }
2119                                 }
2120                         }
2121
2122                         public override bool IsSynchronized 
2123                         {
2124                                 get 
2125                                 {
2126                                         return true;
2127                                 }
2128                         }
2129
2130                         public override object SyncRoot 
2131                         {
2132                                 get 
2133                                 {
2134                                         lock (m_SyncRoot) 
2135                                         {
2136                                                 return m_InnerList.SyncRoot;
2137                                         }
2138                                 }
2139                         }
2140
2141                         public override bool IsFixedSize 
2142                         {
2143                                 get 
2144                                 {
2145                                         lock (m_SyncRoot) 
2146                                         {
2147                                                 return m_InnerList.IsFixedSize;
2148                                         }
2149                                 }
2150                         }
2151
2152                         public override bool IsReadOnly 
2153                         {
2154                                 get 
2155                                 {
2156                                         lock (m_SyncRoot) 
2157                                         {
2158                                                 return m_InnerList.IsReadOnly;
2159                                         }
2160                                 }
2161                         }
2162
2163                         public override object this[int index] 
2164                         {
2165                                 get 
2166                                 {
2167                                         lock (m_SyncRoot) 
2168                                         {
2169                                                 return m_InnerList[index];
2170                                         }
2171                                 }
2172
2173                                 set 
2174                                 {
2175                                         lock (m_SyncRoot) 
2176                                         {
2177                                                 m_InnerList[index] = value;
2178                                         }
2179                                 }
2180                         }
2181
2182                         public override int Add(object value) 
2183                         {
2184                                 lock (m_SyncRoot) 
2185                                 {
2186                                         return m_InnerList.Add(value);
2187                                 }
2188                         }
2189
2190                         public override void Clear() 
2191                         {
2192                                 lock (m_SyncRoot) 
2193                                 {
2194                                         m_InnerList.Clear();
2195                                 }
2196                         }
2197
2198                         public override bool Contains(object value) 
2199                         {
2200                                 lock (m_SyncRoot) 
2201                                 {
2202                                         return m_InnerList.Contains(value);
2203                                 }
2204                         }
2205
2206                         public override int IndexOf(object value) 
2207                         {
2208                                 lock (m_SyncRoot) 
2209                                 {
2210                                         return m_InnerList.IndexOf(value);
2211                                 }
2212                         }
2213
2214                         public override void Insert(int index, object value) 
2215                         {
2216                                 lock (m_SyncRoot) 
2217                                 {
2218                                         m_InnerList.Insert(index, value);
2219                                 }
2220                         }
2221
2222                         public override void Remove(object value) 
2223                         {
2224                                 lock (m_SyncRoot) 
2225                                 {
2226                                         m_InnerList.Remove(value);
2227                                 }
2228                         }
2229
2230                         public override void RemoveAt(int index) 
2231                         {
2232                                 lock (m_SyncRoot) 
2233                                 {
2234                                         m_InnerList.RemoveAt(index);
2235                                 }
2236                         }
2237
2238                         public override void CopyTo(Array array, int index) 
2239                         {
2240                                 lock (m_SyncRoot) 
2241                                 {
2242                                         m_InnerList.CopyTo(array, index);
2243                                 }
2244                         }
2245
2246                         public override IEnumerator GetEnumerator() 
2247                         {
2248                                 lock (m_SyncRoot) 
2249                                 {
2250                                         return m_InnerList.GetEnumerator();
2251                                 }
2252                         }
2253                 }
2254
2255                 #endregion
2256
2257                 #region FixedSizeListWrapper
2258
2259                 [Serializable]
2260                         private class FixedSizeListWrapper
2261                         : ListWrapper 
2262                 {
2263                         protected virtual string ErrorMessage 
2264                         {               
2265                                 get 
2266                                 {
2267                                         return "List is fixed-size.";
2268                                 }
2269                         }
2270
2271                         public override bool IsFixedSize 
2272                         {
2273                                 get 
2274                                 {
2275                                         return true;
2276                                 }
2277                         }
2278
2279                         public FixedSizeListWrapper(IList innerList)
2280                                 : base(innerList) 
2281                         {
2282                         }
2283
2284                         public override int Add(object value) 
2285                         {
2286                                 throw new NotSupportedException(this.ErrorMessage);
2287                         }
2288
2289                         public override void Clear() 
2290                         {
2291                                 throw new NotSupportedException(this.ErrorMessage);
2292                         }
2293
2294                         public override void Insert(int index, object value) 
2295                         {
2296                                 throw new NotSupportedException(this.ErrorMessage);
2297                         }
2298
2299                         public override void Remove(object value) 
2300                         {
2301                                 throw new NotSupportedException(this.ErrorMessage);
2302                         }
2303
2304                         public override void RemoveAt(int index) 
2305                         {
2306                                 throw new NotSupportedException(this.ErrorMessage);
2307                         }
2308                 }
2309
2310                 #endregion
2311
2312                 #region ReadOnlyListWrapper
2313
2314                 [Serializable]
2315                 private sealed class ReadOnlyListWrapper
2316                         : FixedSizeListWrapper 
2317                 {
2318                         protected override string ErrorMessage 
2319                         {               
2320                                 get 
2321                                 {
2322                                         return "List is read-only.";
2323                                 }
2324                         }
2325
2326                         public override bool IsReadOnly 
2327                         {
2328                                 get 
2329                                 {
2330                                         return true;
2331                                 }
2332                         }
2333
2334                         public ReadOnlyListWrapper(IList innerList)
2335                                 : base(innerList) 
2336                         {
2337                         }
2338
2339                         public override object this[int index] 
2340                         {
2341                                 get 
2342                                 {
2343                                         return m_InnerList[index];
2344                                 }
2345
2346                                 set 
2347                                 {
2348                                         throw new NotSupportedException(this.ErrorMessage);
2349                                 }
2350                         }
2351                 }
2352
2353                 #endregion
2354
2355                 #region ListWrapper
2356
2357                 /// <summary>
2358                 /// Decorates/Wraps any <c>IList</c> implementing object.
2359                 /// </summary>
2360                 [Serializable]
2361                 private class ListWrapper
2362                         : IList 
2363                 {
2364                         #region Fields
2365
2366                         protected IList m_InnerList;
2367
2368                         #endregion
2369
2370                         #region Constructors
2371
2372                         public ListWrapper(IList innerList) 
2373                         {                       
2374                                 m_InnerList = innerList;
2375                         }
2376
2377                         #endregion
2378
2379                         #region Indexers
2380
2381                         public virtual object this[int index] 
2382                         {
2383                                 get 
2384                                 {
2385                                         return m_InnerList[index];
2386                                 }
2387
2388                                 set 
2389                                 {
2390                                         m_InnerList[index] = value;
2391                                 }
2392                         }
2393
2394                         #endregion
2395
2396                         #region Properties
2397
2398                         public virtual int Count 
2399                         {
2400                                 get 
2401                                 {
2402                                         return m_InnerList.Count;
2403                                 }
2404                         }
2405
2406                         public virtual bool IsSynchronized 
2407                         {
2408                                 get 
2409                                 {
2410                                         return m_InnerList.IsSynchronized;
2411                                 }
2412                         }
2413
2414                         public virtual object SyncRoot 
2415                         {
2416                                 get 
2417                                 {
2418                                         return m_InnerList.SyncRoot;
2419                                 }
2420                         }
2421
2422                         public virtual bool IsFixedSize 
2423                         {
2424                                 get 
2425                                 {
2426                                         return m_InnerList.IsFixedSize;
2427                                 }
2428                         }
2429
2430                         public virtual bool IsReadOnly 
2431                         {
2432                                 get 
2433                                 {
2434                                         return m_InnerList.IsReadOnly;
2435                                 }
2436                         }
2437
2438                         #endregion
2439
2440                         #region Methods
2441
2442                         public virtual int Add(object value) 
2443                         {
2444                                 return m_InnerList.Add(value);
2445                         }
2446
2447                         public virtual void Clear() 
2448                         {
2449                                 m_InnerList.Clear();
2450                         }
2451
2452                         public virtual bool Contains(object value) 
2453                         {
2454                                 return m_InnerList.Contains(value);
2455                         }
2456
2457                         public virtual int IndexOf(object value) 
2458                         {
2459                                 return m_InnerList.IndexOf(value);
2460                         }
2461
2462                         public virtual void Insert(int index, object value) 
2463                         {
2464                                 m_InnerList.Insert(index, value);
2465                         }
2466
2467                         public virtual void Remove(object value) 
2468                         {
2469                                 m_InnerList.Remove(value);
2470                         }
2471
2472                         public virtual void RemoveAt(int index) 
2473                         {
2474                                 m_InnerList.RemoveAt(index);
2475                         }
2476
2477                         public virtual void CopyTo(Array array, int index) 
2478                         {
2479                                 m_InnerList.CopyTo(array, index);
2480                         }
2481
2482                         public virtual IEnumerator GetEnumerator() 
2483                         {
2484                                 return m_InnerList.GetEnumerator();
2485                         }
2486
2487                         #endregion
2488                 }
2489
2490                 #endregion
2491
2492                 //
2493                 // Start of ArrayList
2494                 //
2495
2496                 #region Fields
2497
2498 #if NET_2_0
2499                 private const int DefaultInitialCapacity = 4;
2500 #else
2501                 private const int DefaultInitialCapacity = 16;
2502 #endif
2503                 
2504                 /// <summary>
2505                 /// Number of items in the list.
2506                 /// </summary>
2507                 private int _size;
2508
2509                 /// <summary>
2510                 /// Array to store the items.
2511                 /// </summary>
2512                 private object[] _items;
2513                 
2514                 /// <summary>
2515                 /// Total number of state changes.
2516                 /// </summary>
2517                 private int _version;
2518                 
2519                 private static readonly object [] EmptyArray = new object [0]; 
2520
2521                 #endregion
2522                 
2523                 #region Constructors
2524
2525                 /// <summary>
2526                 /// Initializes a new instance of the <see cref="ArrayList"/> class that is empty and
2527                 /// has the default initial capacity (16).
2528                 /// </summary>
2529                 public ArrayList()
2530                 {
2531 #if NET_2_0
2532                         _items = EmptyArray;
2533 #else
2534                         _items = new object[DefaultInitialCapacity];
2535 #endif
2536                 }               
2537
2538                 /// <summary>
2539                 /// Initializes a new instance of the <see cref="ArrayList"/> class that contains 
2540                 /// elements copied from the specified collection and that has the same initial capacity
2541                 /// as the number of elements copied.
2542                 /// </summary>
2543                 /// <param name="c">
2544                 /// The <see cref="ICollection"/> whose elements are copied into the new list.
2545                 /// </param>
2546                 /// <exception cref="ArgumentNullException">
2547                 /// The argument <c>c</c> is a null reference.
2548                 /// </exception>
2549                 public ArrayList(ICollection c) 
2550                 {
2551                         Array array;
2552
2553                         if (c == null) 
2554                         {
2555                                 throw new ArgumentNullException("c");
2556                         }
2557                                                 
2558                         array = c as Array;
2559
2560                         if (array != null && array.Rank != 1) 
2561                         {
2562                                 throw new RankException();
2563                         }
2564
2565                         _items = new object[c.Count];
2566
2567                         AddRange(c);
2568                 }
2569
2570                 /// <summary>
2571                 /// Initializes a new instance of the <see cref="ArrayList"/> class that is empty and
2572                 /// has the specified initial capacity.
2573                 /// </summary>
2574                 /// <param name="capacity">
2575                 /// The number of elements that hte new list is initially capable of storing.
2576                 /// </param>
2577                 /// <exception cref="ArgumentOutOfRangeException">
2578                 /// The <c>capacity</c> is less than zero.
2579                 /// </exception>
2580                 public ArrayList(int capacity) 
2581                 {
2582                         if (capacity < 0) 
2583                         {
2584                                 ThrowNewArgumentOutOfRangeException ("capacity",
2585                                         capacity, "The initial capacity can't be smaller than zero.");
2586                         }
2587
2588                         if (capacity == 0) 
2589                         {
2590                                 capacity = DefaultInitialCapacity;
2591                         }
2592                         _items = new object [capacity];
2593                 }
2594
2595                 /// <summary>
2596                 /// Used by ArrayListAdapter to allow creation of an ArrayList with no storage buffer.
2597                 /// </summary>
2598                 private ArrayList(int initialCapacity, bool forceZeroSize) 
2599                 {
2600                         if (forceZeroSize) 
2601                         {                               
2602                                 _items = null;
2603                         }
2604                         else 
2605                         {
2606                                 throw new InvalidOperationException("Use ArrayList(int)");
2607                         }
2608                 }
2609
2610                 /// <summary>
2611                 /// Initializes a new array list that contains a copy of the given array and with the
2612                 /// given count.
2613                 /// </summary>
2614                 /// <param name="array"></param>
2615                 private ArrayList(object[] array, int index, int count) 
2616                 {
2617                         if (count == 0) 
2618                         {
2619                                 _items = new object[DefaultInitialCapacity];
2620                         }
2621                         else 
2622                         {
2623                                 _items = new object[count];
2624                         }
2625
2626                         Array.Copy(array, index, _items, 0, count);
2627
2628                         _size = count;
2629                 }
2630
2631                 #endregion
2632
2633                 #region Indexers
2634
2635                 /// <summary>
2636                 /// Gets/Sets an element in the list by index.
2637                 /// </summary>
2638                 /// <exception cref="ArgumentOutOfRangeException">
2639                 /// The index is less than 0 or more then or equal to the list count.
2640                 /// </exception>
2641                 public virtual object this[int index] 
2642                 {
2643                         get 
2644                         {
2645                                 if (index < 0 || index >= _size) 
2646                                 {
2647                                         ThrowNewArgumentOutOfRangeException ("index", index,
2648                                                 "Index is less than 0 or more than or equal to the list count.");
2649                                 }
2650
2651                                 return _items[index];
2652                         }
2653
2654                         set 
2655                         {
2656                                 if (index < 0 || index >= _size) 
2657                                 {
2658                                         ThrowNewArgumentOutOfRangeException ("index", index,
2659                                                 "Index is less than 0 or more than or equal to the list count.");
2660                                 }
2661
2662                                 _items[index] = value;
2663                                 _version++;
2664                         }
2665                 }
2666
2667                 #endregion
2668
2669                 #region Properties
2670
2671                 /// <summary>
2672                 /// Gets the number of elements in the list.
2673                 /// </summary>
2674                 public virtual int Count 
2675                 {
2676                         get 
2677                         {                               
2678                                 return _size;
2679                         }
2680                 }
2681
2682                 /// <summary>
2683                 /// Gets the number of elements the list can carry without needing to expand.
2684                 /// </summary>
2685                 /// <remarks>
2686                 /// ArrayLists automatically double their capacity when the capacity limit is broken.
2687                 /// </remarks>
2688                 /// <exception cref="ArgumentOutOfRangeException">
2689                 /// The capacity is less than the count.
2690                 /// </exception>
2691                 public virtual int Capacity 
2692                 {
2693                         get 
2694                         {
2695                                 return _items.Length;
2696                         }
2697
2698                         set 
2699                         {
2700                                 if (value < _size) 
2701                                 {
2702                                         ThrowNewArgumentOutOfRangeException ("Capacity", value,
2703                                                 "Must be more than count.");
2704                                 }
2705
2706                                 object[] newArray;
2707
2708                                 newArray = new object[value];
2709
2710                                 Array.Copy(_items, 0, newArray, 0, _size);
2711
2712                                 _items = newArray;
2713                         }
2714                 }
2715
2716                 /// <summary>
2717                 /// <see cref="IList.IsFixedSize"/>
2718                 /// </summary>
2719                 /// <remarks/>
2720                 public virtual bool IsFixedSize 
2721                 {
2722                         get 
2723                         {
2724                                 return false;
2725                         }
2726                 }
2727
2728                 /// <summary>
2729                 /// <see cref="IList.IsReadOnly"/>
2730                 /// </summary>
2731                 public virtual bool IsReadOnly 
2732                 {
2733                         get 
2734                         {
2735                                 return false;
2736                         }
2737                 }
2738
2739                 /// <summary>
2740                 /// <see cref="ICollection.IsSynchronized"/>
2741                 /// </summary>
2742                 public virtual bool IsSynchronized 
2743                 {
2744                         get 
2745                         {
2746                                 return false;
2747                         }
2748                 }
2749
2750                 /// <summary>
2751                 /// <see cref="ICollection.SyncRoot"/>
2752                 /// </summary>
2753                 public virtual object SyncRoot 
2754                 {
2755                         get 
2756                         {
2757                                 return this;
2758                         }
2759                 }
2760
2761                 #endregion
2762
2763                 #region Methods
2764
2765                 /// <remarks>
2766                 /// Ensures that the list has the capacity to contain the given <c>count</c> by
2767                 /// automatically expanding the capacity when required.
2768                 /// </remarks>
2769                 private void EnsureCapacity(int count) 
2770                 {
2771                         if (count <= _items.Length) 
2772                         {
2773                                 return;
2774                         }
2775
2776                         int newLength;
2777                         object[] newData;
2778
2779                         newLength = _items.Length << 1;
2780                         if (newLength == 0)
2781                                 newLength = DefaultInitialCapacity;
2782
2783                         while (newLength < count) 
2784                         {
2785                                 newLength <<= 1;
2786                         }
2787
2788                         newData = new object[newLength];
2789
2790                         Array.Copy(_items, 0, newData, 0, _items.Length);
2791
2792                         _items = newData;
2793                 }
2794                 
2795                 /// <summary>
2796                 /// Shifts a section of the list.
2797                 /// </summary>
2798                 /// <param name="index">
2799                 /// The start of the section to shift (the element at index is included in the shift).
2800                 /// </param>
2801                 /// <param name="count">
2802                 /// The number of positions to shift by (can be negative).
2803                 /// </param>
2804                 private void Shift(int index, int count) 
2805                 {
2806                         if (count > 0) 
2807                         {
2808                                 if (_size + count > _items.Length) 
2809                                 {
2810                                         int newLength;
2811                                         object[] newData;
2812                                         
2813                                         newLength = (_items.Length > 0) ? _items.Length << 1 : 1;
2814
2815                                         while (newLength < _size + count) 
2816                                         {
2817                                                 newLength <<= 1;
2818                                         }
2819                                         
2820                                         newData = new object[newLength];
2821
2822                                         Array.Copy(_items, 0, newData, 0, index);
2823                                         Array.Copy(_items, index, newData, index + count, _size - index);
2824
2825                                         _items = newData;
2826                                 }
2827                                 else 
2828                                 {
2829                                         Array.Copy(_items, index, _items, index + count, _size - index);
2830                                 }
2831                         }
2832                         else if (count < 0) 
2833                         {
2834                                 // Remember count is negative so this is actually index + (-count)
2835
2836                                 int x = index - count ;
2837
2838                                 Array.Copy(_items, x, _items, index, _size - x);
2839                                 Array.Clear(_items, _size + count, - count);
2840                         }
2841                 }
2842
2843                 public virtual int Add(object value) 
2844                 {
2845                         // Do a check here in case EnsureCapacity isn't inlined.
2846
2847                         if (_items.Length <= _size /* same as _items.Length < _size + 1) */) 
2848                         {
2849                                 EnsureCapacity(_size + 1);
2850                         }
2851
2852                         _items[_size] = value;
2853                         
2854                         _version++;
2855
2856                         return _size++;
2857                 }
2858
2859                 public virtual void Clear() 
2860                 {
2861                         // Keep the array but null all members so they can be garbage collected.
2862
2863                         Array.Clear(_items, 0, _size);
2864
2865                         _size = 0;
2866                         _version++;
2867                 }
2868
2869                 public virtual bool Contains(object item) 
2870                 {
2871                         return IndexOf(item, 0, _size) > -1;
2872                 }
2873
2874                 internal virtual bool Contains(object value, int startIndex, int count) 
2875                 {
2876                         return IndexOf(value, startIndex, count) > -1;
2877                 }
2878
2879                 public virtual int IndexOf(object value) 
2880                 {                       
2881                         return IndexOf(value, 0);
2882                 }
2883
2884                 public virtual int IndexOf(object value, int startIndex) 
2885                 {
2886                         return IndexOf(value, startIndex, _size - startIndex);
2887                 }
2888
2889                 public virtual int IndexOf(object value, int startIndex, int count) 
2890                 {
2891                         if (startIndex < 0 || startIndex > _size) 
2892                         {
2893                                 ThrowNewArgumentOutOfRangeException ("startIndex", startIndex,
2894                                         "Does not specify valid index.");
2895                         }
2896
2897                         if (count < 0) 
2898                         {
2899                                 ThrowNewArgumentOutOfRangeException ("count", count,
2900                                         "Can't be less than 0.");
2901                         }
2902
2903                         // re-ordered to avoid integer overflow
2904                         if (startIndex > _size - count) 
2905                         {
2906                                 // LAMESPEC: Every other method throws ArgumentException
2907
2908                                 throw new ArgumentOutOfRangeException("count",
2909                                         "Start index and count do not specify a valid range.");
2910                         }
2911
2912                         return Array.IndexOf(_items, value, startIndex, count);
2913                 }
2914
2915                 public virtual int LastIndexOf(object value) 
2916                 {
2917                         return LastIndexOf(value, _size - 1);
2918                 }
2919
2920                 public virtual int LastIndexOf(object value, int startIndex) 
2921                 {
2922                         return LastIndexOf(value, startIndex, startIndex + 1);
2923                 }
2924
2925                 public virtual int LastIndexOf (object value, int startIndex, int count) 
2926                 {
2927                         // Array will catch the exceptions
2928                         return Array.LastIndexOf (_items, value, startIndex, count);
2929                 }
2930
2931                 public virtual void Insert(int index, object value) 
2932                 {
2933                         if (index < 0 || index > _size) 
2934                         {
2935                                 ThrowNewArgumentOutOfRangeException ("index", index,
2936                                         "Index must be >= 0 and <= Count.");
2937                         }
2938
2939                         Shift(index, 1);
2940
2941                         _items[index] = value;
2942                         _size++;
2943                         _version++;
2944                 }
2945
2946                 public virtual void InsertRange(int index, ICollection c) 
2947                 {
2948                         int i;
2949
2950                         if (c == null) 
2951                         {
2952                                 throw new ArgumentNullException("c");
2953                         }
2954
2955                         if (index < 0 || index > _size) 
2956                         {
2957                                 ThrowNewArgumentOutOfRangeException ("index", index,
2958                                         "Index must be >= 0 and <= Count.");
2959                         }
2960
2961                         i = c.Count;
2962                         
2963                         // Do a check here in case EnsureCapacity isn't inlined.
2964
2965                         if (_items.Length < _size + i) 
2966                         {
2967                                 EnsureCapacity(_size + i);
2968                         }
2969
2970                         if (index < _size) 
2971                         {
2972                                 Array.Copy(_items, index, _items, index + i, _size - index);
2973                         }
2974                 
2975                         // Handle inserting a range from a list to itself specially.
2976
2977                         if (this == c.SyncRoot) 
2978                         {
2979                                 // Copy range before the insert point.
2980
2981                                 Array.Copy(_items, 0, _items, index, index);
2982
2983                                 // Copy range after the insert point.
2984
2985                                 Array.Copy(_items, index + i, _items, index << 1, _size - index);
2986                         }
2987                         else 
2988                         {
2989                                 c.CopyTo(_items, index);
2990                         }
2991                 
2992                         _size += c.Count;
2993                         _version++;
2994                 }
2995
2996                 public virtual void Remove(object obj) 
2997                 {
2998                         int x;
2999
3000                         x = IndexOf(obj);
3001
3002                         if (x > -1) 
3003                         {
3004                                 RemoveAt(x);
3005                         }
3006
3007                         _version++;
3008                 }
3009
3010                 public virtual void RemoveAt(int index) 
3011                 {
3012                         if (index < 0 || index >= _size) 
3013                         {
3014                                 ThrowNewArgumentOutOfRangeException ("index", index,
3015                                         "Less than 0 or more than list count.");
3016                         }
3017
3018                         Shift(index, -1);
3019                         _size--;
3020                         _version++;
3021                 }
3022
3023                 public virtual void RemoveRange(int index, int count) 
3024                 {
3025                         ArrayList.CheckRange(index, count, _size);
3026                                                 
3027                         Shift(index, -count);
3028                         _size -= count;
3029                         _version++;                     
3030                 }
3031
3032                 public virtual void Reverse() 
3033                 {
3034                         Array.Reverse(_items, 0, _size);
3035                         _version++;
3036                 }
3037
3038                 public virtual void Reverse(int index, int count) 
3039                 {
3040                         ArrayList.CheckRange(index, count, _size);
3041
3042                         Array.Reverse(_items, index, count);
3043                         _version++;
3044                 }
3045
3046                 public virtual void CopyTo(System.Array array) 
3047                 {
3048                         Array.Copy(_items, array, _size);
3049                 }
3050
3051                 public virtual void CopyTo(System.Array array, int arrayIndex) 
3052                 {                       
3053                         CopyTo(0, array, arrayIndex, _size);
3054                 }
3055
3056                 public virtual void CopyTo(int index, System.Array array, int arrayIndex, int count) 
3057                 {
3058                         if (array == null) 
3059                         {
3060                                 throw new ArgumentNullException("array");
3061                         }
3062
3063                         if (array.Rank != 1) 
3064                         {
3065                                 // LAMESPEC:
3066                                 // This should be a RankException because Array.Copy throws RankException.
3067
3068                                 throw new ArgumentException("Must have only 1 dimensions.", "array");
3069                         }
3070
3071                         Array.Copy(_items, index, array, arrayIndex, count);
3072                 }
3073
3074                 public virtual IEnumerator GetEnumerator() 
3075                 {
3076                         return new SimpleEnumerator(this);
3077                 }
3078
3079                 public virtual IEnumerator GetEnumerator(int index, int count) 
3080                 {
3081                         ArrayList.CheckRange(index, count, _size);
3082
3083                         return new ArrayListEnumerator(this, index, count);
3084                 }
3085
3086                 public virtual void AddRange(ICollection c) 
3087                 {
3088                         InsertRange(_size, c);
3089                 }
3090
3091                 public virtual int BinarySearch(object value) 
3092                 {
3093                         try 
3094                         {
3095                                 return Array.BinarySearch(_items, 0, _size, value);
3096                         }
3097                         catch (InvalidOperationException e) 
3098                         {
3099                                 throw new ArgumentException(e.Message);
3100                         }
3101                 }
3102
3103                 public virtual int BinarySearch(object value, IComparer comparer) 
3104                 {
3105                         try 
3106                         {
3107                                 return Array.BinarySearch(_items, 0, _size, value, comparer);
3108                         }
3109                         catch (InvalidOperationException e) 
3110                         {
3111                                 throw new ArgumentException(e.Message);
3112                         }
3113                 }
3114
3115                 public virtual int BinarySearch(int index, int count, object value, IComparer comparer) 
3116                 {
3117                         try 
3118                         {
3119                                 return Array.BinarySearch(_items, index, count, value, comparer);
3120                         }
3121                         catch (InvalidOperationException e) 
3122                         {
3123                                 throw new ArgumentException(e.Message);
3124                         }
3125                 }
3126                 public virtual ArrayList GetRange(int index, int count) 
3127                 {
3128                         ArrayList.CheckRange(index, count, _size);
3129
3130                         if (this.IsSynchronized)
3131                         {
3132                                 return ArrayList.Synchronized(new RangedArrayList(this, index, count));
3133                         }
3134                         else
3135                         {
3136                                 return new RangedArrayList(this, index, count);
3137                         }
3138                 }
3139
3140                 public virtual void SetRange(int index, ICollection c) 
3141                 {
3142                         if (c == null) 
3143                         {
3144                                 throw new ArgumentNullException("c");
3145                         }
3146
3147                         if (index < 0 || index + c.Count > _size) 
3148                         {
3149                                 throw new ArgumentOutOfRangeException("index");
3150                         }
3151
3152                         c.CopyTo(_items, index);
3153
3154                         _version++;
3155                 }
3156
3157                 public virtual void TrimToSize() 
3158                 {
3159                         if (_items.Length > _size) 
3160                         {
3161                                 object[] newArray;
3162
3163                                 if (_size == 0) 
3164                                 {
3165                                         newArray = new object[DefaultInitialCapacity];
3166                                 }
3167                                 else 
3168                                 {
3169                                         newArray = new object[_size];
3170                                 }
3171                                                                 
3172                                 Array.Copy(_items, 0, newArray, 0, _size);
3173
3174                                 _items = newArray;
3175                         }
3176                 }
3177
3178                 public virtual void Sort() 
3179                 {
3180                         Array.Sort(_items, 0, _size);
3181
3182                         _version++;
3183                 }
3184
3185                 public virtual void Sort(IComparer comparer) 
3186                 {
3187                         Array.Sort(_items, 0, _size, comparer);
3188                 }
3189
3190                 public virtual void Sort(int index, int count, IComparer comparer) 
3191                 {
3192                         ArrayList.CheckRange(index, count, _size);
3193
3194                         Array.Sort(_items, index, count, comparer);
3195                 }
3196
3197                 public virtual object[] ToArray() 
3198                 {
3199                         object[] retval;
3200
3201                         retval = new object[_size];
3202
3203                         CopyTo(retval);
3204                         
3205                         return retval;
3206                 }
3207
3208                 public virtual Array ToArray(Type type) 
3209                 {
3210                         Array retval;
3211                         
3212                         retval = Array.CreateInstance(type, _size);
3213
3214                         CopyTo(retval);
3215
3216                         return retval;
3217                 }
3218
3219                 public virtual object Clone() 
3220                 {
3221                         return new ArrayList(this._items, 0, this._size);
3222                 }
3223
3224                 #endregion
3225
3226                 #region Static Methods
3227
3228                 /// <summary>
3229                 /// Does a check of the arguments many of the methods in ArrayList use.
3230                 /// </summary>
3231                 /// <remarks>
3232                 /// The choice of exceptions thrown sometimes seem to be arbitrarily chosen so
3233                 /// not all methods actually make use of CheckRange.
3234                 /// </remarks>
3235                 internal static void CheckRange(int index, int count, int listCount) 
3236                 {
3237                         if (index < 0) 
3238                         {
3239                                 ThrowNewArgumentOutOfRangeException ("index", index, "Can't be less than 0.");
3240                         }
3241
3242                         if (count < 0) 
3243                         {
3244                                 ThrowNewArgumentOutOfRangeException ("count", count, "Can't be less than 0.");
3245                         }
3246
3247                         // re-ordered to avoid possible integer overflow
3248                         if (index > listCount - count) 
3249                         {
3250                                 throw new ArgumentException("Index and count do not denote a valid range of elements.", "index");
3251                         }
3252                 }
3253
3254                 internal static void ThrowNewArgumentOutOfRangeException (string name, object actual, string message)
3255                 {
3256                         throw new ArgumentOutOfRangeException (
3257 #if !INSIDE_CORLIB && NET_2_1
3258                                 name, message
3259 #else
3260                                 name, actual, message
3261 #endif
3262                         );
3263                 }
3264
3265                 public static ArrayList Adapter(IList list) 
3266                 {
3267                         // LAMESPEC: EWWW.  Other lists aren't *Array*Lists.
3268
3269                         if (list == null) 
3270                         {
3271                                 throw new ArgumentNullException("list");
3272                         }
3273
3274                         ArrayList arrayList = list as ArrayList;
3275                         if (arrayList != null)
3276                                 return arrayList;
3277                         else
3278                                 arrayList = new ArrayListAdapter(list);
3279
3280                         if (list.IsSynchronized)
3281                                 return ArrayList.Synchronized(arrayList);
3282                         else 
3283                                 return arrayList;
3284                 }
3285
3286                 public static ArrayList Synchronized(ArrayList list) 
3287                 {
3288                         if (list == null) 
3289                         {
3290                                 throw new ArgumentNullException("list");
3291                         }
3292
3293                         if (list.IsSynchronized)
3294                         {
3295                                 return list;
3296                         }
3297
3298                         return new SynchronizedArrayListWrapper(list);
3299                 }
3300
3301                 public static IList Synchronized(IList list) 
3302                 {
3303                         if (list == null) 
3304                         {
3305                                 throw new ArgumentNullException("list");
3306                         }
3307
3308                         if (list.IsSynchronized)
3309                         {
3310                                 return list;
3311                         }
3312
3313                         return new SynchronizedListWrapper(list);
3314                 }
3315
3316                 public static ArrayList ReadOnly(ArrayList list) 
3317                 {
3318                         if (list == null) 
3319                         {
3320                                 throw new ArgumentNullException("list");
3321                         }
3322
3323                         if (list.IsReadOnly)
3324                         {
3325                                 return list;
3326                         }
3327
3328                         return new ReadOnlyArrayListWrapper(list);
3329                 }
3330
3331                 public static IList ReadOnly(IList list) 
3332                 {
3333                         if (list == null) 
3334                         {
3335                                 throw new ArgumentNullException("list");
3336                         }
3337
3338                         if (list.IsReadOnly)
3339                         {
3340                                 return list;
3341                         }
3342
3343                         return new ReadOnlyListWrapper(list);
3344                 }
3345
3346                 public static ArrayList FixedSize(ArrayList list) 
3347                 {
3348                         if (list == null) 
3349                         {
3350                                 throw new ArgumentNullException("list");
3351                         }
3352
3353                         if (list.IsFixedSize)
3354                         {
3355                                 return list;
3356                         }
3357
3358                         return new FixedSizeArrayListWrapper(list);
3359                 }
3360
3361                 public static IList FixedSize(IList list) 
3362                 {
3363                         if (list == null) 
3364                         {
3365                                 throw new ArgumentNullException("list");
3366                         }
3367
3368                         if (list.IsFixedSize)
3369                         {
3370                                 return list;
3371                         }
3372
3373                         return new FixedSizeListWrapper(list);
3374                 }
3375
3376                 public static ArrayList Repeat(object value, int count) 
3377                 {
3378                         ArrayList arrayList = new ArrayList(count);
3379
3380                         for (int i = 0; i < count; i++) 
3381                         {
3382                                 arrayList.Add(value);
3383                         }
3384
3385                         return arrayList;
3386                 }
3387
3388                 #endregion
3389         }
3390 }