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