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