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