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