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