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