Merge pull request #900 from Blewzman/FixAggregateExceptionGetBaseException
[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                 [Category ("TargetJvmNotWorking")]
349                 public void SerializeTest ()
350                 {
351                         List <int> list = new List <int> ();
352                         list.Add (5);
353                         list.Add (0);
354                         list.Add (7);
355
356 #if TARGET_JVM
357                         BinaryFormatter bf = (BinaryFormatter)vmw.@internal.remoting.BinaryFormatterUtils.CreateBinaryFormatter (false);
358 #else
359                         BinaryFormatter bf = new BinaryFormatter ();
360 #endif // TARGET_JVM
361                         MemoryStream ms = new MemoryStream ();
362                         bf.Serialize (ms, list);
363
364                         byte [] buffer = new byte [ms.Length];
365                         ms.Position = 0;
366                         ms.Read (buffer, 0, buffer.Length);
367
368                         Assert.AreEqual (_serializedList, buffer);
369                 }
370
371 #endif
372
373                 [Test]
374                 [Category ("TargetJvmNotWorking")]
375                 public void DeserializeTest ()
376                 {
377                         MemoryStream ms = new MemoryStream ();
378                         ms.Write (_serializedList, 0, _serializedList.Length);
379                         ms.Position = 0;
380
381 #if TARGET_JVM
382                         BinaryFormatter bf = (BinaryFormatter)vmw.@internal.remoting.BinaryFormatterUtils.CreateBinaryFormatter (false);
383 #else
384                         BinaryFormatter bf = new BinaryFormatter ();
385 #endif // TARGET_JVM
386                         List<int> list = (List<int>) bf.Deserialize (ms);
387                         Assert.AreEqual (3, list.Count, "#1");
388                         Assert.AreEqual (5, list [0], "#2");
389                         Assert.AreEqual (0, list [1], "#3");
390                         Assert.AreEqual (7, list [2], "#4");
391                 }
392
393                 [Test]
394                 public void SortTest ()
395                 {
396                         List <int> l = new List <int> (_list1);
397                         l.Sort ();
398                         Assert.AreEqual (_list1.Count, l.Count);
399                         Assert.AreEqual (22, l [0]);
400                         int minimum = 22;
401                         foreach (int i in l)
402                         {
403                                 Assert.IsTrue (minimum <= i);
404                                 minimum = i;
405                         }
406                 }
407
408                 [Test]
409                 public void ClearTest ()
410                 {
411                         int capacity = _list1.Capacity;
412                         _list1.Clear ();
413                         Assert.AreEqual (0, _list1.Count);
414                         Assert.AreEqual (capacity, _list1.Capacity);
415                 }
416
417                 [Test]
418                 public void ContainsTest ()
419                 {
420                         Assert.IsTrue (_list1.Contains (22));
421                         Assert.IsFalse (_list1.Contains (23));
422                 }
423
424                 private string StringConvert (int i)
425                 {
426                         return i.ToString ();
427                 }
428                 
429                 [Test]
430                 public void ConvertAllTest ()
431                 {
432                         List <string> s = _list1.ConvertAll ( (Converter <int, string>)StringConvert);
433                         Assert.AreEqual (_list1.Count, s.Count);
434                         Assert.AreEqual ("55", s [0]);
435                 }
436
437                 [Test]
438                 public void CopyToTest ()
439                 {
440                         int [] a = new int [2];
441                         _list1.CopyTo (1, a, 0, 2);
442                         Assert.AreEqual (50, a [0]);
443                         Assert.AreEqual (22, a [1]);
444
445                         int [] b = new int [_list1.Count + 1];
446                         b [_list1.Count] = 555;
447                         _list1.CopyTo (b);
448                         Assert.AreEqual (55, b [0]);
449                         Assert.AreEqual (555, b [_list1.Count]);
450
451                         b [0] = 888;
452                         _list1.CopyTo (b, 1);
453                         Assert.AreEqual (888, b [0]);
454                         Assert.AreEqual (55, b [1]);
455                 }
456
457                 [Test, ExpectedException (typeof (ArgumentNullException))]
458                 public void CopyToNullTest ()
459                 {
460                         int [] a = null;
461                         _list1.CopyTo (0, a, 0, 0);
462                 }
463
464                 static bool FindMultipleOfThree (int i)
465                 {
466                         return (i % 3) == 0;
467                 }
468
469                 static bool FindMultipleOfFour (int i)
470                 {
471                         return (i % 4) == 0;
472                 }
473
474                 static bool FindMultipleOfTwelve (int i)
475                 {
476                         return (i % 12) == 0;
477                 }
478
479                 [Test]
480                 public void FindTest ()
481                 {
482                         int i = _list1.Find (FindMultipleOfThree);
483                         Assert.AreEqual (63, i);
484
485                         i = _list1.Find (FindMultipleOfTwelve);
486                         Assert.AreEqual (default (int), i);
487                 }
488
489                 [Test, ExpectedException (typeof (ArgumentNullException))]
490                 public void FindNullTest ()
491                 {
492                         int i = _list1.Find (null);
493                 }
494
495                 [Test]
496                 public void FindAllSmallTest ()
497                 {
498                         List <int> findings = _list1.FindAll (FindMultipleOfFour);
499                         Assert.AreEqual (4, findings.Count);
500                         Assert.AreEqual (80, findings [0]);
501                         Assert.AreEqual (56, findings [1]);
502                         Assert.AreEqual (52, findings [2]);
503                         Assert.AreEqual (40, findings [3]);
504
505                         findings = _list1.FindAll (FindMultipleOfTwelve);
506                         Assert.IsNotNull (findings);
507                         Assert.AreEqual (0, findings.Count);
508                 }
509                 
510                 [Test]
511                 public void FindAllMediumTest ()
512                 {
513                         List <int> integers = new List <int> (10000);
514                         for (int i = 1; i <= 10000; i++)
515                                 integers.Add (i);
516                         
517                         List <int> results = integers.FindAll (FindMultipleOfFour);
518                         
519                         Assert.IsNotNull (results);
520                         Assert.AreEqual (2500, results.Count);
521                         
522                         results = integers.FindAll (FindMultipleOfTwelve);
523                         
524                         Assert.IsNotNull (results);
525                         Assert.AreEqual (833, results.Count);
526                 }
527                 
528                 [Test]
529                 public void FindAllLargeTest ()
530                 {
531                         List <int> integers = new List <int> (70000);
532                         for (int i = 1; i <= 80000; i++)
533                                 integers.Add (i);
534                         
535                         List <int> results = integers.FindAll (FindMultipleOfFour);
536                         
537                         Assert.IsNotNull (results);
538                         Assert.AreEqual (20000, results.Count);
539                         
540                         results = integers.FindAll (FindMultipleOfTwelve);
541                         
542                         Assert.IsNotNull (results);
543                         Assert.AreEqual (6666, results.Count);
544                 }
545
546                 [Test, ExpectedException (typeof (ArgumentNullException))]
547                 public void FindAllNullTest ()
548                 {
549                         List <int> findings = _list1.FindAll (null);
550                 }
551
552                 [Test]
553                 public void FindIndexTest ()
554                 {
555                         int i = _list1.FindIndex (FindMultipleOfThree);
556                         Assert.AreEqual (7, i);
557
558                         i = _list1.FindIndex (FindMultipleOfTwelve);
559                         Assert.AreEqual (-1, i);
560
561                         var a = new List<int> () { 2, 2, 2, 3, 2 };
562                         Assert.AreEqual (2, a.FindIndex (2, 2, l => true));
563                 }
564
565                 [Test]
566                 public void FindIndex_Invalid ()
567                 {
568                         try {
569                                 _list1.FindIndex (null);
570                                 Assert.Fail ("#1");
571                         } catch (ArgumentNullException) {
572                         }
573
574                         try {
575                                 _list1.FindIndex (-1, l => true);
576                                 Assert.Fail ("#2");
577                         } catch (ArgumentOutOfRangeException) {
578                         }
579
580                         try {
581                                 _list1.FindIndex (-1, 0, l => true);
582                                 Assert.Fail ("#2b");
583                         } catch (ArgumentOutOfRangeException) {
584                         }
585
586                         try {
587                                 _list1.FindIndex (0, -1, l => true);
588                                 Assert.Fail ("#3");
589                         } catch (ArgumentOutOfRangeException) {
590                         }
591
592                         try {
593                                 _list1.FindIndex (100, l => true);
594                                 Assert.Fail ("#4");
595                         } catch (ArgumentOutOfRangeException) {
596                         }
597
598                         try {
599                                 _list1.FindIndex (100, 0, l => true);
600                                 Assert.Fail ("#4b");
601                         } catch (ArgumentOutOfRangeException) {
602                         }
603
604                         try {
605                                 _list1.FindIndex (7, 2, l => true);
606                                 Assert.Fail ("#5");
607                         } catch (ArgumentOutOfRangeException) {
608                         }
609                 }
610
611                 [Test]
612                 public void FindLastTest ()
613                 {
614                         int i = _list1.FindLast (FindMultipleOfFour);
615                         Assert.AreEqual (40, i);
616
617                         i = _list1.FindLast (FindMultipleOfTwelve);
618                         Assert.AreEqual (default (int), i);
619                 }
620
621                 [Test, ExpectedException (typeof (ArgumentNullException))]
622                 public void FindLastNullTest ()
623                 {
624                         int i = _list1.FindLast (null);
625                 }
626
627                 [Test]
628                 public void ForEachTest ()
629                 {
630                         int i = 0;
631                         _list1.ForEach (delegate (int j) { i += j; });
632
633                         Assert.AreEqual (418, i);
634                 }
635
636                 [Test]
637                 public void FindLastIndexTest ()
638                 {
639                         int i = _list1.FindLastIndex (FindMultipleOfFour);
640                         Assert.AreEqual (6, i);
641
642                         i = _list1.FindLastIndex (5, FindMultipleOfFour);
643                         Assert.AreEqual (5, i);
644
645                         i = _list1.FindIndex (FindMultipleOfTwelve);
646                         Assert.AreEqual (-1, i);
647
648                         Assert.AreEqual (2, _list1.FindLastIndex (2, 3, l => true));
649                         Assert.AreEqual (2, _list1.FindLastIndex (2, 2, l => true));
650                         Assert.AreEqual (1, _list1.FindLastIndex (1, 2, l => true));
651                 }
652
653                 [Test]
654                 public void FindLastIndex_Invalid ()
655                 {
656                         try {
657                                 _list1.FindLastIndex (null);
658                                 Assert.Fail ("#1");
659                         } catch (ArgumentNullException) {
660                         }
661
662                         try {
663                                 _list1.FindLastIndex (-1, l => true);
664                                 Assert.Fail ("#2");
665                         } catch (ArgumentOutOfRangeException) {
666                         }
667
668                         try {
669                                 _list1.FindLastIndex (-1, 0, l => true);
670                                 Assert.Fail ("#2b");
671                         } catch (ArgumentOutOfRangeException) {
672                         }
673
674                         try {
675                                 _list1.FindLastIndex (0, -1, l => true);
676                                 Assert.Fail ("#3");
677                         } catch (ArgumentOutOfRangeException) {
678                         }
679
680                         try {
681                                 _list1.FindLastIndex (100, l => true);
682                                 Assert.Fail ("#4");
683                         } catch (ArgumentOutOfRangeException) {
684                         }
685
686                         try {
687                                 _list1.FindLastIndex (100, 0, l => true);
688                                 Assert.Fail ("#4b");
689                         } catch (ArgumentOutOfRangeException) {
690                         }
691
692                         try {
693                                 _list1.FindLastIndex (2, 4, l => true);
694                                 Assert.Fail ("#5");
695                         } catch (ArgumentOutOfRangeException) {
696                         }
697                 }
698
699                 [Test]
700                 public void RemoveTest ()
701                 {
702                         int count = _list1.Count;
703                         bool result = _list1.Remove (22);
704                         Assert.IsTrue (result);
705                         Assert.AreEqual (count - 1, _list1.Count);
706
707                         Assert.AreEqual (-1, _list1.IndexOf (22));
708
709                         result = _list1.Remove (0);
710                         Assert.IsFalse (result);
711                 }
712
713                 [Test]
714                 public void RemoveAllTest ()
715                 {
716                         int count = _list1.Count;
717                         int removedCount = _list1.RemoveAll (FindMultipleOfFour);
718                         Assert.AreEqual (4, removedCount);
719                         Assert.AreEqual (count - 4, _list1.Count);
720
721                         removedCount = _list1.RemoveAll (FindMultipleOfTwelve);
722                         Assert.AreEqual (0, removedCount);
723                         Assert.AreEqual (count - 4, _list1.Count);
724                 }
725
726                 [Test]
727                 public void RemoveAtTest ()
728                 {
729                         int count = _list1.Count;
730                         _list1.RemoveAt (0);
731                         Assert.AreEqual (count - 1, _list1.Count);
732                         Assert.AreEqual (50, _list1 [0]);
733                 }
734
735                 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
736                 public void RemoveOutOfRangeTest ()
737                 {
738                         _list1.RemoveAt (_list1.Count);
739                 }
740
741                 [Test]
742                 public void RemoveRangeTest ()
743                 {
744                         int count = _list1.Count;
745                         _list1.RemoveRange (1, 2);
746                         Assert.AreEqual (count - 2, _list1.Count);
747                         Assert.AreEqual (55, _list1 [0]);
748                         Assert.AreEqual (80, _list1 [1]);
749
750                         _list1.RemoveRange (0, 0);
751                         Assert.AreEqual (count - 2, _list1.Count);
752                 }
753
754                 [Test]
755                 public void RemoveRangeFromEmptyListTest ()
756                 {
757                         List<int> l = new List<int> ();
758                         l.RemoveRange (0, 0);
759                 }
760
761                 [Test, ExpectedException (typeof (ArgumentException))]
762                 public void RemoveRangeOutOfRangeTest ()
763                 {
764                         _list1.RemoveRange (1, _list1.Count);
765                 }
766
767                 [Test]
768                 public void ReverseTest ()
769                 {
770                         int count = _list1.Count;
771                         _list1.Reverse ();
772                         Assert.AreEqual (count, _list1.Count);
773
774                         Assert.AreEqual (63, _list1 [0]);
775                         Assert.AreEqual (55, _list1 [count - 1]);
776
777                         _list1.Reverse (0, 2);
778
779                         Assert.AreEqual (40, _list1 [0]);
780                         Assert.AreEqual (63, _list1 [1]);
781                 }
782
783                 [Test, ExpectedException (typeof (ArgumentException))]
784                 public void ReverseOutOfRangeTest ()
785                 {
786                         _list1.Reverse (1, _list1.Count);
787                 }
788
789                 [Test]
790                 public void ToArrayTest ()
791                 {
792                         int [] copiedContents = _list1.ToArray ();
793                         Assert.IsFalse (ReferenceEquals (copiedContents, _list1_contents));
794
795                         Assert.AreEqual (_list1.Count, copiedContents.Length);
796                         Assert.AreEqual (_list1 [0], copiedContents [0]);
797                 }
798
799                 [Test]
800                 public void TrimExcessTest ()
801                 {
802                         List <string> l = new List <string> ();
803                         l.Add ("foo");
804
805                         Assert.IsTrue (l.Count < l.Capacity);
806                         l.TrimExcess ();
807                         Assert.AreEqual (l.Count, l.Capacity);
808                 }
809
810                 bool IsPositive (int i)
811                 {
812                         return i >= 0;
813                 }
814
815                 [Test]
816                 public void TrueForAllTest ()
817                 {
818                         Assert.IsFalse (_list1.TrueForAll (FindMultipleOfFour));
819                         Assert.IsTrue (_list1.TrueForAll (IsPositive));
820                 }
821
822                 [Test, ExpectedException (typeof (ArgumentNullException))]
823                 public void TrueForAllNullTest ()
824                 {
825                         _list1.TrueForAll (null);
826                 }
827
828                 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
829                 public void CapacityOutOfRangeTest ()
830                 {
831                         _list1.Capacity = _list1.Count - 1;
832                 }
833
834                 [Test]
835                 public void BinarySearch_EmptyList ()
836                 {
837                         GenericComparer<int> comparer = new GenericComparer<int> ();
838                         List<int> l = new List<int> ();
839                         Assert.AreEqual (-1, l.BinarySearch (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 BinarySearch2_EmptyList ()
846                 {
847                         GenericComparer<int> comparer = new GenericComparer<int> ();
848                         List<int> l = new List<int> ();
849                         Assert.AreEqual (-1, l.BinarySearch (0, 0, 0, comparer), "BinarySearch");
850                         // bug 77030 - the comparer isn't called for an empty array/list
851                         Assert.IsFalse (comparer.Called, "Called");
852                 }
853
854                 [Test]
855                 public void AddRange_Bug77019 ()
856                 {
857                         List<int> l = new List<int> ();
858                         Dictionary<string, int> d = new Dictionary<string, int> ();
859                         l.AddRange (d.Values);
860                         Assert.AreEqual (0, l.Count, "Count");
861                 }
862
863                 [Test]
864                 public void VersionCheck_Add ()
865                 {
866                         List<int> list = new List<int> ();
867                         IEnumerator enumerator = list.GetEnumerator ();
868                         list.Add (5);
869
870                         try {
871                                 enumerator.MoveNext ();
872                                 Assert.Fail ("#1");
873                         } catch (InvalidOperationException) {
874                         }
875
876                         try {
877                                 enumerator.Reset ();
878                                 Assert.Fail ("#2");
879                         } catch (InvalidOperationException) {
880                         }
881
882                         enumerator = list.GetEnumerator ();
883                         enumerator.MoveNext ();
884                 }
885
886                 [Test]
887                 public void VersionCheck_AddRange ()
888                 {
889                         List<int> list = new List<int> ();
890                         IEnumerator enumerator = list.GetEnumerator ();
891                         list.AddRange (new int [] { 5, 7 });
892
893                         try {
894                                 enumerator.MoveNext ();
895                                 Assert.Fail ("#1");
896                         } catch (InvalidOperationException) {
897                         }
898
899                         try {
900                                 enumerator.Reset ();
901                                 Assert.Fail ("#2");
902                         } catch (InvalidOperationException) {
903                         }
904
905                         enumerator = list.GetEnumerator ();
906                         enumerator.MoveNext ();
907                 }
908
909                 [Test]
910                 public void VersionCheck_Clear ()
911                 {
912                         List<int> list = new List<int> ();
913                         IEnumerator enumerator = list.GetEnumerator ();
914                         list.Clear ();
915
916                         try {
917                                 enumerator.MoveNext ();
918                                 Assert.Fail ("#1");
919                         } catch (InvalidOperationException) {
920                         }
921
922                         try {
923                                 enumerator.Reset ();
924                                 Assert.Fail ("#2");
925                         } catch (InvalidOperationException) {
926                         }
927
928                         enumerator = list.GetEnumerator ();
929                         enumerator.MoveNext ();
930                 }
931
932                 [Test]
933                 public void VersionCheck_Insert ()
934                 {
935                         List<int> list = new List<int> ();
936                         IEnumerator enumerator = list.GetEnumerator ();
937                         list.Insert (0, 7);
938
939                         try {
940                                 enumerator.MoveNext ();
941                                 Assert.Fail ("#1");
942                         } catch (InvalidOperationException) {
943                         }
944
945                         try {
946                                 enumerator.Reset ();
947                                 Assert.Fail ("#2");
948                         } catch (InvalidOperationException) {
949                         }
950
951                         enumerator = list.GetEnumerator ();
952                         enumerator.MoveNext ();
953                 }
954
955                 [Test]
956                 public void VersionCheck_InsertRange ()
957                 {
958                         List<int> list = new List<int> ();
959                         IEnumerator enumerator = list.GetEnumerator ();
960                         list.InsertRange (0, new int [] { 5, 7 });
961
962                         try {
963                                 enumerator.MoveNext ();
964                                 Assert.Fail ("#1");
965                         } catch (InvalidOperationException) {
966                         }
967
968                         try {
969                                 enumerator.Reset ();
970                                 Assert.Fail ("#2");
971                         } catch (InvalidOperationException) {
972                         }
973
974                         enumerator = list.GetEnumerator ();
975                         enumerator.MoveNext ();
976                 }
977
978                 [Test]
979                 public void VersionCheck_Remove ()
980                 {
981                         List<int> list = new List<int> ();
982                         list.Add (5);
983                         IEnumerator enumerator = list.GetEnumerator ();
984                         // version number is not incremented if item does not exist in list
985                         list.Remove (7);
986                         enumerator.MoveNext ();
987                         list.Remove (5);
988
989                         try {
990                                 enumerator.MoveNext ();
991                                 Assert.Fail ("#1");
992                         } catch (InvalidOperationException) {
993                         }
994
995                         try {
996                                 enumerator.Reset ();
997                                 Assert.Fail ("#2");
998                         } catch (InvalidOperationException) {
999                         }
1000
1001                         enumerator = list.GetEnumerator ();
1002                         enumerator.MoveNext ();
1003                 }
1004
1005                 [Test]
1006                 public void VersionCheck_RemoveAll ()
1007                 {
1008                         List<int> list = new List<int> ();
1009                         list.Add (5);
1010                         IEnumerator enumerator = list.GetEnumerator ();
1011                         // version is not incremented if there are no items to remove
1012                         list.RemoveAll (FindMultipleOfFour);
1013                         enumerator.MoveNext ();
1014                         list.Add (4);
1015
1016                         enumerator = list.GetEnumerator ();
1017                         list.RemoveAll (FindMultipleOfFour);
1018
1019                         try {
1020                                 enumerator.MoveNext ();
1021                                 Assert.Fail ("#1");
1022                         } catch (InvalidOperationException) {
1023                         }
1024
1025                         try {
1026                                 enumerator.Reset ();
1027                                 Assert.Fail ("#2");
1028                         } catch (InvalidOperationException) {
1029                         }
1030
1031                         enumerator = list.GetEnumerator ();
1032                         enumerator.MoveNext ();
1033                 }
1034
1035                 [Test]
1036                 public void VersionCheck_RemoveAt ()
1037                 {
1038                         List<int> list = new List<int> ();
1039                         list.Add (5);
1040                         IEnumerator enumerator = list.GetEnumerator ();
1041                         list.RemoveAt (0);
1042
1043                         try {
1044                                 enumerator.MoveNext ();
1045                                 Assert.Fail ("#1");
1046                         } catch (InvalidOperationException) {
1047                         }
1048
1049                         try {
1050                                 enumerator.Reset ();
1051                                 Assert.Fail ("#2");
1052                         } catch (InvalidOperationException) {
1053                         }
1054
1055                         enumerator = list.GetEnumerator ();
1056                         enumerator.MoveNext ();
1057                 }
1058
1059                 [Test]
1060                 public void VersionCheck_RemoveRange ()
1061                 {
1062                         List<int> list = new List<int> ();
1063                         list.Add (5);
1064                         IEnumerator enumerator = list.GetEnumerator ();
1065                         // version is not incremented if count is zero
1066                         list.RemoveRange (0, 0);
1067                         enumerator.MoveNext ();
1068                         enumerator.Reset ();
1069                         list.RemoveRange (0, 1);
1070
1071                         try {
1072                                 enumerator.MoveNext ();
1073                                 Assert.Fail ("#1");
1074                         } catch (InvalidOperationException) {
1075                         }
1076
1077                         try {
1078                                 enumerator.Reset ();
1079                                 Assert.Fail ("#2");
1080                         } catch (InvalidOperationException) {
1081                         }
1082
1083                         enumerator = list.GetEnumerator ();
1084                         enumerator.MoveNext ();
1085                 }
1086
1087                 [Test, ExpectedException (typeof (InvalidOperationException))] // #699182
1088                 public void VersionCheck_Indexer ()
1089                 {
1090                         var list = new List<int> () { 0, 2, 3 };
1091                         var enumerator = list.GetEnumerator ();
1092
1093                         list [0] = 1;
1094
1095                         enumerator.MoveNext ();
1096                 }
1097
1098                 [Test]
1099                 public void VersionCheck_Reverse ()
1100                 {
1101                         List<int> list = new List<int> ();
1102                         IEnumerator enumerator = list.GetEnumerator ();
1103                         list.Reverse ();
1104
1105                         try {
1106                                 enumerator.MoveNext ();
1107                                 Assert.Fail ("#A1");
1108                         } catch (InvalidOperationException) {
1109                         }
1110
1111                         try {
1112                                 enumerator.Reset ();
1113                                 Assert.Fail ("#A2");
1114                         } catch (InvalidOperationException) {
1115                         }
1116
1117                         enumerator = list.GetEnumerator ();
1118                         list.Reverse (0, 0);
1119
1120                         try {
1121                                 enumerator.MoveNext ();
1122                                 Assert.Fail ("#B1");
1123                         } catch (InvalidOperationException) {
1124                         }
1125
1126                         try {
1127                                 enumerator.Reset ();
1128                                 Assert.Fail ("#B2");
1129                         } catch (InvalidOperationException) {
1130                         }
1131
1132                         enumerator = list.GetEnumerator ();
1133                         enumerator.MoveNext ();
1134                 }
1135
1136                 class SortTestComparer: IComparer<string> {
1137
1138                         public int Compare (string s1, string s2)
1139                         {
1140                                 return String.Compare (s1, s2);
1141                         }
1142                 }
1143
1144                 [Test]
1145                 public void Sort_Bug76361 ()
1146                 {
1147                         SortTestComparer comparer = new SortTestComparer ();
1148                         List<string> l = new List<string> ();
1149                         l.Add ("foo");
1150                         l.Add ("bar");
1151                         l.Sort (comparer);
1152                         Assert.AreEqual ("bar", l[0], "0");
1153                         Assert.AreEqual ("foo", l[1], "1");
1154                         Assert.AreEqual (2, l.Count, "Count");
1155                 }
1156
1157                 // for bug #77039 test case
1158                 class GenericIComparable: IComparable<GenericIComparable> {
1159                         private int _NumberToSortOn;
1160
1161                         public int NumberToSortOn {
1162                                 get { return _NumberToSortOn; }
1163                                 set { _NumberToSortOn = value; }
1164                         }
1165
1166                         public GenericIComparable (int val)
1167                         {
1168                                 _NumberToSortOn = val;
1169                         }
1170
1171                         public int CompareTo (GenericIComparable other)
1172                         {
1173                                 return NumberToSortOn.CompareTo (other.NumberToSortOn);
1174                         }
1175                 }
1176
1177                 [Test]
1178                 public void Sort_GenericIComparable_Bug77039 ()
1179                 {
1180                         List<GenericIComparable> l = new List<GenericIComparable> ();
1181                         l.Add (new GenericIComparable (2));
1182                         l.Add (new GenericIComparable (1));
1183                         l.Add (new GenericIComparable (3));
1184                         l.Sort ();
1185                         Assert.AreEqual (1, l[0].NumberToSortOn, "0");
1186                         Assert.AreEqual (2, l[1].NumberToSortOn, "1");
1187                         Assert.AreEqual (3, l[2].NumberToSortOn, "2");
1188                 }
1189
1190                 class NonGenericIComparable: IComparable {
1191                         private int _NumberToSortOn;
1192
1193                         public int NumberToSortOn {
1194                                 get { return _NumberToSortOn; }
1195                                 set { _NumberToSortOn = value; }
1196                         }
1197
1198                         public NonGenericIComparable (int val)
1199                         {
1200                                 _NumberToSortOn = val;
1201                         }
1202
1203                         public int CompareTo (object obj)
1204                         {
1205                                 return NumberToSortOn.CompareTo ((obj as NonGenericIComparable).NumberToSortOn);
1206                         }
1207                 }
1208
1209                 [Test]
1210                 public void Sort_NonGenericIComparable ()
1211                 {
1212                         List<NonGenericIComparable> l = new List<NonGenericIComparable> ();
1213                         l.Add (new NonGenericIComparable (2));
1214                         l.Add (new NonGenericIComparable (1));
1215                         l.Add (new NonGenericIComparable (3));
1216                         l.Sort ();
1217                         Assert.AreEqual (1, l[0].NumberToSortOn, "0");
1218                         Assert.AreEqual (2, l[1].NumberToSortOn, "1");
1219                         Assert.AreEqual (3, l[2].NumberToSortOn, "2");
1220                 }
1221
1222                 class NonComparable {
1223                 }
1224
1225                 [Test]
1226                 public void Sort_GenericNonIComparable ()
1227                 {
1228                         List<NonComparable> l = new List<NonComparable> ();
1229                         l.Sort ();
1230                         // no element -> no sort -> no exception
1231                         l.Add (new NonComparable ());
1232                         l.Sort ();
1233                         // one element -> no sort -> no exception
1234                 }
1235
1236                 [Test]
1237                 [ExpectedException (typeof (InvalidOperationException))]
1238                 public void Sort_GenericNonIComparable_2 ()
1239                 {
1240                         List<NonComparable> l = new List<NonComparable> ();
1241                         l.Add (new NonComparable ());
1242                         l.Add (new NonComparable ());
1243                         l.Sort ();
1244                         // two element -> sort -> exception!
1245                 }
1246                 
1247                 [Test]
1248                 public void IList_Contains_InvalidType()
1249                 {
1250                         List<string> list = new List<string>();
1251                         list.Add("foo");
1252                         Assert.IsFalse (((IList)list).Contains(new object()));
1253
1254                         Assert.IsFalse (((IList)_list1).Contains(null));
1255                 }
1256                 
1257                 [Test]
1258                 public void IList_IndexOf_InvalidType()
1259                 {
1260                         List<string> list = new List<string>();
1261                         list.Add("foo");
1262                         Assert.AreEqual (-1, ((IList)list).IndexOf(new object()));
1263
1264                         Assert.AreEqual (-1, ((IList)_list1).IndexOf(null));
1265                 }
1266
1267                 // for bug #77277 test case
1268                 [Test]
1269                 public void Test_ContainsAndIndexOf_EquatableItem ()
1270                 {
1271                         List<EquatableClass> list = new List<EquatableClass> ();
1272                         EquatableClass item0 = new EquatableClass (0);
1273                         EquatableClass item1 = new EquatableClass (1);
1274
1275                         list.Add (item0);
1276                         list.Add (item1);
1277                         list.Add (item0);
1278
1279                         Assert.AreEqual (true, list.Contains (item0), "#0");
1280                         Assert.AreEqual (true, list.Contains (new EquatableClass (0)), "#1");
1281                         Assert.AreEqual (0, list.IndexOf (item0), "#2");
1282                         Assert.AreEqual (0, list.IndexOf (new EquatableClass (0)), "#3");
1283                         Assert.AreEqual (2, list.LastIndexOf (item0), "#4");
1284                         Assert.AreEqual (2, list.LastIndexOf (new EquatableClass (0)), "#5");
1285                 }
1286
1287                 // for bug #81387 test case
1288                 [Test]
1289                 public void Test_Contains_After_Remove ()
1290                 {
1291                         List<int> list = new List<int> ();
1292             list.Add (2);
1293
1294             list.Remove (2);
1295
1296                         Assert.AreEqual (false, list.Contains (2), "#0");
1297                 }
1298                 
1299                 [Test]
1300                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
1301                 public void SetItem_OutOfRange()
1302                 {
1303                         List<string> list = new List<string>();
1304                         list[0] = "foo";
1305                 }
1306                 
1307                 [Test]
1308                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
1309                 public void SetItem_IList_OutOfRange()
1310                 {
1311                         IList<string> list = new List<string>();
1312                         list[0] = "foo";
1313                 }
1314
1315                 public class EquatableClass : IEquatable<EquatableClass>
1316                 {
1317                         int _x;
1318                         public EquatableClass (int x)
1319                         {
1320                                 _x = x;
1321                         }
1322
1323                         public bool Equals (EquatableClass other)
1324                         {
1325                                 return this._x == other._x;
1326                         }
1327                 }
1328
1329                 delegate void D ();
1330                 bool Throws (D d)
1331                 {
1332                         try {
1333                                 d ();
1334                                 return false;
1335                         } catch {
1336                                 return true;
1337                         }
1338                 }
1339
1340                 [Test]
1341                 // based on #491858, #517415
1342                 public void Enumerator_Current ()
1343                 {
1344                         var e1 = new List<int>.Enumerator ();
1345                         Assert.IsFalse (Throws (delegate { var x = e1.Current; }));
1346
1347                         var d = new List<int> ();
1348                         var e2 = d.GetEnumerator ();
1349                         Assert.IsFalse (Throws (delegate { var x = e2.Current; }));
1350                         e2.MoveNext ();
1351                         Assert.IsFalse (Throws (delegate { var x = e2.Current; }));
1352                         e2.Dispose ();
1353                         Assert.IsFalse (Throws (delegate { var x = e2.Current; }));
1354
1355                         var e3 = ((IEnumerable<int>) d).GetEnumerator ();
1356                         Assert.IsFalse (Throws (delegate { var x = e3.Current; }));
1357                         e3.MoveNext ();
1358                         Assert.IsFalse (Throws (delegate { var x = e3.Current; }));
1359                         e3.Dispose ();
1360                         Assert.IsFalse (Throws (delegate { var x = e3.Current; }));
1361
1362                         var e4 = ((IEnumerable) d).GetEnumerator ();
1363                         Assert.IsTrue (Throws (delegate { var x = e4.Current; }));
1364                         e4.MoveNext ();
1365                         Assert.IsTrue (Throws (delegate { var x = e4.Current; }));
1366                         ((IDisposable) e4).Dispose ();
1367                         Assert.IsTrue (Throws (delegate { var x = e4.Current; }));
1368                 }
1369
1370                 [Test]
1371                 public void Enumerator_Reset ()
1372                 {
1373                         var l = new List<int> () {
1374                                 4
1375                         };
1376
1377                         IEnumerator<int> e = l.GetEnumerator ();
1378                         Assert.IsTrue (e.MoveNext (), "#1");
1379                         Assert.AreEqual (4, e.Current, "#2");
1380                         e.Reset ();
1381                         Assert.AreEqual (0, e.Current, "#3");
1382                 }
1383
1384                 [Test] //bug #672907
1385                 public void ICollectionCopyToExceptions ()
1386                 {
1387                         var l = new List <int> ();
1388                         ICollection x = l;
1389                         try {
1390                                 x.CopyTo (null, 0);
1391                                 Assert.Fail ("#1");
1392                         } catch (Exception e) {
1393                                 Assert.IsTrue (e is ArgumentNullException, "#2");
1394                         }
1395
1396                         try {
1397                                 x.CopyTo (new int [10], -1);
1398                                 Assert.Fail ("#3");
1399                         } catch (Exception e) {
1400                                 Assert.IsTrue (e is ArgumentOutOfRangeException, "#4");
1401                         }
1402
1403                         try {
1404                                 x.CopyTo (new int [10, 1], 0);
1405                                 Assert.Fail ("#5");
1406                         } catch (Exception e) {
1407                                 Assert.IsTrue (e is ArgumentException, "#6");
1408                         }
1409
1410                         try {
1411                                 x.CopyTo (Array.CreateInstance (typeof (int), new int [] { 10 }, new int[] { 1 }), 0);
1412                                 Assert.Fail ("#7");
1413                         } catch (Exception e) {
1414                                 Assert.IsTrue (e is ArgumentException, "#8");
1415                         }
1416
1417                         l.Add (10); l.Add (20);
1418                         try {
1419                                 x.CopyTo (new int [1], 0);
1420                                 Assert.Fail ("#9");
1421                         } catch (Exception e) {
1422                                 Assert.IsTrue (e is ArgumentException, "#10");
1423                         }
1424                 }
1425
1426                 [Test]
1427                 public void LastIndexOfEmpty_2558 () {
1428                         var l = new List<int> ();
1429                         Assert.AreEqual (-1, l.IndexOf (-1));
1430                 }
1431
1432
1433 #region Enumerator mutability
1434
1435                 class Bar
1436                 {
1437                 }
1438
1439                 class Foo : IEnumerable<Bar>
1440                 {
1441                         Baz enumerator;
1442
1443                         public Foo ()
1444                         {
1445                                 enumerator = new Baz ();
1446                         }
1447
1448                         public IEnumerator<Bar> GetEnumerator ()
1449                         {
1450                                 return enumerator;
1451                         }
1452
1453                         IEnumerator IEnumerable.GetEnumerator ()
1454                         {
1455                                 return enumerator;
1456                         }
1457                 }
1458
1459                 class Baz : IEnumerator<Bar>
1460                 {
1461                         public bool DisposeWasCalled = false;
1462
1463                         public void Dispose ()
1464                         {
1465                                 DisposeWasCalled = true;
1466                         }
1467
1468                         public bool MoveNext ()
1469                         {
1470                                 return false; //assume empty collection
1471                         }
1472
1473                         public void Reset ()
1474                         {
1475                         }
1476
1477                         public Bar Current
1478                         {
1479                                 get { return null; }
1480                         }
1481
1482                         object IEnumerator.Current
1483                         {
1484                                 get { return Current; }
1485                         }
1486                 }
1487
1488                 [Test]
1489                 public void PremiseAboutDisposeBeingCalledWhenLooping ()
1490                 {
1491                         Foo enumerable = new Foo ();
1492                         Baz enumerator = enumerable.GetEnumerator () as Baz;
1493                         Assert.IsNotNull (enumerator);
1494                         Assert.AreEqual (false, enumerator.DisposeWasCalled);
1495                         foreach (var element in enumerable) ; //sic
1496                         Assert.AreEqual (true, enumerator.DisposeWasCalled);
1497                 }
1498
1499                 [Test]
1500                 public void TwoEnumeratorsOfTwoDifferentListsAreDifferent ()
1501                 {
1502                         var twoThree = new List<int> { 2, 3 };
1503                         var oneTwo = new List<int> { 2, 4 };
1504                         Assert.IsFalse (oneTwo.GetEnumerator ().Equals (twoThree.GetEnumerator ()));
1505                 }
1506
1507                 [Test]
1508                 public void TwoEnumeratorsOfTwoDifferentListsWithSameElementsAreDifferent ()
1509                 {
1510                         var twoThree = new List<int> { 2, 3 };
1511                         var anotherTwoThree = new List<int> { 2, 3 };
1512                         Assert.IsFalse(twoThree.GetEnumerator ().Equals (anotherTwoThree.GetEnumerator ()));
1513                 }
1514
1515                 [Test]
1516                 public void EnumeratorIsSameInSameListAfterSubsequentCalls ()
1517                 {
1518                         var enumerable = new List<Bar> ();
1519                         var enumerator = enumerable.GetEnumerator ();
1520                         var enumerator2 = enumerable.GetEnumerator ();
1521
1522                         Assert.IsFalse (ReferenceEquals (enumerator2, enumerator)); //because they are value-types
1523
1524                         Assert.IsTrue (enumerator2.Equals (enumerator));
1525                 }
1526
1527
1528                 [Test] // was bug in Mono 2.10.9
1529                 public void EnumeratorIsStillSameInSubsequentCallsEvenHavingADisposalInBetween ()
1530                 {
1531                         var enumerable = new List<Bar> ();
1532                         var enumerator = enumerable.GetEnumerator ();
1533                         enumerator.Dispose ();
1534                         var enumerator2 = enumerable.GetEnumerator ();
1535
1536                         Assert.IsFalse (ReferenceEquals (enumerator2, enumerator)); //because they are value-types
1537
1538                         Assert.IsTrue (enumerator2.Equals (enumerator));
1539                 }
1540
1541                 [Test]
1542                 public void EnumeratorIsObviouslyDifferentAfterListChanges ()
1543                 {
1544                         var enumerable = new List<Bar> ();
1545                         var enumerator = enumerable.GetEnumerator ();
1546                         enumerable.Add (new Bar ());
1547                         var enumerator2 = enumerable.GetEnumerator ();
1548
1549                         Assert.IsFalse (ReferenceEquals (enumerator2, enumerator)); //because they are value-types
1550
1551                         Assert.IsFalse (enumerator2.Equals (enumerator));
1552                 }
1553
1554                 [Test] // was bug in Mono 2.10.9
1555                 public void DotNetDoesntThrowObjectDisposedExceptionAfterSubsequentDisposes()
1556                 {
1557                         var enumerable = new List<Bar> ();
1558                         var enumerator = enumerable.GetEnumerator ();
1559                         Assert.AreEqual (false, enumerator.MoveNext ());
1560                         enumerator.Dispose();
1561                         Assert.AreEqual (false, enumerator.MoveNext ());
1562                 }
1563 #endregion
1564
1565
1566         }
1567 }
1568