Merge pull request #656 from LogosBible/collection_lock
[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]
2514         public void Sort_NullValues ()
2515         {
2516                 var s = new [] { "a", null, "b", null };
2517                 Array.Sort (s, (a, b) => {
2518                         if (a == null) {
2519                                 return b == null ? 0 : 1;
2520                         }
2521
2522                         if (b == null)
2523                                 return -1;
2524
2525                         return a.CompareTo (b);
2526                 });
2527
2528                 Assert.AreEqual ("a", s [0], "#1");
2529                 Assert.AreEqual ("b", s [1], "#2");
2530                 Assert.IsNull (s [2], "#3");
2531                 Assert.IsNull (s [3], "#4");
2532         }
2533
2534         [Test] // #616416
2535         public void SortNonGenericDoubleItems () {
2536             double[] doubleValues = new double[11];
2537
2538                         doubleValues[0] = 0.221788066253601;
2539                         doubleValues[1] = 0.497278285809481;
2540                         doubleValues[2] = 0.100565033883643;
2541                         doubleValues[3] = 0.0433309347749905;
2542                         doubleValues[4] = 0.00476726438463812;
2543                         doubleValues[5] = 0.1354609735456;
2544                         doubleValues[6] = 0.57690356588135;
2545                         doubleValues[7] = 0.466239434334826;
2546                         doubleValues[8] = 0.409741461978934;
2547                         doubleValues[9] = 0.0112412763949565;
2548                         doubleValues[10] = 0.668704347674307;
2549
2550             int[] indices = new int[11];
2551             indices[0] = 0;
2552             indices[1] = 1;
2553             indices[2] = 2;
2554             indices[3] = 3;
2555             indices[4] = 4;
2556             indices[5] = 5;
2557             indices[6] = 6;
2558             indices[7] = 7;
2559             indices[8] = 8;
2560             indices[9] = 9;
2561             indices[10] = 10;
2562
2563                         Array.Sort ((Array)doubleValues, (Array)indices);
2564                         Assert.AreEqual (4, indices [0]);
2565         }
2566
2567         [Test]
2568         public void TestInitializeEmpty()
2569         {
2570                 bool catched=false;
2571                 int[] a = {};
2572                 try
2573                 {
2574                         a.Initialize();
2575                 }
2576                 catch(Exception)
2577                 {
2578                         catched=true;
2579                 }
2580                 Assert.IsTrue (!catched, "#TI01");
2581         }
2582
2583         [Test]
2584         public void TestInitializeInt()
2585         {
2586                 int[] a = {1,2,0};
2587                 a.Initialize();
2588                 int[] b = {1,2,0};
2589                 for(int i=a.GetLowerBound(0);i<=a.GetUpperBound(0);i++)
2590                 {
2591                         Assert.AreEqual (a[i], b[i], "#TI02 " + i);
2592                 }
2593         }
2594
2595         [Test]
2596         public void TestInitializeDouble()
2597         {
2598                 double[] a = {1.0,2.0,0.0};
2599                 a.Initialize();
2600                 double[] b = {1.0,2.0,0.0};
2601                 for(int i=a.GetLowerBound(0);i<=a.GetUpperBound(0);i++)
2602                 {
2603                         Assert.AreEqual (a[i], b[i], "#TI03 " + i);
2604                 }
2605         }
2606
2607         [Test]
2608         public void TestInitializeFloat()
2609         {
2610                 float[] a = {1.0F,2.0F,0.0F};
2611                 a.Initialize();
2612                 float[] b = {1.0F,2.0F,0.0F};
2613                 for(int i=a.GetLowerBound(0);i<=a.GetUpperBound(0);i++)
2614                 {
2615                         Assert.AreEqual (a[i], b[i], "#TI04 " + i);
2616                 }
2617         }
2618
2619         [Test]
2620         public void TestInitializeChar()
2621         {
2622                 char[] a = {'1','.','0','F','2','.','0','F'};
2623                 a.Initialize();
2624                 char[] b = {'1','.','0','F','2','.','0','F'};
2625                 for(int i=a.GetLowerBound(0);i<=a.GetUpperBound(0);i++)
2626                 {
2627                         Assert.AreEqual (a[i], b[i], "#TI05 " + i);
2628                 }
2629         }
2630
2631         [Test]
2632         public void TestInitializeString()
2633         {
2634                 string[] a = {"hola","adios","menos","mas"};
2635                 a.Initialize();
2636                 string[] b = {"hola","adios","menos","mas"};
2637                 for(int i=a.GetLowerBound(0);i<=a.GetUpperBound(0);i++)
2638                 {
2639                         Assert.AreEqual (a[i], b[i], "#TI06 " + i);
2640                 }
2641         }
2642
2643         [Test]
2644         public void TestInitializeEnum()
2645         {
2646                 enua[] a = {enua.hola,enua.adios,enua.menos,enua.mas};
2647                 a.Initialize();
2648                 enua[] b = {enua.hola,enua.adios,enua.menos,enua.mas};
2649                 for(int i=a.GetLowerBound(0);i<=a.GetUpperBound(0);i++)
2650                 {
2651                         Assert.AreEqual (a[i], b[i], "#TI07 " + i);
2652                 }
2653         }
2654         
2655         [Test]
2656         public void TestInitializeIntNI()
2657         {
2658                 int[] a = new int[20];
2659                 a.Initialize();
2660                 foreach(int b in a)
2661                 {
2662                         Assert.AreEqual (b, 0, "#TI08");
2663                 }
2664         }
2665         
2666         [Test]
2667         public void TestInitializeCharNI()
2668         {
2669                 char[] a = new char[20];
2670                 a.Initialize();
2671                 foreach(char b in a)
2672                 {
2673                         Assert.AreEqual (b, 0, "#TI09");
2674                 }
2675         }
2676         
2677         [Test]
2678         public void TestInitializeDoubleNI()
2679         {
2680                 double[] a = new double[20];
2681                 a.Initialize();
2682                 foreach(double b in a)
2683                 {
2684                         Assert.AreEqual (b, 0.0, "#TI09");
2685                 }
2686         }
2687         
2688         [Test]
2689         public void TestInitializeStringNI()
2690         {
2691                 string[] a = new string[20];
2692                 a.Initialize();
2693                 foreach(string b in a)
2694                 {
2695                         Assert.AreEqual (b, null, "#TI10");
2696                 }
2697         }
2698         
2699         [Test]
2700         public void TestInitializeObjectNI()
2701         {
2702                 object[] a = new object[20];
2703                 a.Initialize();
2704                 foreach(object b in a)
2705                 {
2706                         Assert.AreEqual (b, null, "#TI11");
2707                 }
2708         }
2709
2710         [Test]
2711         public void TestInitializeAClassNI()
2712         {
2713                 AClass[] a = new AClass[20];
2714                 a.Initialize();
2715                 foreach(AClass b in a)
2716                 {
2717                         Assert.AreEqual (b, null, "#TI12");
2718                 }
2719         }
2720
2721
2722         [Test]
2723         public void TestInitializeAStructNI()
2724         {
2725                 AStruct[] a = new AStruct[20];
2726                 a.Initialize();
2727                 foreach(AStruct b in a)
2728                 {
2729                         Assert.AreEqual (b, new AStruct(), "#TI14");
2730                 }
2731         }
2732
2733         [Test]
2734         public void TestInitializeAStruct()
2735         {
2736                 AStruct[] a = new AStruct[3];
2737                 a[1].a = "ADIOS";
2738                 a[1].s = "HOLA";
2739                 a.Initialize();
2740                 AStruct[] b = new AStruct[3];
2741                 b[1].a = "ADIOS";
2742                 b[1].s = "HOLA";
2743                 for(int i=a.GetLowerBound(0);i<=a.GetUpperBound(0);i++)
2744                 {
2745                         Assert.AreEqual (a[i], b[i], "#TI15 " + i);
2746                 }
2747         }
2748
2749         [Test]
2750         public void TestInitializeDateTimeNI()
2751         {
2752                 DateTime[] a = new DateTime[20];
2753                 a.Initialize();
2754                 foreach(DateTime b in a)
2755                 {
2756                         Assert.AreEqual (b, new DateTime(), "#TI16");
2757                 }
2758         }
2759         
2760         [Test]
2761         [ExpectedException (typeof (ArgumentNullException))]
2762         public void MoreSort1 ()
2763         {
2764                 Array.Sort (null, 0, 1);
2765         }
2766
2767         [Test]
2768         [ExpectedException (typeof (ArgumentOutOfRangeException))]
2769         public void MoreSort2 ()
2770         {
2771                 Array.Sort (arrsort, -1, 3);
2772         }
2773
2774         [Test]
2775         [ExpectedException (typeof (ArgumentOutOfRangeException))]
2776         public void MoreSort3 ()
2777         {
2778                 Array.Sort (arrsort, 1, -3);
2779         }
2780
2781         [Test]
2782         [ExpectedException (typeof (ArgumentException))]
2783         public void MoreSort4 ()
2784         {
2785                 Array.Sort (arrsort, arrsort.Length, arrsort.Length + 2);
2786         }
2787
2788         [Test]
2789         [ExpectedException (typeof (RankException))]
2790         public void MoreSort5 ()
2791         {
2792                 char [,] arr = new char [,] {{'a'}, {'b'}};
2793                 Array.Sort (arr, 0, 1);
2794         }
2795
2796         [Test]
2797         public void MoreSort6 ()
2798         {
2799                 Array.Sort (arrsort, 0, 0);
2800         }
2801
2802         [Test]
2803         [ExpectedException (typeof (ArgumentException))]
2804         public void MoreSort7 ()
2805         {
2806                 Array.Sort (arrsort, arrsort.Length - 1, 2);
2807         }
2808
2809         [Test]
2810         [ExpectedException (typeof (ArgumentException))]
2811         public void MoreSort8 ()
2812         {
2813                 Array.Sort (arrsort, 0, arrsort.Length + 1);
2814         }
2815
2816         [Test]
2817         public void MoreSort9 ()
2818         {
2819                 Array.Sort (arrsort, null, 0, arrsort.Length, null);
2820         }
2821
2822         [Test]
2823         [ExpectedException (typeof (InvalidOperationException))]
2824         public void MoreSort10 ()
2825         {
2826                 object [] array = {true, 'k', SByte.MinValue, Byte.MinValue, (short) 2, 634, (long) 436, (float) 1.1, 1.23, "Hello World"};
2827                 Array.Sort (array, (IComparer) null);
2828         }
2829
2830         [Test] // bug #81941
2831         public void Sort ()
2832         {
2833                 double [] a = new double [2] { 0.9, 0.3 };
2834                 uint [] b = new uint [2] { 4, 7 };
2835                 Array.Sort (a, b);
2836                 Assert.AreEqual (0.3, a [0], "#1");
2837                 Assert.AreEqual (0.9, a [1], "#2");
2838                 Assert.AreEqual (7, b [0], "#3");
2839                 Assert.AreEqual (4, b [1], "#4");
2840         }
2841
2842         [Test]
2843         public void ClearJaggedArray () 
2844         {
2845                 byte[][] matrix = new byte [8][];
2846                 for (int i=0; i < 8; i++) {
2847                         matrix [i] = new byte [8];
2848                         for (int j=0; j < 8; j++) {
2849                                 matrix [i][j] = 1;
2850                         }
2851                 }
2852                 Array.Clear (matrix, 0, 8);
2853                 for (int i=0; i < 8; i++) {
2854                         Assert.IsNull (matrix [i], i.ToString ());
2855                 }
2856         }
2857
2858         [Test]
2859         public void ClearMultidimentionalArray () 
2860         {
2861                 byte[,] matrix = new byte [2,2] { {1, 1}, {2, 2} };
2862                 Array.Clear (matrix, 0, 2);
2863                 Assert.AreEqual (0, matrix [0, 0], "0,0");
2864                 Assert.AreEqual (0, matrix [0, 1], "0,1");
2865                 Assert.AreEqual (2, matrix [1, 0], "1,0");
2866                 Assert.AreEqual (2, matrix [1, 1], "1,1");
2867         }
2868
2869         [Test]
2870         [ExpectedException (typeof (IndexOutOfRangeException))]
2871         public void ClearOutsideMultidimentionalArray () 
2872         {
2873                 byte[,] matrix = new byte [2,2] { {1, 1}, {2, 2} };
2874                 Array.Clear (matrix, 0, 5);
2875         }
2876
2877         [Test]
2878         [ExpectedException (typeof (IndexOutOfRangeException))]
2879         public void Clear_IndexOverflow () 
2880         {
2881                 byte[] array = new byte [16];
2882                 Array.Clear (array, 4, Int32.MaxValue);
2883         }
2884
2885         [Test]
2886         [ExpectedException (typeof (IndexOutOfRangeException))]
2887         public void Clear_LengthOverflow () 
2888         {
2889                 byte[] array = new byte [16];
2890                 Array.Clear (array, Int32.MaxValue, 4);
2891         }
2892
2893         [Test]
2894         [ExpectedException (typeof (ArgumentException))]
2895         public void Copy_SourceIndexOverflow () 
2896         {
2897                 byte[] array = new byte [16];
2898                 Array.Copy (array, Int32.MaxValue, array, 8, 8);
2899         }
2900
2901         [Test]
2902         [ExpectedException (typeof (ArgumentException))]
2903         public void Copy_DestinationIndexOverflow () 
2904         {
2905                 byte[] array = new byte [16];
2906                 Array.Copy (array, 8, array, Int32.MaxValue, 8);
2907         }
2908
2909         [Test]
2910         [ExpectedException (typeof (ArgumentException))]
2911         public void Copy_LengthOverflow () 
2912         {
2913                 byte[] array = new byte [16];
2914                 Array.Copy (array, 8, array, 8, Int32.MaxValue);
2915         }
2916
2917         [Test]
2918         [ExpectedException (typeof (ArgumentException))]
2919         public void Reverse_IndexOverflow () 
2920         {
2921                 byte[] array = new byte [16];
2922                 Array.Reverse (array, Int32.MaxValue, 8);
2923         }
2924
2925         [Test]
2926         [ExpectedException (typeof (ArgumentException))]
2927         public void Reverse_LengthOverflow () 
2928         {
2929                 byte[] array = new byte [16];
2930                 Array.Reverse (array, 8, Int32.MaxValue);
2931         }
2932         
2933         public struct CharX : IComparable {
2934                 public char c;
2935         
2936                 public CharX (char c)
2937                 {
2938                         this.c = c;
2939                 }
2940         
2941                 public int CompareTo (object obj)
2942                 {
2943                         if (obj is CharX)
2944                                 return c.CompareTo (((CharX) obj).c);
2945                         else
2946                                 return c.CompareTo (obj);
2947                 }
2948         }
2949
2950         [Test]
2951         public void BinarySearch_ArgPassingOrder ()
2952         {
2953                 //
2954                 // This tests that arguments are passed to the comprer in the correct
2955                 // order. The IComparable of the *array* elements must get called, not
2956                 // that of the search object.
2957                 //
2958                 CharX [] x = { new CharX ('a'), new CharX ('b'), new CharX ('c') };
2959                 Assert.AreEqual (1, Array.BinarySearch (x, 'b'));
2960         }
2961
2962         class Comparer: IComparer {
2963
2964                 private bool called = false;
2965
2966                 public bool Called {
2967                         get {
2968                                 bool result = called;
2969                                 called = false;
2970                                 return called;
2971                         }
2972                 }
2973
2974                 public int Compare (object x, object y)
2975                 {
2976                         called = true;
2977                         return 0;
2978                 }
2979         }
2980
2981         [Test]
2982         public void BinarySearch1_EmptyList ()
2983         {
2984                 int[] array = new int[0];
2985                 Assert.AreEqual (- 1, Array.BinarySearch (array, 0), "BinarySearch");
2986         }
2987
2988         [Test]
2989         public void BinarySearch2_EmptyList ()
2990         {
2991                 int[] array = new int[0];
2992                 Assert.AreEqual (-1, Array.BinarySearch (array, 0, 0, 0), "BinarySearch");
2993         }
2994
2995         [Test]
2996         public void BinarySearch3_EmptyList ()
2997         {
2998                 Comparer comparer = new Comparer ();
2999                 int[] array = new int[0];
3000                 Assert.AreEqual (-1, Array.BinarySearch (array, 0, comparer), "BinarySearch");
3001                 // bug 77030 - the comparer isn't called for an empty array/list
3002                 Assert.IsTrue (!comparer.Called, "Called");
3003         }
3004
3005         [Test]
3006         public void BinarySearch4_EmptyList ()
3007         {
3008                 Comparer comparer = new Comparer ();
3009                 int[] array = new int[0];
3010                 Assert.AreEqual (-1, Array.BinarySearch (array, 0, 0, comparer), "BinarySearch");
3011                 // bug 77030 - the comparer isn't called for an empty array/list
3012                 Assert.IsTrue (!comparer.Called, "Called");
3013         }
3014
3015         [Test]
3016         [ExpectedException (typeof (ArgumentNullException))]
3017         public void AsReadOnly_NullArray ()
3018         {
3019                 Array.AsReadOnly <int> (null);
3020         }
3021
3022         [Test]
3023         public void ReadOnly_Count ()
3024         {
3025                 Assert.AreEqual (10, Array.AsReadOnly (new int [10]).Count);
3026         }
3027
3028         [Test]
3029         public void ReadOnly_Contains ()
3030         {
3031                 int[] arr = new int [2];
3032                 arr [0] = 3;
3033                 arr [1] = 5;
3034                 IList<int> a = Array.AsReadOnly (arr);
3035
3036                 Assert.IsTrue (a.Contains (3));
3037                 Assert.IsTrue (!a.Contains (6));
3038         }
3039
3040         [Test]
3041         public void ReadOnly_IndexOf ()
3042         {
3043                 int[] arr = new int [2];
3044                 arr [0] = 3;
3045                 arr [1] = 5;
3046                 IList<int> a = Array.AsReadOnly (arr);
3047
3048                 Assert.AreEqual (0, a.IndexOf (3));
3049                 Assert.AreEqual (1, a.IndexOf (5));
3050                 Assert.AreEqual (-1, a.IndexOf (6));
3051         }
3052
3053         [Test]
3054         public void ReadOnly_Indexer ()
3055         {
3056                 int[] arr = new int [2];
3057                 arr [0] = 3;
3058                 arr [1] = 5;
3059                 IList<int> a = Array.AsReadOnly (arr);
3060
3061                 Assert.AreEqual (3, a [0]);
3062                 Assert.AreEqual (5, a [1]);
3063
3064                 /* Check that modifications to the original array are visible */
3065                 arr [0] = 6;
3066                 Assert.AreEqual (6, a [0]);
3067         }
3068
3069         [Test]
3070         public void ReadOnly_Enumerator ()
3071         {
3072                 int[] arr = new int [10];
3073
3074                 for (int i = 0; i < 10; ++i)
3075                         arr [i] = i;
3076
3077                 int sum = 0;
3078                 foreach (int i in Array.AsReadOnly (arr))
3079                         sum += i;
3080
3081                 Assert.AreEqual (45, sum);
3082         }
3083
3084         [Test]
3085         public void ReadOnly_CopyTo ()
3086         {
3087                 int[] arr = new int [2];
3088                 arr [0] = 3;
3089                 arr [1] = 5;
3090                 IList<int> a = Array.AsReadOnly (arr);
3091
3092                 int[] arr2 = new int [3];
3093                 a.CopyTo (arr2, 1);
3094
3095                 Assert.AreEqual (0, arr2 [0]);
3096                 Assert.AreEqual (3, arr2 [1]);
3097                 Assert.AreEqual (5, arr2 [2]);
3098         }
3099
3100         [Test]
3101         public void Resize ()
3102         {
3103                 int [] arr = new int [] { 1, 3, 5 };
3104                 Array.Resize <int> (ref arr, 3);
3105                 Assert.AreEqual (3, arr.Length, "#A1");
3106                 Assert.AreEqual (1, arr [0], "#A2");
3107                 Assert.AreEqual (3, arr [1], "#A3");
3108                 Assert.AreEqual (5, arr [2], "#A4");
3109
3110                 Array.Resize <int> (ref arr, 2);
3111                 Assert.AreEqual (2, arr.Length, "#B1");
3112                 Assert.AreEqual (1, arr [0], "#B2");
3113                 Assert.AreEqual (3, arr [1], "#B3");
3114
3115                 Array.Resize <int> (ref arr, 4);
3116                 Assert.AreEqual (4, arr.Length, "#C1");
3117                 Assert.AreEqual (1, arr [0], "#C2");
3118                 Assert.AreEqual (3, arr [1], "#C3");
3119                 Assert.AreEqual (0, arr [2], "#C4");
3120                 Assert.AreEqual (0, arr [3], "#C5");
3121         }
3122
3123         [Test]
3124         public void Resize_null ()
3125         {
3126                 int [] arr = null;
3127                 Array.Resize (ref arr, 10);
3128                 Assert.AreEqual (arr.Length, 10);
3129         }
3130
3131         [Test]
3132         public void Test_ContainsAndIndexOf_EquatableItem ()
3133         {
3134                 EquatableClass[] list = new EquatableClass[] {new EquatableClass (0), new EquatableClass (1), new EquatableClass (0)};
3135
3136                 Assert.AreEqual (0, Array.IndexOf<EquatableClass> (list, list[0]), "#0");
3137                 Assert.AreEqual (0, Array.IndexOf<EquatableClass> (list, new EquatableClass (0)), "#1");
3138                 Assert.AreEqual (2, Array.LastIndexOf<EquatableClass> (list, list[0]), "#2");
3139                 Assert.AreEqual (2, Array.LastIndexOf<EquatableClass> (list, new EquatableClass (0)), "#3");
3140         }
3141
3142         public class EquatableClass : IEquatable<EquatableClass>
3143         {
3144                 int _x;
3145                 public EquatableClass (int x)
3146                 {
3147                         _x = x;
3148                 }
3149
3150                 public bool Equals (EquatableClass other)
3151                 {
3152                         return this._x == other._x;
3153                 }
3154         }
3155
3156         [Test]
3157         public void AsIList ()
3158         {
3159                 IList<int> arr = new int [10];
3160                 arr [0] = 5;
3161                 Assert.AreEqual (5, arr [0]);
3162
3163                 IList<FooStruct> arr2 = new FooStruct [10];
3164                 FooStruct s = new FooStruct ();
3165                 s.i = 11;
3166                 s.j = 22;
3167                 arr2 [5] = s;
3168                 s = arr2 [5];
3169                 Assert.AreEqual (11, s.i);
3170                 Assert.AreEqual (22, s.j);
3171
3172                 IList<string> arr3 = new string [10];
3173                 arr3 [5] = "ABC";
3174                 Assert.AreEqual ("ABC", arr3 [5]);
3175         }
3176
3177         struct FooStruct {
3178                 public int i, j;
3179         }
3180
3181 #if !TARGET_JVM // BugBUG: T[] is not yet ICollection<T> under TARGET_JVM
3182         [Test]
3183         // From bug #80563
3184         public void ICollectionNull ()
3185         {
3186                 ICollection<object> test;
3187                 
3188                 test = new List<object>();
3189                 Assert.AreEqual (test.Contains (null), false, "list<o>");
3190
3191                 test = new object[] {};
3192                 Assert.AreEqual (test.Contains (null), false, "empty array");
3193
3194                 test = new object[] {null};
3195                 Assert.AreEqual (test.Contains (null), true, "array with null");
3196
3197                 test = new object[] { 1, null};
3198                 Assert.IsTrue (test.Contains (null), "array with last null");
3199                 
3200                 test = new List<object>(test);
3201                 Assert.AreEqual (test.Contains (null), true, "List<object> with test");
3202                 
3203                 test = new object[] {new object()};
3204                 Assert.AreEqual (test.Contains (null), false, "array with object");
3205
3206                 test = new List<object>(test);
3207                 Assert.AreEqual (test.Contains (null), false, "array with test");
3208         }
3209         
3210         [Test]
3211         public void IListNull ()
3212         {
3213                 IList<object> test;
3214                 
3215                 test = new List<object>();
3216                 Assert.AreEqual (-1, test.IndexOf (null), "list<o>");
3217
3218                 test = new object[] {};
3219                 Assert.AreEqual (-1, test.IndexOf (null), "empty array");
3220
3221                 test = new object[] {null};
3222                 Assert.AreEqual (0, test.IndexOf (null), "array with null");
3223
3224                 test = new object[] { 1, null};
3225                 Assert.AreEqual (1, test.IndexOf (null), "array with last null");
3226                 
3227                 test = new List<object>(test);
3228                 Assert.AreEqual (1, test.IndexOf (null), "List<object> with test");
3229                 
3230                 test = new object[] {new object()};
3231                 Assert.AreEqual (-1, test.IndexOf (null), "array with object");
3232
3233                 test = new List<object>(test);
3234                 Assert.AreEqual (-1, test.IndexOf (null), "array with test");
3235         }
3236         
3237 #endif // TARGET_JVM
3238
3239         #region Bug 80299
3240
3241         enum ByteEnum : byte {}
3242         enum IntEnum : int {}
3243
3244         [Test]
3245         public void TestByteEnumArrayToByteArray ()
3246         {
3247                 ByteEnum[] a = new ByteEnum[] {(ByteEnum) 1, (ByteEnum) 2};
3248                 byte[] b = new byte[a.Length];
3249                 a.CopyTo (b, 0);
3250         }
3251
3252         [Test]
3253         public void TestByteEnumArrayToIntArray ()
3254         {
3255                 ByteEnum[] a = new ByteEnum[] {(ByteEnum) 1, (ByteEnum) 2};
3256                 int[] b = new int[a.Length];
3257                 a.CopyTo (b, 0);
3258         }
3259
3260         [Test]
3261         [ExpectedException (typeof (ArrayTypeMismatchException))]
3262         public void TestIntEnumArrayToByteArray ()
3263         {
3264                 IntEnum[] a = new IntEnum[] {(IntEnum) 1, (IntEnum) 2};
3265                 byte[] b = new byte[a.Length];
3266                 a.CopyTo (b, 0);
3267         }
3268
3269         [Test]
3270         public void TestIntEnumArrayToIntArray ()
3271         {
3272                 IntEnum[] a = new IntEnum[] {(IntEnum) 1, (IntEnum) 2};
3273                 int[] b = new int[a.Length];
3274                 a.CopyTo (b, 0);
3275         }
3276
3277         #endregion
3278
3279         [Test] // bug #322248
3280         public void IEnumerator_Reset ()
3281         {
3282                 int[] array = new int[] { 1, 2, 3};
3283                 IEnumerator<int> e = ((IEnumerable<int>)array).GetEnumerator ();
3284                 Assert.IsTrue (e.MoveNext (), "#A1");
3285                 Assert.AreEqual (1, e.Current, "#A2");
3286                 Assert.IsTrue (e.MoveNext (), "#A3");
3287                 Assert.AreEqual (2, e.Current, "#A4");
3288
3289                 e.Reset ();
3290
3291                 Assert.IsTrue (e.MoveNext (), "#C1");
3292                 Assert.AreEqual (1, e.Current, "#C2");
3293         }
3294
3295         [Test]
3296         public void IEnumerator_Current_Finished ()
3297         {
3298                 int[] array = new int[] { 1, 2, 3 };
3299                 IEnumerator<int> e = ((IEnumerable<int>)array).GetEnumerator ();
3300                 Assert.IsTrue (e.MoveNext (), "#A1");
3301                 Assert.AreEqual (1, e.Current, "#A2");
3302                 Assert.IsTrue (e.MoveNext (), "#A3");
3303                 Assert.AreEqual (2, e.Current, "#A4");
3304                 Assert.IsTrue (e.MoveNext (), "#A5");
3305                 Assert.AreEqual (3, e.Current, "#A6");
3306                 Assert.IsTrue (!e.MoveNext (), "#A6");
3307
3308                 try {
3309                         Assert.Fail ("#B1:" + e.Current);
3310                 } catch (InvalidOperationException ex) {
3311                         // Enumeration already finished
3312                         Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
3313                         Assert.IsNull (ex.InnerException, "#B3");
3314                         Assert.IsNotNull (ex.Message, "#B4");
3315                 }
3316         }
3317
3318         [Test]
3319         public void IEnumerator_Current_NotStarted ()
3320         {
3321                 int[] array = new int[] { 1, 2, 3 };
3322                 IEnumerator<int> e = ((IEnumerable<int>)array).GetEnumerator ();
3323
3324                 try {
3325                         Assert.Fail ("#A1:" + e.Current);
3326                 } catch (InvalidOperationException ex) {
3327                         // Enumeration has not started. Call MoveNext
3328                         Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2");
3329                         Assert.IsNull (ex.InnerException, "#A3");
3330                         Assert.IsNotNull (ex.Message, "#A4");
3331                 }
3332         }
3333
3334         [Test]
3335         public void IEnumerator_Current_Reset ()
3336         {
3337                 int[] array = new int[] { 1, 2, 3 };
3338                 IEnumerator<int> e = ((IEnumerable<int>)array).GetEnumerator ();
3339                 e.MoveNext ();
3340                 e.Reset ();
3341
3342                 try {
3343                         Assert.Fail ("#B1:" + e.Current);
3344                 } catch (InvalidOperationException ex) {
3345                         // Enumeration has not started. Call MoveNext
3346                         Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
3347                         Assert.IsNull (ex.InnerException, "#B3");
3348                         Assert.IsNotNull (ex.Message, "#B4");
3349                 }
3350         }
3351
3352         public void ICollection_IsReadOnly() {
3353                 ICollection<string> arr = new string [10];
3354
3355                 Assert.IsTrue (arr.IsReadOnly);
3356         }
3357
3358         [Test]
3359         [ExpectedException (typeof (NotSupportedException))]
3360         public void ArrayCreateInstanceOfVoid ()
3361         {
3362                 Array.CreateInstance (typeof (void), 42);
3363         }
3364
3365         class Foo<T> {}
3366
3367         [Test]
3368         [ExpectedException (typeof (NotSupportedException))]
3369         public void ArrayCreateInstanceOfOpenGenericType ()
3370         {
3371                 Array.CreateInstance (typeof (Foo<>), 42);
3372         }
3373
3374         [Test]
3375         [ExpectedException (typeof (IndexOutOfRangeException))]
3376         public void ClearNegativeLength ()
3377         {
3378                 Array.Clear (new int [] { 1, 2 }, 0, -1);
3379         }
3380
3381         [Test]
3382         [ExpectedException (typeof (ArgumentException))]
3383         public void MultiDimension_IList_setItem ()
3384         {
3385                 IList array = new int [1, 1];
3386                 array [0] = 2;
3387         }
3388
3389         [Test]
3390         [ExpectedException (typeof (ArgumentException))]
3391         public void MultiDimension_IList_getItem ()
3392         {
3393                 IList array = new int [1, 1];
3394                 int a = (int) array [0];
3395         }
3396
3397         [Test]
3398         public void SetValue_Nullable () {
3399                 Array array = Array.CreateInstance (typeof (int?), 7);
3400
3401                 object o = 42;
3402
3403                 array.SetValue (o, 0);
3404                 Assert.AreEqual (42, array.GetValue (0));
3405
3406                 array.SetValue (null, 0);
3407                 Assert.AreEqual (null, array.GetValue (0));
3408         }
3409
3410         [Test]
3411         public void SortNullsWithGenericVersion ()
3412         {
3413             string[] s1 = new string[6]{
3414                 "J",
3415                 "M",
3416                  null,
3417                 "P",
3418                 "T",
3419                 "A"};
3420
3421             string[] s2 = new string[]{null,
3422                 "A",
3423                 "J",
3424                 "M",
3425                 "P",
3426                 "T"};
3427
3428             Array.Sort<string> (s1);
3429             for (int i = 0; i < 6; i++) {
3430                     Assert.AreEqual (s1[i], s2[i], "At:" + i);
3431             }
3432         }
3433         
3434         //
3435         // This is a test case for the case that was broken by the code contributed
3436         // for bug  #351638.
3437         //
3438         // This tests the fix for: #622101
3439         //
3440         [Test]
3441         public void SortActuallyWorks ()
3442         {
3443                 string[] data = new string[9]{"Foo", "Bar", "Dingus", null, "Dingu4", "123", "Iam", null, "NotNull"};
3444                 IComparer comparer = new NullAtEndComparer ();
3445                 Array.Sort (data, comparer);
3446
3447                 Assert.AreEqual (data [7], null);
3448                 Assert.AreNotEqual (data [0], null);
3449         }
3450
3451         class NullAtEndComparer : IComparer {
3452                 public int Compare(object x, object y)
3453                 {
3454                         if (x == null) return 1;
3455                         if (y == null) return -1;
3456                         return ((string)x).CompareTo((string)y);
3457                 }
3458         }
3459
3460         [Test] //bxc #11184
3461         public void UnalignedArrayClear ()
3462         {
3463                 byte[] input = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
3464                 byte[] expected = new byte[] { 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
3465                 Array.Clear (input, 5, 11);
3466                 
3467                 Assert.AreEqual (input, expected);
3468         }
3469
3470 #if NET_4_0
3471         [Test]
3472         [ExpectedException (typeof (ArgumentException))]
3473         public void CompareToWithJaggedArray () {
3474                 IStructuralComparable a = new int[][] { new int [] { 1,2 }, new int [] { 3,4 }};
3475                 IStructuralComparable b = new int[][] { new int [] { 1,2 }, new int [] { 3,4 }};
3476                 a.CompareTo (b, Comparer<object>.Default);
3477         }
3478
3479         [Test]
3480         [ExpectedException (typeof (ArgumentException))]
3481         public void CompareToWithArrayOfTheWrongKind () {
3482                 IStructuralComparable a = new int[] { 1, 2 };
3483                 IStructuralComparable b = new double[] { 1, 2 };
3484                 a.CompareTo (b, Comparer<object>.Default);
3485         }
3486
3487         [Test]
3488         [ExpectedException (typeof (ArgumentException))]
3489         public void CompareToWithNonArrayType () {
3490                 IStructuralComparable a = new int[] { 1, 2 };
3491                 a.CompareTo (99, Comparer<object>.Default);
3492         }
3493
3494         [Test]
3495         [ExpectedException (typeof (ArgumentException))]
3496         public void CompareToWithNonArrayOfDifferentSize () {
3497                 IStructuralComparable a = new int[] { 1, 2 };
3498                 IStructuralComparable b = new int[] { 1, 2, 3 };
3499                 a.CompareTo (b, Comparer<object>.Default);
3500         }
3501
3502         [Test]
3503         [ExpectedException (typeof (ArgumentException))]
3504         public void CompareToWithMultiDimArray1 () {
3505                 IStructuralComparable a = new int [2,2] { {10, 10 }, { 10, 10 } };
3506                 IStructuralComparable b = new int [2,2] { {10, 10 }, { 10, 10 } };
3507                 a.CompareTo (b, Comparer<object>.Default);
3508         }
3509
3510         [Test]
3511         [ExpectedException (typeof (ArgumentException))]
3512         public void CompareToWithMultiDimArray2 () {
3513                 IStructuralComparable a = new int [2] { 10, 10 };
3514                 IStructuralComparable b = new int [2,2] { {10, 10 }, { 10, 10 } };
3515                 a.CompareTo (b, Comparer<object>.Default);
3516         }
3517
3518         [Test]
3519         [ExpectedException (typeof (ArgumentException))]
3520         public void CompareToWithMultiDimArray3 () {
3521                 IStructuralComparable a = new int [4] { 10, 10, 10, 10 };
3522                 IStructuralComparable b = new int [2,2] { {10, 10 }, { 10, 10 } };
3523                 a.CompareTo (b, Comparer<object>.Default);
3524         }
3525
3526         [Test]
3527         [ExpectedException (typeof (IndexOutOfRangeException))]
3528         public void CompareToWithBoundedArray1 () {
3529                 IStructuralComparable a = new int [2] { 10, 10 };
3530                 Array ab = Array.CreateInstance (typeof (int), new int[] { 2 }, new int [] { 5 });
3531                 IStructuralComparable b = ab;
3532                 ab.SetValue (10, 5);
3533                 ab.SetValue (10, 6);
3534
3535                 a.CompareTo (b, Comparer<object>.Default);
3536         }
3537
3538         [Test]
3539         [ExpectedException (typeof (IndexOutOfRangeException))]
3540         public void CompareToWithBoundedArray2 () {
3541                 IStructuralComparable a = new int [2] { 10, 10 };
3542                 Array ab = Array.CreateInstance (typeof (int), new int[] { 2 }, new int [] { 5 });
3543                 IStructuralComparable b = ab;
3544                 ab.SetValue (10, 5);
3545                 ab.SetValue (10, 6);
3546
3547                 //Yes, CompareTo simply doesn't work with bounded arrays!
3548                 b.CompareTo (b, Comparer<object>.Default);
3549         }
3550
3551         [Test]
3552         [ExpectedException (typeof (NullReferenceException))]
3553         public void CompareToWithNullComparer () {
3554                 IStructuralComparable a = new int[] { 1, 2 };
3555                 IStructuralComparable b = new int[] { 1, 2 };
3556                 a.CompareTo (b, null);
3557         }
3558
3559         [Test]
3560         public void CompareToWithNullArray () {
3561                 IStructuralComparable a = new int[] { 1, 2 };
3562                 Assert.AreEqual (1, a.CompareTo (null, Comparer<object>.Default));
3563         }
3564
3565         [Test]
3566         public void CompareToWithGoodArrays () {
3567                 IStructuralComparable a = new int[] { 10, 20 };
3568                 Assert.AreEqual (0, a.CompareTo (a, Comparer<object>.Default));
3569                 Assert.AreEqual (0, a.CompareTo (new int [] { 10, 20 }, Comparer<object>.Default));
3570                 Assert.AreEqual (-1, a.CompareTo (new int [] { 11, 20 }, Comparer<object>.Default));
3571                 Assert.AreEqual (-1, a.CompareTo (new int [] { 10, 21 }, Comparer<object>.Default));
3572                 Assert.AreEqual (1, a.CompareTo (new int [] { 9, 20 }, Comparer<object>.Default));
3573                 Assert.AreEqual (1, a.CompareTo (new int [] { 10, 19 }, Comparer<object>.Default));
3574         }
3575
3576         [Test]
3577         public void IStructuralEquatable_Equals ()
3578         {
3579                 IStructuralEquatable array = new int[] {1, 2, 3};
3580                 IStructuralEquatable array2 = new int[] {1, 2, 3};
3581                 Assert.AreEqual (false, array.Equals (null, null));
3582                 Assert.AreEqual (true, array.Equals (array, null));
3583                 Assert.AreEqual (true, array.Equals (array2, EqualityComparer<int>.Default));
3584         }
3585
3586         [Test]
3587         [ExpectedException (typeof (NullReferenceException))]
3588         public void IStructuralEquatable_Equals_NoComparer ()
3589         {
3590                 IStructuralEquatable array = new int[] {1, 2, 3};
3591                 IStructuralComparable array2 = new int[] {1, 2, 3};
3592                 array.Equals (array2, null);
3593         }
3594
3595         [Test]
3596         [ExpectedException (typeof (ArgumentException))]
3597         public void IStructuralEquatable_Equals_ComparerThrows ()
3598         {
3599                 IStructuralEquatable array = new int[] {1, 2, 3};
3600                 IStructuralComparable array2 = new int[] {1, 2, 3};
3601                 array.Equals (array2, EqualityComparer<long>.Default);
3602         }
3603
3604         [Test]
3605         [ExpectedException (typeof (ArgumentNullException))]    
3606         public void IStructuralEquatable_GetHashCode_NullComparer ()
3607         {
3608                 IStructuralEquatable a = new int[] { 1, 2 };
3609                 a.GetHashCode (null);
3610         }
3611
3612         class TestComparer_GetHashCode : IEqualityComparer
3613         {
3614                 public int Counter;
3615
3616                 bool IEqualityComparer.Equals (object x, object y)
3617                 {
3618                         throw new NotImplementedException ();
3619                 }
3620
3621                 public int GetHashCode (object obj)
3622                 {
3623                         return Counter++;
3624                 }
3625         }
3626
3627         [Test]
3628         public void IStructuralEquatable_GetHashCode ()
3629         {
3630                 IStructuralEquatable a = new int[] { 1, 2, 9 };
3631
3632                 var c = new TestComparer_GetHashCode ();
3633                 a.GetHashCode (c);
3634                 Assert.AreEqual (3, c.Counter);         
3635         }
3636
3637 #endif
3638
3639 }
3640 }