[runtime] Fix Empty generic enumerator equality
[mono.git] / mcs / class / corlib / Test / System / ArrayTest.cs
1 // ArrayTest.cs - NUnit Test Cases for the System.Array class
2 //
3 // David Brandt (bucky@keystreams.com)
4 // Eduardo Garcia (kiwnix@yahoo.es)
5 // 
6 // (C) Ximian, Inc.  http://www.ximian.com
7 // Copyright (C) 2004 Novell (http://www.novell.com)
8 // 
9
10 using NUnit.Framework;
11 using System;
12 using System.Collections;
13 using System.Globalization;
14 using System.Reflection;
15 using System.Collections.Generic;
16
17 namespace MonoTests.System
18 {
19         //Auxiliary Things
20         enum enua  {hola,adios,mas,menos};
21
22         class AClass
23         {
24                 public AClass()
25                 {
26
27                 }
28         }
29
30         class BClass : AClass
31         {
32         }
33
34         class CClass : AClass
35         {
36         }
37
38         struct AStruct
39         {
40                 public string s;
41                 public string a;
42         }
43         
44         class DataEqual
45         {
46                 public override bool Equals (object obj)
47                 {
48                         return true;
49                 }
50
51                 public override int GetHashCode ()
52                 {
53                         return 0;
54                 }
55         }
56                 
57         //End Auxiliary Things
58
59 [TestFixture]
60 public class ArrayTest
61 {
62         char [] arrsort = {'d', 'b', 'f', 'e', 'a', 'c'};
63
64         interface I
65         {
66         }
67
68         class C
69         {
70         }
71
72         class DC : C
73         {
74         }
75
76         class DI : I
77         {
78         }
79
80         [Test]
81         public void TestIsFixedSize() {
82                 char[] a1 = {'a'};
83                 Assert.IsTrue (a1.IsFixedSize, "All arrays are fixed");
84         }
85         
86         [Test]
87         public void TestIsReadOnly() {
88                 char[] a1 = {'a'};
89                 Assert.IsTrue (!a1.IsReadOnly, "No array is readonly");
90         }
91
92         [Test]
93         public void TestIsSynchronized() {
94                 char[] a1 = {'a'};
95                 Assert.IsTrue (!a1.IsSynchronized, "No array is synchronized");
96         }
97
98         [Test]
99         public void TestLength() {
100                 {
101                         char[] a1 = { };
102                         Assert.AreEqual (0, a1.Length, "Zero length array");
103                 }
104                 {
105                         char[] a1 = {'c'};
106                         Assert.AreEqual (1, a1.Length, "One-length array");
107                 }
108                 {
109                         char[] a1 = {'c', 'c'};
110                         Assert.AreEqual (2, a1.Length, "Two-length array");
111                 }
112         }
113
114         [Test]
115         public void TestRank() {
116                 char[] a1 = { 'c', 'd', 'e' };
117                 Assert.AreEqual (1, a1.Rank, "Rank one");
118
119                 char[,] a2 = new Char[3,3];
120                 Assert.AreEqual (2, a2.Rank, "Rank two");
121
122                 char[,,] a3 = new Char[3,3,3];
123                 Assert.AreEqual (3, a3.Rank, "Rank three");
124         }
125
126         [Test]
127         public void TestBinarySearch1() {
128                 bool errorThrown = false;
129                 try {
130                         Array.BinarySearch(null, "blue");
131                 } catch (ArgumentNullException) {
132                         errorThrown = true;
133                 }
134                 Assert.IsTrue (errorThrown, "#B01");
135                 errorThrown = false;
136                 try {
137                         char[,] c1 = new Char[2,2];
138                         Array.BinarySearch(c1, "needle");
139                 } catch (RankException) {
140                         errorThrown = true;
141                 }
142                 Assert.IsTrue (errorThrown, "#B02");
143
144                 {
145                         char[] arr = {'a', 'b', 'b', 'c', 'c', 'c', 'd', 'd'};
146                         Assert.IsTrue (Array.BinarySearch(arr, 'c') >= 3, "#B05");
147                         Assert.IsTrue (Array.BinarySearch(arr, 'c') < 6, "#B06");
148                 }
149                 {
150                         char[] arr = {'a', 'b', 'b', 'd', 'd', 'd', 'e', 'e'};
151                         Assert.AreEqual (-4, Array.BinarySearch(arr, 'c'), "#B07");
152                 }
153                 {
154                         char[] arr = {'a', 'b', 'b', 'c', 'c', 'c', 'd', 'd'};
155                         Assert.AreEqual (-9, Array.BinarySearch(arr, 'e'), "#B08");
156                 }
157         }
158
159         [Test]
160         public void TestBinarySearch2() {
161                 bool errorThrown = false;
162                 try {
163                         Array.BinarySearch(null, 0, 1, "blue");
164                 } catch (ArgumentNullException) {
165                         errorThrown = true;
166                 }
167                 Assert.IsTrue (errorThrown, "#B20");
168                 errorThrown = false;
169                 try {
170                         char[,] c1 = new Char[2,2];
171                         Array.BinarySearch(c1, 0, 1, "needle");
172                 } catch (RankException) {
173                         errorThrown = true;
174                 }
175                 Assert.IsTrue (errorThrown, "#B21");
176                 errorThrown = false;
177                 try {
178                         char[] c1 = {'a'};
179                         Array.BinarySearch(c1, -1, 1, 'a');
180                 } catch (ArgumentOutOfRangeException) {
181                         errorThrown = true;
182                 }
183                 Assert.IsTrue (errorThrown, "#B22");
184                 errorThrown = false;
185                 try {
186                         char[] c1 = {'a'};
187                         Array.BinarySearch(c1, 0, -1, 'a');
188                 } catch (ArgumentOutOfRangeException) {
189                         errorThrown = true;
190                 }
191                 Assert.IsTrue (errorThrown, "#B23");
192                 errorThrown = false;
193                 try {
194                         char[] c1 = {'a'};
195                         Array.BinarySearch(c1, 0, 4, 'a');
196                 } catch (ArgumentException) {
197                         errorThrown = true;
198                 }
199                 Assert.IsTrue (errorThrown, "#B24");
200
201                 {
202                         char[] arr = {'z', 'z', 'a', 'b', 'b', 'c', 'c', 'c', 'd', 'd'};
203                         Assert.IsTrue (Array.BinarySearch(arr, 2, 8, 'c') >= 5, "#B26");
204                         Assert.IsTrue (Array.BinarySearch(arr, 2, 8, 'c') < 8, "#B27");
205                 }
206                 {
207                         char[] arr = {'z', 'z', 'a', 'b', 'b', 'd', 'd', 'd', 'e', 'e'};
208                         Assert.AreEqual (-6, Array.BinarySearch(arr, 2, 8, 'c'), "#B28");
209                 }
210                 {
211                         char[] arr = {'z', 'z', 'a', 'b', 'b', 'c', 'c', 'c', 'd', 'd'};
212                         Assert.AreEqual (-11, Array.BinarySearch(arr, 2, 8, 'e'), "#B29");
213                 }
214         }
215
216         public void TestBinarySearch3()
217         {
218                 int[] array = new int[100];
219
220                 for (int i = 0; i < 100; i++)
221                         array[i] = 10;
222
223                 Assert.AreEqual (49, Array.BinarySearch(array, 10), "#B30");
224         }
225
226         [Test]
227         public void BinarySearch_NullValue () 
228         {
229                 int[] array = new int[1];
230                 Assert.AreEqual (-1, Array.BinarySearch (array, null), "I=a,o");
231                 Assert.AreEqual (-1, Array.BinarySearch (array, null, null), "I=a,o,c");
232                 Assert.AreEqual (-1, Array.BinarySearch (array, 0, 1, null), "I=a,i,i,o");
233                 Assert.AreEqual (-1, Array.BinarySearch (array, 0, 1, null, null), "I=a,i,i,o,c");
234
235                 object[] o = new object [3] { this, this, null };
236                 Assert.AreEqual (-1, Array.BinarySearch (o, null), "O=a,o");
237                 Assert.AreEqual (-1, Array.BinarySearch (o, null, null), "O=a,o,c");
238                 Assert.AreEqual (-1, Array.BinarySearch (o, 0, 3, null), "O=a,i,i,o");
239                 Assert.AreEqual (-1, Array.BinarySearch (o, 0, 3, null, null), "O=a,i,i,o,c");
240         }
241
242         class TestComparer7 : IComparer<int>
243         {
244                 public int Compare (int x, int y)
245                 {
246                         if (y != 7)
247                                 throw new ApplicationException ();
248
249                         return x.CompareTo (y);
250                 }
251         }
252
253         [Test]
254         public void BinarySearch_WithComparer ()
255         {
256                 var a = new int[] { 2, 6, 9 };
257                 Assert.AreEqual (-3, Array.BinarySearch (a, 7, new TestComparer7 ()));
258         }
259
260         [Test]
261         public void TestClear() {
262                 bool errorThrown = false;
263                 try {
264                         Array.Clear(null, 0, 1);
265                 } catch (ArgumentNullException) {
266                         errorThrown = true;
267                 }
268                 Assert.IsTrue (errorThrown, "#C01");
269
270                 int[] i1 = { 1, 2, 3, 4 };
271                 {
272                         int[] compare = {1,2,3,4};
273                         Assert.AreEqual (compare[0], i1[0], "#C02");
274                         Assert.AreEqual (compare[1], i1[1], "#C03");
275                         Assert.AreEqual (compare[2], i1[2], "#C04");
276                         Assert.AreEqual (compare[3], i1[3], "#C05");
277                 }
278                 Array.Clear(i1, 3, 1);
279                 {
280                         int[] compare = {1,2,3,0};
281                         Assert.AreEqual (compare[0], i1[0], "#C06");
282                         Assert.AreEqual (compare[1], i1[1], "#C07");
283                         Assert.AreEqual (compare[2], i1[2], "#C08");
284                         Assert.AreEqual (compare[3], i1[3], "#C09");
285                 }
286                 Array.Clear(i1, 1, 1);
287                 {
288                         int[] compare = {1,0,3,0};
289                         Assert.AreEqual (compare[0], i1[0], "#C10");
290                         Assert.AreEqual (compare[1], i1[1], "#C11");
291                         Assert.AreEqual (compare[2], i1[2], "#C12");
292                         Assert.AreEqual (compare[3], i1[3], "#C13");
293                 }
294                 Array.Clear(i1, 1, 3);
295                 {
296                         int[] compare = {1,0,0,0};
297                         Assert.AreEqual (compare[0], i1[0], "#C14");
298                         Assert.AreEqual (compare[1], i1[1], "#C15");
299                         Assert.AreEqual (compare[2], i1[2], "#C16");
300                         Assert.AreEqual (compare[3], i1[3], "#C17");
301                 }
302
303                 string[] s1 = { "red", "green", "blue" };
304                 Array.Clear(s1, 0, 3);
305                 {
306                         string[] compare = {null, null, null};
307                         Assert.AreEqual (compare[0], s1[0], "#C18");
308                         Assert.AreEqual (compare[1], s1[1], "#C19");
309                         Assert.AreEqual (compare[2], s1[2], "#C20");
310                 }
311         }
312
313         [Test]
314         public void TestClone() {
315                 char[] c1 = {'a', 'b', 'c'};
316                 char[] c2 = (char[])c1.Clone();
317                 Assert.AreEqual (c1[0], c2[0], "#D01");
318                 Assert.AreEqual (c1[1], c2[1], "#D02");
319                 Assert.AreEqual (c1[2], c2[2], "#D03");
320
321                 char[] d10 = {'a', 'b'};
322                 char[] d11 = {'a', 'c'};
323                 char[] d12 = {'b', 'c'};
324                 char[][] d1 = {d10, d11, d12};
325                 char[][] d2 = (char[][])d1.Clone();
326                 Assert.AreEqual (d1[0], d2[0], "#D04");
327                 Assert.AreEqual (d1[1], d2[1], "#D05");
328                 Assert.AreEqual (d1[2], d2[2], "#D06");
329
330                 d1[0][0] = 'z';
331                 Assert.AreEqual (d1[0], d2[0], "#D07");
332         }
333
334         [Test]
335         public void TestMemberwiseClone () {
336                 int[] array = new int[] { 1, 2, 3 };
337                 MethodBase mi = array.GetType ().GetMethod("MemberwiseClone",
338                                                                                                    BindingFlags.Instance | BindingFlags.NonPublic);
339                 int[] res = (int[])mi.Invoke (array, null);
340                 Assert.AreEqual (3, res.Length);
341         }
342
343         [Test] public void TestIndexer ()
344         {
345                 int [] a = new int [10];
346                 IList b = a;
347                 try {
348                         object c = b [-1];
349                         Assert.Fail ("IList.this [-1] should throw");
350                 } catch (IndexOutOfRangeException) {
351                         // Good
352                 } catch (Exception){
353                         Assert.Fail ("Should have thrown an IndexOutOfRangeException");
354                 }
355         }
356                 
357         [Test]
358         public void TestCopy() {
359                 {
360                         bool errorThrown = false;
361                         try {
362                                 Char[] c1 = {};
363                                 Array.Copy(c1, null, 1);
364                         } catch (ArgumentNullException) {
365                                 errorThrown = true;
366                         }
367                         Assert.IsTrue (errorThrown, "#E01");
368                 }
369                 {
370                         bool errorThrown = false;
371                         try {
372                                 Char[] c1 = {};
373                                 Array.Copy(null, c1, 1);
374                         } catch (ArgumentNullException) {
375                                 errorThrown = true;
376                         }
377                         Assert.IsTrue (errorThrown, "#E02");
378                 }
379                 {
380                         bool errorThrown = false;
381                         try {
382                                 Char[] c1 = new Char[1];
383                                 Char[,] c2 = new Char[1,1];
384                                 Array.Copy(c1, c2, 1);
385                         } catch (RankException) {
386                                 errorThrown = true;
387                         }
388                         Assert.IsTrue (errorThrown, "#E03");
389                 }
390                 {
391                         bool errorThrown = false;
392                         try {
393                                 Char[] c1 = new Char[1];
394                                 string[] s1 = new String[1];
395                                 Array.Copy(c1, s1, 1);
396                         } catch (ArrayTypeMismatchException) {
397                                 errorThrown = true;
398                         }
399                         Assert.IsTrue (errorThrown, "#E04");
400                 }
401                 {
402                         bool errorThrown = false;
403                         try {
404                                 Char[] c1 = new Char[1];
405                                 Object[] o1 = new Object[1];
406                                 o1[0] = "hello";
407                                 Array.Copy(o1, c1, 1);
408                         } catch (InvalidCastException) {
409                                 errorThrown = true;
410                         }
411                         Assert.IsTrue (errorThrown, "#E05");
412                 }
413                 {
414                         bool errorThrown = false;
415                         try {
416                                 Char[] c1 = new Char[1];
417                                 Char[] c2 = new Char[1];
418                                 Array.Copy(c1, c2, -1);
419                         } catch (ArgumentOutOfRangeException) {
420                                 errorThrown = true;
421                         }
422                         Assert.IsTrue (errorThrown, "#E06");
423                 }
424                 {
425                         bool errorThrown = false;
426                         try {
427                                 Char[] c1 = new Char[1];
428                                 Char[] c2 = new Char[2];
429                                 Array.Copy(c1, c2, 2);
430                         } catch (ArgumentException) {
431                                 errorThrown = true;
432                         }
433                         Assert.IsTrue (errorThrown, "#E07");
434                 }
435                 {
436                         bool errorThrown = false;
437                         try {
438                                 Char[] c1 = new Char[1];
439                                 Char[] c2 = new Char[2];
440                                 Array.Copy(c2, c1, 2);
441                         } catch (ArgumentException) {
442                                 errorThrown = true;
443                         }
444                         Assert.IsTrue (errorThrown, "#E08");
445                 }
446
447                 char[] orig = {'a', 'b', 'd', 'a'};
448                 char[] copy = new Char[4];
449                 Array.Copy(orig, copy, 4);
450                 for (int i = 0; i < orig.Length; i++) {
451                         Assert.AreEqual (orig[i], copy[i], "#E09(" + i + ")");
452                 }
453                 Array.Clear(copy, 0, copy.Length);
454                 for (int i = 0; i < orig.Length; i++) {
455                         Assert.AreEqual ((char)0, copy[i], "#E10(" + i + ")");
456                 }
457                 Array.Copy(orig, copy, 2);
458                 Assert.AreEqual (orig[0], copy[0], "#E11");
459                 Assert.AreEqual (orig[1], copy[1], "#E12");
460                 Assert.IsTrue (orig[2] != copy[2], "#E13");
461                 Assert.IsTrue (orig[3] != copy[3], "#E14");
462         }
463
464         [Test]
465         public void TestCopy2() {
466                 {
467                         bool errorThrown = false;
468                         try {
469                                 Char[] c1 = new Char[2];
470                                 Char[] c2 = new Char[2];
471                                 Array.Copy(c2, 1, c1, 0, 2);
472                         } catch (ArgumentException) {
473                                 errorThrown = true;
474                         }
475                         Assert.IsTrue (errorThrown, "#E31");
476                 }
477                 {
478                         bool errorThrown = false;
479                         try {
480                                 Char[] c1 = new Char[2];
481                                 Char[] c2 = new Char[2];
482                                 Array.Copy(c2, 0, c1, 1, 2);
483                         } catch (ArgumentException) {
484                                 errorThrown = true;
485                         }
486                         Assert.IsTrue (errorThrown, "#E32");
487                 }
488                 
489                 char[] orig = {'a', 'b', 'd', 'a'};
490                 char[] copy = new Char[4];
491                 Array.Copy(orig, 1, copy, 1, 3);
492                 Assert.IsTrue (copy[0] != orig[0], "#E33");
493                 for (int i = 1; i < orig.Length; i++) {
494                         Assert.AreEqual (orig[i], copy[i], "#E34(" + i + ")");
495                 }
496                 Array.Clear(copy, 0, copy.Length);
497                 Array.Copy(orig, 1, copy, 0, 2);
498                 Assert.AreEqual (orig[1], copy[0], "#E35");
499                 Assert.AreEqual (orig[2], copy[1], "#E36");
500                 Assert.IsTrue (copy[2] != orig[2], "#E37");
501                 Assert.IsTrue (copy[3] != orig[3], "#E38");
502         }
503
504         [Test]
505         public void Copy_InvalidCast () {
506                 object[] arr1 = new object [10];
507                 Type[] arr2 = new Type [10];
508                 arr1 [0] = new object ();
509
510                 try {
511                         Array.Copy (arr1, 0, arr2, 0, 10);
512                         Assert.Fail ("#1");
513                 } catch (InvalidCastException) {
514                 }
515
516                 var arr1_2 = new I [1] { new DI () };
517                 var arr2_2 = new C [1] { new DC () };
518                 try {
519                         Array.Copy (arr2_2, arr1_2, 1);
520                         Assert.Fail ("#1");
521                 } catch (InvalidCastException) {
522                 }
523         }
524
525         [Test]
526         public void TestCopyTo() {
527                 {
528                         bool errorThrown = false;
529                         try {
530                                 Char[] c1 = new Char[2];
531                                 c1.CopyTo(null, 2);
532                         } catch (ArgumentNullException) {
533                                 errorThrown = true;
534                         }
535                         Assert.IsTrue (errorThrown, "#E61");
536                 }
537                 {
538                         bool errorThrown = false;
539                         try {
540                                 Char[] c1 = new Char[2];
541                                 Char[,] c2 = new Char[2,2];
542                                 c1.CopyTo(c2, 2);
543                         } catch (ArgumentException) {
544                                 errorThrown = true;
545                         }
546                         Assert.IsTrue (errorThrown, "#E62");
547                 }
548                 {
549                         bool errorThrown = false;
550                         try {
551                                 Char[,] c1 = new Char[2,2];
552                                 Char[] c2 = new Char[2];
553                                 c1.CopyTo(c2, -1);
554                         } catch (RankException) {
555                                 errorThrown = true;
556                         }
557                         Assert.IsTrue (errorThrown, "#E63");
558                 }
559                 {
560                         bool errorThrown = false;
561                         try {
562                                 Char[,] c1 = new Char[2,2];
563                                 Char[] c2 = new Char[2];
564                                 c1.CopyTo(c2, 2);
565                         } catch (RankException) {
566                                 errorThrown = true;
567                         }
568                         Assert.IsTrue (errorThrown, "#E64");
569                 }
570                 {
571                         bool errorThrown = false;
572                         try {
573                                 Char[] c1 = new Char[2];
574                                 Char[] c2 = new Char[2];
575                                 c1.CopyTo(c2, -1);
576                         } catch (ArgumentOutOfRangeException) {
577                                 errorThrown = true;
578                         }
579                         Assert.IsTrue (errorThrown, "#E65");
580                 }
581                 {
582                         bool errorThrown = false;
583                         try {
584                                 Char[] c1 = new Char[2];
585                                 Char[] c2 = new Char[2];
586                                 c1.CopyTo(c2, 3);
587                         } catch (ArgumentException) {
588                                 errorThrown = true;
589                         }
590                         Assert.IsTrue (errorThrown, "#E66");
591                 }
592                 {
593                         bool errorThrown = false;
594                         try {
595                                 Char[] c1 = new Char[2];
596                                 Char[] c2 = new Char[2];
597                                 c1.CopyTo(c2, 1);
598                         } catch (ArgumentException) {
599                                 errorThrown = true;
600                         }
601                         Assert.IsTrue (errorThrown, "#E67");
602                 }
603
604                 {
605                         bool errorThrown = false;
606                         try {
607                                 String[] c1 = new String[2];
608                                 // TODO: this crashes mono if there are null
609                                 // values in the array.
610                                 c1[1] = "hey";
611                                 c1[0] = "you";
612                                 Char[] c2 = new Char[2];
613                                 c2[1] = 'a';
614                                 c2[0] = 'z';
615                                 c1.CopyTo(c2, 0);
616                         } catch (ArrayTypeMismatchException) {
617                                 errorThrown = true;
618                         }
619                         Assert.IsTrue (errorThrown, "#E68");
620                 }
621
622                 Char[] orig = {'a', 'b', 'c', 'd'};
623                 Char[] copy = new Char[10];
624                 Array.Clear(copy, 0, copy.Length);
625                 orig.CopyTo(copy, 3);
626                 Assert.AreEqual ((char)0, copy[0], "#E69");
627                 Assert.AreEqual ((char)0, copy[1], "#E70");
628                 Assert.AreEqual ((char)0, copy[2], "#E71");
629                 Assert.AreEqual (orig[0], copy[3], "#E72");
630                 Assert.AreEqual (orig[1], copy[4], "#E73");
631                 Assert.AreEqual (orig[2], copy[5], "#E74");
632                 Assert.AreEqual (orig[3], copy[6], "#E75");
633                 Assert.AreEqual ((char)0, copy[7], "#E76");
634                 Assert.AreEqual ((char)0, copy[8], "#E77");
635                 Assert.AreEqual ((char)0, copy[9], "#E78");
636
637                 {
638                         // The following is valid and must not throw an exception.
639                         bool errorThrown = false;
640                         try {
641                                 int[] src = new int [0];
642                                 int[] dest = new int [0];
643                                 src.CopyTo (dest, 0);
644                         } catch (ArgumentException) {
645                                 errorThrown = true;
646                         }
647                         Assert.IsTrue (!errorThrown, "#E79");
648                 }
649
650                 {
651                         // bug #38812
652                         bool errorThrown = false;
653                         try {
654                                 CClass[] src = new CClass [] { new CClass () };
655                                 BClass[] dest = new BClass [1];
656
657                                 src.CopyTo (dest, 0);
658
659                         } catch (ArrayTypeMismatchException) {
660                                 errorThrown = true;
661                         }
662                         Assert.IsTrue (errorThrown, "#E80");
663                 }
664         }
665
666         [Test]
667         public void TestCreateInstance() {
668                 {
669                         bool errorThrown = false;
670                         try {
671                                 Array.CreateInstance(null, 12);
672                         } catch (ArgumentNullException) {
673                                 errorThrown = true;
674                         }
675                         Assert.IsTrue (errorThrown, "#F01");
676                 }
677                 {
678                         bool errorThrown = false;
679                         try {
680                                 Array.CreateInstance(Type.GetType("System.Char"), -3);
681                         } catch (ArgumentOutOfRangeException) {
682                                 errorThrown = true;
683                         }
684                         Assert.IsTrue (errorThrown, "#F02");
685                 }
686                 {
687                         bool errorThrown = false;
688                         try {
689                                 Array.CreateInstance(Type.GetType("System.Char"), (int [])null);
690                         } catch (ArgumentNullException) {
691                                 errorThrown = true;
692                         }
693                         Assert.IsTrue (errorThrown, "#F03a");
694                 }
695
696                 {
697                         bool errorThrown = false;
698                         try {
699                                 Array.CreateInstance(Type.GetType("System.Char"), (int [])null);
700                         } catch (ArgumentNullException) {
701                                 errorThrown = true;
702                         }
703                         Assert.IsTrue (errorThrown, "#F03b");
704                 }
705                 {
706                         bool errorThrown = false;
707                         try {
708                                 Array.CreateInstance(Type.GetType("System.Char"), null, null);
709                         } catch (ArgumentNullException) {
710                                 errorThrown = true;
711                         }
712                         Assert.IsTrue (errorThrown, "#F04");
713                 }
714                 {
715                         bool errorThrown = false;
716                         try {
717                                 int[] lengths = new int [0];
718                                 Array.CreateInstance(Type.GetType("System.Char"), lengths);
719                         } catch (ArgumentException) {
720                                 errorThrown = true;
721                         }
722                         Assert.IsTrue (errorThrown, "#F05");
723                 }
724                 {
725                         bool errorThrown = false;
726                         try {
727                                 int[] lengths = new int [1];
728                                 int[] bounds = new int [2];
729                                 Array.CreateInstance(Type.GetType("System.Char"), lengths, bounds);
730                                 errorThrown = true;
731                         } catch (ArgumentException) {
732                                 errorThrown = true;
733                         }
734                         Assert.IsTrue (errorThrown, "#F06");
735                 }
736
737                 char[] c1 = (char[])Array.CreateInstance(Type.GetType("System.Char"), 12);
738                 Assert.AreEqual (12, c1.Length, "#F07");
739
740                 Array c2 = Array.CreateInstance(Type.GetType("System.Char"), 12, 5);
741                 Assert.AreEqual (2, c2.Rank, "#F08");
742                 Assert.AreEqual (60, c2.Length, "#F09");
743
744
745                 {
746                         int[] lengths = { 3 };
747                         int[] bounds = { 5 };
748                         int[] src = { 512, 718, 912 };
749                         Array array = Array.CreateInstance(typeof(int), lengths, bounds);
750
751                         Assert.AreEqual (3, array.Length, "#F10");
752                         Assert.AreEqual (5, array.GetLowerBound(0), "#F11");
753                         Assert.AreEqual (7, array.GetUpperBound(0), "#F12");
754
755                         src.CopyTo (array, 5);
756
757                         for (int i = 0; i < src.Length; i++)
758                                 Assert.AreEqual (src[i], array.GetValue(i+5), "#F13(" + i + ")");
759                 }
760
761                 // Test that a 1 dimensional array with 0 lower bound is the
762                 // same as an szarray
763                 Type szarrayType = new int [10].GetType ();
764                 Assert.IsTrue (szarrayType == (Array.CreateInstance (typeof (int), new int[] {1}, new int[] {0})).GetType ());
765                 Assert.IsTrue (szarrayType != (Array.CreateInstance (typeof (int), new int[] {1}, new int[] {1})).GetType ());
766         }
767         
768         [Test]
769         [ExpectedException (typeof (ArgumentNullException))]
770         public void TestCreateInstance2 ()
771         {
772                 Array.CreateInstance (typeof (Int32), (int[])null);
773         }
774
775         [Test]
776         [ExpectedException (typeof (ArgumentNullException))]
777         public void TestCreateInstance2b ()
778         {
779                 Array.CreateInstance (typeof (Int32), (long[])null);
780         }
781
782         [Test]
783         public void CreateInstanceVoid ()
784         {
785                 Assert.Throws<NotSupportedException> (delegate () {
786                                 Array.CreateInstance (typeof (void), 1);
787                         });
788         }
789
790         [Test]
791         public void TestGetEnumerator() {
792                 String[] s1 = {"this", "is", "a", "test"};
793                 IEnumerator en = s1.GetEnumerator ();
794                 Assert.IsNotNull (en, "#G01");
795
796                 Assert.IsTrue (en.MoveNext (), "#G02");
797                 Assert.AreEqual ("this", en.Current, "#G03");
798                 Assert.IsTrue (en.MoveNext (), "#G04");
799                 Assert.AreEqual ("is", en.Current, "#G05");
800                 Assert.IsTrue (en.MoveNext (), "#G06");
801                 Assert.AreEqual ("a", en.Current, "#G07");
802                 Assert.IsTrue (en.MoveNext (), "#G08");
803                 Assert.AreEqual ("test", en.Current, "#G09");
804                 Assert.IsTrue (!en.MoveNext (), "#G10");
805
806                 en.Reset ();
807                 Assert.IsTrue (en.MoveNext (), "#G11");
808                 Assert.AreEqual ("this", en.Current, "#G12");
809
810                 // mutation does not invalidate array enumerator!
811                 s1.SetValue ("change", 1);
812                 Assert.IsTrue (en.MoveNext (), "#G13");
813                 Assert.AreEqual ("change", en.Current, "#G14");
814         }
815
816         [Test]
817         public void TestGetEnumeratorMultipleDimension() {
818                 String[,] s1 = {{"this", "is"}, {"a", "test"}};
819                 IEnumerator en = s1.GetEnumerator ();
820                 Assert.IsNotNull (en, "#AA01");
821
822                 Assert.IsTrue (en.MoveNext (), "#AA02");
823                 Assert.AreEqual ("this", en.Current, "#AA03");
824                 Assert.IsTrue (en.MoveNext (), "#AA04");
825                 Assert.AreEqual ("is", en.Current, "#AA05");
826                 Assert.IsTrue (en.MoveNext (), "#AA06");
827                 Assert.AreEqual ("a", en.Current, "#AA07");
828                 Assert.IsTrue (en.MoveNext (), "#AA08");
829                 Assert.AreEqual ("test", en.Current, "#AA09");
830                 Assert.IsTrue (!en.MoveNext (), "#AA10");
831
832                 en.Reset ();
833                 Assert.IsTrue (en.MoveNext (), "#AA11");
834                 Assert.AreEqual ("this", en.Current, "#AA12");
835
836                 int[] idxs = {0,1};
837                 // mutation does not invalidate array enumerator!
838                 s1.SetValue ("change", idxs);
839                 Assert.IsTrue (en.MoveNext (), "#AA13");
840                 Assert.AreEqual ("change", en.Current, "#AA14");
841         }
842
843         [Test]
844         public void TestGetEnumeratorNonZeroLowerBounds() {
845                 int[] myLengthsArray = new int[2] { 3, 5 };
846                 int[] myBoundsArray = new int[2] { 2, 3 };
847
848                 Array myArray=Array.CreateInstance( typeof(String), myLengthsArray, myBoundsArray );
849                 for ( int i = myArray.GetLowerBound(0); i <= myArray.GetUpperBound(0); i++ )
850                         for ( int j = myArray.GetLowerBound(1); j <= myArray.GetUpperBound(1); j++ )  {
851                                 int[] myIndicesArray = new int[2] { i, j };
852                                 myArray.SetValue( Convert.ToString(i) + j, myIndicesArray );
853                         }
854                 IEnumerator en = myArray.GetEnumerator ();
855                 Assert.IsNotNull (en, "#AB01");
856
857                 // check the first couple of values
858                 Assert.IsTrue (en.MoveNext (), "#AB02");
859                 Assert.AreEqual ("23", en.Current, "#AB03");
860                 Assert.IsTrue (en.MoveNext (), "#AB04");
861                 Assert.AreEqual ("24", en.Current, "#AB05");
862
863                 // then check the last element's value
864                 string lastElement;
865                 do {  
866                         lastElement = (string)en.Current;
867                 } while (en.MoveNext());
868                 Assert.AreEqual ("47", lastElement, "#AB06");
869         }
870
871         [Test]
872         public void TestIList_Add () {
873                 int[] myLengthsArray = new int[2] { 3, 5 };
874                 int[] myBoundsArray = new int[2] { 2, 3 };
875
876                 Array myArray=Array.CreateInstance ( typeof(String), myLengthsArray, myBoundsArray );
877                 try {
878                         ((IList)myArray).Add ("can not");
879                         Assert.Fail ("IList.Add should throw");
880                 }
881                 catch (NotSupportedException) {
882                         return;
883                 }
884                 catch (Exception) {
885                         Assert.Fail ("IList.Add threw wrong exception type");
886                 }
887
888                 Assert.Fail ("IList.Add shouldn't get this far");
889         }
890
891         [Test]
892         public void TestIList_Insert () {
893                 int[] myLengthsArray = new int[2] { 3, 5 };
894                 int[] myBoundsArray = new int[2] { 2, 3 };
895
896                 Array myArray=Array.CreateInstance ( typeof(String), myLengthsArray, myBoundsArray );
897                 try {
898                         ((IList)myArray).Insert (0, "can not");
899                         Assert.Fail ("IList.Insert should throw");
900                 }
901                 catch (NotSupportedException) {
902                         return;
903                 }
904                 catch (Exception) {
905                         Assert.Fail ("IList.Insert threw wrong exception type");
906                 }
907
908                 Assert.Fail ("IList.Insert shouldn't get this far");
909         }
910
911         [Test]
912         public void TestIList_Remove () {
913                 int[] myLengthsArray = new int[2] { 3, 5 };
914                 int[] myBoundsArray = new int[2] { 2, 3 };
915
916                 Array myArray=Array.CreateInstance ( typeof(String), myLengthsArray, myBoundsArray );
917                 try {
918                         ((IList)myArray).Remove ("can not");
919                         Assert.Fail ("IList.Remove should throw");
920                 }
921                 catch (NotSupportedException) {
922                         return;
923                 }
924                 catch (Exception) {
925                         Assert.Fail ("IList.Remove threw wrong exception type");
926                 }
927
928                 Assert.Fail ("IList.Remove shouldn't get this far");
929         }
930
931         [Test]
932         public void TestIList_RemoveAt () {
933                 int[] myLengthsArray = new int[2] { 3, 5 };
934                 int[] myBoundsArray = new int[2] { 2, 3 };
935
936                 Array myArray=Array.CreateInstance ( typeof(String), myLengthsArray, myBoundsArray );
937                 try {
938                         ((IList)myArray).RemoveAt (0);
939                         Assert.Fail ("IList.RemoveAt should throw");
940                 }
941                 catch (NotSupportedException) {
942                         return;
943                 }
944                 catch (Exception) {
945                         Assert.Fail ("IList.RemoveAt threw wrong exception type");
946                 }
947
948                 Assert.Fail ("IList.RemoveAt shouldn't get this far");
949         }
950
951         [Test]
952         public void TestIList_Contains () {
953                 int[] myLengthsArray = new int[2] { 3, 5 };
954                 int[] myBoundsArray = new int[2] { 2, 3 };
955
956                 Array myArray=Array.CreateInstance ( typeof(String), myLengthsArray, myBoundsArray );
957
958                 try {
959                         bool b = ((IList)myArray).Contains ("23");
960                         Assert.Fail ("IList.Contains should throw with multi-dimensional arrays");
961                 }
962                 catch (RankException) {
963                         int[] iArr = new int[3] { 1, 2, 3};
964                         // check the first and last items
965                         Assert.IsTrue (((IList)iArr).Contains (1), "AC01");
966                         Assert.IsTrue (((IList)iArr).Contains (3), "AC02");
967
968                         // and one that is definately not there
969                         Assert.IsTrue (!((IList)iArr).Contains (42), "AC03");
970                         return;
971                 }
972
973                 Assert.Fail ("Should not get here");
974         }
975
976         [Test]
977         public void TestIList_IndexOf () {
978                 int[] myLengthsArray = new int[2] { 3, 5 };
979                 int[] myBoundsArray = new int[2] { 2, 3 };
980
981                 Array myArray=Array.CreateInstance ( typeof(String), myLengthsArray, myBoundsArray );
982
983                 try {
984                         bool b = ((IList)myArray).Contains ("23");
985                         Assert.Fail ("IList.Contains should throw with multi-dimensional arrays");
986                 }
987                 catch (RankException) {
988                         int[] iArr = new int[3] { 1, 2, 3};
989                         // check the first and last items
990                         Assert.AreEqual (0, ((IList)iArr).IndexOf (1), "AD01");
991                         Assert.AreEqual (2, ((IList)iArr).IndexOf (3), "AD02");
992
993                         // and one that is definately not there
994                         Assert.AreEqual (-1, ((IList)iArr).IndexOf (42), "AD03");
995                 }
996                 catch (Exception e) {
997                         Assert.Fail ("Unexpected exception: " + e.ToString());
998                 }
999
1000                 // check that wierd case whem lowerbound is Int32.MinValue,
1001                 // so that IndexOf() needs to return Int32.MaxValue when it cannot find the object
1002                 int[] myLengthArray = new int[1] { 3 };
1003                 int[] myBoundArray = new int[1] { Int32.MinValue };
1004                 Array myExtremeArray=Array.CreateInstance ( typeof(String), myLengthArray, myBoundArray );
1005                 Assert.AreEqual (Int32.MaxValue, ((IList)myExtremeArray).IndexOf (42), "AD04");
1006         }
1007
1008         [Test]
1009         public void TestGetLength() {
1010                 {
1011                         bool errorThrown = false;
1012                         try {
1013                                 char[] c1 = {'a', 'b', 'c'};
1014                                 c1.GetLength(-1);
1015                         } catch (IndexOutOfRangeException) {
1016                                 errorThrown = true;
1017                         }
1018                         Assert.IsTrue (errorThrown, "#H01");
1019                 }
1020                 {
1021                         bool errorThrown = false;
1022                         try {
1023                                 char[] c1 = {'a', 'b', 'c'};
1024                                 c1.GetLength(1);
1025                         } catch (IndexOutOfRangeException) {
1026                                 errorThrown = true;
1027                         }
1028                         Assert.IsTrue (errorThrown, "#H02");
1029                 }
1030
1031                 char[] c2 = new Char[5];
1032                 Assert.AreEqual (5, c2.GetLength(0), "#H03");
1033
1034                 char[,] c3 = new Char[6,7];
1035                 Assert.AreEqual (6, c3.GetLength(0), "#H04");
1036                 Assert.AreEqual (7, c3.GetLength(1), "#H05");
1037         }
1038
1039         [Test]
1040         public void TestGetLowerBound() {
1041                 {
1042                         bool errorThrown = false;
1043                         try {
1044                                 char[] c = {'a', 'b', 'c'};
1045                                 c.GetLowerBound(-1);
1046                         } catch (IndexOutOfRangeException) {
1047                                 errorThrown = true;
1048                         }
1049                         Assert.IsTrue (errorThrown, "#H31");
1050                 }
1051                 {
1052                         bool errorThrown = false;
1053                         try {
1054                                 char[] c = {'a', 'b', 'c'};
1055                                 c.GetLowerBound(1);
1056                         } catch (IndexOutOfRangeException) {
1057                                 errorThrown = true;
1058                         }
1059                         Assert.IsTrue (errorThrown, "#H32");
1060                 }
1061
1062                 char[] c1 = new Char[5];
1063                 Assert.AreEqual (0, c1.GetLowerBound(0), "#H33");
1064
1065                 char[,] c2 = new Char[4,4];
1066                 Assert.AreEqual (0, c2.GetLowerBound(0), "#H34");
1067                 Assert.AreEqual (0, c2.GetLowerBound(1), "#H35");
1068         }
1069
1070         [Test]
1071         public void TestGetUpperBound() {
1072                 {
1073                         bool errorThrown = false;
1074                         try {
1075                                 char[] c = {'a', 'b', 'c'};
1076                                 c.GetUpperBound(-1);
1077                         } catch (IndexOutOfRangeException) {
1078                                 errorThrown = true;
1079                         }
1080                         Assert.IsTrue (errorThrown, "#H61");
1081                 }
1082                 {
1083                         bool errorThrown = false;
1084                         try {
1085                                 char[] c = {'a', 'b', 'c'};
1086                                 c.GetUpperBound(1);
1087                         } catch (IndexOutOfRangeException) {
1088                                 errorThrown = true;
1089                         }
1090                         Assert.IsTrue (errorThrown, "#H62");
1091                 }
1092
1093                 char[] c1 = new Char[5];
1094                 Assert.AreEqual (4, c1.GetUpperBound(0), "#H63");
1095
1096                 char[,] c2 = new Char[4,6];
1097                 Assert.AreEqual (3, c2.GetUpperBound(0), "#H64");
1098                 Assert.AreEqual (5, c2.GetUpperBound(1), "#H65");
1099         }
1100
1101         [Test]
1102         public void TestGetValue1() {
1103                 {
1104                         bool errorThrown = false;
1105                         try {
1106                                 char[,] c = new Char[2,2];
1107                                 c.GetValue(1);
1108                         } catch (ArgumentException) {
1109                                 errorThrown = true;
1110                         }
1111                         Assert.IsTrue (errorThrown, "#I01");
1112                 }
1113                 {
1114                         bool errorThrown = false;
1115                         try {
1116                                 char[] c = {'a', 'b', 'c'};
1117                                 c.GetValue(-1);
1118                         } catch (IndexOutOfRangeException) {
1119                                 errorThrown = true;
1120                         }
1121                         Assert.IsTrue (errorThrown, "#I02");
1122                 }
1123                 {
1124                         bool errorThrown = false;
1125                         try {
1126                                 char[] c = {'a', 'b', 'c'};
1127                                 c.GetValue(4);
1128                         } catch (IndexOutOfRangeException) {
1129                                 errorThrown = true;
1130                         }
1131                         Assert.IsTrue (errorThrown, "#I03");
1132                 }
1133
1134                 char[] c1 = {'a', 'b', 'c', 'd'};
1135                 for (int i = 0; i < c1.Length; i++) {
1136                         Assert.AreEqual (c1[i], c1.GetValue(i), "#I04(" + i + ")");
1137                 }
1138         }
1139
1140         [Test]
1141         public void TestGetValue2() {
1142                 {
1143                         bool errorThrown = false;
1144                         try {
1145                                 char[] c = new Char[2];
1146                                 c.GetValue(1,1);
1147                         } catch (ArgumentException) {
1148                                 errorThrown = true;
1149                         }
1150                         Assert.IsTrue (errorThrown, "#I21");
1151                 }
1152                 {
1153                         bool errorThrown = false;
1154                         try {
1155                                 char[,] c = new Char[2,2];
1156                                 c.GetValue(-1, 1);
1157                         } catch (IndexOutOfRangeException) {
1158                                 errorThrown = true;
1159                         }
1160                         Assert.IsTrue (errorThrown, "#I22");
1161                 }
1162                 {
1163                         bool errorThrown = false;
1164                         try {
1165                                 char[,] c = new Char[2,2];
1166                                 c.GetValue(4,1);
1167                         } catch (IndexOutOfRangeException) {
1168                                 errorThrown = true;
1169                         }
1170                         Assert.IsTrue (errorThrown, "#I23");
1171                 }
1172
1173                 char[,] c1 = new Char[4,6];
1174                 for (int i = 0; i < 24; i++) {
1175                         int first = i / 6;
1176                         int second = i % 6;
1177                         c1[first,second] = (char)(((int)'a')+i);
1178                 }
1179                 for (int i = 0; i < c1.GetLength(0); i++) {
1180                         for (int j = 0; j < c1.GetLength(1); j++) {
1181                                 Assert.AreEqual (c1[i, j], c1.GetValue(i, j), "#I24(" + i + "," + j + ")");
1182                         }
1183                 }
1184         }
1185
1186         [Test]
1187         public void TestGetValue3() {
1188                 {
1189                         bool errorThrown = false;
1190                         try {
1191                                 char[] c = new Char[2];
1192                                 c.GetValue(1,1,1);
1193                         } catch (ArgumentException) {
1194                                 errorThrown = true;
1195                         }
1196                         Assert.IsTrue (errorThrown, "#I41");
1197                 }
1198                 {
1199                         bool errorThrown = false;
1200                         try {
1201                                 char[,,] c = new Char[2,2,2];
1202                                 c.GetValue(-1, 1, 1);
1203                         } catch (IndexOutOfRangeException) {
1204                                 errorThrown = true;
1205                         }
1206                         Assert.IsTrue (errorThrown, "#I42");
1207                 }
1208                 {
1209                         bool errorThrown = false;
1210                         try {
1211                                 char[,,] c = new Char[2,2,2];
1212                                 c.GetValue(4,1,1);
1213                         } catch (IndexOutOfRangeException) {
1214                                 errorThrown = true;
1215                         }
1216                         Assert.IsTrue (errorThrown, "#I43");
1217                 }
1218
1219                 char[,,] c1 = new Char[4,2,3];
1220                 for (int i = 0; i < 24; i++) {
1221                         int first = i / 6;
1222                         int remains = i % 6;
1223                         int second = remains / 3;
1224                         int third = remains % 3;
1225                         c1[first,second, third] = (char)(((int)'a')+i);
1226                 }
1227                 for (int i = 0; i < c1.GetLength(0); i++) {
1228                         for (int j = 0; j < c1.GetLength(1); j++) {
1229                                 for (int k = 0; k < c1.GetLength(2); k++) {
1230                                         Assert.AreEqual (c1[i, j, k], c1.GetValue(i, j, k), "#I44(" + i + "," + j + ")");
1231                                 }
1232                         }
1233                 }
1234         }
1235
1236         [Test]
1237         [ExpectedException (typeof (ArgumentNullException))]
1238         public void TestGetValueLongArray ()
1239         {
1240                 char[] c = new Char[2];
1241                 c.GetValue((long [])null);
1242         }
1243
1244         [Test]
1245         public void TestGetValueN() {
1246                 {
1247                         bool errorThrown = false;
1248                         try {
1249                                 char[] c = new Char[2];
1250                                 c.GetValue((int [])null);
1251                         } catch (ArgumentNullException) {
1252                                 errorThrown = true;
1253                         }
1254                         Assert.IsTrue (errorThrown, "#I61a");
1255                 }
1256                 {
1257                         bool errorThrown = false;
1258                         try {
1259                                 char[] c = new Char[2];
1260                                 int[] coords = {1, 1};
1261                                 c.GetValue(coords);
1262                         } catch (ArgumentException) {
1263                                 errorThrown = true;
1264                         }
1265                         Assert.IsTrue (errorThrown, "#I62");
1266                 }
1267                 {
1268                         bool errorThrown = false;
1269                         try {
1270                                 char[,] c = new Char[2,2];
1271                                 int[] coords = {-1, 1};
1272                                 c.GetValue(coords);
1273                         } catch (IndexOutOfRangeException) {
1274                                 errorThrown = true;
1275                         }
1276                         Assert.IsTrue (errorThrown, "#I63");
1277                 }
1278                 {
1279                         bool errorThrown = false;
1280                         try {
1281                                 char[,] c = new Char[2,2];
1282                                 int[] coords = {4, 1};
1283                                 c.GetValue(coords);
1284                         } catch (IndexOutOfRangeException) {
1285                                 errorThrown = true;
1286                         }
1287                         Assert.IsTrue (errorThrown, "#I64");
1288                 }
1289
1290                 char[,] c1 = new Char[4,6];
1291                 for (int i = 0; i < 24; i++) {
1292                         int first = i / 6;
1293                         int second = i % 6;
1294                         c1[first,second] = (char)(((int)'a')+i);
1295                 }
1296                 for (int i = 0; i < c1.GetLength(0); i++) {
1297                         for (int j = 0; j < c1.GetLength(1); j++) {
1298                                 int[] coords = {i, j};
1299                                 Assert.AreEqual (c1[i, j], c1.GetValue(coords), "#I65(" + i + "," + j + ")");
1300                         }
1301                 }
1302         }
1303
1304         [Test]
1305         public void TestIndexOf1() {
1306                 {
1307                         bool errorThrown = false;
1308                         try {
1309                                 Array.IndexOf(null, "huh?");
1310                         } catch (ArgumentNullException) {
1311                                 errorThrown = true;
1312                         }
1313                         Assert.IsTrue (errorThrown, "#J01");
1314                 }
1315                 {
1316                         bool errorThrown = false;
1317                         try {
1318                                 char[,] c = new Char[2,2];
1319                                 Array.IndexOf(c, "huh?");
1320                         } catch (RankException) {
1321                                 errorThrown = true;
1322                         }
1323                         Assert.IsTrue (errorThrown, "#J02");
1324                 }
1325
1326                 String[] s1 = {"this", "is", "a", "test"};
1327                 Assert.AreEqual (-1, Array.IndexOf(s1, null), "#J03");
1328                 Assert.AreEqual (-1, Array.IndexOf(s1, "nothing"), "#J04");
1329                 Assert.AreEqual (0, Array.IndexOf(s1, "this"), "#J05");
1330                 Assert.AreEqual (3, Array.IndexOf(s1, "test"), "#J06");
1331         }
1332
1333         [Test]
1334         public void TestIndexOf2() {
1335                 {
1336                         bool errorThrown = false;
1337                         try {
1338                                 Array.IndexOf(null, "huh?", 0);
1339                         } catch (ArgumentNullException) {
1340                                 errorThrown = true;
1341                         }
1342                         Assert.IsTrue (errorThrown, "#J21");
1343                 }
1344                 {
1345                         bool errorThrown = false;
1346                         try {
1347                                 char[,] c = new Char[2,2];
1348                                 Array.IndexOf(c, "huh?", 0);
1349                         } catch (RankException) {
1350                                 errorThrown = true;
1351                         }
1352                         Assert.IsTrue (errorThrown, "#J22");
1353                 }
1354                 {
1355                         bool errorThrown = false;
1356                         try {
1357                                 char[] c = new Char[2];
1358                                 Array.IndexOf(c, "huh?", 3);
1359                         } catch (ArgumentOutOfRangeException) {
1360                                 errorThrown = true;
1361                         }
1362                         Assert.IsTrue (errorThrown, "#J23");
1363                 }
1364
1365                 String[] s1 = {"this", "is", "really", "a", "test"};
1366                 Assert.AreEqual (-1, Array.IndexOf(s1, null, 1), "#J24");
1367                 Assert.AreEqual (-1, Array.IndexOf(s1, "nothing", 1), "#J25");
1368                 Assert.AreEqual (-1, Array.IndexOf(s1, "this", 1), "#J26");
1369                 Assert.AreEqual (1, Array.IndexOf(s1, "is", 1), "#J27");
1370                 Assert.AreEqual (4, Array.IndexOf(s1, "test", 1), "#J28");
1371         }
1372
1373         [Test]
1374         public void TestIndexOf3() {
1375                 {
1376                         bool errorThrown = false;
1377                         try {
1378                                 Array.IndexOf(null, "huh?", 0, 1);
1379                         } catch (ArgumentNullException) {
1380                                 errorThrown = true;
1381                         }
1382                         Assert.IsTrue (errorThrown, "#J41");
1383                 }
1384                 {
1385                         bool errorThrown = false;
1386                         try {
1387                                 char[,] c = new Char[2,2];
1388                                 Array.IndexOf(c, "huh?", 0, 1);
1389                         } catch (RankException) {
1390                                 errorThrown = true;
1391                         }
1392                         Assert.IsTrue (errorThrown, "#J42");
1393                 }
1394                 {
1395                         bool errorThrown = false;
1396                         try {
1397                                 char[] c = new Char[2];
1398                                 Array.IndexOf(c, "huh?", 3, 1);
1399                         } catch (ArgumentOutOfRangeException) {
1400                                 errorThrown = true;
1401                         }
1402                         Assert.IsTrue (errorThrown, "#J43");
1403                 }
1404                 {
1405                         bool errorThrown = false;
1406                         try {
1407                                 char[] c = new Char[2];
1408                                 Array.IndexOf(c, "huh?", 0, 5);
1409                         } catch (ArgumentOutOfRangeException) {
1410                                 errorThrown = true;
1411                         }
1412                         Assert.IsTrue (errorThrown, "#J44");
1413                 }
1414
1415                 String[] s1 = {"this", "is", "really", "a", "test"};
1416                 Assert.AreEqual (-1, Array.IndexOf(s1, null, 1, 3), "#J45");
1417                 Assert.AreEqual (-1, Array.IndexOf(s1, "nothing", 1, 3), "#J46");
1418                 Assert.AreEqual (-1, Array.IndexOf(s1, "this", 1, 3), "#J47");
1419                 Assert.AreEqual (1, Array.IndexOf(s1, "is", 1, 3), "#J48");
1420                 Assert.AreEqual (-1, Array.IndexOf(s1, "test", 1, 3), "#J49");
1421                 Assert.AreEqual (3, Array.IndexOf(s1, "a", 1, 3), "#J50");
1422         }
1423         
1424         [Test]
1425         public void TestIndexOf_CustomEqual ()
1426         {
1427                 DataEqual[] test = new DataEqual [] { new DataEqual () };
1428                 Assert.AreEqual (0, Array.IndexOf (test, "asdfas", 0));
1429                 
1430                 IList array = (IList)test;
1431                 Assert.AreEqual (0, array.IndexOf ("asdfas"));
1432         }
1433         
1434         [Test]
1435         public void TestLastIndexOf1() {
1436                 {
1437                         bool errorThrown = false;
1438                         try {
1439                                 Array.LastIndexOf(null, "huh?");
1440                         } catch (ArgumentNullException) {
1441                                 errorThrown = true;
1442                         }
1443                         Assert.IsTrue (errorThrown, "#K01");
1444                 }
1445                 {
1446                         bool errorThrown = false;
1447                         try {
1448                                 char[,] c = new Char[2,2];
1449                                 Array.LastIndexOf(c, "huh?");
1450                         } catch (RankException) {
1451                                 errorThrown = true;
1452                         }
1453                         Assert.IsTrue (errorThrown, "#K02");
1454                 }
1455
1456                 String[] s1 = {"this", "is", "a", "a", "test"};
1457                 Assert.AreEqual (-1, Array.LastIndexOf(s1, null), "#K03");
1458                 Assert.AreEqual (-1, Array.LastIndexOf(s1, "nothing"), "#K04");
1459                 Assert.AreEqual (0, Array.LastIndexOf(s1, "this"), "#K05");
1460                 Assert.AreEqual (4, Array.LastIndexOf(s1, "test"), "#K06");
1461                 Assert.AreEqual (3, Array.LastIndexOf(s1, "a"), "#K07");
1462
1463                 Assert.AreEqual (-1, Array.LastIndexOf (new String [0], "foo"));
1464         }
1465
1466         [Test]
1467         public void TestLastIndexOf2() {
1468                 {
1469                         bool errorThrown = false;
1470                         try {
1471                                 Array.LastIndexOf(null, "huh?", 0);
1472                         } catch (ArgumentNullException) {
1473                                 errorThrown = true;
1474                         }
1475                         Assert.IsTrue (errorThrown, "#K21");
1476                 }
1477                 {
1478                         bool errorThrown = false;
1479                         try {
1480                                 char[,] c = new Char[2,2];
1481                                 Array.LastIndexOf(c, "huh?", 0);
1482                         } catch (RankException) {
1483                                 errorThrown = true;
1484                         }
1485                         Assert.IsTrue (errorThrown, "#K22");
1486                 }
1487                 {
1488                         bool errorThrown = false;
1489                         try {
1490                                 char[] c = new Char[2];
1491                                 Array.LastIndexOf(c, "huh?", 3);
1492                         } catch (ArgumentOutOfRangeException) {
1493                                 errorThrown = true;
1494                         }
1495                         Assert.IsTrue (errorThrown, "#K23");
1496                 }
1497
1498                 String[] s1 = {"this", "is", "really", "a", "test"};
1499                 Assert.AreEqual (-1, Array.LastIndexOf(s1, null, 3), "#K24");
1500                 Assert.AreEqual (-1, Array.LastIndexOf(s1, "nothing", 3), "#K25");
1501                 Assert.AreEqual (-1, Array.LastIndexOf(s1, "test", 3), "#K26");
1502                 Assert.AreEqual (3, Array.LastIndexOf(s1, "a", 3), "#K27");
1503                 Assert.AreEqual (0, Array.LastIndexOf(s1, "this", 3), "#K28");
1504         }
1505
1506         [Test]
1507         public void TestLastIndexOf3() {
1508                 {
1509                         bool errorThrown = false;
1510                         try {
1511                                 Array.LastIndexOf(null, "huh?", 0, 1);
1512                         } catch (ArgumentNullException) {
1513                                 errorThrown = true;
1514                         }
1515                         Assert.IsTrue (errorThrown, "#K41");
1516                 }
1517                 {
1518                         bool errorThrown = false;
1519                         try {
1520                                 char[,] c = new Char[2,2];
1521                                 Array.LastIndexOf(c, "huh?", 0, 1);
1522                         } catch (RankException) {
1523                                 errorThrown = true;
1524                         }
1525                         Assert.IsTrue (errorThrown, "#K42");
1526                 }
1527                 {
1528                         bool errorThrown = false;
1529                         try {
1530                                 char[] c = new Char[2];
1531                                 Array.LastIndexOf(c, "huh?", 3, 1);
1532                         } catch (ArgumentOutOfRangeException) {
1533                                 errorThrown = true;
1534                         }
1535                         Assert.IsTrue (errorThrown, "#K43");
1536                 }
1537                 {
1538                         bool errorThrown = false;
1539                         try {
1540                                 char[] c = new Char[2];
1541                                 Array.LastIndexOf(c, "huh?", 0, 5);
1542                         } catch (ArgumentOutOfRangeException) {
1543                                 errorThrown = true;
1544                         }
1545                         Assert.IsTrue (errorThrown, "#K44");
1546                 }
1547
1548                 String[] s1 = {"this", "is", "really", "a", "test"};
1549                 Assert.AreEqual (-1, Array.LastIndexOf(s1, null, 3, 3), "#K45");
1550                 Assert.AreEqual (-1, Array.LastIndexOf(s1, "nothing", 3, 3), "#K46");
1551                 Assert.AreEqual (-1, Array.LastIndexOf(s1, "this", 3, 3), "#K47");
1552                 Assert.AreEqual (1, Array.LastIndexOf(s1, "is", 3, 3), "#K48");
1553                 Assert.AreEqual (-1, Array.LastIndexOf(s1, "test", 3, 3), "#K49");
1554                 Assert.AreEqual (3, Array.LastIndexOf(s1, "a", 3, 3), "#K50");
1555         }
1556
1557         [Test]
1558         public void TestLastIndexOf4 ()
1559         {
1560                 short [] a = new short [] { 19, 238, 317, 6, 565, 0, -52, 60, -563, 753, 238, 238};
1561                 try {
1562                         Array.LastIndexOf (a, (object)16, -1);
1563                         NUnit.Framework.Assert.Fail ("#1");
1564                 } catch (ArgumentOutOfRangeException) { }
1565                 
1566                 try {
1567                         Array.LastIndexOf<short> (a, 16, -1);
1568                         NUnit.Framework.Assert.Fail ("#2");
1569                 } catch (ArgumentOutOfRangeException) { }
1570         }
1571
1572         [Test]
1573         public void TestLastIndexOf5 ()
1574         {
1575                 char [] a = new char [] {'j', 'i', 'h', 'g', 'f', 'e', 'd', 'c', 'b', 'a', 'j', 'i', 'h'};
1576                 string s;
1577                 int retval;
1578                 bool error = false;
1579
1580                 for (int i = a.Length - 1; i >= 0 ; i--) {
1581                         s = i.ToString ();
1582                         retval = Array.LastIndexOf(a, a [i], i, i + 1);
1583                         if (retval != i)
1584                                 error = true;
1585                 }
1586                 Assert.IsTrue (!error);
1587         }
1588
1589         [Test]
1590         [ExpectedException (typeof (ArgumentOutOfRangeException))]
1591         public void LastIndexOf_StartIndexOverflow ()
1592         {
1593                 // legal - no exception
1594                 byte[] array = new byte [16];
1595                 Array.LastIndexOf (array, this, Int32.MaxValue, 1);
1596         }
1597
1598         [Test]
1599         [ExpectedException (typeof (ArgumentOutOfRangeException))]
1600         public void LastIndexOf_CountOverflow ()
1601         {
1602                 // legal - no exception
1603                 byte[] array = new byte [16];
1604                 Array.LastIndexOf (array, this, 1, Int32.MaxValue);
1605         }
1606
1607         [Test]
1608         public void LastIndexOf_0LengthArray ()
1609         {
1610                 Array array = Array.CreateInstance (typeof (char), 0);
1611                 int idx = Array.LastIndexOf (array, (object) null, -1, 0);
1612                 Assert.IsTrue (idx == -1, "#01");
1613                 idx = Array.LastIndexOf (array, (object) null, -1, 10);
1614                 Assert.IsTrue (idx == -1, "#02");
1615                 idx = Array.LastIndexOf (array, (object) null, -100, 10);
1616                 Assert.IsTrue (idx == -1, "#02");
1617
1618                 array = Array.CreateInstance (typeof (char), 1);
1619                 try {
1620                         Array.LastIndexOf (array, (object) null, -1, 0);
1621                         Assert.Fail ("#04");
1622                 } catch (ArgumentOutOfRangeException e) {
1623                 }
1624                 try {
1625                         Array.LastIndexOf (array, (object) null, -1, 10);
1626                         Assert.Fail ("#05");
1627                 } catch (ArgumentOutOfRangeException e) {
1628                 }
1629                 try {
1630                         Array.LastIndexOf (array, (object) null, -100, 10);
1631                         Assert.Fail ("#06");
1632                 } catch (ArgumentOutOfRangeException e) {
1633                 }
1634         }
1635
1636
1637         [Test]
1638         public void FindIndexTest ()
1639         {
1640                 var a = new int[] { 2, 2, 2, 3, 2 };
1641                 Assert.AreEqual (2, Array.FindIndex (a, 2, 2, l => true));
1642         }
1643
1644         [Test]
1645         public void FindIndex_Invalid ()
1646         {
1647                 var array = new int [] { 1, 2, 3, 4, 5 };
1648
1649                 try {
1650                         Array.FindIndex (array, null);
1651                         Assert.Fail ("#1");
1652                 } catch (ArgumentNullException) {
1653                 }
1654
1655                 try {
1656                         Array.FindIndex (array, -1, l => true);
1657                         Assert.Fail ("#2");
1658                 } catch (ArgumentOutOfRangeException) {
1659                 }
1660
1661                 try {
1662                         Array.FindIndex (array, -1, 0, l => true);
1663                         Assert.Fail ("#2b");
1664                 } catch (ArgumentOutOfRangeException) {
1665                 }
1666
1667                 try {
1668                         Array.FindIndex (array, 0, -1, l => true);
1669                         Assert.Fail ("#3");
1670                 } catch (ArgumentOutOfRangeException) {
1671                 }
1672
1673                 try {
1674                         Array.FindIndex (array, 100, l => true);
1675                         Assert.Fail ("#4");
1676                 } catch (ArgumentOutOfRangeException) {
1677                 }
1678
1679                 try {
1680                         Array.FindIndex (array, 100, 0, l => true);
1681                         Assert.Fail ("#4b");
1682                 } catch (ArgumentOutOfRangeException) {
1683                 }
1684
1685                 try {
1686                         Array.FindIndex (array, 7, 2, l => true);
1687                         Assert.Fail ("#5");
1688                 } catch (ArgumentOutOfRangeException) {
1689                 }
1690         }
1691
1692         [Test, ExpectedException (typeof (ArgumentNullException))]
1693         public void FindLastNullTest ()
1694         {
1695                 var array = new int [] { 1, 2, 3, 4, 5 };               
1696                 Array.FindLast (array, null);
1697         }
1698
1699         [Test]
1700         public void FindLastIndexTest ()
1701         {
1702                 var array = new int [] { 1, 2, 3, 4, 5 };
1703
1704                 Assert.AreEqual (2, Array.FindLastIndex (array, 2, 3, l => true));
1705                 Assert.AreEqual (2, Array.FindLastIndex (array, 2, 2, l => true));
1706                 Assert.AreEqual (1, Array.FindLastIndex (array, 1, 2, l => true));
1707         }
1708
1709         [Test]
1710         public void FindLastIndex_Invalid ()
1711         {
1712                 var array = new int [] { 1, 2, 3, 4, 5 };
1713                 try {
1714                         Array.FindLastIndex (array, null);
1715                         Assert.Fail ("#1");
1716                 } catch (ArgumentNullException) {
1717                 }
1718
1719                 try {
1720                         Array.FindLastIndex (array, -1, l => true);
1721                         Assert.Fail ("#2");
1722                 } catch (ArgumentOutOfRangeException) {
1723                 }
1724
1725                 try {
1726                         Array.FindLastIndex (array, -1, 0, l => true);
1727                         Assert.Fail ("#2b");
1728                 } catch (ArgumentOutOfRangeException) {
1729                 }
1730
1731                 try {
1732                         Array.FindLastIndex (array, 0, -1, l => true);
1733                         Assert.Fail ("#3");
1734                 } catch (ArgumentOutOfRangeException) {
1735                 }
1736
1737                 try {
1738                         Array.FindLastIndex (array, 100, l => true);
1739                         Assert.Fail ("#4");
1740                 } catch (ArgumentOutOfRangeException) {
1741                 }
1742
1743                 try {
1744                         Array.FindLastIndex (array, 100, 0, l => true);
1745                         Assert.Fail ("#4b");
1746                 } catch (ArgumentOutOfRangeException) {
1747                 }
1748
1749                 try {
1750                         Array.FindLastIndex (array, 2, 4, l => true);
1751                         Assert.Fail ("#5");
1752                 } catch (ArgumentOutOfRangeException) {
1753                 }
1754         }
1755
1756         [Test]
1757         public void TestReverse() {
1758                 {
1759                         bool errorThrown = false;
1760                         try {
1761                                 Array.Reverse(null);
1762                         } catch (ArgumentNullException) {
1763                                 errorThrown = true;
1764                         }
1765                         Assert.IsTrue (errorThrown, "#L01");
1766                 }
1767                 {
1768                         bool errorThrown = false;
1769                         try {
1770                                 char[,] c = new Char[2,2];
1771                                 Array.Reverse(c);
1772                         } catch (RankException) {
1773                                 errorThrown = true;
1774                         }
1775                         Assert.IsTrue (errorThrown, "#L02");
1776                 }
1777                 
1778                 char[] c1 = {'a', 'b', 'c', 'd'};
1779                 Array.Reverse(c1);
1780                 Assert.AreEqual ('d', c1[0], "#L03");
1781                 Assert.AreEqual ('c', c1[1], "#L04");
1782                 Assert.AreEqual ('b', c1[2], "#L05");
1783                 Assert.AreEqual ('a', c1[3], "#L06");
1784
1785                 {
1786                         bool errorThrown = false;
1787                         try {
1788                                 Array.Reverse(null, 0, 0);
1789                         } catch (ArgumentNullException) {
1790                                 errorThrown = true;
1791                         }
1792                         Assert.IsTrue (errorThrown, "#L07");
1793                 }
1794                 {
1795                         bool errorThrown = false;
1796                         try {
1797                                 char[,] c = new Char[2,2];
1798                                 Array.Reverse(c, 0, 0);
1799                         } catch (RankException) {
1800                                 errorThrown = true;
1801                         }
1802                         Assert.IsTrue (errorThrown, "#L08");
1803                 }
1804                 //{
1805                 //bool errorThrown = false;
1806                 //try {
1807                 //      char[] c = new Char[2];
1808                 //      Array.Reverse(c, 0, 3);
1809                 //} catch (ArgumentOutOfRangeException) {
1810                 //      errorThrown = true;
1811                 //}
1812                 //Assert.IsTrue (errorThrown, "#L09");
1813                 //}
1814                 //{
1815                 //bool errorThrown = false;
1816                 //try {
1817                 //      char[] c = new Char[2];
1818                 //      Array.Reverse(c, 3, 0);
1819                 //} catch (ArgumentOutOfRangeException) {
1820                 //      errorThrown = true;
1821                 //}
1822                 //Assert.IsTrue (errorThrown, "#L10");
1823                 //}
1824
1825                 char[] c2 = { 'a', 'b', 'c', 'd'};
1826                 Array.Reverse(c2, 1, 2);
1827                 Assert.AreEqual ('a', c2[0], "#L11");
1828                 Assert.AreEqual ('c', c2[1], "#L12");
1829                 Assert.AreEqual ('b', c2[2], "#L13");
1830                 Assert.AreEqual ('d', c2[3], "#L14");
1831         }
1832
1833         [Test]
1834         // #8904
1835         public void ReverseStruct () {
1836                 BStruct[] c3 = new BStruct[2];
1837                 c3 [0] = new BStruct () { i1 = 1, i2 = 2, i3 = 3 };
1838                 c3 [1] = new BStruct () { i1 = 4, i2 = 5, i3 = 6 };
1839                 Array.Reverse (c3);
1840                 Assert.AreEqual (4, c3 [0].i1);
1841                 Assert.AreEqual (5, c3 [0].i2);
1842                 Assert.AreEqual (6, c3 [0].i3);
1843                 Assert.AreEqual (1, c3 [1].i1);
1844                 Assert.AreEqual (2, c3 [1].i2);
1845                 Assert.AreEqual (3, c3 [1].i3);
1846         }
1847
1848         struct BStruct {
1849                 public int i1, i2, i3;
1850         }
1851
1852         [Test]
1853         public void TestSetValue1() {
1854                 {
1855                         bool errorThrown = false;
1856                         try {
1857                                 char[,] c = new Char[2,2];
1858                                 c.SetValue("buh", 1);
1859                         } catch (ArgumentException) {
1860                                 errorThrown = true;
1861                         }
1862                         Assert.IsTrue (errorThrown, "#M01");
1863                 }
1864                 {
1865                         bool errorThrown = false;
1866                         try {
1867                                 char[] c = {'a', 'b', 'c'};
1868                                 c.SetValue("buh", -1);
1869                         } catch (IndexOutOfRangeException) {
1870                                 errorThrown = true;
1871                         }
1872                         Assert.IsTrue (errorThrown, "#M02");
1873                 }
1874                 {
1875                         bool errorThrown = false;
1876                         try {
1877                                 char[] c = {'a', 'b', 'c'};
1878                                 c.SetValue("buh", 4);
1879                         } catch (IndexOutOfRangeException) {
1880                                 errorThrown = true;
1881                         }
1882                         Assert.IsTrue (errorThrown, "#M03");
1883                 }
1884
1885                 char[] c1 = {'a', 'b', 'c', 'd'};
1886                 char[] c2 = new char[4];
1887                 for (int i = 0; i < c1.Length; i++) {
1888                         c2.SetValue(c1[i], i);
1889                 }
1890                 for (int i = 0; i < c1.Length; i++) {
1891                         Assert.AreEqual (c1[i], c2[i], "#M04(" + i + ")");
1892                 }
1893
1894                 int[] c3 = { 1, 2, 3 };
1895                 long[] c4 = new long [3];
1896
1897                 for (int i = 0; i < c3.Length; i++)
1898                         c4.SetValue (c3 [i], i);
1899
1900                 try {
1901                         c3.CopyTo (c4, 0);
1902                 } catch (Exception e) {
1903                         Assert.Fail ("c3.CopyTo(): e=" + e);
1904                 }
1905                 for (int i = 0; i < c3.Length; i++)
1906                         Assert.IsTrue (c3[i] == c4[i], "#M05(" + i + ")");
1907
1908                 Object[] c5 = new Object [3];
1909                 long[] c6 = new long [3];
1910
1911                 try {
1912                         c4.CopyTo (c5, 0);
1913                 } catch (Exception e) {
1914                         Assert.Fail ("c4.CopyTo(): e=" + e);
1915                 }
1916
1917                 try {
1918                         c5.CopyTo (c6, 0);
1919                 } catch (Exception e) {
1920                         Assert.Fail ("c5.CopyTo(): e=" + e);
1921                 }
1922                 // for (int i = 0; i < c5.Length; i++)
1923                 // Assert.IsTrue (c5[i] == c6[i], "#M06(" + i + ")");
1924         }
1925
1926         [Test]
1927         public void TestSetValue2() {
1928                 {
1929                         bool errorThrown = false;
1930                         try {
1931                                 char[] c = new Char[2];
1932                                 c.SetValue("buh", 1,1);
1933                         } catch (ArgumentException) {
1934                                 errorThrown = true;
1935                         }
1936                         Assert.IsTrue (errorThrown, "#M21");
1937                 }
1938                 {
1939                         bool errorThrown = false;
1940                         try {
1941                                 char[,] c = new Char[2,2];
1942                                 c.SetValue("buh", -1, 1);
1943                         } catch (IndexOutOfRangeException) {
1944                                 errorThrown = true;
1945                         }
1946                         Assert.IsTrue (errorThrown, "#M22");
1947                 }
1948                 {
1949                         bool errorThrown = false;
1950                         try {
1951                                 char[,] c = new Char[2,2];
1952                                 c.SetValue("buh", 4,1);
1953                         } catch (IndexOutOfRangeException) {
1954                                 errorThrown = true;
1955                         }
1956                         Assert.IsTrue (errorThrown, "#M23");
1957                 }
1958
1959                 char[,] c1 = new Char[4,6];
1960                 char[,] c2 = new Char[4,6];
1961                 for (int i = 0; i < 24; i++) {
1962                         int first = i / 6;
1963                         int second = i % 6;
1964                         c1[first,second] = (char)(((int)'a')+i);
1965                         c2.SetValue(c1[first,second], first, second);
1966                 }
1967                 for (int i = 0; i < c1.GetLength(0); i++) {
1968                         for (int j = 0; j < c1.GetLength(1); j++) {
1969                                 Assert.AreEqual (c1[i, j], c2[i, j], "#M24(" + i + "," + j + ")");
1970                         }
1971                 }
1972         }
1973
1974         [Test]
1975         public void TestSetValue3() {
1976                 {
1977                         bool errorThrown = false;
1978                         try {
1979                                 char[] c = new Char[2];
1980                                 c.SetValue("buh", 1,1,1);
1981                         } catch (ArgumentException) {
1982                                 errorThrown = true;
1983                         }
1984                         Assert.IsTrue (errorThrown, "#M41");
1985                 }
1986                 {
1987                         bool errorThrown = false;
1988                         try {
1989                                 char[,,] c = new Char[2,2,2];
1990                                 c.SetValue("buh", -1, 1, 1);
1991                         } catch (IndexOutOfRangeException) {
1992                                 errorThrown = true;
1993                         }
1994                         Assert.IsTrue (errorThrown, "#M42");
1995                 }
1996                 {
1997                         bool errorThrown = false;
1998                         try {
1999                                 char[,,] c = new Char[2,2,2];
2000                                 c.SetValue("buh", 4,1,1);
2001                         } catch (IndexOutOfRangeException) {
2002                                 errorThrown = true;
2003                         }
2004                         Assert.IsTrue (errorThrown, "#M43");
2005                 }
2006
2007                 char[,,] c1 = new Char[4,2,3];
2008                 char[,,] c2 = new Char[4,2,3];
2009                 for (int i = 0; i < 24; i++) {
2010                         int first = i / 6;
2011                         int remains = i % 6;
2012                         int second = remains / 3;
2013                         int third = remains % 3;
2014                         c1[first,second, third] = (char)(((int)'a')+i);
2015                         c2.SetValue(c1[first, second, third], first, second, third);
2016                 }
2017                 for (int i = 0; i < c1.GetLength(0); i++) {
2018                         for (int j = 0; j < c1.GetLength(1); j++) {
2019                                 for (int k = 0; k < c1.GetLength(2); k++) {
2020                                         Assert.AreEqual (c1[i, j, k], c2[i, j, k], "#M44(" + i + "," + j + " )");
2021                                 }
2022                         }
2023                 }
2024         }
2025
2026         [Test]
2027         [ExpectedException (typeof (ArgumentNullException))]
2028         public void TestSetValueLongArray ()
2029         {
2030                 char[] c = new Char[2];
2031                 c.SetValue("buh", (long [])null);
2032         }
2033
2034         [Test]
2035         public void TestSetValueN() {
2036                 {
2037                         bool errorThrown = false;
2038                         try {
2039                                 char[] c = new Char[2];
2040                                 c.SetValue("buh", (int [])null);
2041                         } catch (ArgumentNullException) {
2042                                 errorThrown = true;
2043                         }
2044                         Assert.IsTrue (errorThrown, "#M61a");
2045                 }
2046                 {
2047                         bool errorThrown = false;
2048                         try {
2049                                 char[] c = new Char[2];
2050                                 int[] coords = {1, 1};
2051                                 c.SetValue("buh", coords);
2052                         } catch (ArgumentException) {
2053                                 errorThrown = true;
2054                         }
2055                         Assert.IsTrue (errorThrown, "#M62");
2056                 }
2057                 {
2058                         bool errorThrown = false;
2059                         try {
2060                                 char[,] c = new Char[2,2];
2061                                 int[] coords = {-1, 1};
2062                                 c.SetValue("buh", coords);
2063                         } catch (IndexOutOfRangeException) {
2064                                 errorThrown = true;
2065                         }
2066                         Assert.IsTrue (errorThrown, "#M63");
2067                 }
2068                 {
2069                         bool errorThrown = false;
2070                         try {
2071                                 char[,] c = new Char[2,2];
2072                                 int[] coords = {4, 1};
2073                                 c.SetValue("buh", coords);
2074                         } catch (IndexOutOfRangeException) {
2075                                 errorThrown = true;
2076                         }
2077                         Assert.IsTrue (errorThrown, "#M64");
2078                 }
2079
2080                 char[,] c1 = new Char[4,6];
2081                 char[,] c2 = new Char[4,6];
2082                 for (int i = 0; i < 24; i++) {
2083                         int first = i / 6;
2084                         int second = i % 6;
2085                         c1[first,second] = (char)(((int)'a')+i);
2086                         int[] coords = {first, second};
2087                         c2.SetValue(c1[first,second], coords);
2088                 }
2089                 for (int i = 0; i < c1.GetLength(0); i++) {
2090                         for (int j = 0; j < c1.GetLength(1); j++) {
2091                                 Assert.AreEqual (c1[i, j], c2[i, j], "#M65(" + i + "," + j + ")");
2092                         }
2093                 }
2094         }
2095
2096         [Test]
2097         public void TestSetValue4() {
2098                 {
2099                         int[] c1 = { 1, 2, 3 };
2100                         long[] c2 = new long [3];
2101
2102                         for (int i = 0; i < c1.Length; i++)
2103                                 c2.SetValue (c1 [i], i);
2104
2105                         for (int i = 0; i < c1.Length; i++) {
2106                                 Assert.IsTrue (c1[i] == c2[i], "#M81(" + i + ")");
2107                                 Assert.AreEqual (typeof (long), c2[i].GetType (), "#M82(" + i + ")");
2108                         }
2109                 }
2110                 {
2111                         long[] c1 = { 1, 2, 3 };
2112                         int[] c2 = new int [3];
2113                         bool errorThrown = false;
2114                         try {
2115                                 c2.SetValue (c1 [0], 0);
2116                         } catch (ArgumentException) {
2117                                 errorThrown = true;
2118                         }
2119                         Assert.IsTrue (errorThrown, "#M83");
2120                 }
2121                 {
2122                         int[] c1 = { 1, 2, 3 };
2123                         Object[] c2 = new Object [3];
2124
2125                         for (int i = 0; i < c1.Length; i++)
2126                                 c2.SetValue (c1 [i], i);
2127
2128                         for (int i = 0; i < c1.Length; i++)
2129                                 Assert.AreEqual (c1[i], Convert.ToInt32 (c2[i]), "#M84(" + i + ")");
2130                 }
2131                 {
2132                         Object[] c1 = new Object [3];
2133                         Object[] c2 = new Object [3];
2134                         c1[0] = new Object ();
2135
2136                         for (int i = 0; i < c1.Length; i++)
2137                                 c2.SetValue (c1 [i], i);
2138
2139                         for (int i = 0; i < c1.Length; i++)
2140                                 Assert.AreEqual (c1[i], c2[i], "#M85(" + i + ")");
2141                 }
2142                 {
2143                         Object[] c1 = new Object [3];
2144                         string[] c2 = new String [3];
2145                         string test = "hello";
2146                         c1[0] = test;
2147
2148                         c2.SetValue (c1 [0], 0);
2149                         Assert.AreEqual (c1[0], c2[0], "#M86");
2150                         Assert.AreEqual ("hello", c2[0], "#M87");
2151                 }
2152                 {
2153                         char[] c1 = { 'a', 'b', 'c' };
2154                         string[] c2 = new string [3];
2155                         try {
2156                                 c2.SetValue (c1 [0], 0);
2157                                 Assert.Fail ("#M88");
2158                         } catch (InvalidCastException) {}
2159                 }
2160                 {
2161                         Single[] c1 = { 1.2F, 2.3F, 3.4F, 4.5F };
2162                         long[] c2 = new long [3];
2163                         try {
2164                                 c2.SetValue (c1 [0], 0);
2165                                 Assert.Fail ("#M89");
2166                         } catch (ArgumentException) {}
2167                 }
2168                 {
2169                         Type[] types = {
2170                                 typeof (Boolean),
2171                                 typeof (Byte),
2172                                 typeof (Char),
2173                                 typeof (Double),
2174                                 typeof (Int16),
2175                                 typeof (Int32),
2176                                 typeof (Int64),
2177                                 typeof (SByte),
2178                                 typeof (Single),
2179                                 typeof (UInt16),
2180                                 typeof (UInt32),
2181                                 typeof (UInt64)
2182                         };
2183
2184                         bool v1 = true;
2185                         Byte v2 = 1;
2186                         Char v3 = 'a';
2187                         Double v4 = -1.2;
2188                         Int16 v5 = -32;
2189                         Int32 v6 = -234;
2190                         Int64 v7 = -34523;
2191                         SByte v8 = -1;
2192                         Single v9 = -4.8F;
2193                         UInt16 v10 = 24234;
2194                         UInt32 v11 = 235354;
2195                         UInt64 v12 = 234552;
2196
2197                         Object[] va1 = { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12 };
2198                         Object[] va2 = { "true", "1", "a", "-1.2", "-32", "-234", "-34523", "-1",
2199                                          "-4.8F", "24234", "235354", "234552" };
2200
2201                         Object[][] vt = { va1, va1, va1, va1, va1, va1, va1, va1, va1, va1, va1, va1 };
2202
2203                         int[] arg_ex = {
2204                                 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2205                                 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
2206                                 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
2207                                 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
2208                                 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1,
2209                                 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1,
2210                                 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1,
2211                                 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1,
2212                                 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1,
2213                                 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
2214                                 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0,
2215                                 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0
2216                         };
2217
2218                         // SetValue
2219
2220                         for (int i = 0; i < types.Length; i++) {
2221                                 for (int j = 0; j < types.Length; j++) {
2222                                         Array array = Array.CreateInstance (types [j], 2);
2223
2224                                         Object value = vt[j][i];
2225
2226                                         bool errorThrown = false;
2227                                         try {
2228                                                 array.SetValue (value, 0);
2229                                         } catch (ArgumentException) {
2230                                                 errorThrown = true;
2231                                         }
2232
2233                                         int ex_index = (i * types.Length) + j;
2234
2235                                         Assert.AreEqual (errorThrown, arg_ex [ex_index] == 1, "#M90(" + types [i] + "," + types [j] + ")");
2236                                 }
2237                         }
2238
2239                         for (int i = 0; i < types.Length; i++) {
2240                                 String[] array = new String [2];
2241
2242                                 Object value = va1 [i];
2243
2244                                 bool errorThrown = false;
2245                                 try {
2246                                         array.SetValue (value, 0);
2247                                 } catch (InvalidCastException) {
2248                                         errorThrown = true;
2249                                 }
2250
2251                                 Assert.IsTrue (errorThrown, "#M91(" + types [i] + ")");
2252                         }
2253
2254                         for (int i = 0; i < types.Length; i++) {
2255                                 Array array = Array.CreateInstance (types [i], 2);
2256
2257                                 Object value = va2 [i];
2258
2259                                 bool errorThrown = false;
2260                                 try {
2261                                         array.SetValue (value, 0);
2262                                 } catch (InvalidCastException) {
2263                                         errorThrown = true;
2264                                 }
2265
2266                                 Assert.IsTrue (errorThrown, "#M92(" + types [i] + ")");
2267                         }
2268
2269                         for (int i = 0; i < types.Length; i++) {
2270                                 Array array = Array.CreateInstance (types [i], 2);
2271
2272                                 Object value = null;
2273
2274                                 bool errorThrown = false;
2275                                 try {
2276                                         array.SetValue (value, 0);
2277                                 } catch (InvalidCastException) {
2278                                         errorThrown = true;
2279                                 }
2280
2281                                 Assert.IsTrue (!errorThrown, "#M93(" + types [i] + ")");
2282                         }
2283
2284                         // Copy
2285
2286                         for (int i = 0; i < types.Length; i++) {
2287                                 for (int j = 0; j < types.Length; j++) {
2288                                         Array source = Array.CreateInstance (types [i], 2);
2289                                         Array array = Array.CreateInstance (types [j], 2);
2290
2291                                         source.SetValue (vt[j][i], 0);
2292                                         source.SetValue (vt[j][i], 1);
2293
2294                                         bool errorThrown = false;
2295                                         try {
2296                                                 Array.Copy (source, array, 2);
2297                                         } catch (ArrayTypeMismatchException) {
2298                                                 errorThrown = true;
2299                                         }
2300
2301                                         int ex_index = (i * types.Length) + j;
2302
2303                                         Assert.AreEqual (errorThrown, arg_ex [ex_index] == 1, "#M94(" + types [i] + "," + types [j] + ")");
2304                                 }
2305                         }
2306
2307                         for (int i = 0; i < types.Length; i++) {
2308                                 Array source = Array.CreateInstance (types [i], 2);
2309                                 String[] array = new String [2];
2310
2311                                 source.SetValue (va1 [i], 0);
2312                                 source.SetValue (va1 [i], 1);
2313
2314                                 bool errorThrown = false;
2315                                 try {
2316                                         Array.Copy (source, array, 2);
2317                                 } catch (ArrayTypeMismatchException) {
2318                                         errorThrown = true;
2319                                 }
2320
2321                                 Assert.IsTrue (errorThrown, "#M95(" + types [i] + ")");
2322                         }
2323
2324                         for (int i = 0; i < types.Length; i++) {
2325                                 String[] source = new String [2];
2326                                 Array array = Array.CreateInstance (types [i], 2);
2327
2328                                 source.SetValue (va2 [i], 0);
2329                                 source.SetValue (va2 [i], 1);
2330
2331                                 bool errorThrown = false;
2332                                 try {
2333                                         Array.Copy (source, array, 2);
2334                                 } catch (ArrayTypeMismatchException) {
2335                                         errorThrown = true;
2336                                 }
2337
2338                                 Assert.IsTrue (errorThrown, "#M96(" + types [i] + ")");
2339                         }
2340                 }
2341         }
2342
2343         [Test]
2344         public void TestSort() {
2345                 {
2346                         bool errorThrown = false;
2347                         try {
2348                                 Array.Sort(null);
2349                         } catch (ArgumentNullException) {
2350                                 errorThrown = true;
2351                         }
2352                         Assert.IsTrue (errorThrown, "#N01");
2353                 }
2354                 {
2355                         bool errorThrown = false;
2356                         try {
2357                                 Array.Sort(null, 0, 1);
2358                         } catch (ArgumentNullException) {
2359                                 errorThrown = true;
2360                         }
2361                         Assert.IsTrue (errorThrown, "#N02");
2362                 }
2363                 {
2364                         bool errorThrown = false;
2365                         try {
2366                                 char[] c1 = new Char[2];
2367                                 Array.Sort(null, c1);
2368                         } catch (ArgumentNullException) {
2369                                 errorThrown = true;
2370                         }
2371                         Assert.IsTrue (errorThrown, "#N03");
2372                 }
2373                 {
2374                         bool errorThrown = false;
2375                         try {
2376                                 char[] c1 = new Char[2];
2377                                 Array.Sort(null, c1, 0, 1);
2378                         } catch (ArgumentNullException) {
2379                                 errorThrown = true;
2380                         }
2381                         Assert.IsTrue (errorThrown, "#N04");
2382                 }
2383                 {
2384                         int tc = 5;
2385                         char[] arr = {'d', 'b', 'f', 'e', 'a', 'c'};
2386                         
2387                         try {
2388                                 Array.Sort (null, 0, 1);
2389                                 Assert.Fail ("#N" + tc.ToString ());
2390                         }
2391                         catch (ArgumentException) {}
2392                         catch (Exception) { Assert.Fail ("#N" + tc.ToString ()); }
2393                         tc++;
2394                         
2395                         try {
2396                                 Array.Sort (arr, -1, 3);
2397                                 Assert.Fail ("#N" + tc.ToString ());
2398                         }
2399                         catch (ArgumentException) {}
2400                         catch (Exception) { Assert.Fail ("#N" + tc.ToString ()); }
2401                         tc++;
2402                         
2403                         try {
2404                                 Array.Sort (arr, 1, -3);
2405                                 Assert.Fail ("#N" + tc.ToString ());
2406                         }
2407                         catch (ArgumentException) {}
2408                         catch (Exception) { Assert.Fail ("#N" + tc.ToString ()); }
2409                         tc++;
2410                         
2411                         try {
2412                                 Array.Sort (arr, arr.Length, arr.Length + 2);
2413                                 Assert.Fail ("#N" + tc.ToString ());
2414                         }
2415                         catch (ArgumentException) {}
2416                         catch (Exception) { Assert.Fail ("#N" + tc.ToString ()); }
2417                 }
2418                 
2419                 // note: null second array => just sort first array
2420                 char[] starter = {'d', 'b', 'f', 'e', 'a', 'c'};
2421                 int[] starter1 = {1,2,3,4,5,6};
2422                 {
2423                         char[] c1 = (char[])starter.Clone();
2424                         Array.Sort(c1);
2425                         Assert.AreEqual ('a', c1[0], "#N21");
2426                         Assert.AreEqual ('b', c1[1], "#N22");
2427                         Assert.AreEqual ('c', c1[2], "#N23");
2428                         Assert.AreEqual ('d', c1[3], "#N24");
2429                         Assert.AreEqual ('e', c1[4], "#N25");
2430                         Assert.AreEqual ('f', c1[5], "#N26");
2431                 }
2432                 {
2433                         char[] c1 = (char[])starter.Clone();
2434                         int[] i1 = (int[])starter1.Clone();
2435                         Array.Sort(c1, i1);
2436                         Assert.AreEqual ('a', c1[0], "#N41");
2437                         Assert.AreEqual ('b', c1[1], "#N42");
2438                         Assert.AreEqual ('c', c1[2], "#N43");
2439                         Assert.AreEqual ('d', c1[3], "#N44");
2440                         Assert.AreEqual ('e', c1[4], "#N45");
2441                         Assert.AreEqual ('f', c1[5], "#N46");
2442                         Assert.AreEqual (5, i1[0], "#N47");
2443                         Assert.AreEqual (2, i1[1], "#N48");
2444                         Assert.AreEqual (6, i1[2], "#N49");
2445                         Assert.AreEqual (1, i1[3], "#N50");
2446                         Assert.AreEqual (4, i1[4], "#N51");
2447                         Assert.AreEqual (3, i1[5], "#N52");
2448                 }
2449                 {
2450                         char[] c1 = (char[])starter.Clone();
2451                         Array.Sort(c1, 1, 4);
2452                         Assert.AreEqual ('d', c1[0], "#N61");
2453                         Assert.AreEqual ('a', c1[1], "#N62");
2454                         Assert.AreEqual ('b', c1[2], "#N63");
2455                         Assert.AreEqual ('e', c1[3], "#N64");
2456                         Assert.AreEqual ('f', c1[4], "#N65");
2457                         Assert.AreEqual ('c', c1[5], "#N66");
2458                 }
2459                 {
2460                         char[] c1 = (char[])starter.Clone();
2461                         int[] i1 = (int[])starter1.Clone();
2462                         Array.Sort(c1, i1, 1, 4);
2463                         Assert.AreEqual ('d', c1[0], "#N81");
2464                         Assert.AreEqual ('a', c1[1], "#N82");
2465                         Assert.AreEqual ('b', c1[2], "#N83");
2466                         Assert.AreEqual ('e', c1[3], "#N84");
2467                         Assert.AreEqual ('f', c1[4], "#N85");
2468                         Assert.AreEqual ('c', c1[5], "#N86");
2469                         Assert.AreEqual (1, i1[0], "#N87");
2470                         Assert.AreEqual (5, i1[1], "#N88");
2471                         Assert.AreEqual (2, i1[2], "#N89");
2472                         Assert.AreEqual (4, i1[3], "#N90");
2473                         Assert.AreEqual (3, i1[4], "#N91");
2474                         Assert.AreEqual (6, i1[5], "#N92");
2475                 }
2476
2477                 {
2478                         // #648828
2479                         double[] a = new double[115];
2480                         int[] b = new int[256];
2481                         Array.Sort<double, int> (a, b, 0, 115);
2482                 }
2483
2484                 /* Check that ulong[] is not sorted as long[] */
2485                 {
2486                         string[] names = new string[] {
2487                                 "A", "B", "C", "D", "E"
2488                         };
2489
2490                         ulong[] arr = new ulong [] {
2491                                 5,
2492                                 unchecked((ulong)0xffffFFFF00000000),
2493                                         0,
2494                                                 0x7FFFFFFFffffffff,
2495                                                 100
2496                                                 };
2497
2498                         Array a = arr;
2499                         Array.Sort (a, names, null);
2500                         Assert.AreEqual (0, a.GetValue (0));
2501                 }
2502         }
2503
2504         [Test]
2505         public void Sort_NullValues ()
2506         {
2507                 var s = new [] { "a", null, "b", null };
2508                 Array.Sort (s, (a, b) => {
2509                         if (a == null) {
2510                                 return b == null ? 0 : 1;
2511                         }
2512
2513                         if (b == null)
2514                                 return -1;
2515
2516                         return a.CompareTo (b);
2517                 });
2518
2519                 Assert.AreEqual ("a", s [0], "#1");
2520                 Assert.AreEqual ("b", s [1], "#2");
2521                 Assert.IsNull (s [2], "#3");
2522                 Assert.IsNull (s [3], "#4");
2523         }
2524
2525         [Test] // #616416
2526         public void SortNonGenericDoubleItems () {
2527             double[] doubleValues = new double[11];
2528
2529                         doubleValues[0] = 0.221788066253601;
2530                         doubleValues[1] = 0.497278285809481;
2531                         doubleValues[2] = 0.100565033883643;
2532                         doubleValues[3] = 0.0433309347749905;
2533                         doubleValues[4] = 0.00476726438463812;
2534                         doubleValues[5] = 0.1354609735456;
2535                         doubleValues[6] = 0.57690356588135;
2536                         doubleValues[7] = 0.466239434334826;
2537                         doubleValues[8] = 0.409741461978934;
2538                         doubleValues[9] = 0.0112412763949565;
2539                         doubleValues[10] = 0.668704347674307;
2540
2541             int[] indices = new int[11];
2542             indices[0] = 0;
2543             indices[1] = 1;
2544             indices[2] = 2;
2545             indices[3] = 3;
2546             indices[4] = 4;
2547             indices[5] = 5;
2548             indices[6] = 6;
2549             indices[7] = 7;
2550             indices[8] = 8;
2551             indices[9] = 9;
2552             indices[10] = 10;
2553
2554                         Array.Sort ((Array)doubleValues, (Array)indices);
2555                         Assert.AreEqual (4, indices [0]);
2556         }
2557
2558         [Test]
2559         public void TestSortComparable()
2560         {
2561                 int[] source = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
2562                 int[] expected = { 6, 5, 4, 3, 2, 1, 7, 8, 9 };
2563                 Comp[] c = { new Comp (100), new Comp (16), new Comp (11), new Comp (9), new Comp (0), new Comp (-100) };
2564                 IComparer<Comp> comp = null;
2565                 Array.Sort<Comp, int> (c, source, comp);
2566
2567                 Assert.AreEqual (expected, source);
2568         }
2569
2570         class Comp : IComparable
2571         {
2572                 readonly int val;
2573
2574                 public Comp (int a)
2575                 {
2576                         val = a;
2577                 }
2578
2579                 int IComparable.CompareTo (object obj)
2580                 {
2581                         return val.CompareTo ((obj as Comp).val);
2582                 }
2583         }
2584
2585         [Test]
2586         public void TestSortComparableMixed()
2587         {
2588                 var m = new TestSortComparableMixed_Comparer ();
2589                 var arr = new object [] { 1, 2, m, 4, 5, 6, 7, 8, 9, 10 };
2590
2591                 Array.Sort (arr);
2592
2593                 var expected = new object [] { m, 1, 2, 4, 5, 6, 7, 8, 9, 10 };
2594                 Assert.AreEqual (expected, arr);
2595         }
2596
2597         class TestSortComparableMixed_Comparer : IComparable
2598         {
2599                 public int CompareTo (object other)
2600                 {
2601                         return -1;
2602                 }
2603         }
2604
2605         [Test]
2606         public void TestInitializeEmpty()
2607         {
2608                 bool catched=false;
2609                 int[] a = {};
2610                 try
2611                 {
2612                         a.Initialize();
2613                 }
2614                 catch(Exception)
2615                 {
2616                         catched=true;
2617                 }
2618                 Assert.IsTrue (!catched, "#TI01");
2619         }
2620
2621         [Test]
2622         public void TestInitializeInt()
2623         {
2624                 int[] a = {1,2,0};
2625                 a.Initialize();
2626                 int[] b = {1,2,0};
2627                 for(int i=a.GetLowerBound(0);i<=a.GetUpperBound(0);i++)
2628                 {
2629                         Assert.AreEqual (a[i], b[i], "#TI02 " + i);
2630                 }
2631         }
2632
2633         [Test]
2634         public void TestInitializeDouble()
2635         {
2636                 double[] a = {1.0,2.0,0.0};
2637                 a.Initialize();
2638                 double[] b = {1.0,2.0,0.0};
2639                 for(int i=a.GetLowerBound(0);i<=a.GetUpperBound(0);i++)
2640                 {
2641                         Assert.AreEqual (a[i], b[i], "#TI03 " + i);
2642                 }
2643         }
2644
2645         [Test]
2646         public void TestInitializeFloat()
2647         {
2648                 float[] a = {1.0F,2.0F,0.0F};
2649                 a.Initialize();
2650                 float[] b = {1.0F,2.0F,0.0F};
2651                 for(int i=a.GetLowerBound(0);i<=a.GetUpperBound(0);i++)
2652                 {
2653                         Assert.AreEqual (a[i], b[i], "#TI04 " + i);
2654                 }
2655         }
2656
2657         [Test]
2658         public void TestInitializeChar()
2659         {
2660                 char[] a = {'1','.','0','F','2','.','0','F'};
2661                 a.Initialize();
2662                 char[] b = {'1','.','0','F','2','.','0','F'};
2663                 for(int i=a.GetLowerBound(0);i<=a.GetUpperBound(0);i++)
2664                 {
2665                         Assert.AreEqual (a[i], b[i], "#TI05 " + i);
2666                 }
2667         }
2668
2669         [Test]
2670         public void TestInitializeString()
2671         {
2672                 string[] a = {"hola","adios","menos","mas"};
2673                 a.Initialize();
2674                 string[] b = {"hola","adios","menos","mas"};
2675                 for(int i=a.GetLowerBound(0);i<=a.GetUpperBound(0);i++)
2676                 {
2677                         Assert.AreEqual (a[i], b[i], "#TI06 " + i);
2678                 }
2679         }
2680
2681         [Test]
2682         public void TestInitializeEnum()
2683         {
2684                 enua[] a = {enua.hola,enua.adios,enua.menos,enua.mas};
2685                 a.Initialize();
2686                 enua[] b = {enua.hola,enua.adios,enua.menos,enua.mas};
2687                 for(int i=a.GetLowerBound(0);i<=a.GetUpperBound(0);i++)
2688                 {
2689                         Assert.AreEqual (a[i], b[i], "#TI07 " + i);
2690                 }
2691         }
2692         
2693         [Test]
2694         public void TestInitializeIntNI()
2695         {
2696                 int[] a = new int[20];
2697                 a.Initialize();
2698                 foreach(int b in a)
2699                 {
2700                         Assert.AreEqual (b, 0, "#TI08");
2701                 }
2702         }
2703         
2704         [Test]
2705         public void TestInitializeCharNI()
2706         {
2707                 char[] a = new char[20];
2708                 a.Initialize();
2709                 foreach(char b in a)
2710                 {
2711                         Assert.AreEqual (b, 0, "#TI09");
2712                 }
2713         }
2714         
2715         [Test]
2716         public void TestInitializeDoubleNI()
2717         {
2718                 double[] a = new double[20];
2719                 a.Initialize();
2720                 foreach(double b in a)
2721                 {
2722                         Assert.AreEqual (b, 0.0, "#TI09");
2723                 }
2724         }
2725         
2726         [Test]
2727         public void TestInitializeStringNI()
2728         {
2729                 string[] a = new string[20];
2730                 a.Initialize();
2731                 foreach(string b in a)
2732                 {
2733                         Assert.AreEqual (b, null, "#TI10");
2734                 }
2735         }
2736         
2737         [Test]
2738         public void TestInitializeObjectNI()
2739         {
2740                 object[] a = new object[20];
2741                 a.Initialize();
2742                 foreach(object b in a)
2743                 {
2744                         Assert.AreEqual (b, null, "#TI11");
2745                 }
2746         }
2747
2748         [Test]
2749         public void TestInitializeAClassNI()
2750         {
2751                 AClass[] a = new AClass[20];
2752                 a.Initialize();
2753                 foreach(AClass b in a)
2754                 {
2755                         Assert.AreEqual (b, null, "#TI12");
2756                 }
2757         }
2758
2759
2760         [Test]
2761         public void TestInitializeAStructNI()
2762         {
2763                 AStruct[] a = new AStruct[20];
2764                 a.Initialize();
2765                 foreach(AStruct b in a)
2766                 {
2767                         Assert.AreEqual (b, new AStruct(), "#TI14");
2768                 }
2769         }
2770
2771         [Test]
2772         public void TestInitializeAStruct()
2773         {
2774                 AStruct[] a = new AStruct[3];
2775                 a[1].a = "ADIOS";
2776                 a[1].s = "HOLA";
2777                 a.Initialize();
2778                 AStruct[] b = new AStruct[3];
2779                 b[1].a = "ADIOS";
2780                 b[1].s = "HOLA";
2781                 for(int i=a.GetLowerBound(0);i<=a.GetUpperBound(0);i++)
2782                 {
2783                         Assert.AreEqual (a[i], b[i], "#TI15 " + i);
2784                 }
2785         }
2786
2787         [Test]
2788         public void TestInitializeDateTimeNI()
2789         {
2790                 DateTime[] a = new DateTime[20];
2791                 a.Initialize();
2792                 foreach(DateTime b in a)
2793                 {
2794                         Assert.AreEqual (b, new DateTime(), "#TI16");
2795                 }
2796         }
2797         
2798         [Test]
2799         [ExpectedException (typeof (ArgumentNullException))]
2800         public void MoreSort1 ()
2801         {
2802                 Array.Sort (null, 0, 1);
2803         }
2804
2805         [Test]
2806         [ExpectedException (typeof (ArgumentOutOfRangeException))]
2807         public void MoreSort2 ()
2808         {
2809                 Array.Sort (arrsort, -1, 3);
2810         }
2811
2812         [Test]
2813         [ExpectedException (typeof (ArgumentOutOfRangeException))]
2814         public void MoreSort3 ()
2815         {
2816                 Array.Sort (arrsort, 1, -3);
2817         }
2818
2819         [Test]
2820         [ExpectedException (typeof (ArgumentException))]
2821         public void MoreSort4 ()
2822         {
2823                 Array.Sort (arrsort, arrsort.Length, arrsort.Length + 2);
2824         }
2825
2826         [Test]
2827         [ExpectedException (typeof (RankException))]
2828         public void MoreSort5 ()
2829         {
2830                 char [,] arr = new char [,] {{'a'}, {'b'}};
2831                 Array.Sort (arr, 0, 1);
2832         }
2833
2834         [Test]
2835         public void MoreSort6 ()
2836         {
2837                 Array.Sort (arrsort, 0, 0);
2838         }
2839
2840         [Test]
2841         [ExpectedException (typeof (ArgumentException))]
2842         public void MoreSort7 ()
2843         {
2844                 Array.Sort (arrsort, arrsort.Length - 1, 2);
2845         }
2846
2847         [Test]
2848         [ExpectedException (typeof (ArgumentException))]
2849         public void MoreSort8 ()
2850         {
2851                 Array.Sort (arrsort, 0, arrsort.Length + 1);
2852         }
2853
2854         [Test]
2855         public void MoreSort9 ()
2856         {
2857                 Array.Sort (arrsort, null, 0, arrsort.Length, null);
2858         }
2859
2860         [Test]
2861         [ExpectedException (typeof (InvalidOperationException))]
2862         public void MoreSort10 ()
2863         {
2864                 object [] array = {true, 'k', SByte.MinValue, Byte.MinValue, (short) 2, 634, (long) 436, (float) 1.1, 1.23, "Hello World"};
2865                 Array.Sort (array, (IComparer) null);
2866         }
2867
2868         [Test] // bug #81941
2869         public void Sort ()
2870         {
2871                 double [] a = new double [2] { 0.9, 0.3 };
2872                 uint [] b = new uint [2] { 4, 7 };
2873                 Array.Sort (a, b);
2874                 Assert.AreEqual (0.3, a [0], "#1");
2875                 Assert.AreEqual (0.9, a [1], "#2");
2876                 Assert.AreEqual (7, b [0], "#3");
2877                 Assert.AreEqual (4, b [1], "#4");
2878         }
2879
2880         [Test]
2881         public void ClearJaggedArray () 
2882         {
2883                 byte[][] matrix = new byte [8][];
2884                 for (int i=0; i < 8; i++) {
2885                         matrix [i] = new byte [8];
2886                         for (int j=0; j < 8; j++) {
2887                                 matrix [i][j] = 1;
2888                         }
2889                 }
2890                 Array.Clear (matrix, 0, 8);
2891                 for (int i=0; i < 8; i++) {
2892                         Assert.IsNull (matrix [i], i.ToString ());
2893                 }
2894         }
2895
2896         [Test]
2897         public void ClearMultidimentionalArray () 
2898         {
2899                 byte[,] matrix = new byte [2,2] { {1, 1}, {2, 2} };
2900                 Array.Clear (matrix, 0, 2);
2901                 Assert.AreEqual (0, matrix [0, 0], "0,0");
2902                 Assert.AreEqual (0, matrix [0, 1], "0,1");
2903                 Assert.AreEqual (2, matrix [1, 0], "1,0");
2904                 Assert.AreEqual (2, matrix [1, 1], "1,1");
2905         }
2906
2907         [Test]
2908         [ExpectedException (typeof (IndexOutOfRangeException))]
2909         public void ClearOutsideMultidimentionalArray () 
2910         {
2911                 byte[,] matrix = new byte [2,2] { {1, 1}, {2, 2} };
2912                 Array.Clear (matrix, 0, 5);
2913         }
2914
2915         [Test]
2916         [ExpectedException (typeof (IndexOutOfRangeException))]
2917         public void Clear_IndexOverflow () 
2918         {
2919                 byte[] array = new byte [16];
2920                 Array.Clear (array, 4, Int32.MaxValue);
2921         }
2922
2923         [Test]
2924         [ExpectedException (typeof (IndexOutOfRangeException))]
2925         public void Clear_LengthOverflow () 
2926         {
2927                 byte[] array = new byte [16];
2928                 Array.Clear (array, Int32.MaxValue, 4);
2929         }
2930
2931         [Test]
2932         [ExpectedException (typeof (ArgumentException))]
2933         public void Copy_SourceIndexOverflow () 
2934         {
2935                 byte[] array = new byte [16];
2936                 Array.Copy (array, Int32.MaxValue, array, 8, 8);
2937         }
2938
2939         [Test]
2940         [ExpectedException (typeof (ArgumentException))]
2941         public void Copy_DestinationIndexOverflow () 
2942         {
2943                 byte[] array = new byte [16];
2944                 Array.Copy (array, 8, array, Int32.MaxValue, 8);
2945         }
2946
2947         [Test]
2948         [ExpectedException (typeof (ArgumentException))]
2949         public void Copy_LengthOverflow () 
2950         {
2951                 byte[] array = new byte [16];
2952                 Array.Copy (array, 8, array, 8, Int32.MaxValue);
2953         }
2954
2955         [Test]
2956         [ExpectedException (typeof (ArgumentException))]
2957         public void Reverse_IndexOverflow () 
2958         {
2959                 byte[] array = new byte [16];
2960                 Array.Reverse (array, Int32.MaxValue, 8);
2961         }
2962
2963         [Test]
2964         [ExpectedException (typeof (ArgumentException))]
2965         public void Reverse_LengthOverflow () 
2966         {
2967                 byte[] array = new byte [16];
2968                 Array.Reverse (array, 8, Int32.MaxValue);
2969         }
2970         
2971         public struct CharX : IComparable {
2972                 public char c;
2973         
2974                 public CharX (char c)
2975                 {
2976                         this.c = c;
2977                 }
2978         
2979                 public int CompareTo (object obj)
2980                 {
2981                         if (obj is CharX)
2982                                 return c.CompareTo (((CharX) obj).c);
2983                         else
2984                                 return c.CompareTo (obj);
2985                 }
2986         }
2987
2988         [Test]
2989         public void BinarySearch_ArgPassingOrder ()
2990         {
2991                 //
2992                 // This tests that arguments are passed to the comprer in the correct
2993                 // order. The IComparable of the *array* elements must get called, not
2994                 // that of the search object.
2995                 //
2996                 CharX [] x = { new CharX ('a'), new CharX ('b'), new CharX ('c') };
2997                 Assert.AreEqual (1, Array.BinarySearch (x, 'b'));
2998         }
2999
3000         class Comparer: IComparer {
3001
3002                 private bool called = false;
3003
3004                 public bool Called {
3005                         get {
3006                                 bool result = called;
3007                                 called = false;
3008                                 return called;
3009                         }
3010                 }
3011
3012                 public int Compare (object x, object y)
3013                 {
3014                         called = true;
3015                         return 0;
3016                 }
3017         }
3018
3019         [Test]
3020         public void BinarySearch1_EmptyList ()
3021         {
3022                 int[] array = new int[0];
3023                 Assert.AreEqual (- 1, Array.BinarySearch (array, 0), "BinarySearch");
3024         }
3025
3026         [Test]
3027         public void BinarySearch2_EmptyList ()
3028         {
3029                 int[] array = new int[0];
3030                 Assert.AreEqual (-1, Array.BinarySearch (array, 0, 0, 0), "BinarySearch");
3031         }
3032
3033         [Test]
3034         public void BinarySearch3_EmptyList ()
3035         {
3036                 Comparer comparer = new Comparer ();
3037                 int[] array = new int[0];
3038                 Assert.AreEqual (-1, Array.BinarySearch (array, 0, comparer), "BinarySearch");
3039                 // bug 77030 - the comparer isn't called for an empty array/list
3040                 Assert.IsTrue (!comparer.Called, "Called");
3041         }
3042
3043         [Test]
3044         public void BinarySearch4_EmptyList ()
3045         {
3046                 Comparer comparer = new Comparer ();
3047                 int[] array = new int[0];
3048                 Assert.AreEqual (-1, Array.BinarySearch (array, 0, 0, comparer), "BinarySearch");
3049                 // bug 77030 - the comparer isn't called for an empty array/list
3050                 Assert.IsTrue (!comparer.Called, "Called");
3051         }
3052
3053         [Test]
3054         [ExpectedException (typeof (ArgumentNullException))]
3055         public void AsReadOnly_NullArray ()
3056         {
3057                 Array.AsReadOnly <int> (null);
3058         }
3059
3060         [Test]
3061         public void ReadOnly_Count ()
3062         {
3063                 Assert.AreEqual (10, Array.AsReadOnly (new int [10]).Count);
3064         }
3065
3066         [Test]
3067         public void ReadOnly_Contains ()
3068         {
3069                 int[] arr = new int [2];
3070                 arr [0] = 3;
3071                 arr [1] = 5;
3072                 IList<int> a = Array.AsReadOnly (arr);
3073
3074                 Assert.IsTrue (a.Contains (3));
3075                 Assert.IsTrue (!a.Contains (6));
3076         }
3077
3078         [Test]
3079         public void ReadOnly_IndexOf ()
3080         {
3081                 int[] arr = new int [2];
3082                 arr [0] = 3;
3083                 arr [1] = 5;
3084                 IList<int> a = Array.AsReadOnly (arr);
3085
3086                 Assert.AreEqual (0, a.IndexOf (3));
3087                 Assert.AreEqual (1, a.IndexOf (5));
3088                 Assert.AreEqual (-1, a.IndexOf (6));
3089         }
3090
3091         [Test]
3092         public void ReadOnly_Indexer ()
3093         {
3094                 int[] arr = new int [2];
3095                 arr [0] = 3;
3096                 arr [1] = 5;
3097                 IList<int> a = Array.AsReadOnly (arr);
3098
3099                 Assert.AreEqual (3, a [0]);
3100                 Assert.AreEqual (5, a [1]);
3101
3102                 /* Check that modifications to the original array are visible */
3103                 arr [0] = 6;
3104                 Assert.AreEqual (6, a [0]);
3105         }
3106
3107         [Test]
3108         public void ReadOnly_Enumerator ()
3109         {
3110                 int[] arr = new int [10];
3111
3112                 for (int i = 0; i < 10; ++i)
3113                         arr [i] = i;
3114
3115                 int sum = 0;
3116                 foreach (int i in Array.AsReadOnly (arr))
3117                         sum += i;
3118
3119                 Assert.AreEqual (45, sum);
3120         }
3121
3122         [Test]
3123         public void ReadOnly_CopyTo ()
3124         {
3125                 int[] arr = new int [2];
3126                 arr [0] = 3;
3127                 arr [1] = 5;
3128                 IList<int> a = Array.AsReadOnly (arr);
3129
3130                 int[] arr2 = new int [3];
3131                 a.CopyTo (arr2, 1);
3132
3133                 Assert.AreEqual (0, arr2 [0]);
3134                 Assert.AreEqual (3, arr2 [1]);
3135                 Assert.AreEqual (5, arr2 [2]);
3136         }
3137
3138         [Test]
3139         public void Resize ()
3140         {
3141                 int [] arr = new int [] { 1, 3, 5 };
3142                 Array.Resize <int> (ref arr, 3);
3143                 Assert.AreEqual (3, arr.Length, "#A1");
3144                 Assert.AreEqual (1, arr [0], "#A2");
3145                 Assert.AreEqual (3, arr [1], "#A3");
3146                 Assert.AreEqual (5, arr [2], "#A4");
3147
3148                 Array.Resize <int> (ref arr, 2);
3149                 Assert.AreEqual (2, arr.Length, "#B1");
3150                 Assert.AreEqual (1, arr [0], "#B2");
3151                 Assert.AreEqual (3, arr [1], "#B3");
3152
3153                 Array.Resize <int> (ref arr, 4);
3154                 Assert.AreEqual (4, arr.Length, "#C1");
3155                 Assert.AreEqual (1, arr [0], "#C2");
3156                 Assert.AreEqual (3, arr [1], "#C3");
3157                 Assert.AreEqual (0, arr [2], "#C4");
3158                 Assert.AreEqual (0, arr [3], "#C5");
3159         }
3160
3161         [Test]
3162         public void Resize_null ()
3163         {
3164                 int [] arr = null;
3165                 Array.Resize (ref arr, 10);
3166                 Assert.AreEqual (arr.Length, 10);
3167         }
3168
3169         [Test]
3170         public void Test_ContainsAndIndexOf_EquatableItem ()
3171         {
3172                 EquatableClass[] list = new EquatableClass[] {new EquatableClass (0), new EquatableClass (1), new EquatableClass (0)};
3173
3174                 Assert.AreEqual (0, Array.IndexOf<EquatableClass> (list, list[0]), "#0");
3175                 Assert.AreEqual (0, Array.IndexOf<EquatableClass> (list, new EquatableClass (0)), "#1");
3176                 Assert.AreEqual (2, Array.LastIndexOf<EquatableClass> (list, list[0]), "#2");
3177                 Assert.AreEqual (2, Array.LastIndexOf<EquatableClass> (list, new EquatableClass (0)), "#3");
3178         }
3179
3180         public class EquatableClass : IEquatable<EquatableClass>
3181         {
3182                 int _x;
3183                 public EquatableClass (int x)
3184                 {
3185                         _x = x;
3186                 }
3187
3188                 public bool Equals (EquatableClass other)
3189                 {
3190                         return this._x == other._x;
3191                 }
3192         }
3193
3194         [Test]
3195         public void AsIList ()
3196         {
3197                 IList<int> arr = new int [10];
3198                 arr [0] = 5;
3199                 Assert.AreEqual (5, arr [0]);
3200
3201                 IList<FooStruct> arr2 = new FooStruct [10];
3202                 FooStruct s = new FooStruct ();
3203                 s.i = 11;
3204                 s.j = 22;
3205                 arr2 [5] = s;
3206                 s = arr2 [5];
3207                 Assert.AreEqual (11, s.i);
3208                 Assert.AreEqual (22, s.j);
3209
3210                 IList<string> arr3 = new string [10];
3211                 arr3 [5] = "ABC";
3212                 Assert.AreEqual ("ABC", arr3 [5]);
3213         }
3214
3215         struct FooStruct {
3216                 public int i, j;
3217         }
3218
3219         [Test]
3220         // From bug #80563
3221         public void ICollectionNull ()
3222         {
3223                 ICollection<object> test;
3224                 
3225                 test = new List<object>();
3226                 Assert.AreEqual (test.Contains (null), false, "list<o>");
3227
3228                 test = new object[] {};
3229                 Assert.AreEqual (test.Contains (null), false, "empty array");
3230
3231                 test = new object[] {null};
3232                 Assert.AreEqual (test.Contains (null), true, "array with null");
3233
3234                 test = new object[] { 1, null};
3235                 Assert.IsTrue (test.Contains (null), "array with last null");
3236                 
3237                 test = new List<object>(test);
3238                 Assert.AreEqual (test.Contains (null), true, "List<object> with test");
3239                 
3240                 test = new object[] {new object()};
3241                 Assert.AreEqual (test.Contains (null), false, "array with object");
3242
3243                 test = new List<object>(test);
3244                 Assert.AreEqual (test.Contains (null), false, "array with test");
3245         }
3246         
3247         [Test]
3248         public void IListNull ()
3249         {
3250                 IList<object> test;
3251                 
3252                 test = new List<object>();
3253                 Assert.AreEqual (-1, test.IndexOf (null), "list<o>");
3254
3255                 test = new object[] {};
3256                 Assert.AreEqual (-1, test.IndexOf (null), "empty array");
3257
3258                 test = new object[] {null};
3259                 Assert.AreEqual (0, test.IndexOf (null), "array with null");
3260
3261                 test = new object[] { 1, null};
3262                 Assert.AreEqual (1, test.IndexOf (null), "array with last null");
3263                 
3264                 test = new List<object>(test);
3265                 Assert.AreEqual (1, test.IndexOf (null), "List<object> with test");
3266                 
3267                 test = new object[] {new object()};
3268                 Assert.AreEqual (-1, test.IndexOf (null), "array with object");
3269
3270                 test = new List<object>(test);
3271                 Assert.AreEqual (-1, test.IndexOf (null), "array with test");
3272         }
3273         
3274
3275         #region Bug 80299
3276
3277         enum ByteEnum : byte {}
3278         enum IntEnum : int {}
3279
3280         [Test]
3281         public void TestByteEnumArrayToByteArray ()
3282         {
3283                 ByteEnum[] a = new ByteEnum[] {(ByteEnum) 1, (ByteEnum) 2};
3284                 byte[] b = new byte[a.Length];
3285                 a.CopyTo (b, 0);
3286         }
3287
3288         [Test]
3289         public void TestByteEnumArrayToIntArray ()
3290         {
3291                 ByteEnum[] a = new ByteEnum[] {(ByteEnum) 1, (ByteEnum) 2};
3292                 int[] b = new int[a.Length];
3293                 a.CopyTo (b, 0);
3294         }
3295
3296         [Test]
3297         [ExpectedException (typeof (ArrayTypeMismatchException))]
3298         public void TestIntEnumArrayToByteArray ()
3299         {
3300                 IntEnum[] a = new IntEnum[] {(IntEnum) 1, (IntEnum) 2};
3301                 byte[] b = new byte[a.Length];
3302                 a.CopyTo (b, 0);
3303         }
3304
3305         [Test]
3306         public void TestIntEnumArrayToIntArray ()
3307         {
3308                 IntEnum[] a = new IntEnum[] {(IntEnum) 1, (IntEnum) 2};
3309                 int[] b = new int[a.Length];
3310                 a.CopyTo (b, 0);
3311         }
3312
3313         #endregion
3314
3315         [Test] // bug #322248
3316         public void IEnumerator_Reset ()
3317         {
3318                 int[] array = new int[] { 1, 2, 3};
3319                 IEnumerator<int> e = ((IEnumerable<int>)array).GetEnumerator ();
3320                 Assert.IsTrue (e.MoveNext (), "#A1");
3321                 Assert.AreEqual (1, e.Current, "#A2");
3322                 Assert.IsTrue (e.MoveNext (), "#A3");
3323                 Assert.AreEqual (2, e.Current, "#A4");
3324
3325                 e.Reset ();
3326
3327                 Assert.IsTrue (e.MoveNext (), "#C1");
3328                 Assert.AreEqual (1, e.Current, "#C2");
3329         }
3330
3331         [Test]
3332         public void IEnumerator_Current_Finished ()
3333         {
3334                 int[] array = new int[] { 1, 2, 3 };
3335                 IEnumerator<int> e = ((IEnumerable<int>)array).GetEnumerator ();
3336                 Assert.IsTrue (e.MoveNext (), "#A1");
3337                 Assert.AreEqual (1, e.Current, "#A2");
3338                 Assert.IsTrue (e.MoveNext (), "#A3");
3339                 Assert.AreEqual (2, e.Current, "#A4");
3340                 Assert.IsTrue (e.MoveNext (), "#A5");
3341                 Assert.AreEqual (3, e.Current, "#A6");
3342                 Assert.IsTrue (!e.MoveNext (), "#A6");
3343
3344                 try {
3345                         Assert.Fail ("#B1:" + e.Current);
3346                 } catch (InvalidOperationException ex) {
3347                         // Enumeration already finished
3348                         Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
3349                         Assert.IsNull (ex.InnerException, "#B3");
3350                         Assert.IsNotNull (ex.Message, "#B4");
3351                 }
3352         }
3353
3354         [Test]
3355         public void IEnumerator_Current_NotStarted ()
3356         {
3357                 int[] array = new int[] { 1, 2, 3 };
3358                 IEnumerator<int> e = ((IEnumerable<int>)array).GetEnumerator ();
3359
3360                 try {
3361                         Assert.Fail ("#A1:" + e.Current);
3362                 } catch (InvalidOperationException ex) {
3363                         // Enumeration has not started. Call MoveNext
3364                         Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2");
3365                         Assert.IsNull (ex.InnerException, "#A3");
3366                         Assert.IsNotNull (ex.Message, "#A4");
3367                 }
3368         }
3369
3370         [Test]
3371         public void IEnumerator_Current_Reset ()
3372         {
3373                 int[] array = new int[] { 1, 2, 3 };
3374                 IEnumerator<int> e = ((IEnumerable<int>)array).GetEnumerator ();
3375                 e.MoveNext ();
3376                 e.Reset ();
3377
3378                 try {
3379                         Assert.Fail ("#B1:" + e.Current);
3380                 } catch (InvalidOperationException ex) {
3381                         // Enumeration has not started. Call MoveNext
3382                         Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
3383                         Assert.IsNull (ex.InnerException, "#B3");
3384                         Assert.IsNotNull (ex.Message, "#B4");
3385                 }
3386         }
3387
3388         [Test]
3389         public void IEnumerator_Dispose ()
3390         {
3391                 IEnumerable<int> e = new int[] { 1 };
3392                 var en = e.GetEnumerator ();
3393                 Assert.IsTrue (en.MoveNext (), "#1");
3394                 Assert.IsFalse (en.MoveNext (), "#2");
3395                 en.Dispose ();
3396                 Assert.IsFalse (en.MoveNext (), "#3");
3397         }
3398
3399         [Test]
3400         public void IEnumerator_ZeroSize ()
3401         {
3402                 IEnumerable<int> e = Array.Empty<int> ();
3403                 var en = e.GetEnumerator ();
3404                 Assert.IsFalse (en.MoveNext (), "#1");
3405
3406                 e = Array.Empty<int> ();
3407                 en = e.GetEnumerator ();
3408                 Assert.IsFalse (en.MoveNext (), "#2");
3409         }
3410
3411         [Test]
3412         public void ICollection_IsReadOnly() {
3413                 ICollection<string> arr = new string [10];
3414
3415                 Assert.IsTrue (arr.IsReadOnly);
3416         }
3417
3418         [Test]
3419         [ExpectedException (typeof (NotSupportedException))]
3420         public void ArrayCreateInstanceOfVoid ()
3421         {
3422                 Array.CreateInstance (typeof (void), 42);
3423         }
3424
3425         class Foo<T> {}
3426
3427         [Test]
3428         [ExpectedException (typeof (NotSupportedException))]
3429         public void ArrayCreateInstanceOfOpenGenericType ()
3430         {
3431                 Array.CreateInstance (typeof (Foo<>), 42);
3432         }
3433
3434         [Test]
3435         [ExpectedException (typeof (IndexOutOfRangeException))]
3436         public void ClearNegativeLength ()
3437         {
3438                 Array.Clear (new int [] { 1, 2 }, 0, -1);
3439         }
3440
3441         [Test]
3442         [ExpectedException (typeof (ArgumentException))]
3443         public void MultiDimension_IList_setItem ()
3444         {
3445                 IList array = new int [1, 1];
3446                 array [0] = 2;
3447         }
3448
3449         [Test]
3450         [ExpectedException (typeof (ArgumentException))]
3451         public void MultiDimension_IList_getItem ()
3452         {
3453                 IList array = new int [1, 1];
3454                 int a = (int) array [0];
3455         }
3456
3457         [Test]
3458         public void SetValue_Nullable () {
3459                 Array array = Array.CreateInstance (typeof (int?), 7);
3460
3461                 object o = 42;
3462
3463                 array.SetValue (o, 0);
3464                 Assert.AreEqual (42, array.GetValue (0));
3465
3466                 array.SetValue (null, 0);
3467                 Assert.AreEqual (null, array.GetValue (0));
3468         }
3469
3470         [Test]
3471         public void SortNullsWithGenericVersion ()
3472         {
3473             string[] s1 = new string[6]{
3474                 "J",
3475                 "M",
3476                  null,
3477                 "P",
3478                 "T",
3479                 "A"};
3480
3481             string[] s2 = new string[]{null,
3482                 "A",
3483                 "J",
3484                 "M",
3485                 "P",
3486                 "T"};
3487
3488             Array.Sort<string> (s1);
3489             for (int i = 0; i < 6; i++) {
3490                     Assert.AreEqual (s1[i], s2[i], "At:" + i);
3491             }
3492         }
3493         
3494         //
3495         // This is a test case for the case that was broken by the code contributed
3496         // for bug  #351638.
3497         //
3498         // This tests the fix for: #622101
3499         //
3500         [Test]
3501         public void SortActuallyWorks ()
3502         {
3503                 string[] data = new string[9]{"Foo", "Bar", "Dingus", null, "Dingu4", "123", "Iam", null, "NotNull"};
3504                 IComparer comparer = new NullAtEndComparer ();
3505                 Array.Sort (data, comparer);
3506
3507                 Assert.AreEqual (data [7], null);
3508                 Assert.AreNotEqual (data [0], null);
3509         }
3510
3511         class NullAtEndComparer : IComparer {
3512                 public int Compare(object x, object y)
3513                 {
3514                         if (x == null) return 1;
3515                         if (y == null) return -1;
3516                         return ((string)x).CompareTo((string)y);
3517                 }
3518         }
3519
3520         [Test] //bxc #11184
3521         public void UnalignedArrayClear ()
3522         {
3523                 byte[] input = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
3524                 byte[] expected = new byte[] { 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
3525                 Array.Clear (input, 5, 11);
3526                 
3527                 Assert.AreEqual (input, expected);
3528         }
3529
3530         [Test]
3531         [ExpectedException (typeof (ArgumentException))]
3532         public void CompareToWithJaggedArray () {
3533                 IStructuralComparable a = new int[][] { new int [] { 1,2 }, new int [] { 3,4 }};
3534                 IStructuralComparable b = new int[][] { new int [] { 1,2 }, new int [] { 3,4 }};
3535                 a.CompareTo (b, Comparer<object>.Default);
3536         }
3537
3538         [Test]
3539         [ExpectedException (typeof (ArgumentException))]
3540         public void CompareToWithArrayOfTheWrongKind () {
3541                 IStructuralComparable a = new int[] { 1, 2 };
3542                 IStructuralComparable b = new double[] { 1, 2 };
3543                 a.CompareTo (b, Comparer<object>.Default);
3544         }
3545
3546         [Test]
3547         [ExpectedException (typeof (ArgumentException))]
3548         public void CompareToWithNonArrayType () {
3549                 IStructuralComparable a = new int[] { 1, 2 };
3550                 a.CompareTo (99, Comparer<object>.Default);
3551         }
3552
3553         [Test]
3554         [ExpectedException (typeof (ArgumentException))]
3555         public void CompareToWithNonArrayOfDifferentSize () {
3556                 IStructuralComparable a = new int[] { 1, 2 };
3557                 IStructuralComparable b = new int[] { 1, 2, 3 };
3558                 a.CompareTo (b, Comparer<object>.Default);
3559         }
3560
3561         [Test]
3562         [ExpectedException (typeof (ArgumentException))]
3563         public void CompareToWithMultiDimArray1 () {
3564                 IStructuralComparable a = new int [2,2] { {10, 10 }, { 10, 10 } };
3565                 IStructuralComparable b = new int [2,2] { {10, 10 }, { 10, 10 } };
3566                 a.CompareTo (b, Comparer<object>.Default);
3567         }
3568
3569         [Test]
3570         [ExpectedException (typeof (ArgumentException))]
3571         public void CompareToWithMultiDimArray2 () {
3572                 IStructuralComparable a = new int [2] { 10, 10 };
3573                 IStructuralComparable b = new int [2,2] { {10, 10 }, { 10, 10 } };
3574                 a.CompareTo (b, Comparer<object>.Default);
3575         }
3576
3577         [Test]
3578         [ExpectedException (typeof (ArgumentException))]
3579         public void CompareToWithMultiDimArray3 () {
3580                 IStructuralComparable a = new int [4] { 10, 10, 10, 10 };
3581                 IStructuralComparable b = new int [2,2] { {10, 10 }, { 10, 10 } };
3582                 a.CompareTo (b, Comparer<object>.Default);
3583         }
3584
3585         [Test]
3586         [ExpectedException (typeof (IndexOutOfRangeException))]
3587         public void CompareToWithBoundedArray1 () {
3588                 IStructuralComparable a = new int [2] { 10, 10 };
3589                 Array ab = Array.CreateInstance (typeof (int), new int[] { 2 }, new int [] { 5 });
3590                 IStructuralComparable b = ab;
3591                 ab.SetValue (10, 5);
3592                 ab.SetValue (10, 6);
3593
3594                 a.CompareTo (b, Comparer<object>.Default);
3595         }
3596
3597         [Test]
3598         [ExpectedException (typeof (IndexOutOfRangeException))]
3599         public void CompareToWithBoundedArray2 () {
3600                 IStructuralComparable a = new int [2] { 10, 10 };
3601                 Array ab = Array.CreateInstance (typeof (int), new int[] { 2 }, new int [] { 5 });
3602                 IStructuralComparable b = ab;
3603                 ab.SetValue (10, 5);
3604                 ab.SetValue (10, 6);
3605
3606                 //Yes, CompareTo simply doesn't work with bounded arrays!
3607                 b.CompareTo (b, Comparer<object>.Default);
3608         }
3609
3610         [Test]
3611         [ExpectedException (typeof (NullReferenceException))]
3612         public void CompareToWithNullComparer () {
3613                 IStructuralComparable a = new int[] { 1, 2 };
3614                 IStructuralComparable b = new int[] { 1, 2 };
3615                 a.CompareTo (b, null);
3616         }
3617
3618         [Test]
3619         public void CompareToWithNullArray () {
3620                 IStructuralComparable a = new int[] { 1, 2 };
3621                 Assert.AreEqual (1, a.CompareTo (null, Comparer<object>.Default));
3622         }
3623
3624         [Test]
3625         public void CompareToWithGoodArrays () {
3626                 IStructuralComparable a = new int[] { 10, 20 };
3627                 Assert.AreEqual (0, a.CompareTo (a, Comparer<object>.Default));
3628                 Assert.AreEqual (0, a.CompareTo (new int [] { 10, 20 }, Comparer<object>.Default));
3629                 Assert.AreEqual (-1, a.CompareTo (new int [] { 11, 20 }, Comparer<object>.Default));
3630                 Assert.AreEqual (-1, a.CompareTo (new int [] { 10, 21 }, Comparer<object>.Default));
3631                 Assert.AreEqual (1, a.CompareTo (new int [] { 9, 20 }, Comparer<object>.Default));
3632                 Assert.AreEqual (1, a.CompareTo (new int [] { 10, 19 }, Comparer<object>.Default));
3633         }
3634
3635         [Test]
3636         public void IStructuralEquatable_Equals ()
3637         {
3638                 IStructuralEquatable array = new int[] {1, 2, 3};
3639                 IStructuralEquatable array2 = new int[] {1, 2, 3};
3640                 Assert.AreEqual (false, array.Equals (null, null));
3641                 Assert.AreEqual (true, array.Equals (array, null));
3642                 Assert.AreEqual (true, array.Equals (array2, EqualityComparer<int>.Default));
3643         }
3644
3645         [Test]
3646         [ExpectedException (typeof (NullReferenceException))]
3647         public void IStructuralEquatable_Equals_NoComparer ()
3648         {
3649                 IStructuralEquatable array = new int[] {1, 2, 3};
3650                 IStructuralComparable array2 = new int[] {1, 2, 3};
3651                 array.Equals (array2, null);
3652         }
3653
3654         [Test]
3655         [ExpectedException (typeof (ArgumentException))]
3656         public void IStructuralEquatable_Equals_ComparerThrows ()
3657         {
3658                 IStructuralEquatable array = new int[] {1, 2, 3};
3659                 IStructuralComparable array2 = new int[] {1, 2, 3};
3660                 array.Equals (array2, EqualityComparer<long>.Default);
3661         }
3662
3663         [Test]
3664         [ExpectedException (typeof (ArgumentNullException))]    
3665         public void IStructuralEquatable_GetHashCode_NullComparer ()
3666         {
3667                 IStructuralEquatable a = new int[] { 1, 2 };
3668                 a.GetHashCode (null);
3669         }
3670
3671         class TestComparer_GetHashCode : IEqualityComparer
3672         {
3673                 public int Counter;
3674
3675                 bool IEqualityComparer.Equals (object x, object y)
3676                 {
3677                         throw new NotImplementedException ();
3678                 }
3679
3680                 public int GetHashCode (object obj)
3681                 {
3682                         return Counter++;
3683                 }
3684         }
3685
3686         [Test]
3687         public void IStructuralEquatable_GetHashCode ()
3688         {
3689                 IStructuralEquatable a = new int[] { 1, 2, 9 };
3690
3691                 var c = new TestComparer_GetHashCode ();
3692                 a.GetHashCode (c);
3693                 Assert.AreEqual (3, c.Counter);         
3694         }
3695
3696         [Test]
3697         public void EnumeratorsEquality ()
3698         {
3699                 int [] normalBase = new int [0];
3700                 IEnumerable<int> specialBase = new int [0];
3701
3702                 var firstSpecial = specialBase.GetEnumerator ();
3703                 var secondSpecial = specialBase.GetEnumerator ();
3704                 var firstNormal = normalBase.GetEnumerator ();
3705                 var secondNormal = normalBase.GetEnumerator ();
3706
3707                 Assert.IsFalse (object.ReferenceEquals (firstNormal, secondNormal));
3708                 Assert.IsTrue (object.ReferenceEquals (firstSpecial, secondSpecial));
3709         }
3710
3711         [Test]
3712         public void JaggedArrayCtor ()
3713         {
3714         var type = Type.GetType ("System.Object[][]");
3715
3716                 ConstructorInfo ctor = null;
3717         foreach (var c in type.GetConstructors ()) {
3718                         if (c.GetParameters ().Length == 2)
3719                                 ctor = c;
3720                 }
3721                 Assert.IsNotNull (ctor);
3722                 var arr = (object[])ctor.Invoke (new object [] { 4, 10 });
3723                 for (int i = 0; i < 4; ++i) {
3724                         Assert.IsNotNull (arr [i]);
3725                         Assert.AreEqual (10, ((object[])arr [i]).Length);
3726                 }
3727         }
3728
3729         [Test]
3730         public unsafe void PointerArraysBoxing ()
3731         {
3732                 var x = new int*[10];
3733                 var e = x.GetEnumerator ();
3734                 e.MoveNext ();
3735
3736                 Assert.Throws<NotSupportedException> (() => { var _ = e.Current; }, "#1");
3737                 Assert.Throws<NotSupportedException> (() => { var _ = x.GetValue (0); }, "#2");
3738                 Assert.Throws<NotSupportedException> (() => { x.SetValue (0, 0); }, "#3");
3739         }
3740 }
3741 }