Fix bugs in sizing TableLayoutPanel (Xamarin bug 18638)
[mono.git] / mcs / class / corlib / Test / System.Collections.Generic / ListTest.cs
1 //
2 // MonoTests.System.Collections.Generic.Test.ListTest
3 //
4 // Authors:
5 //      David Waite (mass@akuma.org)
6 //      Andres G. Aragoneses (andres.aragoneses@7digital.com)
7 //
8 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
9 // Copyright (C) 2005 David Waite (mass@akuma.org)
10 // Copyright 2011 Xamarin Inc (http://www.xamarin.com).
11 // Copyright 2012 7digital Ltd (http://www.7digital.com).
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 //
32
33 using System;
34 using System.Collections;
35 using System.Collections.Generic;
36 using System.Collections.ObjectModel;
37 using System.IO;
38 using System.Runtime.Serialization.Formatters.Binary;
39 using System.Text;
40
41 using NUnit.Framework;
42
43 namespace MonoTests.System.Collections.Generic {
44
45         class GenericComparer<T> : IComparer<T> {
46
47                 private bool called = false;
48
49                 public bool Called {
50                         get {
51                                 bool result = called;
52                                 called = false;
53                                 return called;
54                         }
55                 }
56
57                 public int Compare (T x, T y)
58                 {
59                         called = true;
60                         return 0;
61                 }
62         }
63
64         [TestFixture]
65         public class ListTest
66         {
67                 static byte [] _serializedList = new byte [] {
68                         0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00,
69                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00,
70                         0x7e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x43, 0x6f, 0x6c,
71                         0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x47, 0x65,
72                         0x6e, 0x65, 0x72, 0x69, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x60,
73                         0x31, 0x5b, 0x5b, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x49,
74                         0x6e, 0x74, 0x33, 0x32, 0x2c, 0x20, 0x6d, 0x73, 0x63, 0x6f, 0x72,
75                         0x6c, 0x69, 0x62, 0x2c, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
76                         0x6e, 0x3d, 0x32, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x30, 0x2c, 0x20,
77                         0x43, 0x75, 0x6c, 0x74, 0x75, 0x72, 0x65, 0x3d, 0x6e, 0x65, 0x75,
78                         0x74, 0x72, 0x61, 0x6c, 0x2c, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69,
79                         0x63, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x3d, 0x62,
80                         0x37, 0x37, 0x61, 0x35, 0x63, 0x35, 0x36, 0x31, 0x39, 0x33, 0x34,
81                         0x65, 0x30, 0x38, 0x39, 0x5d, 0x5d, 0x03, 0x00, 0x00, 0x00, 0x06,
82                         0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x05, 0x5f, 0x73, 0x69, 0x7a,
83                         0x65, 0x08, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x07,
84                         0x00, 0x00, 0x08, 0x08, 0x08, 0x09, 0x02, 0x00, 0x00, 0x00, 0x03,
85                         0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0f, 0x02, 0x00, 0x00,
86                         0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00,
87                         0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88                         0x0b };
89                 int [] _list1_contents;
90                 List <int> _list1;
91
92                 [SetUp]
93                 public void SetUp ()
94                 {
95                         // FIXME arrays currently do not support generic collection
96                         // interfaces
97                         _list1_contents = new int [] { 55, 50, 22, 80, 56, 52, 40, 63 };
98                         // _list1 = new List <int> (_list1_contents);
99                         
100                         _list1 = new List <int> (8);
101                         foreach (int i in _list1_contents)
102                                 _list1.Add (i);
103                 }
104
105                 [Test]  // This was for bug #74980
106                 public void InsertTest ()
107                 {
108                         List <string> test = new List <string> ();
109                         test.Insert (0, "a");
110                         test.Insert (0, "b");
111                         test.Insert (1, "c");
112
113                         Assert.AreEqual (3, test.Count);
114                         Assert.AreEqual ("b", test [0]);
115                         Assert.AreEqual ("c", test [1]);
116                         Assert.AreEqual ("a", test [2]);
117                 }
118
119                 [Test]
120                 public void InsertRangeTest ()
121                 {
122                         int count = _list1.Count;
123                         // FIXME arrays currently do not support generic collection 
124                         // interfaces
125                         int [] items = {1, 2, 3};
126                         // List <int> newRange = new List <int> (items);
127                         List <int> newRange = new List <int> (3);
128                         foreach (int i in items)
129                                 newRange.Add (i);
130                         _list1.InsertRange (1, newRange);
131                         Assert.AreEqual (count + 3, _list1.Count);
132                         Assert.AreEqual (55, _list1 [0]);
133                         Assert.AreEqual (1, _list1 [1]);
134                         Assert.AreEqual (2, _list1 [2]);
135                         Assert.AreEqual (3, _list1 [3]);
136                         Assert.AreEqual (50, _list1 [4]);
137
138                         newRange = new List <int> ();
139                         List <int> li = new List <int> ();
140                         li.Add (1);
141                         newRange.InsertRange (0, li);
142                         newRange.InsertRange (newRange.Count, li);
143                         Assert.AreEqual (2, newRange.Count);
144                 }
145                 
146                 [Test]
147                 public void InsertSelfTest()
148                 {
149                         List <int> range = new List <int> (5);
150                         for (int i = 0; i < 5; ++ i)
151                                 range.Add (i);
152                         
153                         range.InsertRange(2, range);
154                         Assert.AreEqual (10, range.Count);
155                         Assert.AreEqual (0, range [0]);
156                         Assert.AreEqual (1, range [1]);
157                         Assert.AreEqual (0, range [2]);
158                         Assert.AreEqual (1, range [3]);
159                         Assert.AreEqual (2, range [4]);
160                         Assert.AreEqual (3, range [5]);
161                         Assert.AreEqual (4, range [6]);
162                         Assert.AreEqual (2, range [7]);
163                         Assert.AreEqual (3, range [8]);
164                         Assert.AreEqual (4, range [9]);
165                 }
166
167                 [Test, ExpectedException (typeof (ArgumentNullException))]
168                 public void InsertRangeNullTest ()
169                 {
170                         IEnumerable <int> n = null;
171                         _list1.InsertRange (0, n);
172                 }
173
174                 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
175                 public void InsertRangeNegativeIndexTest ()
176                 {
177                         _list1.InsertRange (-1, _list1);
178                 }
179
180                 [Test]
181                 public void IndexOfTest ()
182                 {
183                         List <int> l = new List <int> ();
184
185                         l.Add (100);
186                         l.Add (200);
187
188                         Assert.AreEqual (1, l.IndexOf (200), "Could not find value");
189                 }
190                 
191                 [Test, ExpectedException(typeof (ArgumentException))]
192                 public void IList_InsertInvalidType1 ()
193                 {
194                         IList list = _list1 as IList;
195                         list.Insert(0, new object());
196                 }
197
198                 [Test, ExpectedException(typeof (ArgumentException))]
199                 public void IList_InsertInvalidType2 ()
200                 {
201                         IList list = _list1 as IList;
202                         list.Insert(0, null);
203                 }
204                 
205                 [Test, ExpectedException(typeof (ArgumentException))]
206                 public void IList_AddInvalidType1()
207                 {
208                         IList list = _list1 as IList;
209                         list.Add(new object());
210                 }
211
212                 [Test, ExpectedException(typeof (ArgumentException))]
213                 public void IList_AddInvalidType2()
214                 {
215                         IList list = _list1 as IList;
216                         list.Add(null);
217                 }
218                 
219                 [Test]
220                 public void IList_RemoveInvalidType()
221                 {
222                         IList list = _list1 as IList;
223                         int nCount = list.Count;
224                         list.Remove(new object());
225                         Assert.AreEqual(nCount, list.Count);
226
227                         list.Remove(null);
228                         Assert.AreEqual(nCount, list.Count);
229                 }
230
231                 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
232                 public void IndexOfOutOfRangeTest ()
233                 {
234                         List <int> l = new List <int> (4);
235                         l.IndexOf (0, 0, 4);
236                 }
237
238                 [Test]
239                 public void GetRangeTest ()
240                 {
241                         List <int> r = _list1.GetRange (2, 4);
242                         Assert.AreEqual (4, r.Count);
243                         Assert.AreEqual (22, r [0]);
244                         Assert.AreEqual (80, r [1]);
245                         Assert.AreEqual (56, r [2]);
246                         Assert.AreEqual (52, r [3]);
247                 }
248
249                 [Test]
250                 public void EnumeratorTest ()
251                 {
252                         List <int>.Enumerator e = _list1.GetEnumerator ();
253                         for (int i = 0; i < _list1_contents.Length; i++)
254                         {
255                                 Assert.IsTrue (e.MoveNext ());
256                                 Assert.AreEqual (_list1_contents [i], e.Current);
257                         }
258                         Assert.IsFalse (e.MoveNext ());
259                 }
260
261                 [Test]
262                 public void ConstructWithSizeTest ()
263                 {
264                         List <object> l_1 = new List <object> (1);
265                         List <object> l_2 = new List <object> (50);
266                         List <object> l_3 = new List <object> (0);
267
268                         Assert.AreEqual (1, l_1.Capacity);
269                         Assert.AreEqual (50, l_2.Capacity);
270                         Assert.AreEqual (0, l_3.Capacity);
271                 }
272
273                 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
274                 public void ConstructWithInvalidSizeTest ()
275                 {
276                         List <int> l = new List <int> (-1);
277                 }
278
279                 [Test]
280                 public void ConstructWithCollectionTest ()
281                 {
282                         List <int> l1 = new List <int> (_list1);
283                         Assert.AreEqual (_list1.Count, l1.Count);
284                         Assert.AreEqual (l1.Count, l1.Capacity);
285                         for (int i = 0; i < l1.Count; i++)
286                                 Assert.AreEqual (_list1 [i], l1 [i]);
287
288                         var input = new [] { "a", "b", "c" };
289                         var l2 = new List<string>(input);
290                         Assert.AreEqual (3, l2.Capacity);
291                 }
292
293                 [Test, ExpectedException (typeof (ArgumentNullException))]
294                 public void ConstructWithInvalidCollectionTest ()
295                 {
296                         List <int> n = null;
297                         List <int> l1 = new List <int> (n);
298                 }
299
300                 [Test]
301                 public void AddTest ()
302                 {
303                         int count = _list1.Count;
304                         _list1.Add (-1);
305                         Assert.AreEqual (count + 1, _list1.Count);
306                         Assert.AreEqual (-1, _list1 [_list1.Count - 1]);
307                 }
308
309                 [Test]
310                 public void AddRangeTest ()
311                 {
312                         int count = _list1.Count;
313                         // FIXME arrays currently do not support generic collection
314                         // interfaces
315                         int [] range = { -1, -2, -3 };
316                         List <int> tmp = new List <int> (3);
317                         foreach (int i in range)
318                                 tmp.Add (i);
319                         // _list1.AddRange (range);
320                         _list1.AddRange (tmp);
321                         
322                         Assert.AreEqual (count + 3, _list1.Count);
323                         Assert.AreEqual (-1, _list1 [_list1.Count - 3]);
324                         Assert.AreEqual (-2, _list1 [_list1.Count - 2]);
325                         Assert.AreEqual (-3, _list1 [_list1.Count - 1]);
326                 }
327
328                 [Test, ExpectedException (typeof (ArgumentNullException))]
329                 public void AddNullRangeTest ()
330                 {
331                         int [] n = null;
332                         _list1.AddRange (n);
333                 }
334
335                 [Test]
336                 public void BinarySearchTest ()
337                 {
338                         List <int> l = new List <int> (_list1);
339                         l.Sort ();
340                         Assert.AreEqual (0, l.BinarySearch (22));
341                         Assert.AreEqual (-2, l.BinarySearch (23));
342                         Assert.AreEqual (- (l.Count + 1), l.BinarySearch (int.MaxValue));
343                 }
344
345 #if !NET_4_0 // FIXME: the blob contains the 2.0 mscorlib version
346
347                 [Test]
348                 public void SerializeTest ()
349                 {
350                         List <int> list = new List <int> ();
351                         list.Add (5);
352                         list.Add (0);
353                         list.Add (7);
354
355                         BinaryFormatter bf = new BinaryFormatter ();
356                         MemoryStream ms = new MemoryStream ();
357                         bf.Serialize (ms, list);
358
359                         byte [] buffer = new byte [ms.Length];
360                         ms.Position = 0;
361                         ms.Read (buffer, 0, buffer.Length);
362
363                         Assert.AreEqual (_serializedList, buffer);
364                 }
365
366 #endif
367
368                 [Test]
369                 public void DeserializeTest ()
370                 {
371                         MemoryStream ms = new MemoryStream ();
372                         ms.Write (_serializedList, 0, _serializedList.Length);
373                         ms.Position = 0;
374
375                         BinaryFormatter bf = new BinaryFormatter ();
376                         List<int> list = (List<int>) bf.Deserialize (ms);
377                         Assert.AreEqual (3, list.Count, "#1");
378                         Assert.AreEqual (5, list [0], "#2");
379                         Assert.AreEqual (0, list [1], "#3");
380                         Assert.AreEqual (7, list [2], "#4");
381                 }
382
383                 [Test]
384                 public void SortTest ()
385                 {
386                         List <int> l = new List <int> (_list1);
387                         l.Sort ();
388                         Assert.AreEqual (_list1.Count, l.Count);
389                         Assert.AreEqual (22, l [0]);
390                         int minimum = 22;
391                         foreach (int i in l)
392                         {
393                                 Assert.IsTrue (minimum <= i);
394                                 minimum = i;
395                         }
396                 }
397
398                 [Test]
399                 public void ClearTest ()
400                 {
401                         int capacity = _list1.Capacity;
402                         _list1.Clear ();
403                         Assert.AreEqual (0, _list1.Count);
404                         Assert.AreEqual (capacity, _list1.Capacity);
405                 }
406
407                 [Test]
408                 public void ContainsTest ()
409                 {
410                         Assert.IsTrue (_list1.Contains (22));
411                         Assert.IsFalse (_list1.Contains (23));
412                 }
413
414                 private string StringConvert (int i)
415                 {
416                         return i.ToString ();
417                 }
418                 
419                 [Test]
420                 public void ConvertAllTest ()
421                 {
422                         List <string> s = _list1.ConvertAll ( (Converter <int, string>)StringConvert);
423                         Assert.AreEqual (_list1.Count, s.Count);
424                         Assert.AreEqual ("55", s [0]);
425                 }
426
427                 [Test]
428                 public void CopyToTest ()
429                 {
430                         int [] a = new int [2];
431                         _list1.CopyTo (1, a, 0, 2);
432                         Assert.AreEqual (50, a [0]);
433                         Assert.AreEqual (22, a [1]);
434
435                         int [] b = new int [_list1.Count + 1];
436                         b [_list1.Count] = 555;
437                         _list1.CopyTo (b);
438                         Assert.AreEqual (55, b [0]);
439                         Assert.AreEqual (555, b [_list1.Count]);
440
441                         b [0] = 888;
442                         _list1.CopyTo (b, 1);
443                         Assert.AreEqual (888, b [0]);
444                         Assert.AreEqual (55, b [1]);
445                 }
446
447                 [Test, ExpectedException (typeof (ArgumentNullException))]
448                 public void CopyToNullTest ()
449                 {
450                         int [] a = null;
451                         _list1.CopyTo (0, a, 0, 0);
452                 }
453
454                 static bool FindMultipleOfThree (int i)
455                 {
456                         return (i % 3) == 0;
457                 }
458
459                 static bool FindMultipleOfFour (int i)
460                 {
461                         return (i % 4) == 0;
462                 }
463
464                 static bool FindMultipleOfTwelve (int i)
465                 {
466                         return (i % 12) == 0;
467                 }
468
469                 [Test]
470                 public void FindTest ()
471                 {
472                         int i = _list1.Find (FindMultipleOfThree);
473                         Assert.AreEqual (63, i);
474
475                         i = _list1.Find (FindMultipleOfTwelve);
476                         Assert.AreEqual (default (int), i);
477                 }
478
479                 [Test, ExpectedException (typeof (ArgumentNullException))]
480                 public void FindNullTest ()
481                 {
482                         int i = _list1.Find (null);
483                 }
484
485                 [Test]
486                 public void FindAllSmallTest ()
487                 {
488                         List <int> findings = _list1.FindAll (FindMultipleOfFour);
489                         Assert.AreEqual (4, findings.Count);
490                         Assert.AreEqual (80, findings [0]);
491                         Assert.AreEqual (56, findings [1]);
492                         Assert.AreEqual (52, findings [2]);
493                         Assert.AreEqual (40, findings [3]);
494
495                         findings = _list1.FindAll (FindMultipleOfTwelve);
496                         Assert.IsNotNull (findings);
497                         Assert.AreEqual (0, findings.Count);
498                 }
499                 
500                 [Test]
501                 public void FindAllMediumTest ()
502                 {
503                         List <int> integers = new List <int> (10000);
504                         for (int i = 1; i <= 10000; i++)
505                                 integers.Add (i);
506                         
507                         List <int> results = integers.FindAll (FindMultipleOfFour);
508                         
509                         Assert.IsNotNull (results);
510                         Assert.AreEqual (2500, results.Count);
511                         
512                         results = integers.FindAll (FindMultipleOfTwelve);
513                         
514                         Assert.IsNotNull (results);
515                         Assert.AreEqual (833, results.Count);
516                 }
517                 
518                 [Test]
519                 public void FindAllLargeTest ()
520                 {
521                         List <int> integers = new List <int> (70000);
522                         for (int i = 1; i <= 80000; i++)
523                                 integers.Add (i);
524                         
525                         List <int> results = integers.FindAll (FindMultipleOfFour);
526                         
527                         Assert.IsNotNull (results);
528                         Assert.AreEqual (20000, results.Count);
529                         
530                         results = integers.FindAll (FindMultipleOfTwelve);
531                         
532                         Assert.IsNotNull (results);
533                         Assert.AreEqual (6666, results.Count);
534                 }
535
536                 [Test, ExpectedException (typeof (ArgumentNullException))]
537                 public void FindAllNullTest ()
538                 {
539                         List <int> findings = _list1.FindAll (null);
540                 }
541
542                 [Test]
543                 public void FindIndexTest ()
544                 {
545                         int i = _list1.FindIndex (FindMultipleOfThree);
546                         Assert.AreEqual (7, i);
547
548                         i = _list1.FindIndex (FindMultipleOfTwelve);
549                         Assert.AreEqual (-1, i);
550
551                         var a = new List<int> () { 2, 2, 2, 3, 2 };
552                         Assert.AreEqual (2, a.FindIndex (2, 2, l => true));
553                 }
554
555                 [Test]
556                 public void FindIndex_Invalid ()
557                 {
558                         try {
559                                 _list1.FindIndex (null);
560                                 Assert.Fail ("#1");
561                         } catch (ArgumentNullException) {
562                         }
563
564                         try {
565                                 _list1.FindIndex (-1, l => true);
566                                 Assert.Fail ("#2");
567                         } catch (ArgumentOutOfRangeException) {
568                         }
569
570                         try {
571                                 _list1.FindIndex (-1, 0, l => true);
572                                 Assert.Fail ("#2b");
573                         } catch (ArgumentOutOfRangeException) {
574                         }
575
576                         try {
577                                 _list1.FindIndex (0, -1, l => true);
578                                 Assert.Fail ("#3");
579                         } catch (ArgumentOutOfRangeException) {
580                         }
581
582                         try {
583                                 _list1.FindIndex (100, l => true);
584                                 Assert.Fail ("#4");
585                         } catch (ArgumentOutOfRangeException) {
586                         }
587
588                         try {
589                                 _list1.FindIndex (100, 0, l => true);
590                                 Assert.Fail ("#4b");
591                         } catch (ArgumentOutOfRangeException) {
592                         }
593
594                         try {
595                                 _list1.FindIndex (7, 2, l => true);
596                                 Assert.Fail ("#5");
597                         } catch (ArgumentOutOfRangeException) {
598                         }
599                 }
600
601                 [Test]
602                 public void FindLastTest ()
603                 {
604                         int i = _list1.FindLast (FindMultipleOfFour);
605                         Assert.AreEqual (40, i);
606
607                         i = _list1.FindLast (FindMultipleOfTwelve);
608                         Assert.AreEqual (default (int), i);
609                 }
610
611                 [Test, ExpectedException (typeof (ArgumentNullException))]
612                 public void FindLastNullTest ()
613                 {
614                         int i = _list1.FindLast (null);
615                 }
616
617                 [Test]
618                 public void ForEachTest ()
619                 {
620                         int i = 0;
621                         _list1.ForEach (delegate (int j) { i += j; });
622
623                         Assert.AreEqual (418, i);
624                 }
625
626                 [Test]
627                 public void FindLastIndexTest ()
628                 {
629                         int i = _list1.FindLastIndex (FindMultipleOfFour);
630                         Assert.AreEqual (6, i);
631
632                         i = _list1.FindLastIndex (5, FindMultipleOfFour);
633                         Assert.AreEqual (5, i);
634
635                         i = _list1.FindIndex (FindMultipleOfTwelve);
636                         Assert.AreEqual (-1, i);
637
638                         Assert.AreEqual (2, _list1.FindLastIndex (2, 3, l => true));
639                         Assert.AreEqual (2, _list1.FindLastIndex (2, 2, l => true));
640                         Assert.AreEqual (1, _list1.FindLastIndex (1, 2, l => true));
641                 }
642
643                 [Test]
644                 public void FindLastIndex_Invalid ()
645                 {
646                         try {
647                                 _list1.FindLastIndex (null);
648                                 Assert.Fail ("#1");
649                         } catch (ArgumentNullException) {
650                         }
651
652                         try {
653                                 _list1.FindLastIndex (-1, l => true);
654                                 Assert.Fail ("#2");
655                         } catch (ArgumentOutOfRangeException) {
656                         }
657
658                         try {
659                                 _list1.FindLastIndex (-1, 0, l => true);
660                                 Assert.Fail ("#2b");
661                         } catch (ArgumentOutOfRangeException) {
662                         }
663
664                         try {
665                                 _list1.FindLastIndex (0, -1, l => true);
666                                 Assert.Fail ("#3");
667                         } catch (ArgumentOutOfRangeException) {
668                         }
669
670                         try {
671                                 _list1.FindLastIndex (100, l => true);
672                                 Assert.Fail ("#4");
673                         } catch (ArgumentOutOfRangeException) {
674                         }
675
676                         try {
677                                 _list1.FindLastIndex (100, 0, l => true);
678                                 Assert.Fail ("#4b");
679                         } catch (ArgumentOutOfRangeException) {
680                         }
681
682                         try {
683                                 _list1.FindLastIndex (2, 4, l => true);
684                                 Assert.Fail ("#5");
685                         } catch (ArgumentOutOfRangeException) {
686                         }
687                 }
688
689                 [Test]
690                 public void RemoveTest ()
691                 {
692                         int count = _list1.Count;
693                         bool result = _list1.Remove (22);
694                         Assert.IsTrue (result);
695                         Assert.AreEqual (count - 1, _list1.Count);
696
697                         Assert.AreEqual (-1, _list1.IndexOf (22));
698
699                         result = _list1.Remove (0);
700                         Assert.IsFalse (result);
701                 }
702
703                 [Test]
704                 public void RemoveAllTest ()
705                 {
706                         int count = _list1.Count;
707                         int removedCount = _list1.RemoveAll (FindMultipleOfFour);
708                         Assert.AreEqual (4, removedCount);
709                         Assert.AreEqual (count - 4, _list1.Count);
710
711                         removedCount = _list1.RemoveAll (FindMultipleOfTwelve);
712                         Assert.AreEqual (0, removedCount);
713                         Assert.AreEqual (count - 4, _list1.Count);
714                 }
715
716                 [Test]
717                 public void RemoveAtTest ()
718                 {
719                         int count = _list1.Count;
720                         _list1.RemoveAt (0);
721                         Assert.AreEqual (count - 1, _list1.Count);
722                         Assert.AreEqual (50, _list1 [0]);
723                 }
724
725                 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
726                 public void RemoveOutOfRangeTest ()
727                 {
728                         _list1.RemoveAt (_list1.Count);
729                 }
730
731                 [Test]
732                 public void RemoveRangeTest ()
733                 {
734                         int count = _list1.Count;
735                         _list1.RemoveRange (1, 2);
736                         Assert.AreEqual (count - 2, _list1.Count);
737                         Assert.AreEqual (55, _list1 [0]);
738                         Assert.AreEqual (80, _list1 [1]);
739
740                         _list1.RemoveRange (0, 0);
741                         Assert.AreEqual (count - 2, _list1.Count);
742                 }
743
744                 [Test]
745                 public void RemoveRangeFromEmptyListTest ()
746                 {
747                         List<int> l = new List<int> ();
748                         l.RemoveRange (0, 0);
749                 }
750
751                 [Test, ExpectedException (typeof (ArgumentException))]
752                 public void RemoveRangeOutOfRangeTest ()
753                 {
754                         _list1.RemoveRange (1, _list1.Count);
755                 }
756
757                 [Test]
758                 public void ReverseTest ()
759                 {
760                         int count = _list1.Count;
761                         _list1.Reverse ();
762                         Assert.AreEqual (count, _list1.Count);
763
764                         Assert.AreEqual (63, _list1 [0]);
765                         Assert.AreEqual (55, _list1 [count - 1]);
766
767                         _list1.Reverse (0, 2);
768
769                         Assert.AreEqual (40, _list1 [0]);
770                         Assert.AreEqual (63, _list1 [1]);
771                 }
772
773                 [Test, ExpectedException (typeof (ArgumentException))]
774                 public void ReverseOutOfRangeTest ()
775                 {
776                         _list1.Reverse (1, _list1.Count);
777                 }
778
779                 [Test]
780                 public void ToArrayTest ()
781                 {
782                         int [] copiedContents = _list1.ToArray ();
783                         Assert.IsFalse (ReferenceEquals (copiedContents, _list1_contents));
784
785                         Assert.AreEqual (_list1.Count, copiedContents.Length);
786                         Assert.AreEqual (_list1 [0], copiedContents [0]);
787                 }
788
789                 [Test]
790                 public void TrimExcessTest ()
791                 {
792                         List <string> l = new List <string> ();
793                         l.Add ("foo");
794
795                         Assert.IsTrue (l.Count < l.Capacity);
796                         l.TrimExcess ();
797                         Assert.AreEqual (l.Count, l.Capacity);
798                 }
799
800                 bool IsPositive (int i)
801                 {
802                         return i >= 0;
803                 }
804
805                 [Test]
806                 public void TrueForAllTest ()
807                 {
808                         Assert.IsFalse (_list1.TrueForAll (FindMultipleOfFour));
809                         Assert.IsTrue (_list1.TrueForAll (IsPositive));
810                 }
811
812                 [Test, ExpectedException (typeof (ArgumentNullException))]
813                 public void TrueForAllNullTest ()
814                 {
815                         _list1.TrueForAll (null);
816                 }
817
818                 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
819                 public void CapacityOutOfRangeTest ()
820                 {
821                         _list1.Capacity = _list1.Count - 1;
822                 }
823
824                 [Test]
825                 public void BinarySearch_EmptyList ()
826                 {
827                         GenericComparer<int> comparer = new GenericComparer<int> ();
828                         List<int> l = new List<int> ();
829                         Assert.AreEqual (-1, l.BinarySearch (0, comparer), "BinarySearch");
830                         // bug 77030 - the comparer isn't called for an empty array/list
831                         Assert.IsFalse (comparer.Called, "Called");
832                 }
833
834                 [Test]
835                 public void BinarySearch2_EmptyList ()
836                 {
837                         GenericComparer<int> comparer = new GenericComparer<int> ();
838                         List<int> l = new List<int> ();
839                         Assert.AreEqual (-1, l.BinarySearch (0, 0, 0, comparer), "BinarySearch");
840                         // bug 77030 - the comparer isn't called for an empty array/list
841                         Assert.IsFalse (comparer.Called, "Called");
842                 }
843
844                 [Test]
845                 public void AddRange_Bug77019 ()
846                 {
847                         List<int> l = new List<int> ();
848                         Dictionary<string, int> d = new Dictionary<string, int> ();
849                         l.AddRange (d.Values);
850                         Assert.AreEqual (0, l.Count, "Count");
851                 }
852
853                 [Test]
854                 public void VersionCheck_Add ()
855                 {
856                         List<int> list = new List<int> ();
857                         IEnumerator enumerator = list.GetEnumerator ();
858                         list.Add (5);
859
860                         try {
861                                 enumerator.MoveNext ();
862                                 Assert.Fail ("#1");
863                         } catch (InvalidOperationException) {
864                         }
865
866                         try {
867                                 enumerator.Reset ();
868                                 Assert.Fail ("#2");
869                         } catch (InvalidOperationException) {
870                         }
871
872                         enumerator = list.GetEnumerator ();
873                         enumerator.MoveNext ();
874                 }
875
876                 [Test]
877                 public void VersionCheck_AddRange ()
878                 {
879                         List<int> list = new List<int> ();
880                         IEnumerator enumerator = list.GetEnumerator ();
881                         list.AddRange (new int [] { 5, 7 });
882
883                         try {
884                                 enumerator.MoveNext ();
885                                 Assert.Fail ("#1");
886                         } catch (InvalidOperationException) {
887                         }
888
889                         try {
890                                 enumerator.Reset ();
891                                 Assert.Fail ("#2");
892                         } catch (InvalidOperationException) {
893                         }
894
895                         enumerator = list.GetEnumerator ();
896                         enumerator.MoveNext ();
897                 }
898
899                 [Test]
900                 public void VersionCheck_Clear ()
901                 {
902                         List<int> list = new List<int> ();
903                         IEnumerator enumerator = list.GetEnumerator ();
904                         list.Clear ();
905
906                         try {
907                                 enumerator.MoveNext ();
908                                 Assert.Fail ("#1");
909                         } catch (InvalidOperationException) {
910                         }
911
912                         try {
913                                 enumerator.Reset ();
914                                 Assert.Fail ("#2");
915                         } catch (InvalidOperationException) {
916                         }
917
918                         enumerator = list.GetEnumerator ();
919                         enumerator.MoveNext ();
920                 }
921
922                 [Test]
923                 public void VersionCheck_Insert ()
924                 {
925                         List<int> list = new List<int> ();
926                         IEnumerator enumerator = list.GetEnumerator ();
927                         list.Insert (0, 7);
928
929                         try {
930                                 enumerator.MoveNext ();
931                                 Assert.Fail ("#1");
932                         } catch (InvalidOperationException) {
933                         }
934
935                         try {
936                                 enumerator.Reset ();
937                                 Assert.Fail ("#2");
938                         } catch (InvalidOperationException) {
939                         }
940
941                         enumerator = list.GetEnumerator ();
942                         enumerator.MoveNext ();
943                 }
944
945                 [Test]
946                 public void VersionCheck_InsertRange ()
947                 {
948                         List<int> list = new List<int> ();
949                         IEnumerator enumerator = list.GetEnumerator ();
950                         list.InsertRange (0, new int [] { 5, 7 });
951
952                         try {
953                                 enumerator.MoveNext ();
954                                 Assert.Fail ("#1");
955                         } catch (InvalidOperationException) {
956                         }
957
958                         try {
959                                 enumerator.Reset ();
960                                 Assert.Fail ("#2");
961                         } catch (InvalidOperationException) {
962                         }
963
964                         enumerator = list.GetEnumerator ();
965                         enumerator.MoveNext ();
966                 }
967
968                 [Test]
969                 public void VersionCheck_Remove ()
970                 {
971                         List<int> list = new List<int> ();
972                         list.Add (5);
973                         IEnumerator enumerator = list.GetEnumerator ();
974                         // version number is not incremented if item does not exist in list
975                         list.Remove (7);
976                         enumerator.MoveNext ();
977                         list.Remove (5);
978
979                         try {
980                                 enumerator.MoveNext ();
981                                 Assert.Fail ("#1");
982                         } catch (InvalidOperationException) {
983                         }
984
985                         try {
986                                 enumerator.Reset ();
987                                 Assert.Fail ("#2");
988                         } catch (InvalidOperationException) {
989                         }
990
991                         enumerator = list.GetEnumerator ();
992                         enumerator.MoveNext ();
993                 }
994
995                 [Test]
996                 public void VersionCheck_RemoveAll ()
997                 {
998                         List<int> list = new List<int> ();
999                         list.Add (5);
1000                         IEnumerator enumerator = list.GetEnumerator ();
1001                         // version is not incremented if there are no items to remove
1002                         list.RemoveAll (FindMultipleOfFour);
1003                         enumerator.MoveNext ();
1004                         list.Add (4);
1005
1006                         enumerator = list.GetEnumerator ();
1007                         list.RemoveAll (FindMultipleOfFour);
1008
1009                         try {
1010                                 enumerator.MoveNext ();
1011                                 Assert.Fail ("#1");
1012                         } catch (InvalidOperationException) {
1013                         }
1014
1015                         try {
1016                                 enumerator.Reset ();
1017                                 Assert.Fail ("#2");
1018                         } catch (InvalidOperationException) {
1019                         }
1020
1021                         enumerator = list.GetEnumerator ();
1022                         enumerator.MoveNext ();
1023                 }
1024
1025                 [Test]
1026                 public void VersionCheck_RemoveAt ()
1027                 {
1028                         List<int> list = new List<int> ();
1029                         list.Add (5);
1030                         IEnumerator enumerator = list.GetEnumerator ();
1031                         list.RemoveAt (0);
1032
1033                         try {
1034                                 enumerator.MoveNext ();
1035                                 Assert.Fail ("#1");
1036                         } catch (InvalidOperationException) {
1037                         }
1038
1039                         try {
1040                                 enumerator.Reset ();
1041                                 Assert.Fail ("#2");
1042                         } catch (InvalidOperationException) {
1043                         }
1044
1045                         enumerator = list.GetEnumerator ();
1046                         enumerator.MoveNext ();
1047                 }
1048
1049                 [Test]
1050                 public void VersionCheck_RemoveRange ()
1051                 {
1052                         List<int> list = new List<int> ();
1053                         list.Add (5);
1054                         IEnumerator enumerator = list.GetEnumerator ();
1055                         // version is not incremented if count is zero
1056                         list.RemoveRange (0, 0);
1057                         enumerator.MoveNext ();
1058                         enumerator.Reset ();
1059                         list.RemoveRange (0, 1);
1060
1061                         try {
1062                                 enumerator.MoveNext ();
1063                                 Assert.Fail ("#1");
1064                         } catch (InvalidOperationException) {
1065                         }
1066
1067                         try {
1068                                 enumerator.Reset ();
1069                                 Assert.Fail ("#2");
1070                         } catch (InvalidOperationException) {
1071                         }
1072
1073                         enumerator = list.GetEnumerator ();
1074                         enumerator.MoveNext ();
1075                 }
1076
1077                 [Test, ExpectedException (typeof (InvalidOperationException))] // #699182
1078                 public void VersionCheck_Indexer ()
1079                 {
1080                         var list = new List<int> () { 0, 2, 3 };
1081                         var enumerator = list.GetEnumerator ();
1082
1083                         list [0] = 1;
1084
1085                         enumerator.MoveNext ();
1086                 }
1087
1088                 [Test]
1089                 public void VersionCheck_Reverse ()
1090                 {
1091                         List<int> list = new List<int> ();
1092                         IEnumerator enumerator = list.GetEnumerator ();
1093                         list.Reverse ();
1094
1095                         try {
1096                                 enumerator.MoveNext ();
1097                                 Assert.Fail ("#A1");
1098                         } catch (InvalidOperationException) {
1099                         }
1100
1101                         try {
1102                                 enumerator.Reset ();
1103                                 Assert.Fail ("#A2");
1104                         } catch (InvalidOperationException) {
1105                         }
1106
1107                         enumerator = list.GetEnumerator ();
1108                         list.Reverse (0, 0);
1109
1110                         try {
1111                                 enumerator.MoveNext ();
1112                                 Assert.Fail ("#B1");
1113                         } catch (InvalidOperationException) {
1114                         }
1115
1116                         try {
1117                                 enumerator.Reset ();
1118                                 Assert.Fail ("#B2");
1119                         } catch (InvalidOperationException) {
1120                         }
1121
1122                         enumerator = list.GetEnumerator ();
1123                         enumerator.MoveNext ();
1124                 }
1125
1126                 class SortTestComparer: IComparer<string> {
1127
1128                         public int Compare (string s1, string s2)
1129                         {
1130                                 return String.Compare (s1, s2);
1131                         }
1132                 }
1133
1134                 [Test]
1135                 public void Sort_Bug76361 ()
1136                 {
1137                         SortTestComparer comparer = new SortTestComparer ();
1138                         List<string> l = new List<string> ();
1139                         l.Add ("foo");
1140                         l.Add ("bar");
1141                         l.Sort (comparer);
1142                         Assert.AreEqual ("bar", l[0], "0");
1143                         Assert.AreEqual ("foo", l[1], "1");
1144                         Assert.AreEqual (2, l.Count, "Count");
1145                 }
1146
1147                 // for bug #77039 test case
1148                 class GenericIComparable: IComparable<GenericIComparable> {
1149                         private int _NumberToSortOn;
1150
1151                         public int NumberToSortOn {
1152                                 get { return _NumberToSortOn; }
1153                                 set { _NumberToSortOn = value; }
1154                         }
1155
1156                         public GenericIComparable (int val)
1157                         {
1158                                 _NumberToSortOn = val;
1159                         }
1160
1161                         public int CompareTo (GenericIComparable other)
1162                         {
1163                                 return NumberToSortOn.CompareTo (other.NumberToSortOn);
1164                         }
1165                 }
1166
1167                 [Test]
1168                 public void Sort_GenericIComparable_Bug77039 ()
1169                 {
1170                         List<GenericIComparable> l = new List<GenericIComparable> ();
1171                         l.Add (new GenericIComparable (2));
1172                         l.Add (new GenericIComparable (1));
1173                         l.Add (new GenericIComparable (3));
1174                         l.Sort ();
1175                         Assert.AreEqual (1, l[0].NumberToSortOn, "0");
1176                         Assert.AreEqual (2, l[1].NumberToSortOn, "1");
1177                         Assert.AreEqual (3, l[2].NumberToSortOn, "2");
1178                 }
1179
1180                 class NonGenericIComparable: IComparable {
1181                         private int _NumberToSortOn;
1182
1183                         public int NumberToSortOn {
1184                                 get { return _NumberToSortOn; }
1185                                 set { _NumberToSortOn = value; }
1186                         }
1187
1188                         public NonGenericIComparable (int val)
1189                         {
1190                                 _NumberToSortOn = val;
1191                         }
1192
1193                         public int CompareTo (object obj)
1194                         {
1195                                 return NumberToSortOn.CompareTo ((obj as NonGenericIComparable).NumberToSortOn);
1196                         }
1197                 }
1198
1199                 [Test]
1200                 public void Sort_NonGenericIComparable ()
1201                 {
1202                         List<NonGenericIComparable> l = new List<NonGenericIComparable> ();
1203                         l.Add (new NonGenericIComparable (2));
1204                         l.Add (new NonGenericIComparable (1));
1205                         l.Add (new NonGenericIComparable (3));
1206                         l.Sort ();
1207                         Assert.AreEqual (1, l[0].NumberToSortOn, "0");
1208                         Assert.AreEqual (2, l[1].NumberToSortOn, "1");
1209                         Assert.AreEqual (3, l[2].NumberToSortOn, "2");
1210                 }
1211
1212                 class NonComparable {
1213                 }
1214
1215                 [Test]
1216                 public void Sort_GenericNonIComparable ()
1217                 {
1218                         List<NonComparable> l = new List<NonComparable> ();
1219                         l.Sort ();
1220                         // no element -> no sort -> no exception
1221                         l.Add (new NonComparable ());
1222                         l.Sort ();
1223                         // one element -> no sort -> no exception
1224                 }
1225
1226                 [Test]
1227                 [ExpectedException (typeof (InvalidOperationException))]
1228                 public void Sort_GenericNonIComparable_2 ()
1229                 {
1230                         List<NonComparable> l = new List<NonComparable> ();
1231                         l.Add (new NonComparable ());
1232                         l.Add (new NonComparable ());
1233                         l.Sort ();
1234                         // two element -> sort -> exception!
1235                 }
1236                 
1237                 [Test]
1238                 public void IList_Contains_InvalidType()
1239                 {
1240                         List<string> list = new List<string>();
1241                         list.Add("foo");
1242                         Assert.IsFalse (((IList)list).Contains(new object()));
1243
1244                         Assert.IsFalse (((IList)_list1).Contains(null));
1245                 }
1246                 
1247                 [Test]
1248                 public void IList_IndexOf_InvalidType()
1249                 {
1250                         List<string> list = new List<string>();
1251                         list.Add("foo");
1252                         Assert.AreEqual (-1, ((IList)list).IndexOf(new object()));
1253
1254                         Assert.AreEqual (-1, ((IList)_list1).IndexOf(null));
1255                 }
1256
1257                 // for bug #77277 test case
1258                 [Test]
1259                 public void Test_ContainsAndIndexOf_EquatableItem ()
1260                 {
1261                         List<EquatableClass> list = new List<EquatableClass> ();
1262                         EquatableClass item0 = new EquatableClass (0);
1263                         EquatableClass item1 = new EquatableClass (1);
1264
1265                         list.Add (item0);
1266                         list.Add (item1);
1267                         list.Add (item0);
1268
1269                         Assert.AreEqual (true, list.Contains (item0), "#0");
1270                         Assert.AreEqual (true, list.Contains (new EquatableClass (0)), "#1");
1271                         Assert.AreEqual (0, list.IndexOf (item0), "#2");
1272                         Assert.AreEqual (0, list.IndexOf (new EquatableClass (0)), "#3");
1273                         Assert.AreEqual (2, list.LastIndexOf (item0), "#4");
1274                         Assert.AreEqual (2, list.LastIndexOf (new EquatableClass (0)), "#5");
1275                 }
1276
1277                 // for bug #81387 test case
1278                 [Test]
1279                 public void Test_Contains_After_Remove ()
1280                 {
1281                         List<int> list = new List<int> ();
1282             list.Add (2);
1283
1284             list.Remove (2);
1285
1286                         Assert.AreEqual (false, list.Contains (2), "#0");
1287                 }
1288                 
1289                 [Test]
1290                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
1291                 public void SetItem_OutOfRange()
1292                 {
1293                         List<string> list = new List<string>();
1294                         list[0] = "foo";
1295                 }
1296                 
1297                 [Test]
1298                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
1299                 public void SetItem_IList_OutOfRange()
1300                 {
1301                         IList<string> list = new List<string>();
1302                         list[0] = "foo";
1303                 }
1304
1305                 public class EquatableClass : IEquatable<EquatableClass>
1306                 {
1307                         int _x;
1308                         public EquatableClass (int x)
1309                         {
1310                                 _x = x;
1311                         }
1312
1313                         public bool Equals (EquatableClass other)
1314                         {
1315                                 return this._x == other._x;
1316                         }
1317                 }
1318
1319                 delegate void D ();
1320                 bool Throws (D d)
1321                 {
1322                         try {
1323                                 d ();
1324                                 return false;
1325                         } catch {
1326                                 return true;
1327                         }
1328                 }
1329
1330                 [Test]
1331                 // based on #491858, #517415
1332                 public void Enumerator_Current ()
1333                 {
1334                         var e1 = new List<int>.Enumerator ();
1335                         Assert.IsFalse (Throws (delegate { var x = e1.Current; }));
1336
1337                         var d = new List<int> ();
1338                         var e2 = d.GetEnumerator ();
1339                         Assert.IsFalse (Throws (delegate { var x = e2.Current; }));
1340                         e2.MoveNext ();
1341                         Assert.IsFalse (Throws (delegate { var x = e2.Current; }));
1342                         e2.Dispose ();
1343                         Assert.IsFalse (Throws (delegate { var x = e2.Current; }));
1344
1345                         var e3 = ((IEnumerable<int>) d).GetEnumerator ();
1346                         Assert.IsFalse (Throws (delegate { var x = e3.Current; }));
1347                         e3.MoveNext ();
1348                         Assert.IsFalse (Throws (delegate { var x = e3.Current; }));
1349                         e3.Dispose ();
1350                         Assert.IsFalse (Throws (delegate { var x = e3.Current; }));
1351
1352                         var e4 = ((IEnumerable) d).GetEnumerator ();
1353                         Assert.IsTrue (Throws (delegate { var x = e4.Current; }));
1354                         e4.MoveNext ();
1355                         Assert.IsTrue (Throws (delegate { var x = e4.Current; }));
1356                         ((IDisposable) e4).Dispose ();
1357                         Assert.IsTrue (Throws (delegate { var x = e4.Current; }));
1358                 }
1359
1360                 [Test]
1361                 public void Enumerator_Reset ()
1362                 {
1363                         var l = new List<int> () {
1364                                 4
1365                         };
1366
1367                         IEnumerator<int> e = l.GetEnumerator ();
1368                         Assert.IsTrue (e.MoveNext (), "#1");
1369                         Assert.AreEqual (4, e.Current, "#2");
1370                         e.Reset ();
1371                         Assert.AreEqual (0, e.Current, "#3");
1372                 }
1373
1374                 [Test] //bug #672907
1375                 public void ICollectionCopyToExceptions ()
1376                 {
1377                         var l = new List <int> ();
1378                         ICollection x = l;
1379                         try {
1380                                 x.CopyTo (null, 0);
1381                                 Assert.Fail ("#1");
1382                         } catch (Exception e) {
1383                                 Assert.IsTrue (e is ArgumentNullException, "#2");
1384                         }
1385
1386                         try {
1387                                 x.CopyTo (new int [10], -1);
1388                                 Assert.Fail ("#3");
1389                         } catch (Exception e) {
1390                                 Assert.IsTrue (e is ArgumentOutOfRangeException, "#4");
1391                         }
1392
1393                         try {
1394                                 x.CopyTo (new int [10, 1], 0);
1395                                 Assert.Fail ("#5");
1396                         } catch (Exception e) {
1397                                 Assert.IsTrue (e is ArgumentException, "#6");
1398                         }
1399
1400                         try {
1401                                 x.CopyTo (Array.CreateInstance (typeof (int), new int [] { 10 }, new int[] { 1 }), 0);
1402                                 Assert.Fail ("#7");
1403                         } catch (Exception e) {
1404                                 Assert.IsTrue (e is ArgumentException, "#8");
1405                         }
1406
1407                         l.Add (10); l.Add (20);
1408                         try {
1409                                 x.CopyTo (new int [1], 0);
1410                                 Assert.Fail ("#9");
1411                         } catch (Exception e) {
1412                                 Assert.IsTrue (e is ArgumentException, "#10");
1413                         }
1414                 }
1415
1416                 [Test]
1417                 public void LastIndexOfEmpty_2558 () {
1418                         var l = new List<int> ();
1419                         Assert.AreEqual (-1, l.IndexOf (-1));
1420                 }
1421
1422
1423 #region Enumerator mutability
1424
1425                 class Bar
1426                 {
1427                 }
1428
1429                 class Foo : IEnumerable<Bar>
1430                 {
1431                         Baz enumerator;
1432
1433                         public Foo ()
1434                         {
1435                                 enumerator = new Baz ();
1436                         }
1437
1438                         public IEnumerator<Bar> GetEnumerator ()
1439                         {
1440                                 return enumerator;
1441                         }
1442
1443                         IEnumerator IEnumerable.GetEnumerator ()
1444                         {
1445                                 return enumerator;
1446                         }
1447                 }
1448
1449                 class Baz : IEnumerator<Bar>
1450                 {
1451                         public bool DisposeWasCalled = false;
1452
1453                         public void Dispose ()
1454                         {
1455                                 DisposeWasCalled = true;
1456                         }
1457
1458                         public bool MoveNext ()
1459                         {
1460                                 return false; //assume empty collection
1461                         }
1462
1463                         public void Reset ()
1464                         {
1465                         }
1466
1467                         public Bar Current
1468                         {
1469                                 get { return null; }
1470                         }
1471
1472                         object IEnumerator.Current
1473                         {
1474                                 get { return Current; }
1475                         }
1476                 }
1477
1478                 [Test]
1479                 public void PremiseAboutDisposeBeingCalledWhenLooping ()
1480                 {
1481                         Foo enumerable = new Foo ();
1482                         Baz enumerator = enumerable.GetEnumerator () as Baz;
1483                         Assert.IsNotNull (enumerator);
1484                         Assert.AreEqual (false, enumerator.DisposeWasCalled);
1485                         foreach (var element in enumerable) ; //sic
1486                         Assert.AreEqual (true, enumerator.DisposeWasCalled);
1487                 }
1488
1489                 [Test]
1490                 public void TwoEnumeratorsOfTwoDifferentListsAreDifferent ()
1491                 {
1492                         var twoThree = new List<int> { 2, 3 };
1493                         var oneTwo = new List<int> { 2, 4 };
1494                         Assert.IsFalse (oneTwo.GetEnumerator ().Equals (twoThree.GetEnumerator ()));
1495                 }
1496
1497                 [Test]
1498                 public void TwoEnumeratorsOfTwoDifferentListsWithSameElementsAreDifferent ()
1499                 {
1500                         var twoThree = new List<int> { 2, 3 };
1501                         var anotherTwoThree = new List<int> { 2, 3 };
1502                         Assert.IsFalse(twoThree.GetEnumerator ().Equals (anotherTwoThree.GetEnumerator ()));
1503                 }
1504
1505                 [Test]
1506                 public void EnumeratorIsSameInSameListAfterSubsequentCalls ()
1507                 {
1508                         var enumerable = new List<Bar> ();
1509                         var enumerator = enumerable.GetEnumerator ();
1510                         var enumerator2 = enumerable.GetEnumerator ();
1511
1512                         Assert.IsFalse (ReferenceEquals (enumerator2, enumerator)); //because they are value-types
1513
1514                         Assert.IsTrue (enumerator2.Equals (enumerator));
1515                 }
1516
1517
1518                 [Test] // was bug in Mono 2.10.9
1519                 public void EnumeratorIsStillSameInSubsequentCallsEvenHavingADisposalInBetween ()
1520                 {
1521                         var enumerable = new List<Bar> ();
1522                         var enumerator = enumerable.GetEnumerator ();
1523                         enumerator.Dispose ();
1524                         var enumerator2 = enumerable.GetEnumerator ();
1525
1526                         Assert.IsFalse (ReferenceEquals (enumerator2, enumerator)); //because they are value-types
1527
1528                         Assert.IsTrue (enumerator2.Equals (enumerator));
1529                 }
1530
1531                 [Test]
1532                 public void EnumeratorIsObviouslyDifferentAfterListChanges ()
1533                 {
1534                         var enumerable = new List<Bar> ();
1535                         var enumerator = enumerable.GetEnumerator ();
1536                         enumerable.Add (new Bar ());
1537                         var enumerator2 = enumerable.GetEnumerator ();
1538
1539                         Assert.IsFalse (ReferenceEquals (enumerator2, enumerator)); //because they are value-types
1540
1541                         Assert.IsFalse (enumerator2.Equals (enumerator));
1542                 }
1543
1544                 [Test] // was bug in Mono 2.10.9
1545                 public void DotNetDoesntThrowObjectDisposedExceptionAfterSubsequentDisposes()
1546                 {
1547                         var enumerable = new List<Bar> ();
1548                         var enumerator = enumerable.GetEnumerator ();
1549                         Assert.AreEqual (false, enumerator.MoveNext ());
1550                         enumerator.Dispose();
1551                         Assert.AreEqual (false, enumerator.MoveNext ());
1552                 }
1553 #endregion
1554
1555
1556         }
1557 }
1558