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