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