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