]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_8_1_1/main/tests/collate/src/com/ibm/icu/dev/test/collator/CollationMiscTest.java
Added flags.
[Dictionary.git] / jars / icu4j-4_8_1_1 / main / tests / collate / src / com / ibm / icu / dev / test / collator / CollationMiscTest.java
1
2  /*
3  *******************************************************************************
4  * Copyright (C) 2002-2011, International Business Machines Corporation and    *
5  * others. All Rights Reserved.                                                *
6  *******************************************************************************
7  */
8
9 /**
10  * Port From:   ICU4C v2.1 : cintltest
11  * Source File: $ICU4CRoot/source/test/cintltest/cmsccoll.c
12  */
13
14 package com.ibm.icu.dev.test.collator;
15
16 import java.util.Arrays;
17 import java.util.Locale;
18 import java.util.Set;
19 import java.util.TreeSet;
20
21 import com.ibm.icu.dev.test.TestFmwk;
22 import com.ibm.icu.impl.ICUResourceBundle;
23 import com.ibm.icu.impl.ImplicitCEGenerator;
24 import com.ibm.icu.impl.Utility;
25 import com.ibm.icu.lang.UScript;
26 import com.ibm.icu.text.CollationElementIterator;
27 import com.ibm.icu.text.CollationKey;
28 import com.ibm.icu.text.CollationKey.BoundMode;
29 import com.ibm.icu.text.Collator;
30 import com.ibm.icu.text.Collator.ReorderCodes;
31 import com.ibm.icu.text.Normalizer;
32 import com.ibm.icu.text.RawCollationKey;
33 import com.ibm.icu.text.RuleBasedCollator;
34 import com.ibm.icu.text.UTF16;
35 import com.ibm.icu.text.UnicodeSet;
36 import com.ibm.icu.text.UnicodeSetIterator;
37 import com.ibm.icu.util.ULocale;
38 import com.ibm.icu.util.UResourceBundle;
39
40 public class CollationMiscTest extends TestFmwk {
41
42     public static void main(String[] args) throws Exception {
43         new CollationMiscTest().run(args);
44         // new CollationMiscTest().TestLocaleRuleBasedCollators();
45     }
46
47     //private static final int NORM_BUFFER_TEST_LEN_ = 32;
48     private static final class Tester
49     {
50         int u;
51         String NFC;
52         String NFD;
53     }
54
55     private static final boolean hasCollationElements(Locale locale)
56     {
57         ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_COLLATION_BASE_NAME,locale);
58         if (rb != null) {
59             try {
60                 String collkey = rb.getStringWithFallback("collations/default");
61                 ICUResourceBundle elements = rb.getWithFallback("collations/" + collkey);
62                 if (elements != null) {
63                     return true;
64                 }
65             } catch (Exception e) {
66             }
67         }
68         return false;
69     }
70
71     public void TestComposeDecompose()
72     {
73         Tester t[] = new Tester[0x30000];
74         t[0] = new Tester();
75         logln("Testing UCA extensively\n");
76         RuleBasedCollator coll;
77         try {
78             coll = (RuleBasedCollator)Collator.getInstance(Locale.ENGLISH);
79         }
80         catch (Exception e) {
81             warnln("Error opening collator\n");
82             return;
83         }
84
85         int noCases = 0;
86         for (int u = 0; u < 0x30000; u ++) {
87             String comp = UTF16.valueOf(u);
88             int len = comp.length();
89             t[noCases].NFC = Normalizer.normalize(u, Normalizer.NFC);
90             t[noCases].NFD = Normalizer.normalize(u, Normalizer.NFD);
91
92             if (t[noCases].NFC.length() != t[noCases].NFD.length()
93                 || (t[noCases].NFC.compareTo(t[noCases].NFD) != 0)
94                 || (len != t[noCases].NFD.length())
95                 || (comp.compareTo(t[noCases].NFD) != 0)) {
96                 t[noCases].u = u;
97                 if (len != t[noCases].NFD.length()
98                     || (comp.compareTo(t[noCases].NFD) != 0)) {
99                     t[noCases].NFC = comp;
100                 }
101                 noCases ++;
102                 t[noCases] = new Tester();
103             }
104         }
105
106         for (int u = 0; u < noCases; u ++) {
107             if (!coll.equals(t[u].NFC, t[u].NFD)) {
108                 errln("Failure: codePoint \\u" + Integer.toHexString(t[u].u)
109                       + " fails TestComposeDecompose in the UCA");
110                 CollationTest.doTest(this, coll, t[u].NFC, t[u].NFD, 0);
111             }
112         }
113
114         logln("Testing locales, number of cases = " + noCases);
115         Locale loc[] = Collator.getAvailableLocales();
116         for (int i = 0; i < loc.length; i ++) {
117             if (hasCollationElements(loc[i])) {
118                 logln("Testing locale " + loc[i].getDisplayName());
119                 coll = (RuleBasedCollator)Collator.getInstance(loc[i]);
120                 coll.setStrength(Collator.IDENTICAL);
121
122                 for (int u = 0; u < noCases; u ++) {
123                     if (!coll.equals(t[u].NFC, t[u].NFD)) {
124                         errln("Failure: codePoint \\u"
125                               + Integer.toHexString(t[u].u)
126                               + " fails TestComposeDecompose for locale "
127                               + loc[i].getDisplayName());
128                         // this tests for the iterators too
129                         CollationTest.doTest(this, coll, t[u].NFC, t[u].NFD,
130                                              0);
131                     }
132                 }
133             }
134         }
135     }
136
137     public void TestRuleOptions() {
138         // values here are hardcoded and are correct for the current UCA when
139         // the UCA changes, one might be forced to change these values.
140
141         /*
142          * These strings contain the last character before [variable top]
143          * and the first and second characters (by primary weights) after it.
144          * See FractionalUCA.txt. For example:
145             [last variable [0C FE, 05, 05]] # U+10A7F OLD SOUTH ARABIAN NUMERIC INDICATOR
146             [variable top = 0C FE]
147             [first regular [0D 0A, 05, 05]] # U+0060 GRAVE ACCENT
148            and
149             00B4; [0D 0C, 05, 05]
150          *
151          * Note: Starting with UCA 6.0, the [variable top] collation element
152          * is not the weight of any character or string,
153          * which means that LAST_VARIABLE_CHAR_STRING sorts before [last variable].
154          */
155         String LAST_VARIABLE_CHAR_STRING = "\\U00010A7F";
156         String FIRST_REGULAR_CHAR_STRING = "\\u0060";
157         String SECOND_REGULAR_CHAR_STRING = "\\u00B4";
158
159         /*
160          * This string has to match the character that has the [last regular] weight
161          * which changes with each UCA version.
162          * See the bottom of FractionalUCA.txt which says something like
163             [last regular [7A FE, 05, 05]] # U+1342E EGYPTIAN HIEROGLYPH AA032
164          *
165          * Note: Starting with UCA 6.0, the [last regular] collation element
166          * is not the weight of any character or string,
167          * which means that LAST_REGULAR_CHAR_STRING sorts before [last regular].
168          */
169         String LAST_REGULAR_CHAR_STRING = "\\U0001342E";
170
171         String[] rules = {
172             // cannot test this anymore, as [last primary ignorable] doesn't
173             // have a  code point associated to it anymore
174             // "&[before 3][last primary ignorable]<<<k",
175             // - all befores here amount to zero
176             "&[before 3][first tertiary ignorable]<<<a",
177             "&[before 3][last tertiary ignorable]<<<a",
178             "&[before 3][first secondary ignorable]<<<a",
179             "&[before 3][last secondary ignorable]<<<a",
180             // 'normal' befores
181             "&[before 3][first primary ignorable]<<<c<<<b &[first primary ignorable]<a",
182             // we don't have a code point that corresponds to the last primary
183             // ignorable
184             "&[before 3][last primary ignorable]<<<c<<<b &[last primary ignorable]<a",
185             "&[before 3][first variable]<<<c<<<b &[first variable]<a",
186             "&[last variable]<a &[before 3][last variable]<<<c<<<b ",
187             "&[first regular]<a &[before 1][first regular]<b",
188             "&[before 1][last regular]<b &[last regular]<a",
189             "&[before 1][first implicit]<b &[first implicit]<a",
190             "&[before 1][last implicit]<b &[last implicit]<a",
191             "&[last variable]<z&[last primary ignorable]<x&[last secondary ignorable]<<y&[last tertiary ignorable]<<<w&[top]<u",
192         };
193         String[][] data = {
194             // {"k", "\u20e3"},
195             {"\\u0000", "a"}, // you cannot go before first tertiary ignorable
196             {"\\u0000", "a"}, // you cannot go before last tertiary ignorable
197             {"\\u0000", "a"}, // you cannot go before first secondary ignorable
198             {"\\u0000", "a"}, // you cannot go before first secondary ignorable
199             {"c", "b", "\\u0332", "a"},
200             {"\\u0332", "\\u20e3", "c", "b", "a"},
201             {"c", "b", "\\u0009", "a", "\\u000a"},
202             {LAST_VARIABLE_CHAR_STRING, "c", "b", /* [last variable] */ "a", FIRST_REGULAR_CHAR_STRING},
203             {"b", FIRST_REGULAR_CHAR_STRING, "a", SECOND_REGULAR_CHAR_STRING},
204             // The character in the second ordering test string
205             // has to match the character that has the [last regular] weight
206             // which changes with each UCA version.
207             // See the bottom of FractionalUCA.txt which says something like
208             // [last regular [CE 27, 05, 05]] # U+1342E EGYPTIAN HIEROGLYPH AA032
209             {LAST_REGULAR_CHAR_STRING, "b", /* [last regular] */ "a", "\\u4e00"},
210             {"b", "\\u4e00", "a", "\\u4e01"},
211             {"b", "\\U0010FFFD", "a"},
212             {"\ufffb",  "w", "y", "\u20e3", "x", LAST_VARIABLE_CHAR_STRING, "z", "u"},
213         };
214
215         for (int i = 0; i< rules.length; i++) {
216             logln(String.format("rules[%d] = \"%s\"", i, rules[i]));
217             genericRulesStarter(rules[i], data[i]);
218         }
219     }
220
221     void genericRulesStarter(String rules, String[] s) {
222         genericRulesStarterWithResult(rules, s, -1);
223     }
224
225     void genericRulesStarterWithResult(String rules, String[] s, int result) {
226
227         RuleBasedCollator coll = null;
228         try {
229             coll = new RuleBasedCollator(rules);
230             // logln("Rules starter for " + rules);
231             genericOrderingTestWithResult(coll, s, result);
232         } catch (Exception e) {
233             warnln("Unable to open collator with rules " + rules);
234         }
235     }
236
237     void genericRulesStarterWithOptionsAndResult(String rules, String[] s, String[] atts, Object[] attVals, int result) {
238         RuleBasedCollator coll = null;
239         try {
240             coll = new RuleBasedCollator(rules);
241             genericOptionsSetter(coll, atts, attVals);
242             genericOrderingTestWithResult(coll, s, result);
243         } catch (Exception e) {
244             warnln("Unable to open collator with rules " + rules);
245         }
246     }
247     void genericOrderingTestWithResult(Collator coll, String[] s, int result) {
248         String t1 = "";
249         String t2 = "";
250
251         for(int i = 0; i < s.length - 1; i++) {
252             for(int j = i+1; j < s.length; j++) {
253                 t1 = Utility.unescape(s[i]);
254                 t2 = Utility.unescape(s[j]);
255                 // System.out.println(i + " " + j);
256                 CollationTest.doTest(this, (RuleBasedCollator)coll, t1, t2,
257                                      result);
258             }
259         }
260     }
261
262     void reportCResult(String source, String target, CollationKey sourceKey, CollationKey targetKey,
263                        int compareResult, int keyResult, int incResult, int expectedResult ) {
264         if (expectedResult < -1 || expectedResult > 1) {
265             errln("***** invalid call to reportCResult ****");
266             return;
267         }
268         boolean ok1 = (compareResult == expectedResult);
269         boolean ok2 = (keyResult == expectedResult);
270         boolean ok3 = (incResult == expectedResult);
271         if (ok1 && ok2 && ok3 /* synwee to undo && !isVerbose()*/) {
272             return;
273         } else {
274             String msg1 = ok1? "Ok: compare(\"" : "FAIL: compare(\"";
275             String msg2 = "\", \"";
276             String msg3 = "\") returned ";
277             String msg4 = "; expected ";
278             String sExpect = new String("");
279             String sResult = new String("");
280             sResult = appendCompareResult(compareResult, sResult);
281             sExpect = appendCompareResult(expectedResult, sExpect);
282             if (ok1) {
283                 // logln(msg1 + source + msg2 + target + msg3 + sResult);
284             } else {
285                 errln(msg1 + source + msg2 + target + msg3 + sResult + msg4 + sExpect);
286             }
287             msg1 = ok2 ? "Ok: key(\"" : "FAIL: key(\"";
288             msg2 = "\").compareTo(key(\"";
289             msg3 = "\")) returned ";
290             sResult = appendCompareResult(keyResult, sResult);
291             if (ok2) {
292                 // logln(msg1 + source + msg2 + target + msg3 + sResult);
293             } else {
294                 errln(msg1 + source + msg2 + target + msg3 + sResult + msg4 + sExpect);
295                 msg1 = "  ";
296                 msg2 = " vs. ";
297                 errln(msg1 + prettify(sourceKey) + msg2 + prettify(targetKey));
298             }
299             msg1 = ok3 ? "Ok: incCompare(\"" : "FAIL: incCompare(\"";
300             msg2 = "\", \"";
301             msg3 = "\") returned ";
302             sResult = appendCompareResult(incResult, sResult);
303             if (ok3) {
304                 // logln(msg1 + source + msg2 + target + msg3 + sResult);
305             } else {
306                 errln(msg1 + source + msg2 + target + msg3 + sResult + msg4 + sExpect);
307             }
308         }
309     }
310
311     String appendCompareResult(int result, String target) {
312         if (result == -1) {  //LESS
313             target += "LESS";
314         } else if (result == 0) {  //EQUAL
315             target += "EQUAL";
316         } else if (result == 1) {  //GREATER
317             target += "GREATER";
318         } else {
319             String huh = "?";
320             target += huh + result;
321         }
322         return target;
323     }
324
325     static String prettify(CollationKey sourceKey) {
326         int i;
327         byte[] bytes= sourceKey.toByteArray();
328         StringBuilder target = new StringBuilder("[");
329
330         for (i = 0; i < bytes.length; i++) {
331             String numStr = Integer.toHexString(bytes[i] & 0xff);
332             if (numStr.length() < 2) {
333                 target.append('0');
334             }
335             target.append(numStr).append(' ');
336         }
337         target.append(']');
338         return target.toString();
339     }
340
341     public void TestBeforePrefixFailure() {
342         String[] rules = {
343             "&g <<< a&[before 3]\uff41 <<< x",
344             "&\u30A7=\u30A7=\u3047=\uff6a&\u30A8=\u30A8=\u3048=\uff74&[before 3]\u30a7<<<\u30a9",
345             "&[before 3]\u30a7<<<\u30a9&\u30A7=\u30A7=\u3047=\uff6a&\u30A8=\u30A8=\u3048=\uff74",
346         };
347         String[][] data = {
348             {"x", "\uff41"},
349             {"\u30a9", "\u30a7"},
350             {"\u30a9", "\u30a7"},
351         };
352
353         for(int i = 0; i< rules.length; i++) {
354             genericRulesStarter(rules[i], data[i]);
355         }
356     }
357
358     public void TestContractionClosure() {
359         String[] rules = {
360             "&b=\u00e4\u00e4",
361             "&b=\u00C5",
362         };
363         String[][] data = {
364             { "b", "\u00e4\u00e4", "a\u0308a\u0308", "\u00e4a\u0308", "a\u0308\u00e4" },
365             { "b", "\u00C5", "A\u030A", "\u212B" },
366         };
367
368         for(int i = 0; i< rules.length; i++) {
369             genericRulesStarterWithResult(rules[i], data[i], 0);
370         }
371     }
372
373     public void TestPrefixCompose() {
374         String rule1 = "&\u30a7<<<\u30ab|\u30fc=\u30ac|\u30fc";
375
376         String string = rule1;
377         try {
378             RuleBasedCollator coll = new RuleBasedCollator(string);
379             logln("rule:" + coll.getRules());
380         } catch (Exception e) {
381             warnln("Error open RuleBasedCollator rule = " + string);
382         }
383     }
384
385     public void TestStrCollIdenticalPrefix() {
386         String rule = "&\ud9b0\udc70=\ud9b0\udc71";
387         String test[] = {
388             "ab\ud9b0\udc70",
389             "ab\ud9b0\udc71"
390         };
391         genericRulesStarterWithResult(rule, test, 0);
392     }
393
394     public void TestPrefix() {
395         String[] rules = {
396             "&z <<< z|a",
397             "&z <<< z|   a",
398             "[strength I]&a=\ud900\udc25&z<<<\ud900\udc25|a",
399         };
400         String[][] data = {
401             {"zz", "za"},
402             {"zz", "za"},
403             {"aa", "az", "\ud900\udc25z", "\ud900\udc25a", "zz"},
404         };
405
406         for(int i = 0; i<rules.length; i++) {
407             genericRulesStarter(rules[i], data[i]);
408         }
409     }
410
411     public void TestNewJapanese() {
412
413         String test1[] = {
414             "\u30b7\u30e3\u30fc\u30ec",
415             "\u30b7\u30e3\u30a4",
416             "\u30b7\u30e4\u30a3",
417             "\u30b7\u30e3\u30ec",
418             "\u3061\u3087\u3053",
419             "\u3061\u3088\u3053",
420             "\u30c1\u30e7\u30b3\u30ec\u30fc\u30c8",
421             "\u3066\u30fc\u305f",
422             "\u30c6\u30fc\u30bf",
423             "\u30c6\u30a7\u30bf",
424             "\u3066\u3048\u305f",
425             "\u3067\u30fc\u305f",
426             "\u30c7\u30fc\u30bf",
427             "\u30c7\u30a7\u30bf",
428             "\u3067\u3048\u305f",
429             "\u3066\u30fc\u305f\u30fc",
430             "\u30c6\u30fc\u30bf\u30a1",
431             "\u30c6\u30a7\u30bf\u30fc",
432             "\u3066\u3047\u305f\u3041",
433             "\u3066\u3048\u305f\u30fc",
434             "\u3067\u30fc\u305f\u30fc",
435             "\u30c7\u30fc\u30bf\u30a1",
436             "\u3067\u30a7\u305f\u30a1",
437             "\u30c7\u3047\u30bf\u3041",
438             "\u30c7\u30a8\u30bf\u30a2",
439             "\u3072\u3086",
440             "\u3073\u3085\u3042",
441             "\u3074\u3085\u3042",
442             "\u3073\u3085\u3042\u30fc",
443             "\u30d3\u30e5\u30a2\u30fc",
444             "\u3074\u3085\u3042\u30fc",
445             "\u30d4\u30e5\u30a2\u30fc",
446             "\u30d2\u30e5\u30a6",
447             "\u30d2\u30e6\u30a6",
448             "\u30d4\u30e5\u30a6\u30a2",
449             "\u3073\u3085\u30fc\u3042\u30fc",
450             "\u30d3\u30e5\u30fc\u30a2\u30fc",
451             "\u30d3\u30e5\u30a6\u30a2\u30fc",
452             "\u3072\u3085\u3093",
453             "\u3074\u3085\u3093",
454             "\u3075\u30fc\u308a",
455             "\u30d5\u30fc\u30ea",
456             "\u3075\u3045\u308a",
457             "\u3075\u30a5\u308a",
458             "\u3075\u30a5\u30ea",
459             "\u30d5\u30a6\u30ea",
460             "\u3076\u30fc\u308a",
461             "\u30d6\u30fc\u30ea",
462             "\u3076\u3045\u308a",
463             "\u30d6\u30a5\u308a",
464             "\u3077\u3046\u308a",
465             "\u30d7\u30a6\u30ea",
466             "\u3075\u30fc\u308a\u30fc",
467             "\u30d5\u30a5\u30ea\u30fc",
468             "\u3075\u30a5\u308a\u30a3",
469             "\u30d5\u3045\u308a\u3043",
470             "\u30d5\u30a6\u30ea\u30fc",
471             "\u3075\u3046\u308a\u3043",
472             "\u30d6\u30a6\u30ea\u30a4",
473             "\u3077\u30fc\u308a\u30fc",
474             "\u3077\u30a5\u308a\u30a4",
475             "\u3077\u3046\u308a\u30fc",
476             "\u30d7\u30a6\u30ea\u30a4",
477             "\u30d5\u30fd",
478             "\u3075\u309e",
479             "\u3076\u309d",
480             "\u3076\u3075",
481             "\u3076\u30d5",
482             "\u30d6\u3075",
483             "\u30d6\u30d5",
484             "\u3076\u309e",
485             "\u3076\u3077",
486             "\u30d6\u3077",
487             "\u3077\u309d",
488             "\u30d7\u30fd",
489             "\u3077\u3075",
490         };
491
492         String test2[] = {
493             "\u306f\u309d", // H\u309d
494             "\u30cf\u30fd", // K\u30fd
495             "\u306f\u306f", // HH
496             "\u306f\u30cf", // HK
497             "\u30cf\u30cf", // KK
498             "\u306f\u309e", // H\u309e
499             "\u30cf\u30fe", // K\u30fe
500             "\u306f\u3070", // HH\u309b
501             "\u30cf\u30d0", // KK\u309b
502             "\u306f\u3071", // HH\u309c
503             "\u30cf\u3071", // KH\u309c
504             "\u30cf\u30d1", // KK\u309c
505             "\u3070\u309d", // H\u309b\u309d
506             "\u30d0\u30fd", // K\u309b\u30fd
507             "\u3070\u306f", // H\u309bH
508             "\u30d0\u30cf", // K\u309bK
509             "\u3070\u309e", // H\u309b\u309e
510             "\u30d0\u30fe", // K\u309b\u30fe
511             "\u3070\u3070", // H\u309bH\u309b
512             "\u30d0\u3070", // K\u309bH\u309b
513             "\u30d0\u30d0", // K\u309bK\u309b
514             "\u3070\u3071", // H\u309bH\u309c
515             "\u30d0\u30d1", // K\u309bK\u309c
516             "\u3071\u309d", // H\u309c\u309d
517             "\u30d1\u30fd", // K\u309c\u30fd
518             "\u3071\u306f", // H\u309cH
519             "\u30d1\u30cf", // K\u309cK
520             "\u3071\u3070", // H\u309cH\u309b
521             "\u3071\u30d0", // H\u309cK\u309b
522             "\u30d1\u30d0", // K\u309cK\u309b
523             "\u3071\u3071", // H\u309cH\u309c
524             "\u30d1\u30d1", // K\u309cK\u309c
525         };
526
527         String[] att = { "strength", };
528         Object[] val = { new Integer(Collator.QUATERNARY), };
529
530         String[] attShifted = { "strength", "AlternateHandling"};
531         Object valShifted[] = { new Integer(Collator.QUATERNARY),
532                                 Boolean.TRUE };
533
534         genericLocaleStarterWithOptions(Locale.JAPANESE, test1, att, val);
535         genericLocaleStarterWithOptions(Locale.JAPANESE, test2, att, val);
536
537         genericLocaleStarterWithOptions(Locale.JAPANESE, test1, attShifted,
538                                         valShifted);
539         genericLocaleStarterWithOptions(Locale.JAPANESE, test2, attShifted,
540                                         valShifted);
541     }
542
543     void genericLocaleStarter(Locale locale, String s[]) {
544         RuleBasedCollator coll = null;
545         try {
546             coll = (RuleBasedCollator)Collator.getInstance(locale);
547
548         } catch (Exception e) {
549             warnln("Unable to open collator for locale " + locale);
550             return;
551         }
552         // logln("Locale starter for " + locale);
553         genericOrderingTest(coll, s);
554     }
555
556     void genericLocaleStarterWithOptions(Locale locale, String[] s, String[] attrs, Object[] values) {
557         genericLocaleStarterWithOptionsAndResult(locale, s, attrs, values, -1);
558     }
559
560     private void genericOptionsSetter(RuleBasedCollator coll, String[] attrs, Object[] values) {
561         for(int i = 0; i < attrs.length; i++) {
562             if (attrs[i].equals("strength")) {
563                 coll.setStrength(((Integer)values[i]).intValue());
564             }
565             else if (attrs[i].equals("decomp")) {
566                 coll.setDecomposition(((Integer)values[i]).intValue());
567             }
568             else if (attrs[i].equals("AlternateHandling")) {
569                 coll.setAlternateHandlingShifted(((Boolean)values[i]
570                                                   ).booleanValue());
571             }
572             else if (attrs[i].equals("NumericCollation")) {
573                 coll.setNumericCollation(((Boolean)values[i]).booleanValue());
574             }
575             else if (attrs[i].equals("UpperFirst")) {
576                 coll.setUpperCaseFirst(((Boolean)values[i]).booleanValue());
577             }
578             else if (attrs[i].equals("LowerFirst")) {
579                 coll.setLowerCaseFirst(((Boolean)values[i]).booleanValue());
580             }
581             else if (attrs[i].equals("CaseLevel")) {
582                 coll.setCaseLevel(((Boolean)values[i]).booleanValue());
583             }
584         }
585     }
586
587     void genericLocaleStarterWithOptionsAndResult(Locale locale, String[] s, String[] attrs, Object[] values, int result) {
588         RuleBasedCollator coll = null;
589         try {
590             coll = (RuleBasedCollator)Collator.getInstance(locale);
591         } catch (Exception e) {
592             warnln("Unable to open collator for locale " + locale);
593             return;
594         }
595         // logln("Locale starter for " +locale);
596
597         // logln("Setting attributes");
598         genericOptionsSetter(coll, attrs, values);
599
600         genericOrderingTestWithResult(coll, s, result);
601     }
602
603     void genericOrderingTest(Collator coll, String[] s) {
604         genericOrderingTestWithResult(coll, s, -1);
605     }
606
607     public void TestNonChars() {
608         String test[] = {
609             "\u0000",  /* ignorable */
610             "\uFFFE",  /* special merge-sort character with minimum non-ignorable weights */
611             "\uFDD0", "\uFDEF",
612             "\\U0001FFFE", "\\U0001FFFF",  /* UCA 6.0: noncharacters are treated like unassigned, */
613             "\\U0002FFFE", "\\U0002FFFF",  /* not like ignorable. */
614             "\\U0003FFFE", "\\U0003FFFF",
615             "\\U0004FFFE", "\\U0004FFFF",
616             "\\U0005FFFE", "\\U0005FFFF",
617             "\\U0006FFFE", "\\U0006FFFF",
618             "\\U0007FFFE", "\\U0007FFFF",
619             "\\U0008FFFE", "\\U0008FFFF",
620             "\\U0009FFFE", "\\U0009FFFF",
621             "\\U000AFFFE", "\\U000AFFFF",
622             "\\U000BFFFE", "\\U000BFFFF",
623             "\\U000CFFFE", "\\U000CFFFF",
624             "\\U000DFFFE", "\\U000DFFFF",
625             "\\U000EFFFE", "\\U000EFFFF",
626             "\\U000FFFFE", "\\U000FFFFF",
627             "\\U0010FFFE", "\\U0010FFFF",
628             "\uFFFF"  /* special character with maximum primary weight */
629         };
630         Collator coll = null;
631         try {
632             coll = Collator.getInstance(new Locale("en", "US"));
633         } catch (Exception e) {
634             warnln("Unable to open collator");
635             return;
636         }
637         // logln("Test non characters");
638
639         genericOrderingTestWithResult(coll, test, -1);
640     }
641
642     public void TestExtremeCompression() {
643         String[] test = new String[4];
644
645         for(int i = 0; i<4; i++) {
646             StringBuffer temp = new StringBuffer();
647             for (int j = 0; j < 2047; j++) {
648                 temp.append('a');
649             }
650             temp.append((char)('a' + i));
651             test[i] = temp.toString();
652         }
653
654         genericLocaleStarter(new Locale("en", "US"), test);
655     }
656
657     /**
658      * Tests surrogate support.
659      */
660     public void TestSurrogates() {
661         String test[] = {"z","\ud900\udc25", "\ud805\udc50", "\ud800\udc00y",
662                          "\ud800\udc00r", "\ud800\udc00f", "\ud800\udc00",
663                          "\ud800\udc00c", "\ud800\udc00b", "\ud800\udc00fa",
664                          "\ud800\udc00fb", "\ud800\udc00a", "c", "b"};
665
666         String rule = "&z < \ud900\udc25 < \ud805\udc50 < \ud800\udc00y "
667             + "< \ud800\udc00r < \ud800\udc00f << \ud800\udc00 "
668             + "< \ud800\udc00fa << \ud800\udc00fb < \ud800\udc00a "
669             + "< c < b";
670         genericRulesStarter(rule, test);
671     }
672
673     public void TestBocsuCoverage() {
674         String test = "\u0041\u0441\u4441\\U00044441\u4441\u0441\u0041";
675         Collator coll = Collator.getInstance();
676         coll.setStrength(Collator.IDENTICAL);
677         CollationKey key = coll.getCollationKey(test);
678         logln("source:" + key.getSourceString());
679     }
680
681     public void TestCyrillicTailoring() {
682         String test[] = {
683             "\u0410b",
684             "\u0410\u0306a",
685             "\u04d0A"
686         };
687         genericLocaleStarter(new Locale("en", ""), test);
688         genericRulesStarter("&\u0410 = \u0410", test);
689         genericRulesStarter("&Z < \u0410", test);
690         genericRulesStarter("&\u0410 = \u0410 < \u04d0", test);
691         genericRulesStarter("&Z < \u0410 < \u04d0", test);
692         genericRulesStarter("&\u0410 = \u0410 < \u0410\u0301", test);
693         genericRulesStarter("&Z < \u0410 < \u0410\u0301", test);
694     }
695
696     public void TestSuppressContractions() {
697         String testNoCont2[] = {
698             "\u0410\u0302a",
699             "\u0410\u0306b",
700             "\u0410c"
701         };
702         String testNoCont[] = {
703             "a\u0410",
704             "A\u0410\u0306",
705             "\uFF21\u0410\u0302"
706         };
707
708         genericRulesStarter("[suppressContractions [\u0400-\u047f]]", testNoCont);
709         genericRulesStarter("[suppressContractions [\u0400-\u047f]]", testNoCont2);
710     }
711
712     public void TestCase() {
713         String gRules = "\u0026\u0030\u003C\u0031\u002C\u2460\u003C\u0061\u002C\u0041";
714         String[] testCase = {
715             "1a", "1A", "\u2460a", "\u2460A"
716         };
717         int[][] caseTestResults = {
718             { -1, -1, -1, 0, -1, -1, 0, 0, -1 },
719             { 1, -1, -1, 0, -1, -1, 0, 0, 1 },
720             { -1, -1, -1, 0, 1, -1, 0, 0, -1 },
721             { 1, -1, 1, 0, -1, -1, 0, 0, 1 }
722
723         };
724         boolean[][] caseTestAttributes = {
725             { false, false},
726             { true, false},
727             { false, true},
728             { true, true}
729         };
730
731         int i,j,k;
732         Collator  myCollation;
733         try {
734             myCollation = Collator.getInstance(new Locale("en", "US"));
735         } catch (Exception e) {
736             warnln("ERROR: in creation of rule based collator ");
737             return;
738         }
739         // logln("Testing different case settings");
740         myCollation.setStrength(Collator.TERTIARY);
741
742         for(k = 0; k <4; k++) {
743             if (caseTestAttributes[k][0] == true) {
744                 // upper case first
745                 ((RuleBasedCollator)myCollation).setUpperCaseFirst(true);
746             }
747             else {
748                 // upper case first
749                 ((RuleBasedCollator)myCollation).setLowerCaseFirst(true);
750             }
751             ((RuleBasedCollator)myCollation).setCaseLevel(
752                                                           caseTestAttributes[k][1]);
753
754             // logln("Case first = " + caseTestAttributes[k][0] + ", Case level = " + caseTestAttributes[k][1]);
755             for (i = 0; i < 3 ; i++) {
756                 for(j = i+1; j<4; j++) {
757                     CollationTest.doTest(this,
758                                          (RuleBasedCollator)myCollation,
759                                          testCase[i], testCase[j],
760                                          caseTestResults[k][3*i+j-1]);
761                 }
762             }
763         }
764         try {
765             myCollation = new RuleBasedCollator(gRules);
766         } catch (Exception e) {
767             warnln("ERROR: in creation of rule based collator");
768             return;
769         }
770         // logln("Testing different case settings with custom rules");
771         myCollation.setStrength(Collator.TERTIARY);
772
773         for(k = 0; k<4; k++) {
774             if (caseTestAttributes[k][0] == true) {
775                 ((RuleBasedCollator)myCollation).setUpperCaseFirst(true);
776             }
777             else {
778                 ((RuleBasedCollator)myCollation).setUpperCaseFirst(false);
779             }
780             ((RuleBasedCollator)myCollation).setCaseLevel(
781                                                           caseTestAttributes[k][1]);
782             for (i = 0; i < 3 ; i++) {
783                 for(j = i+1; j<4; j++) {
784                     CollationTest.doTest(this,
785                                          (RuleBasedCollator)myCollation,
786                                          testCase[i], testCase[j],
787                                          caseTestResults[k][3*i+j-1]);
788                 }
789             }
790         }
791
792         {
793             String[] lowerFirst = {
794                 "h",
795                 "H",
796                 "ch",
797                 "Ch",
798                 "CH",
799                 "cha",
800                 "chA",
801                 "Cha",
802                 "ChA",
803                 "CHa",
804                 "CHA",
805                 "i",
806                 "I"
807             };
808
809             String[] upperFirst = {
810                 "H",
811                 "h",
812                 "CH",
813                 "Ch",
814                 "ch",
815                 "CHA",
816                 "CHa",
817                 "ChA",
818                 "Cha",
819                 "chA",
820                 "cha",
821                 "I",
822                 "i"
823             };
824             // logln("mixed case test");
825             // logln("lower first, case level off");
826             genericRulesStarter("[casefirst lower]&H<ch<<<Ch<<<CH", lowerFirst);
827             // logln("upper first, case level off");
828             genericRulesStarter("[casefirst upper]&H<ch<<<Ch<<<CH", upperFirst);
829             // logln("lower first, case level on");
830             genericRulesStarter("[casefirst lower][caselevel on]&H<ch<<<Ch<<<CH", lowerFirst);
831             // logln("upper first, case level on");
832             genericRulesStarter("[casefirst upper][caselevel on]&H<ch<<<Ch<<<CH", upperFirst);
833         }
834     }
835
836     public void TestIncompleteCnt() {
837         String[] cnt1 = {
838             "AA",
839             "AC",
840             "AZ",
841             "AQ",
842             "AB",
843             "ABZ",
844             "ABQ",
845             "Z",
846             "ABC",
847             "Q",
848             "B"
849         };
850
851         String[] cnt2 = {
852             "DA",
853             "DAD",
854             "DAZ",
855             "MAR",
856             "Z",
857             "DAVIS",
858             "MARK",
859             "DAV",
860             "DAVI"
861         };
862         RuleBasedCollator coll =  null;
863         String temp = " & Z < ABC < Q < B";
864         try {
865             coll = new RuleBasedCollator(temp);
866         } catch (Exception e) {
867             warnln("fail to create RuleBasedCollator");
868             return;
869         }
870
871         int size = cnt1.length;
872         for(int i = 0; i < size-1; i++) {
873             for(int j = i+1; j < size; j++) {
874                 String t1 = cnt1[i];
875                 String t2 = cnt1[j];
876                 CollationTest.doTest(this, coll, t1, t2, -1);
877             }
878         }
879
880         temp = " & Z < DAVIS < MARK <DAV";
881         try {
882             coll = new RuleBasedCollator(temp);
883         } catch (Exception e) {
884             warnln("fail to create RuleBasedCollator");
885             return;
886         }
887
888         size = cnt2.length;
889         for(int i = 0; i < size-1; i++) {
890             for(int j = i+1; j < size; j++) {
891                 String t1 = cnt2[i];
892                 String t2 = cnt2[j];
893                 CollationTest.doTest(this, coll, t1, t2, -1);
894             }
895         }
896     }
897
898     public void TestBlackBird() {
899         String[] shifted = {
900             "black bird",
901             "black-bird",
902             "blackbird",
903             "black Bird",
904             "black-Bird",
905             "blackBird",
906             "black birds",
907             "black-birds",
908             "blackbirds"
909         };
910         int[] shiftedTert = {
911             0,
912             0,
913             0,
914             -1,
915             0,
916             0,
917             -1,
918             0,
919             0
920         };
921         String[] nonignorable = {
922             "black bird",
923             "black Bird",
924             "black birds",
925             "black-bird",
926             "black-Bird",
927             "black-birds",
928             "blackbird",
929             "blackBird",
930             "blackbirds"
931         };
932         int i = 0, j = 0;
933         int size = 0;
934         Collator coll = Collator.getInstance(new Locale("en", "US"));
935         //ucol_setAttribute(coll, UCOL_NORMALIZATION_MODE, UCOL_OFF, &status);
936         //ucol_setAttribute(coll, UCOL_ALTERNATE_HANDLING, UCOL_NON_IGNORABLE, &status);
937         ((RuleBasedCollator)coll).setAlternateHandlingShifted(false);
938         size = nonignorable.length;
939         for(i = 0; i < size-1; i++) {
940             for(j = i+1; j < size; j++) {
941                 String t1 = nonignorable[i];
942                 String t2 = nonignorable[j];
943                 CollationTest.doTest(this, (RuleBasedCollator)coll, t1, t2, -1);
944             }
945         }
946         ((RuleBasedCollator)coll).setAlternateHandlingShifted(true);
947         coll.setStrength(Collator.QUATERNARY);
948         size = shifted.length;
949         for(i = 0; i < size-1; i++) {
950             for(j = i+1; j < size; j++) {
951                 String t1 = shifted[i];
952                 String t2 = shifted[j];
953                 CollationTest.doTest(this, (RuleBasedCollator)coll, t1, t2, -1);
954             }
955         }
956         coll.setStrength(Collator.TERTIARY);
957         size = shifted.length;
958         for(i = 1; i < size; i++) {
959             String t1 = shifted[i-1];
960             String t2 = shifted[i];
961             CollationTest.doTest(this, (RuleBasedCollator)coll, t1, t2,
962                                  shiftedTert[i]);
963         }
964     }
965
966     public void TestFunkyA() {
967         String[] testSourceCases = {
968             "\u0041\u0300\u0301",
969             "\u0041\u0300\u0316",
970             "\u0041\u0300",
971             "\u00C0\u0301",
972             // this would work with forced normalization
973             "\u00C0\u0316",
974         };
975
976         String[] testTargetCases = {
977             "\u0041\u0301\u0300",
978             "\u0041\u0316\u0300",
979             "\u00C0",
980             "\u0041\u0301\u0300",
981             // this would work with forced normalization
982             "\u0041\u0316\u0300",
983         };
984
985         int[] results = {
986             1,
987             0,
988             0,
989             1,
990             0
991         };
992
993         Collator  myCollation;
994         try {
995             myCollation = Collator.getInstance(new Locale("en", "US"));
996         } catch (Exception e) {
997             warnln("ERROR: in creation of rule based collator");
998             return;
999         }
1000         // logln("Testing some A letters, for some reason");
1001         myCollation.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
1002         myCollation.setStrength(Collator.TERTIARY);
1003         for (int i = 0; i < 4 ; i++)
1004             {
1005                 CollationTest.doTest(this, (RuleBasedCollator)myCollation,
1006                                      testSourceCases[i], testTargetCases[i],
1007                                      results[i]);
1008             }
1009     }
1010
1011     public void TestChMove() {
1012         String[] chTest = {
1013             "c",
1014             "C",
1015             "ca", "cb", "cx", "cy", "CZ",
1016             "c\u030C", "C\u030C",
1017             "h",
1018             "H",
1019             "ha", "Ha", "harly", "hb", "HB", "hx", "HX", "hy", "HY",
1020             "ch", "cH", "Ch", "CH",
1021             "cha", "charly", "che", "chh", "chch", "chr",
1022             "i", "I", "iarly",
1023             "r", "R",
1024             "r\u030C", "R\u030C",
1025             "s",
1026             "S",
1027             "s\u030C", "S\u030C",
1028             "z", "Z",
1029             "z\u030C", "Z\u030C"
1030         };
1031         Collator coll = null;
1032         try {
1033             coll = Collator.getInstance(new Locale("cs", ""));
1034         } catch (Exception e) {
1035             warnln("Cannot create Collator");
1036             return;
1037         }
1038         int size = chTest.length;
1039         for(int i = 0; i < size-1; i++) {
1040             for(int j = i+1; j < size; j++) {
1041                 String t1 = chTest[i];
1042                 String t2 = chTest[j];
1043                 CollationTest.doTest(this, (RuleBasedCollator)coll, t1, t2, -1);
1044             }
1045         }
1046     }
1047
1048     public void TestImplicitTailoring() {
1049         String rules[] = { "&[before 1]\u4e00 < b < c &[before 1]\u4e00 < d < e",
1050                            "&\u4e00 < a <<< A < b <<< B",
1051                            "&[before 1]\u4e00 < \u4e01 < \u4e02",
1052                            "&[before 1]\u4e01 < \u4e02 < \u4e03",
1053         };
1054         String cases[][] = {
1055             { "d", "e", "b", "c", "\u4e00"},
1056             { "\u4e00", "a", "A", "b", "B", "\u4e01"},
1057             { "\u4e01", "\u4e02", "\u4e00"},
1058             { "\u4e02", "\u4e03", "\u4e01"},
1059         };
1060
1061         int i = 0;
1062
1063         for(i = 0; i < rules.length; i++) {
1064             genericRulesStarter(rules[i], cases[i]);
1065         }
1066
1067     }
1068
1069     public void TestFCDProblem() {
1070         String s1 = "\u0430\u0306\u0325";
1071         String s2 = "\u04D1\u0325";
1072         Collator coll = null;
1073         try {
1074             coll = Collator.getInstance();
1075         } catch (Exception e) {
1076             warnln("Can't create collator");
1077             return;
1078         }
1079
1080         coll.setDecomposition(Collator.NO_DECOMPOSITION);
1081         CollationTest.doTest(this, (RuleBasedCollator)coll, s1, s2, 0);
1082         coll.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
1083         CollationTest.doTest(this, (RuleBasedCollator)coll, s1, s2, 0);
1084     }
1085
1086     public void TestEmptyRule() {
1087         String rulez = "";
1088         try {
1089             RuleBasedCollator coll = new RuleBasedCollator(rulez);
1090             logln("rule:" + coll.getRules());
1091         } catch (Exception e) {
1092             warnln(e.getMessage());
1093         }
1094     }
1095
1096     /* superseded by TestBeforePinyin, since Chinese collation rules have changed */
1097     /*
1098     public void TestJ784() {
1099         String[] data = {
1100             "A", "\u0101", "\u00e1", "\u01ce", "\u00e0",
1101             "E", "\u0113", "\u00e9", "\u011b", "\u00e8",
1102             "I", "\u012b", "\u00ed", "\u01d0", "\u00ec",
1103             "O", "\u014d", "\u00f3", "\u01d2", "\u00f2",
1104             "U", "\u016b", "\u00fa", "\u01d4", "\u00f9",
1105             "\u00fc", "\u01d6", "\u01d8", "\u01da", "\u01dc"
1106         };
1107         genericLocaleStarter(new Locale("zh", ""), data);
1108     }
1109     */
1110
1111     public void TestJ815() {
1112         String data[] = {
1113             "aa",
1114             "Aa",
1115             "ab",
1116             "Ab",
1117             "ad",
1118             "Ad",
1119             "ae",
1120             "Ae",
1121             "\u00e6",
1122             "\u00c6",
1123             "af",
1124             "Af",
1125             "b",
1126             "B"
1127         };
1128         genericLocaleStarter(new Locale("fr", ""), data);
1129         genericRulesStarter("[backwards 2]&A<<\u00e6/e<<<\u00c6/E", data);
1130     }
1131
1132     public void TestJ3087()
1133     {
1134         String rule[] = {"&h<H&CH=\u0427",
1135                          "&CH=\u0427&h<H",
1136                          "&CH=\u0427"};
1137         RuleBasedCollator rbc = null;
1138         CollationElementIterator iter1;
1139         CollationElementIterator iter2;
1140         for (int i = 0; i < rule.length; i ++) {
1141             try {
1142                 rbc = new RuleBasedCollator(rule[i]);
1143             } catch (Exception e) {
1144                 warnln(e.getMessage());
1145                 return;
1146             }
1147             iter1 = rbc.getCollationElementIterator("CH");
1148             iter2 = rbc.getCollationElementIterator("\u0427");
1149             int ce1 = CollationElementIterator.IGNORABLE;
1150             int ce2 = CollationElementIterator.IGNORABLE;
1151             while (ce1 != CollationElementIterator.NULLORDER
1152                    && ce2 != CollationElementIterator.NULLORDER) {
1153                 ce1 = iter1.next();
1154                 ce2 = iter2.next();
1155                 if (ce1 != ce2) {
1156                     errln("Error generating RuleBasedCollator with the rule "
1157                           + rule[i]);
1158                     errln("CH != \\u0427");
1159                 }
1160             }
1161         }
1162     }
1163
1164     public void DontTestJ831() { // Latvian does not use upper first
1165         String[] data = {
1166             "I",
1167             "i",
1168             "Y",
1169             "y"
1170         };
1171         genericLocaleStarter(new Locale("lv", ""), data);
1172     }
1173
1174     public void TestBefore() {
1175         String data[] = {
1176             "\u0101", "\u00e1", "\u01ce", "\u00e0", "A",
1177             "\u0113", "\u00e9", "\u011b", "\u00e8", "E",
1178             "\u012b", "\u00ed", "\u01d0", "\u00ec", "I",
1179             "\u014d", "\u00f3", "\u01d2", "\u00f2", "O",
1180             "\u016b", "\u00fa", "\u01d4", "\u00f9", "U",
1181             "\u01d6", "\u01d8", "\u01da", "\u01dc", "\u00fc"
1182         };
1183         genericRulesStarter(
1184                             "&[before 1]a<\u0101<\u00e1<\u01ce<\u00e0"
1185                             + "&[before 1]e<\u0113<\u00e9<\u011b<\u00e8"
1186                             + "&[before 1]i<\u012b<\u00ed<\u01d0<\u00ec"
1187                             + "&[before 1]o<\u014d<\u00f3<\u01d2<\u00f2"
1188                             + "&[before 1]u<\u016b<\u00fa<\u01d4<\u00f9"
1189                             + "&u<\u01d6<\u01d8<\u01da<\u01dc<\u00fc", data);
1190     }
1191
1192     public void TestRedundantRules() {
1193         String[] rules = {
1194             //"& a <<< b <<< c << d <<< e& [before 1] e <<< x",
1195             "& b <<< c <<< d << e <<< f& [before 3] f <<< x",
1196             "& a < b <<< c << d <<< e& [before 1] e <<< x",
1197             "& a < b < c < d& [before 1] c < m",
1198             "& a < b <<< c << d <<< e& [before 3] e <<< x",
1199             "& a < b <<< c << d <<< e& [before 2] e <<< x",
1200             "& a < b <<< c << d <<< e <<< f < g& [before 1] g < x",
1201             "& a <<< b << c < d& a < m",
1202             "&a<b<<b\u0301 &z<b",
1203             "&z<m<<<q<<<m",
1204             "&z<<<m<q<<<m",
1205             "& a < b < c < d& r < c",
1206             "& a < b < c < d& r < c",
1207             "& a < b < c < d& c < m",
1208             "& a < b < c < d& a < m"
1209         };
1210
1211         String[] expectedRules = {
1212             //"&\u2089<<<x",
1213             "&\u0252<<<x",
1214             "& a <<< x < b <<< c << d <<< e",
1215             "& a < b < m < c < d",
1216             "& a < b <<< c << d <<< x <<< e",
1217             "& a < b <<< c <<< x << d <<< e",
1218             "& a < b <<< c << d <<< e <<< f < x < g",
1219             "& a <<< b << c < m < d",
1220             "&a<b\u0301 &z<b",
1221             "&z<q<<<m",
1222             "&z<q<<<m",
1223             "& a < b < d& r < c",
1224             "& a < b < d& r < c",
1225             "& a < b < c < m < d",
1226             "& a < m < b < c < d"
1227         };
1228
1229         String[][] testdata = {
1230             //            {"\u2089", "x"},
1231             {"\u0252", "x"},
1232             {"a", "x", "b", "c", "d", "e"},
1233             {"a", "b", "m", "c", "d"},
1234             {"a", "b", "c", "d", "x", "e"},
1235             {"a", "b", "c", "x", "d", "e"},
1236             {"a", "b", "c", "d", "e", "f", "x", "g"},
1237             {"a", "b", "c", "m", "d"},
1238             {"a", "b\u0301", "z", "b"},
1239             {"z", "q", "m"},
1240             {"z", "q", "m"},
1241             {"a", "b", "d"},
1242             {"r", "c"},
1243             {"a", "b", "c", "m", "d"},
1244             {"a", "m", "b", "c", "d"}
1245         };
1246
1247         String rlz = "";
1248         for(int i = 0; i<rules.length; i++) {
1249             logln("testing rule " + rules[i] + ", expected to be" + expectedRules[i]);
1250             try {
1251                 rlz = rules[i];
1252                 Collator credundant = new RuleBasedCollator(rlz);
1253                 rlz = expectedRules[i];
1254                 Collator cresulting = new RuleBasedCollator(rlz);
1255                 logln(" credundant Rule:" + ((RuleBasedCollator)credundant).getRules());
1256                 logln(" cresulting Rule:" + ((RuleBasedCollator)cresulting).getRules());
1257             } catch (Exception e) {
1258                 warnln("Cannot create RuleBasedCollator");
1259             }
1260             //testAgainstUCA(cresulting, credundant, "expected", TRUE, &status);
1261             // logln("testing using data\n");
1262             genericRulesStarter(rules[i], testdata[i]);
1263         }
1264     }
1265
1266     public void TestExpansionSyntax() {
1267         String[] rules = {
1268             "&AE <<< a << b <<< c &d <<< f",
1269             "&AE <<< a <<< b << c << d < e < f <<< g",
1270             "&AE <<< B <<< C / D <<< F"
1271         };
1272
1273         String[] expectedRules = {
1274             "&A <<< a / E << b / E <<< c /E  &d <<< f",
1275             "&A <<< a / E <<< b / E << c / E << d / E < e < f <<< g",
1276             "&A <<< B / E <<< C / ED <<< F / E"
1277         };
1278
1279         String[][] testdata = {
1280             {"AE", "a", "b", "c"},
1281             {"AE", "a", "b", "c", "d", "e", "f", "g"},
1282             {"AE", "B", "C"} // / ED <<< F / E"},
1283         };
1284
1285         for(int i = 0; i<rules.length; i++) {
1286             // logln("testing rule " + rules[i] + ", expected to be " + expectedRules[i]);
1287             try {
1288                 String rlz = rules[i];
1289                 Collator credundant = new RuleBasedCollator(rlz);
1290                 rlz = expectedRules[i];
1291                 Collator cresulting = new RuleBasedCollator(rlz);
1292                 logln(" credundant Rule:" + ((RuleBasedCollator)credundant).getRules());
1293                 logln(" cresulting Rule:" + ((RuleBasedCollator)cresulting).getRules());
1294             } catch (Exception e) {
1295                 warnln(e.getMessage());
1296             }
1297             // testAgainstUCA still doesn't handle expansions correctly, so this is not run
1298             // as a hard error test, but only in information mode
1299             //testAgainstUCA(cresulting, credundant, "expected", FALSE, &status);
1300
1301             // logln("testing using data");
1302             genericRulesStarter(rules[i], testdata[i]);
1303         }
1304     }
1305
1306     public void TestHangulTailoring() {
1307         String[] koreanData = {
1308             "\uac00", "\u4f3d", "\u4f73", "\u5047", "\u50f9", "\u52a0", "\u53ef", "\u5475",
1309             "\u54e5", "\u5609", "\u5ac1", "\u5bb6", "\u6687", "\u67b6", "\u67b7", "\u67ef",
1310             "\u6b4c", "\u73c2", "\u75c2", "\u7a3c", "\u82db", "\u8304", "\u8857", "\u8888",
1311             "\u8a36", "\u8cc8", "\u8dcf", "\u8efb", "\u8fe6", "\u99d5",
1312             "\u4EEE", "\u50A2", "\u5496", "\u54FF", "\u5777", "\u5B8A", "\u659D", "\u698E",
1313             "\u6A9F", "\u73C8", "\u7B33", "\u801E", "\u8238", "\u846D", "\u8B0C"
1314         };
1315
1316         String rules =
1317             "&\uac00 <<< \u4f3d <<< \u4f73 <<< \u5047 <<< \u50f9 <<< \u52a0 <<< \u53ef <<< \u5475 "
1318             + "<<< \u54e5 <<< \u5609 <<< \u5ac1 <<< \u5bb6 <<< \u6687 <<< \u67b6 <<< \u67b7 <<< \u67ef "
1319             + "<<< \u6b4c <<< \u73c2 <<< \u75c2 <<< \u7a3c <<< \u82db <<< \u8304 <<< \u8857 <<< \u8888 "
1320             + "<<< \u8a36 <<< \u8cc8 <<< \u8dcf <<< \u8efb <<< \u8fe6 <<< \u99d5 "
1321             + "<<< \u4EEE <<< \u50A2 <<< \u5496 <<< \u54FF <<< \u5777 <<< \u5B8A <<< \u659D <<< \u698E "
1322             + "<<< \u6A9F <<< \u73C8 <<< \u7B33 <<< \u801E <<< \u8238 <<< \u846D <<< \u8B0C";
1323
1324         String rlz = rules;
1325
1326         Collator coll = null;
1327         try {
1328             coll = new RuleBasedCollator(rlz);
1329         } catch (Exception e) {
1330             warnln("Unable to open collator with rules" + rules);
1331             return;
1332         }
1333         // logln("Using start of korean rules\n");
1334         genericOrderingTest(coll, koreanData);
1335         // logln("Setting jamoSpecial to TRUE and testing once more\n");
1336
1337         // can't set jamo in icu4j
1338         // ((UCATableHeader *)coll->image)->jamoSpecial = TRUE; // don't try this at home
1339         // genericOrderingTest(coll, koreanData);
1340
1341         // no such locale in icu4j
1342         // logln("Using ko__LOTUS locale\n");
1343         // genericLocaleStarter(new Locale("ko__LOTUS", ""), koreanData);
1344     }
1345
1346     public void TestIncrementalNormalize() {
1347         Collator        coll = null;
1348         // logln("Test 1 ....");
1349         {
1350             /* Test 1.  Run very long unnormalized strings, to force overflow of*/
1351             /*          most buffers along the way.*/
1352
1353             try {
1354                 coll = Collator.getInstance(new Locale("en", "US"));
1355             } catch (Exception e) {
1356                 warnln("Cannot get default instance!");
1357                 return;
1358             }
1359             char baseA     =0x41;
1360             char ccMix[]   = {0x316, 0x321, 0x300};
1361             int          sLen;
1362             int          i;
1363             StringBuffer strA = new StringBuffer();
1364             StringBuffer strB = new StringBuffer();
1365
1366             coll.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
1367
1368             for (sLen = 1000; sLen<1001; sLen++) {
1369                 strA.delete(0, strA.length());
1370                 strA.append(baseA);
1371                 strB.delete(0, strB.length());
1372                 strB.append(baseA);
1373                 for (i=1; i< sLen; i++) {
1374                     strA.append(ccMix[i % 3]);
1375                     strB.insert(1, ccMix[i % 3]);
1376                 }
1377                 coll.setStrength(Collator.TERTIARY);   // Do test with default strength, which runs
1378                 CollationTest.doTest(this, (RuleBasedCollator)coll,
1379                                      strA.toString(), strB.toString(), 0);    //   optimized functions in the impl
1380                 coll.setStrength(Collator.IDENTICAL);   // Do again with the slow, general impl.
1381                 CollationTest.doTest(this, (RuleBasedCollator)coll,
1382                                      strA.toString(), strB.toString(), 0);
1383             }
1384         }
1385         /*  Test 2:  Non-normal sequence in a string that extends to the last character*/
1386         /*         of the string.  Checks a couple of edge cases.*/
1387         // logln("Test 2 ....");
1388         {
1389             String strA = "AA\u0300\u0316";
1390             String strB = "A\u00c0\u0316";
1391             coll.setStrength(Collator.TERTIARY);
1392             CollationTest.doTest(this, (RuleBasedCollator)coll, strA, strB, 0);
1393         }
1394         /*  Test 3:  Non-normal sequence is terminated by a surrogate pair.*/
1395         // logln("Test 3 ....");
1396         {
1397             String strA = "AA\u0300\u0316\uD800\uDC01";
1398             String strB = "A\u00c0\u0316\uD800\uDC00";
1399             coll.setStrength(Collator.TERTIARY);
1400             CollationTest.doTest(this, (RuleBasedCollator)coll, strA, strB, 1);
1401         }
1402         /*  Test 4:  Imbedded nulls do not terminate a string when length is specified.*/
1403         // logln("Test 4 ....");
1404         /*
1405          * not a valid test since string are null-terminated in java{
1406          char strA[] = {0x41, 0x00, 0x42};
1407          char strB[] = {0x41, 0x00, 0x00};
1408
1409          int result = coll.compare(new String(strA), new String(strB));
1410          if (result != 1) {
1411          errln("ERROR 1 in test 4\n");
1412          }
1413
1414          result = coll.compare(new String(strA, 0, 1), new String(strB, 0, 1));
1415          if (result != 0) {
1416          errln("ERROR 1 in test 4\n");
1417          }
1418
1419          CollationKey sortKeyA = coll.getCollationKey(new String(strA));
1420          CollationKey sortKeyB = coll.getCollationKey(new String(strB));
1421
1422          int r = sortKeyA.compareTo(sortKeyB);
1423          if (r <= 0) {
1424          errln("Error 4 in test 4\n");
1425          }
1426
1427          coll.setStrength(Collator.IDENTICAL);
1428          sortKeyA = coll.getCollationKey(new String(strA));
1429          sortKeyB = coll.getCollationKey(new String(strB));
1430
1431          r = sortKeyA.compareTo(sortKeyB);
1432          if (r <= 0) {
1433          errln("Error 7 in test 4\n");
1434          }
1435
1436          coll.setStrength(Collator.TERTIARY);
1437          }
1438         */
1439         /*  Test 5:  Null characters in non-normal source strings.*/
1440         // logln("Test 5 ....");
1441         /*
1442          * not a valid test since string are null-terminated in java{
1443          {
1444          char strA[] = {0x41, 0x41, 0x300, 0x316, 0x00, 0x42,};
1445          char strB[] = {0x41, 0x41, 0x300, 0x316, 0x00, 0x00,};
1446
1447
1448          int result = coll.compare(new String(strA, 0, 6), new String(strB, 0, 6));
1449          if (result < 0) {
1450          errln("ERROR 1 in test 5\n");
1451          }
1452          result = coll.compare(new String(strA, 0, 4), new String(strB, 0, 4));
1453          if (result != 0) {
1454          errln("ERROR 2 in test 5\n");
1455          }
1456
1457          CollationKey sortKeyA = coll.getCollationKey(new String(strA));
1458          CollationKey sortKeyB = coll.getCollationKey(new String(strB));
1459          int r = sortKeyA.compareTo(sortKeyB);
1460          if (r <= 0) {
1461          errln("Error 4 in test 5\n");
1462          }
1463
1464          coll.setStrength(Collator.IDENTICAL);
1465
1466          sortKeyA = coll.getCollationKey(new String(strA));
1467          sortKeyB = coll.getCollationKey(new String(strB));
1468          r = sortKeyA.compareTo(sortKeyB);
1469          if (r <= 0) {
1470          errln("Error 7 in test 5\n");
1471          }
1472
1473          coll.setStrength(Collator.TERTIARY);
1474          }
1475         */
1476         /*  Test 6:  Null character as base of a non-normal combining sequence.*/
1477         // logln("Test 6 ....");
1478         /*
1479          * not a valid test since string are null-terminated in java{
1480          {
1481          char strA[] = {0x41, 0x0, 0x300, 0x316, 0x41, 0x302,};
1482          char strB[] = {0x41, 0x0, 0x302, 0x316, 0x41, 0x300,};
1483
1484          int result = coll.compare(new String(strA, 0, 5), new String(strB, 0, 5));
1485          if (result != -1) {
1486          errln("Error 1 in test 6\n");
1487          }
1488          result = coll.compare(new String(strA, 0, 1), new String(strB, 0, 1));
1489          if (result != 0) {
1490          errln("Error 2 in test 6\n");
1491          }
1492          }
1493         */
1494     }
1495
1496     public void TestContraction() {
1497         String[] testrules = {
1498             "&A = AB / B",
1499             "&A = A\\u0306/\\u0306",
1500             "&c = ch / h",
1501         };
1502         String[] testdata = {
1503             "AB", "AB", "A\u0306", "ch"
1504         };
1505         String[] testdata2 = {
1506             "\u0063\u0067",
1507             "\u0063\u0068",
1508             "\u0063\u006C",
1509         };
1510         String[] testrules3 = {
1511             "&z < xyz &xyzw << B",
1512             "&z < xyz &xyz << B / w",
1513             "&z < ch &achm << B",
1514             "&z < ch &a << B / chm",
1515             "&\ud800\udc00w << B",
1516             "&\ud800\udc00 << B / w",
1517             "&a\ud800\udc00m << B",
1518             "&a << B / \ud800\udc00m",
1519         };
1520
1521         RuleBasedCollator  coll = null;
1522         for (int i = 0; i < testrules.length; i ++) {
1523             CollationElementIterator iter1 = null;
1524             int j = 0;
1525             // logln("Rule " + testrules[i] + " for testing\n");
1526             String rule = testrules[i];
1527             try {
1528                 coll = new RuleBasedCollator(rule);
1529             } catch (Exception e) {
1530                 warnln("Collator creation failed " + testrules[i]);
1531                 return;
1532             }
1533             try {
1534                 iter1 = coll.getCollationElementIterator(testdata[i]);
1535             } catch (Exception e) {
1536                 errln("Collation iterator creation failed\n");
1537                 return;
1538             }
1539             while (j < 2) {
1540                 CollationElementIterator iter2;
1541                 int ce;
1542                 try {
1543                     iter2 = coll.getCollationElementIterator(String.valueOf(testdata[i].charAt(j)));
1544
1545                 }catch (Exception e) {
1546                     errln("Collation iterator creation failed\n");
1547                     return;
1548                 }
1549                 ce = iter2.next();
1550                 while (ce != CollationElementIterator.NULLORDER) {
1551                     if (iter1.next() != ce) {
1552                         errln("Collation elements in contraction split does not match\n");
1553                         return;
1554                     }
1555                     ce = iter2.next();
1556                 }
1557                 j ++;
1558             }
1559             if (iter1.next() != CollationElementIterator.NULLORDER) {
1560                 errln("Collation elements not exhausted\n");
1561                 return;
1562             }
1563         }
1564         String rule = "& a < b < c < ch < d & c = ch / h";
1565         try {
1566             coll = new RuleBasedCollator(rule);
1567         } catch (Exception e) {
1568             errln("cannot create rulebased collator");
1569             return;
1570         }
1571
1572         if (coll.compare(testdata2[0], testdata2[1]) != -1) {
1573             errln("Expected " + testdata2[0] + " < " + testdata2[1]);
1574             return;
1575         }
1576         if (coll.compare(testdata2[1], testdata2[2]) != -1) {
1577             errln("Expected " + testdata2[1] + " < " + testdata2[2]);
1578             return;
1579         }
1580         for (int i = 0; i < testrules3.length; i += 2) {
1581             RuleBasedCollator          coll1, coll2;
1582             CollationElementIterator iter1, iter2;
1583             char               ch = 0x0042;
1584             int            ce;
1585             rule = testrules3[i];
1586             try {
1587                 coll1 = new RuleBasedCollator(rule);
1588             } catch (Exception e) {
1589                 errln("Fail: cannot create rulebased collator, rule:" + rule);
1590                 return;
1591             }
1592             rule = testrules3[i + 1];
1593             try {
1594                 coll2 = new RuleBasedCollator(rule);
1595             } catch (Exception e) {
1596                 errln("Collator creation failed " + testrules[i]);
1597                 return;
1598             }
1599             try {
1600                 iter1 = coll1.getCollationElementIterator(String.valueOf(ch));
1601                 iter2 = coll2.getCollationElementIterator(String.valueOf(ch));
1602             } catch (Exception e) {
1603                 errln("Collation iterator creation failed\n");
1604                 return;
1605             }
1606             ce = iter1.next();
1607
1608             while (ce != CollationElementIterator.NULLORDER) {
1609                 if (ce != iter2.next()) {
1610                     errln("CEs does not match\n");
1611                     return;
1612                 }
1613                 ce = iter1.next();
1614             }
1615             if (iter2.next() != CollationElementIterator.NULLORDER) {
1616                 errln("CEs not exhausted\n");
1617                 return;
1618             }
1619         }
1620     }
1621
1622     public void TestExpansion() {
1623         String[] testrules = {
1624             "&J << K / B & K << M",
1625             "&J << K / B << M"
1626         };
1627         String[] testdata = {
1628             "JA", "MA", "KA", "KC", "JC", "MC",
1629         };
1630
1631         Collator  coll;
1632         for (int i = 0; i < testrules.length; i++) {
1633             // logln("Rule " + testrules[i] + " for testing\n");
1634             String rule = testrules[i];
1635             try {
1636                 coll = new RuleBasedCollator(rule);
1637             } catch (Exception e) {
1638                 warnln("Collator creation failed " + testrules[i]);
1639                 return;
1640             }
1641
1642             for (int j = 0; j < 5; j ++) {
1643                 CollationTest.doTest(this, (RuleBasedCollator)coll,
1644                                      testdata[j], testdata[j + 1], -1);
1645             }
1646         }
1647     }
1648
1649     public void TestContractionEndCompare()
1650     {
1651         String rules = "&b=ch";
1652         String src = "bec";
1653         String tgt = "bech";
1654         Collator coll = null;
1655         try {
1656             coll = new RuleBasedCollator(rules);
1657         } catch (Exception e) {
1658             warnln("Collator creation failed " + rules);
1659             return;
1660         }
1661         CollationTest.doTest(this, (RuleBasedCollator)coll, src, tgt, 1);
1662     }
1663
1664     public void TestLocaleRuleBasedCollators() {
1665         if (getInclusion() < 5) {
1666             // not serious enough to run this
1667             return;
1668         }
1669         Locale locale[] = Collator.getAvailableLocales();
1670         String prevrule = null;
1671         for (int i = 0; i < locale.length; i ++) {
1672             Locale l = locale[i];
1673             try {
1674                 ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_COLLATION_BASE_NAME,l);
1675                 String collkey = rb.getStringWithFallback("collations/default");
1676                 ICUResourceBundle elements = rb.getWithFallback("collations/" + collkey);
1677                 if (elements == null) {
1678                     continue;
1679                 }
1680                 String rule = null;
1681                 /*
1682                   Object[][] colldata = (Object[][])elements;
1683                   // %%CollationBin
1684                   if (colldata[0][1] instanceof byte[]){
1685                   rule = (String)colldata[1][1];
1686                   }
1687                   else {
1688                   rule = (String)colldata[0][1];
1689                   }
1690                 */
1691                 rule = elements.getString("Sequence");
1692
1693                 RuleBasedCollator col1 =
1694                     (RuleBasedCollator)Collator.getInstance(l);
1695                 if (!rule.equals(col1.getRules())) {
1696                     errln("Rules should be the same in the RuleBasedCollator and Locale");
1697                 }
1698                 if (rule != null && rule.length() > 0
1699                     && !rule.equals(prevrule)) {
1700                     RuleBasedCollator col2 = new RuleBasedCollator(rule);
1701                     if (!col1.equals(col2)) {
1702                         errln("Error creating RuleBasedCollator from " +
1703                               "locale rules for " + l.toString());
1704                     }
1705                 }
1706                 prevrule = rule;
1707             } catch (Exception e) {
1708                 warnln("Error retrieving resource bundle for testing: " + e.toString());
1709             }
1710         }
1711     }
1712
1713     public void TestOptimize() {
1714         /* this is not really a test - just trying out
1715          * whether copying of UCA contents will fail
1716          * Cannot really test, since the functionality
1717          * remains the same.
1718          */
1719         String rules[] = {
1720             "[optimize [\\uAC00-\\uD7FF]]"
1721         };
1722         String data[][] = {
1723             { "a", "b"}
1724         };
1725         int i = 0;
1726
1727         for(i = 0; i<rules.length; i++) {
1728             genericRulesStarter(rules[i], data[i]);
1729         }
1730     }
1731
1732     public void TestIdenticalCompare()
1733     {
1734         try {
1735             RuleBasedCollator coll
1736                 = new RuleBasedCollator("& \uD800\uDC00 = \uD800\uDC01");
1737             String strA = "AA\u0300\u0316\uD800\uDC01";
1738             String strB = "A\u00c0\u0316\uD800\uDC00";
1739             coll.setStrength(Collator.IDENTICAL);
1740             CollationTest.doTest(this, coll, strA, strB, 1);
1741         } catch (Exception e) {
1742             warnln(e.getMessage());
1743         }
1744     }
1745
1746     public void TestMergeSortKeys()
1747     {
1748         String cases[] = {"abc", "abcd", "abcde"};
1749         String prefix = "foo";
1750         String suffix = "egg";
1751         CollationKey mergedPrefixKeys[] = new CollationKey[cases.length];
1752         CollationKey mergedSuffixKeys[] = new CollationKey[cases.length];
1753
1754         Collator coll = Collator.getInstance(Locale.ENGLISH);
1755         genericLocaleStarter(Locale.ENGLISH, cases);
1756
1757         int strength = Collator.PRIMARY;
1758         while (strength <= Collator.IDENTICAL) {
1759             coll.setStrength(strength);
1760             CollationKey prefixKey = coll.getCollationKey(prefix);
1761             CollationKey suffixKey = coll.getCollationKey(suffix);
1762             for (int i = 0; i < cases.length; i ++) {
1763                 CollationKey key = coll.getCollationKey(cases[i]);
1764                 mergedPrefixKeys[i] = prefixKey.merge(key);
1765                 mergedSuffixKeys[i] = suffixKey.merge(key);
1766                 if (mergedPrefixKeys[i].getSourceString() != null
1767                     || mergedSuffixKeys[i].getSourceString() != null) {
1768                     errln("Merged source string error: expected null");
1769                 }
1770                 if (i > 0) {
1771                     if (mergedPrefixKeys[i-1].compareTo(mergedPrefixKeys[i])
1772                         >= 0) {
1773                         errln("Error while comparing prefixed keys @ strength "
1774                               + strength);
1775                         errln(prettify(mergedPrefixKeys[i-1]));
1776                         errln(prettify(mergedPrefixKeys[i]));
1777                     }
1778                     if (mergedSuffixKeys[i-1].compareTo(mergedSuffixKeys[i])
1779                         >= 0) {
1780                         errln("Error while comparing suffixed keys @ strength "
1781                               + strength);
1782                         errln(prettify(mergedSuffixKeys[i-1]));
1783                         errln(prettify(mergedSuffixKeys[i]));
1784                     }
1785                 }
1786             }
1787             if (strength == Collator.QUATERNARY) {
1788                 strength = Collator.IDENTICAL;
1789             }
1790             else {
1791                 strength ++;
1792             }
1793         }
1794     }
1795
1796     public void TestVariableTop()
1797     {
1798         // parseNextToken is not released as public so i create my own rules
1799         String rules = "& a < b < c < de < fg & hi = j";
1800         try {
1801             RuleBasedCollator coll = new RuleBasedCollator(rules);
1802             String tokens[] = {"a", "b", "c", "de", "fg", "hi", "j", "ab"};
1803             coll.setAlternateHandlingShifted(true);
1804             for (int i = 0; i < tokens.length; i ++) {
1805                 int varTopOriginal = coll.getVariableTop();
1806                 try {
1807                     int varTop = coll.setVariableTop(tokens[i]);
1808                     if (i > 4) {
1809                         errln("Token " + tokens[i] + " expected to fail");
1810                     }
1811                     if (varTop != coll.getVariableTop()) {
1812                         errln("Error setting and getting variable top");
1813                     }
1814                     CollationKey key1 = coll.getCollationKey(tokens[i]);
1815                     for (int j = 0; j < i; j ++) {
1816                         CollationKey key2 = coll.getCollationKey(tokens[j]);
1817                         if (key2.compareTo(key1) < 0) {
1818                             errln("Setting variable top shouldn't change the comparison sequence");
1819                         }
1820                         byte sortorder[] = key2.toByteArray();
1821                         if (sortorder.length > 0
1822                             && (key2.toByteArray())[0] > 1) {
1823                             errln("Primary sort order should be 0");
1824                         }
1825                     }
1826                 } catch (Exception e) {
1827                     CollationElementIterator iter
1828                         = coll.getCollationElementIterator(tokens[i]);
1829                     /*int ce =*/ iter.next();
1830                     int ce2 = iter.next();
1831                     if (ce2 == CollationElementIterator.NULLORDER) {
1832                         errln("Token " + tokens[i] + " not expected to fail");
1833                     }
1834                     if (coll.getVariableTop() != varTopOriginal) {
1835                         errln("When exception is thrown variable top should "
1836                               + "not be changed");
1837                     }
1838                 }
1839                 coll.setVariableTop(varTopOriginal);
1840                 if (varTopOriginal != coll.getVariableTop()) {
1841                     errln("Couldn't restore old variable top\n");
1842                 }
1843             }
1844
1845             // Testing calling with error set
1846             try {
1847                 coll.setVariableTop("");
1848                 errln("Empty string should throw an IllegalArgumentException");
1849             } catch (IllegalArgumentException e) {
1850                 logln("PASS: Empty string failed as expected");
1851             }
1852             try {
1853                 coll.setVariableTop(null);
1854                 errln("Null string should throw an IllegalArgumentException");
1855             } catch (IllegalArgumentException e) {
1856                 logln("PASS: null string failed as expected");
1857             }
1858         } catch (Exception e) {
1859             warnln("Error creating RuleBasedCollator");
1860         }
1861     }
1862
1863     public void TestUCARules()
1864     {
1865         try {
1866             // only root locale can have empty tailorings .. not English!
1867             RuleBasedCollator coll
1868                 = (RuleBasedCollator)Collator.getInstance(new Locale("","",""));
1869             String rule
1870                 = coll.getRules(false);
1871             if (!rule.equals("")) {
1872                 errln("Empty rule string should have empty rules " + rule);
1873             }
1874             rule = coll.getRules(true);
1875             if (rule.equals("")) {
1876                 errln("UCA rule string should not be empty");
1877             }
1878             coll = new RuleBasedCollator(rule);
1879         } catch (Exception e) {
1880             warnln(e.getMessage());
1881         }
1882     }
1883
1884     /**
1885      * Jitterbug 2726
1886      */
1887     public void TestShifted()
1888     {
1889         RuleBasedCollator collator = (RuleBasedCollator) Collator.getInstance();
1890         collator.setStrength(Collator.PRIMARY);
1891         collator.setAlternateHandlingShifted(true);
1892         CollationTest.doTest(this, collator, " a", "a", 0); // works properly
1893         CollationTest.doTest(this, collator, "a", "a ", 0); // inconsistent results
1894     }
1895
1896     /**
1897      * Test for CollationElementIterator previous and next for the whole set of
1898      * unicode characters with normalization on.
1899      */
1900     public void TestNumericCollation()
1901     {
1902         String basicTestStrings[] = {"hello1", "hello2", "hello123456"};
1903         String preZeroTestStrings[] = {"avery1",
1904                                        "avery01",
1905                                        "avery001",
1906                                        "avery0001"};
1907         String thirtyTwoBitNumericStrings[] = {"avery42949672960",
1908                                                "avery42949672961",
1909                                                "avery42949672962",
1910                                                "avery429496729610"};
1911
1912         String supplementaryDigits[] = {"\uD835\uDFCE", // 0
1913                                         "\uD835\uDFCF", // 1
1914                                         "\uD835\uDFD0", // 2
1915                                         "\uD835\uDFD1", // 3
1916                                         "\uD835\uDFCF\uD835\uDFCE", // 10
1917                                         "\uD835\uDFCF\uD835\uDFCF", // 11
1918                                         "\uD835\uDFCF\uD835\uDFD0", // 12
1919                                         "\uD835\uDFD0\uD835\uDFCE", // 20
1920                                         "\uD835\uDFD0\uD835\uDFCF", // 21
1921                                         "\uD835\uDFD0\uD835\uDFD0" // 22
1922         };
1923
1924         String foreignDigits[] = {"\u0661",
1925                                   "\u0662",
1926                                   "\u0663",
1927                                   "\u0661\u0660",
1928                                   "\u0661\u0662",
1929                                   "\u0661\u0663",
1930                                   "\u0662\u0660",
1931                                   "\u0662\u0662",
1932                                   "\u0662\u0663",
1933                                   "\u0663\u0660",
1934                                   "\u0663\u0662",
1935                                   "\u0663\u0663"
1936         };
1937
1938         // Open our collator.
1939         RuleBasedCollator coll
1940             = (RuleBasedCollator)Collator.getInstance(Locale.ENGLISH);
1941         String att[] = {"NumericCollation"};
1942         Boolean val[] = {Boolean.TRUE};
1943         genericLocaleStarterWithOptions(Locale.ENGLISH, basicTestStrings, att,
1944                                         val);
1945         genericLocaleStarterWithOptions(Locale.ENGLISH,
1946                                         thirtyTwoBitNumericStrings, att, val);
1947         genericLocaleStarterWithOptions(Locale.ENGLISH, foreignDigits, att,
1948                                         val);
1949         genericLocaleStarterWithOptions(Locale.ENGLISH, supplementaryDigits,
1950                                         att, val);
1951
1952         // Setting up our collator to do digits.
1953         coll.setNumericCollation(true);
1954
1955         // Testing that prepended zeroes still yield the correct collation
1956         // behavior.
1957         // We expect that every element in our strings array will be equal.
1958         for (int i = 0; i < preZeroTestStrings.length - 1; i ++) {
1959             for (int j = i + 1; j < preZeroTestStrings.length; j ++) {
1960                 CollationTest.doTest(this, coll, preZeroTestStrings[i],
1961                                      preZeroTestStrings[j],0);
1962             }
1963         }
1964
1965         //cover setNumericCollationDefault, getNumericCollation
1966         assertTrue("The Numeric Collation setting is on", coll.getNumericCollation());
1967         coll.setNumericCollationDefault();
1968         logln("After set Numeric to default, the setting is: " + coll.getNumericCollation());
1969     }
1970
1971     public void Test3249()
1972     {
1973         String rule = "&x < a &z < a";
1974         try {
1975             RuleBasedCollator coll = new RuleBasedCollator(rule);
1976             if(coll!=null){
1977                 logln("Collator did not throw an exception");
1978             }
1979         } catch (Exception e) {
1980             warnln("Error creating RuleBasedCollator with " + rule + " failed");
1981         }
1982     }
1983
1984     public void TestTibetanConformance()
1985     {
1986         String test[] = {"\u0FB2\u0591\u0F71\u0061", "\u0FB2\u0F71\u0061"};
1987         try {
1988             Collator coll = Collator.getInstance();
1989             coll.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
1990             if (coll.compare(test[0], test[1]) != 0) {
1991                 errln("Tibetan comparison error");
1992             }
1993             CollationTest.doTest(this, (RuleBasedCollator)coll,
1994                                  test[0], test[1], 0);
1995         } catch (Exception e) {
1996             warnln("Error creating UCA collator");
1997         }
1998     }
1999
2000     public void TestJ3347()
2001     {
2002         try {
2003             Collator coll = Collator.getInstance(Locale.FRENCH);
2004             ((RuleBasedCollator)coll).setAlternateHandlingShifted(true);
2005             if (coll.compare("6", "!6") != 0) {
2006                 errln("Jitterbug 3347 failed");
2007             }
2008         } catch (Exception e) {
2009             warnln("Error creating UCA collator");
2010         }
2011     }
2012
2013     public void TestPinyinProblem()
2014     {
2015         String test[] = { "\u4E56\u4E56\u7761", "\u4E56\u5B69\u5B50" };
2016         genericLocaleStarter(new Locale("zh", "", "PINYIN"), test);
2017     }
2018
2019     static final long topByte = 0xFF000000L;
2020     static final long bottomByte = 0xFFL;
2021     static final long fourBytes = 0xFFFFFFFFL;
2022
2023     static final int MAX_INPUT = 0x220001; // 2 * Unicode range + 2
2024
2025     private void show(int i, ImplicitCEGenerator imp) {
2026         if (i >= 0 && i <= MAX_INPUT) {
2027             logln(Utility.hex(i) + "\t" + Utility.hex(imp.getImplicitFromRaw(i) & fourBytes));
2028         }
2029     }
2030
2031     private void throwError(String title, int cp, ImplicitCEGenerator imp) {
2032         throw new IllegalArgumentException(title + "\t" + Utility.hex(cp, 6) + "\t" + Utility.hex(imp.getImplicitFromRaw(cp) & fourBytes));
2033     }
2034
2035     private void throwError(String title, long ce) {
2036         errln(title + "\t" + Utility.hex(ce & fourBytes));
2037     }
2038
2039     public void TestImplicitGeneration()
2040     {
2041         logln("Start");
2042         try {
2043             ImplicitCEGenerator foo = new ImplicitCEGenerator(0xE0, 0xE4);
2044
2045             //int x = foo.getRawImplicit(0xF810);
2046             foo.getRawFromImplicit(0xE20303E7);
2047
2048             //int gap4 = foo.getGap4();
2049             //logln("Gap4: " + gap4);
2050             //int gap3 = foo.getGap3();
2051             //int minTrail = foo.getMinTrail();
2052             //int maxTrail = foo.getMaxTrail();
2053             long last = 0;
2054             long current;
2055             for (int i = 0; i <= MAX_INPUT; ++i) {
2056                 current = foo.getImplicitFromRaw(i) & fourBytes;
2057
2058                 // check that it round-trips AND that all intervening ones are illegal
2059                 int roundtrip = foo.getRawFromImplicit((int)current);
2060                 if (roundtrip != i) {
2061                     throwError("No roundtrip", i, foo);
2062                 }
2063                 if (last != 0) {
2064                     for (long j = last + 1; j < current; ++j) {
2065                         roundtrip = foo.getRawFromImplicit((int)j);
2066                         // raise an error if it *doesn't* find an error
2067                         if (roundtrip != -1) {
2068                             throwError("Fails to recognize illegal", j);
2069                         }
2070                     }
2071                 }
2072                 // now do other consistency checks
2073                 long lastBottom = last & bottomByte;
2074                 long currentBottom = current & bottomByte;
2075                 long lastTop = last & topByte;
2076                 long currentTop = current & topByte;
2077
2078                 // do some consistency checks
2079                 /*
2080                   long gap = current - last;
2081                   if (currentBottom != 0) { // if we are a 4-byte
2082                   // gap has to be at least gap4
2083                   // and gap from minTrail, maxTrail has to be at least gap4
2084                   if (gap <= gap4) foo.throwError("Failed gap4 between", i);
2085                   if (currentBottom < minTrail + gap4) foo.throwError("Failed gap4 before", i);
2086                   if (currentBottom > maxTrail - gap4) foo.throwError("Failed gap4 after", i);
2087                   } else { // we are a three-byte
2088                   gap = gap >> 8; // move gap down for comparison.
2089                   long current3Bottom = (current >> 8) & bottomByte;
2090                   if (gap <= gap3) foo.throwError("Failed gap3 between ", i);
2091                   if (current3Bottom < minTrail + gap3) foo.throwError("Failed gap3 before", i);
2092                   if (current3Bottom > maxTrail - gap3) foo.throwError("Failed gap3 after", i);
2093                   }
2094                 */
2095                 // print out some values for spot-checking
2096                 if (lastTop != currentTop || i == 0x10000 || i == 0x110000) {
2097                     show(i-3, foo);
2098                     show(i-2, foo);
2099                     show(i-1, foo);
2100                     if (i == 0) {
2101                         // do nothing
2102                     } else if (lastBottom == 0 && currentBottom != 0) {
2103                         logln("+ primary boundary, 4-byte CE's below");
2104                     } else if (lastTop != currentTop) {
2105                         logln("+ primary boundary");
2106                     }
2107                     show(i, foo);
2108                     show(i+1, foo);
2109                     show(i+2, foo);
2110                     logln("...");
2111                 }
2112                 last = current;
2113                 if(foo.getCodePointFromRaw(foo.getRawFromCodePoint(i)) != i) {
2114                     errln("No raw <-> code point roundtrip for "+Utility.hex(i));
2115                 }
2116             }
2117             show(MAX_INPUT-2, foo);
2118             show(MAX_INPUT-1, foo);
2119             show(MAX_INPUT, foo);
2120         } catch (Exception e) {
2121             e.printStackTrace();
2122             warnln(e.getMessage());
2123         } finally {
2124             logln("End");
2125         }
2126     }
2127
2128     /* supercedes TestJ784 */
2129     public void TestBeforePinyin() {
2130         String rules =
2131             "&[before 2]A << \u0101  <<< \u0100 << \u00E1 <<< \u00C1 << \u01CE <<< \u01CD << \u00E0 <<< \u00C0" +
2132             "&[before 2]e << \u0113 <<< \u0112 << \u00E9 <<< \u00C9 << \u011B <<< \u011A << \u00E8 <<< \u00C8" +
2133             "&[before 2] i << \u012B <<< \u012A << \u00ED <<< \u00CD << \u01D0 <<< \u01CF << \u00EC <<< \u00CC" +
2134             "&[before 2] o << \u014D <<< \u014C << \u00F3 <<< \u00D3 << \u01D2 <<< \u01D1 << \u00F2 <<< \u00D2" +
2135             "&[before 2]u << \u016B <<< \u016A << \u00FA <<< \u00DA << \u01D4 <<< \u01D3 << \u00F9 <<< \u00D9" +
2136             "&U << \u01D6 <<< \u01D5 << \u01D8 <<< \u01D7 << \u01DA <<< \u01D9 << \u01DC <<< \u01DB << \u00FC";
2137
2138         String test[] = {
2139             "l\u0101",
2140             "la",
2141             "l\u0101n",
2142             "lan ",
2143             "l\u0113",
2144             "le",
2145             "l\u0113n",
2146             "len"
2147         };
2148
2149         String test2[] = {
2150             "x\u0101",
2151             "x\u0100",
2152             "X\u0101",
2153             "X\u0100",
2154             "x\u00E1",
2155             "x\u00C1",
2156             "X\u00E1",
2157             "X\u00C1",
2158             "x\u01CE",
2159             "x\u01CD",
2160             "X\u01CE",
2161             "X\u01CD",
2162             "x\u00E0",
2163             "x\u00C0",
2164             "X\u00E0",
2165             "X\u00C0",
2166             "xa",
2167             "xA",
2168             "Xa",
2169             "XA",
2170             "x\u0101x",
2171             "x\u0100x",
2172             "x\u00E1x",
2173             "x\u00C1x",
2174             "x\u01CEx",
2175             "x\u01CDx",
2176             "x\u00E0x",
2177             "x\u00C0x",
2178             "xax",
2179             "xAx"
2180         };
2181         /* TODO: port builder fixes to before */
2182         genericRulesStarter(rules, test);
2183         genericLocaleStarter(new Locale("zh","",""), test);
2184         genericRulesStarter(rules, test2);
2185         genericLocaleStarter(new Locale("zh","",""), test2);
2186     }
2187
2188     public void TestUpperFirstQuaternary()
2189     {
2190       String tests[] = { "B", "b", "Bb", "bB" };
2191       String[] att = { "strength", "UpperFirst" };
2192       Object attVals[] = { new Integer(Collator.QUATERNARY), Boolean.TRUE };
2193       genericLocaleStarterWithOptions(new Locale("root","",""), tests, att, attVals);
2194     }
2195
2196     public void TestJ4960()
2197     {
2198         String tests[] = { "\\u00e2T", "aT" };
2199         String att[] = { "strength", "CaseLevel" };
2200         Object attVals[] = { new Integer(Collator.PRIMARY), Boolean.TRUE };
2201         String tests2[] = { "a", "A" };
2202         String rule = "&[first tertiary ignorable]=A=a";
2203         String att2[] = { "CaseLevel" };
2204         Object attVals2[] = { Boolean.TRUE };
2205         // Test whether we correctly ignore primary ignorables on case level when
2206         // we have only primary & case level
2207         genericLocaleStarterWithOptionsAndResult(new Locale("root", ""), tests, att, attVals, 0);
2208         // Test whether ICU4J will make case level for sortkeys that have primary strength
2209         // and case level
2210         genericLocaleStarterWithOptions(new Locale("root", ""), tests2, att, attVals);
2211         // Test whether completely ignorable letters have case level info (they shouldn't)
2212         genericRulesStarterWithOptionsAndResult(rule, tests2, att2, attVals2, 0);
2213     }
2214
2215     public void TestJB5298(){
2216         ULocale[] locales = Collator.getAvailableULocales();
2217         logln("Number of collator locales returned : " + locales.length);
2218         // double-check keywords
2219         String[] keywords = Collator.getKeywords();
2220         if (keywords.length != 1 || !keywords[0].equals("collation")) {
2221             throw new IllegalArgumentException("internal collation error");
2222         }
2223
2224         String[] values = Collator.getKeywordValues("collation");
2225         log("Collator.getKeywordValues returned: ");
2226         for(int i=0; i<values.length;i++){
2227             log(values[i]+", ");
2228         }
2229         logln("");
2230         logln("Number of collator values returned : " + values.length);
2231
2232         Set foundValues = new TreeSet(Arrays.asList(values));
2233
2234         for (int i = 0; i < locales.length; ++i) {
2235           for (int j = 0; j < values.length; ++j) {
2236             ULocale tryLocale = values[j].equals("standard")
2237             ? locales[i] : new ULocale(locales[i] + "@collation=" + values[j]);
2238             // only append if not standard
2239             ULocale canon = Collator.getFunctionalEquivalent("collation",tryLocale);
2240             if (!canon.equals(tryLocale)) {
2241                 continue; // has a different
2242             }else {// functional equivalent, so skip
2243                 logln(tryLocale + " : "+canon+", ");
2244             }
2245             String can = canon.toString();
2246             int idx = can.indexOf("@collation=");
2247             String val = idx >= 0 ? can.substring(idx+11, can.length()) : "";
2248             if(val.length()>0 && !foundValues.contains(val)){
2249                 errln("Unknown collation found "+ can);
2250             }
2251           }
2252         }
2253         logln(" ");
2254     }
2255
2256     public void
2257     TestJ5367()
2258     {
2259         String[] test = { "a", "y" };
2260         String rules = "&Ny << Y &[first secondary ignorable] <<< a";
2261         genericRulesStarter(rules, test);
2262     }
2263
2264     public void
2265     TestVI5913()
2266     {
2267
2268         String rules[] = {
2269                 "&a < \u00e2 <<< \u00c2",
2270                 "&a < \u1FF3 ",  // OMEGA WITH YPOGEGRAMMENI
2271                 "&s < \u0161 ",  // &s < s with caron
2272                 "&z < a\u00EA",  // &z < a+e with circumflex
2273         };
2274         String cases[][] = {
2275             { "\u1EAC", "A\u0323\u0302", "\u1EA0\u0302", "\u00C2\u0323", },
2276             { "\u1FA2", "\u03C9\u0313\u0300\u0345", "\u1FF3\u0313\u0300",
2277               "\u1F60\u0300\u0345", "\u1f62\u0345", "\u1FA0\u0300", },
2278             { "\u1E63\u030C", "s\u0323\u030C", "s\u030C\u0323"},
2279             { "a\u1EC7", //  a+ e with dot below and circumflex
2280               "a\u1EB9\u0302", // a + e with dot below + combining circumflex
2281               "a\u00EA\u0323", // a + e with circumflex + combining dot below
2282             }
2283         };
2284
2285
2286         for(int i = 0; i < rules.length; i++) {
2287
2288             RuleBasedCollator coll = null;
2289             try {
2290                 coll = new RuleBasedCollator(rules[i]);
2291             } catch (Exception e) {
2292                 warnln("Unable to open collator with rules " + rules[i]);
2293             }
2294
2295             logln("Test case["+i+"]:");
2296             CollationKey expectingKey = coll.getCollationKey(cases[i][0]);
2297             for (int j=1; j<cases[i].length; j++) {
2298                 CollationKey key = coll.getCollationKey(cases[i][j]);
2299                 if ( key.compareTo(expectingKey)!=0) {
2300                     errln("Error! Test case["+i+"]:"+"source:" + key.getSourceString());
2301                     errln("expecting:"+prettify(expectingKey)+ "got:"+  prettify(key));
2302                 }
2303                 logln("   Key:"+  prettify(key));
2304             }
2305         }
2306
2307
2308         RuleBasedCollator vi_vi = null;
2309         try {
2310             vi_vi = (RuleBasedCollator)Collator.getInstance(
2311                                                       new Locale("vi", ""));
2312             logln("VI sort:");
2313             CollationKey expectingKey = vi_vi.getCollationKey(cases[0][0]);
2314             for (int j=1; j<cases[0].length; j++) {
2315                 CollationKey key = vi_vi.getCollationKey(cases[0][j]);
2316                 if ( key.compareTo(expectingKey)!=0) {
2317                     // TODO (claireho): change the logln to errln after vi.res is up-to-date.
2318                     // errln("source:" + key.getSourceString());
2319                     // errln("expecting:"+prettify(expectingKey)+ "got:"+  prettify(key));
2320                     logln("Error!! in Vietnese sort - source:" + key.getSourceString());
2321                     logln("expecting:"+prettify(expectingKey)+ "got:"+  prettify(key));
2322                 }
2323                 // logln("source:" + key.getSourceString());
2324                 logln("   Key:"+  prettify(key));
2325             }
2326         } catch (Exception e) {
2327             warnln("Error creating Vietnese collator");
2328             return;
2329         }
2330
2331     }
2332
2333
2334     public void Test6179()
2335     {
2336         String rules[] = {
2337                 "&[last primary ignorable]<< a  &[first primary ignorable]<<b ",
2338                 "&[last secondary ignorable]<<< a &[first secondary ignorable]<<<b",
2339         };
2340         // defined in UCA5.1
2341         String firstPrimIgn = "\u0332";
2342         String lastPrimIgn = "\uD800\uDDFD";
2343         String firstVariable = "\u0009";
2344         byte[] secIgnKey = {1,1,4,0};
2345
2346         int i=0;
2347         {
2348
2349             RuleBasedCollator coll = null;
2350             try {
2351                 coll = new RuleBasedCollator(rules[i]);
2352             } catch (Exception e) {
2353                 warnln("Unable to open collator with rules " + rules[i]);
2354             }
2355
2356             logln("Test rule["+i+"]"+rules[i]);
2357
2358             CollationKey keyA = coll.getCollationKey("a");
2359             logln("Key for \"a\":"+  prettify(keyA));
2360             if (keyA.compareTo(coll.getCollationKey(lastPrimIgn))<=0) {
2361                 CollationKey key = coll.getCollationKey(lastPrimIgn);
2362                 logln("Collation key for 0xD800 0xDDFD: "+prettify(key));
2363                 errln("Error! String \"a\" must be greater than \uD800\uDDFD -"+
2364                       "[Last Primary Ignorable]");
2365             }
2366             if (keyA.compareTo(coll.getCollationKey(firstVariable))>=0) {
2367                 CollationKey key = coll.getCollationKey(firstVariable);
2368                 logln("Collation key for 0x0009: "+prettify(key));
2369                 errln("Error! String \"a\" must be less than 0x0009 - [First Variable]");
2370             }
2371             CollationKey keyB = coll.getCollationKey("b");
2372             logln("Key for \"b\":"+  prettify(keyB));
2373             if (keyB.compareTo(coll.getCollationKey(firstPrimIgn))<=0) {
2374                 CollationKey key = coll.getCollationKey(firstPrimIgn);
2375                 logln("Collation key for 0x0332: "+prettify(key));
2376                 errln("Error! String \"b\" must be greater than 0x0332 -"+
2377                       "[First Primary Ignorable]");
2378             }
2379             if (keyB.compareTo(coll.getCollationKey(firstVariable))>=0) {
2380                 CollationKey key = coll.getCollationKey(firstVariable);
2381                 logln("Collation key for 0x0009: "+prettify(key));
2382                 errln("Error! String \"b\" must be less than 0x0009 - [First Variable]");
2383             }
2384         }
2385         {
2386             i=1;
2387             RuleBasedCollator coll = null;
2388             try {
2389                 coll = new RuleBasedCollator(rules[i]);
2390             } catch (Exception e) {
2391                 warnln("Unable to open collator with rules " + rules[i]);
2392             }
2393
2394             logln("Test rule["+i+"]"+rules[i]);
2395
2396             CollationKey keyA = coll.getCollationKey("a");
2397             logln("Key for \"a\":"+  prettify(keyA));
2398             byte[] keyAInBytes = keyA.toByteArray();
2399             for (int j=0; j<keyAInBytes.length && j<secIgnKey.length; j++) {
2400                 if (keyAInBytes[j]!=secIgnKey[j]) {
2401                     if ((char)keyAInBytes[j]<=(char)secIgnKey[j]) {
2402                         logln("Error! String \"a\" must be greater than [Last Secondary Ignorable]");
2403                     }
2404                     break;
2405                 }
2406             }
2407             if (keyA.compareTo(coll.getCollationKey(firstVariable))>=0) {
2408                 errln("Error! String \"a\" must be less than 0x0009 - [First Variable]");
2409                 CollationKey key = coll.getCollationKey(firstVariable);
2410                 logln("Collation key for 0x0009: "+prettify(key));
2411             }
2412             CollationKey keyB = coll.getCollationKey("b");
2413             logln("Key for \"b\":"+  prettify(keyB));
2414             byte[] keyBInBytes = keyB.toByteArray();
2415             for (int j=0; j<keyBInBytes.length && j<secIgnKey.length; j++) {
2416                 if (keyBInBytes[j]!=secIgnKey[j]) {
2417                     if ((char)keyBInBytes[j]<=(char)secIgnKey[j]) {
2418                         errln("Error! String \"b\" must be greater than [Last Secondary Ignorable]");
2419                     }
2420                     break;
2421                 }
2422             }
2423             if (keyB.compareTo(coll.getCollationKey(firstVariable))>=0) {
2424                 CollationKey key = coll.getCollationKey(firstVariable);
2425                 logln("Collation key for 0x0009: "+prettify(key));
2426                 errln("Error! String \"b\" must be less than 0x0009 - [First Variable]");
2427             }
2428         }
2429     }
2430
2431     public void TestUCAPrecontext()
2432     {
2433         String rules[] = {
2434                 "& \u00B7<a ",
2435                 "& L\u00B7 << a", // 'a' is an expansion.
2436         };
2437         String cases[] = {
2438             "\u00B7",
2439             "\u0387",
2440             "a",
2441             "l",
2442             "L\u0332",
2443             "l\u00B7",
2444             "l\u0387",
2445             "L\u0387",
2446             "la\u0387",
2447             "La\u00b7",
2448         };
2449
2450         // Test en sort
2451         RuleBasedCollator en = null;
2452
2453         logln("EN sort:");
2454         try {
2455             en = (RuleBasedCollator)Collator.getInstance(
2456                     new Locale("en", ""));
2457             for (int j=0; j<cases.length; j++) {
2458                 CollationKey key = en.getCollationKey(cases[j]);
2459                 if (j>0) {
2460                     CollationKey prevKey = en.getCollationKey(cases[j-1]);
2461                     if (key.compareTo(prevKey)<0) {
2462                         errln("Error! EN test["+j+"]:source:" + cases[j]+
2463                         " is not >= previous test string.");
2464                     }
2465                 }
2466                 /*
2467                 if ( key.compareTo(expectingKey)!=0) {
2468                     errln("Error! Test case["+i+"]:"+"source:" + key.getSourceString());
2469                     errln("expecting:"+prettify(expectingKey)+ "got:"+  prettify(key));
2470                 }
2471                 */
2472                 logln("String:"+cases[j]+"   Key:"+  prettify(key));
2473             }
2474         } catch (Exception e) {
2475             warnln("Error creating English collator");
2476             return;
2477         }
2478
2479         // Test ja sort
2480         RuleBasedCollator ja = null;
2481         logln("JA sort:");
2482         try {
2483             ja = (RuleBasedCollator)Collator.getInstance(
2484                     new Locale("ja", ""));
2485             for (int j=0; j<cases.length; j++) {
2486                 CollationKey key = ja.getCollationKey(cases[j]);
2487                 if (j>0) {
2488                     CollationKey prevKey = ja.getCollationKey(cases[j-1]);
2489                     if (key.compareTo(prevKey)<0) {
2490                         errln("Error! JA test["+j+"]:source:" + cases[j]+
2491                         " is not >= previous test string.");
2492                     }
2493                 }
2494                 logln("String:"+cases[j]+"   Key:"+  prettify(key));
2495             }
2496         } catch (Exception e) {
2497             warnln("Error creating Japanese collator");
2498             return;
2499         }
2500         for(int i = 0; i < rules.length; i++) {
2501
2502             RuleBasedCollator coll = null;
2503             logln("Tailoring rule:"+rules[i]);
2504             try {
2505                 coll = new RuleBasedCollator(rules[i]);
2506             } catch (Exception e) {
2507                 warnln("Unable to open collator with rules " + rules[i]);
2508                 continue;
2509             }
2510
2511             for (int j=0; j<cases.length; j++) {
2512                 CollationKey key = coll.getCollationKey(cases[j]);
2513                 if (j>0) {
2514                     CollationKey prevKey = coll.getCollationKey(cases[j-1]);
2515                     if (i==1 && j==3) {
2516                         if (key.compareTo(prevKey)>0) {
2517                             errln("Error! Rule:"+rules[i]+" test["+j+"]:source:"+
2518                             cases[j]+" is not <= previous test string.");
2519                         }
2520                     }
2521                     else {
2522                         if (key.compareTo(prevKey)<0) {
2523                             errln("Error! Rule:"+rules[i]+" test["+j+"]:source:"+
2524                             cases[j]+" is not >= previous test string.");
2525                         }
2526                     }
2527                 }
2528                 logln("String:"+cases[j]+"   Key:"+  prettify(key));
2529             }
2530         }
2531     }
2532
2533
2534     /**
2535      * Stores a test case for collation testing.
2536      */
2537     private class OneTestCase {
2538         /** The first value to compare.  **/
2539         public String m_source_;
2540
2541         /** The second value to compare. **/
2542         public String m_target_;
2543
2544         /**
2545          *  0 if the two values sort equal,
2546          * -1 if the first value sorts before the second
2547          *  1 if the first value sorts after the first
2548          */
2549         public int m_result_;
2550
2551         public OneTestCase(String source, String target, int result) {
2552             m_source_ = source;
2553             m_target_ = target;
2554             m_result_ = result;
2555         }
2556     }
2557
2558     /**
2559      * Convenient function to test collation rules.
2560      * @param testCases
2561      * @param rules Collation rules in ICU format.  All the strings in this
2562      *     array represent the same rule, expressed in different forms.
2563      */
2564     private void doTestCollation(
2565         OneTestCase[] testCases, String[] rules) {
2566
2567         Collator  myCollation;
2568         for (String rule : rules) {
2569             try {
2570                 myCollation = new RuleBasedCollator(rule);
2571             } catch (Exception e) {
2572                 warnln("ERROR: in creation of rule based collator");
2573                 return;
2574             }
2575
2576             myCollation.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
2577             myCollation.setStrength(Collator.TERTIARY);
2578             for (OneTestCase testCase : testCases) {
2579                 CollationTest.doTest(this, (RuleBasedCollator)myCollation,
2580                                      testCase.m_source_,
2581                                      testCase.m_target_,
2582                                      testCase.m_result_);
2583             }
2584         }
2585     }
2586
2587      // Test cases to check whether the rules equivalent to
2588      // "&a<b<c<d &b<<k<<l<<m &k<<<x<<<y<<<z &a=1=2=3" are working fine.
2589     private OneTestCase[] m_rangeTestCases_ = {
2590         //               Left                  Right             Result
2591         new OneTestCase( "\u0061",             "\u0062",             -1 ),  // "a" < "b"
2592         new OneTestCase( "\u0062",             "\u0063",             -1 ),  // "b" < "c"
2593         new OneTestCase( "\u0061",             "\u0063",             -1 ),  // "a" < "c"
2594
2595         new OneTestCase( "\u0062",             "\u006b",             -1 ),  // "b" << "k"
2596         new OneTestCase( "\u006b",             "\u006c",             -1 ),  // "k" << "l"
2597         new OneTestCase( "\u0062",             "\u006c",             -1 ),  // "b" << "l"
2598         new OneTestCase( "\u0061",             "\u006c",             -1 ),  // "a" << "l"
2599         new OneTestCase( "\u0061",             "\u006d",             -1 ),  // "a" << "m"
2600
2601         new OneTestCase( "\u0079",             "\u006d",             -1 ),  // "y" < "f"
2602         new OneTestCase( "\u0079",             "\u0067",             -1 ),  // "y" < "g"
2603         new OneTestCase( "\u0061",             "\u0068",             -1 ),  // "y" < "h"
2604         new OneTestCase( "\u0061",             "\u0065",             -1 ),  // "g" < "e"
2605
2606         new OneTestCase( "\u0061",             "\u0031",              0 ),   // "a" == "1"
2607         new OneTestCase( "\u0061",             "\u0032",              0 ),   // "a" == "2"
2608         new OneTestCase( "\u0061",             "\u0033",              0 ),   // "a" == "3"
2609         new OneTestCase( "\u0061",             "\u0066",             -1 ),   // "a" < "f",
2610         new OneTestCase( "\u006c\u0061",       "\u006b\u0062",       -1 ),  // "la" < "kb"
2611         new OneTestCase( "\u0061\u0061\u0061", "\u0031\u0032\u0033",  0 ),  // "aaa" == "123"
2612         new OneTestCase( "\u0062",             "\u007a",             -1 ),  // "b" < "z"
2613         new OneTestCase( "\u0061\u007a\u0062", "\u0032\u0079\u006d", -1 ),  // "azm" < "2yc"
2614     };
2615
2616      // Test cases to check whether the rules equivalent to
2617      // "&\ufffe<\uffff<\U00010000<\U00010001<\U00010002
2618      //  &\U00010000<<\U00020001<<\U00020002<<\U00020002
2619      //  &\U00020001=\U0003001=\U0004001=\U0004002
2620      //  &\U00040008<\U00030008<\UU00020008"
2621      // are working fine.
2622     private OneTestCase[] m_rangeTestCasesSupplemental_ = {
2623         //               Left                Right               Result
2624         new OneTestCase( "\ufffe",           "\uffff",             -1 ),
2625         new OneTestCase( "\uffff",           "\ud800\udc00",       -1 ),  // U+FFFF < U+10000
2626         new OneTestCase( "\ud800\udc00",    "\ud800\udc01",        -1 ),  // U+10000 < U+10001
2627
2628         new OneTestCase( "\ufffe",           "\ud800\udc01",       -1 ),  // U+FFFE < U+10001
2629         new OneTestCase( "\ud800\udc01",    "\ud800\udc02",        -1 ),  // U+10001 < U+10002
2630         new OneTestCase( "\ud800\udc00",    "\ud840\udc02",        -1 ),  // U+10000 < U+10002
2631         new OneTestCase( "\ufffe",           "\u0d840\udc02",      -1 ),  // U+FFFF < U+10002
2632
2633     };
2634
2635     // Test cases in disjoint random code points.  To test only the compact syntax.
2636     // Rule:  &q<w<e<r &w<<t<<y<<u &t<<<i<<<o<<<p &o=a=s=d
2637     private OneTestCase[] m_qwertCollationTestCases_ = {
2638         new OneTestCase("q", "w" , -1),
2639         new OneTestCase("w", "e" , -1),
2640
2641         new OneTestCase("y", "u" , -1),
2642         new OneTestCase("q", "u" , -1),
2643
2644         new OneTestCase("t", "i" , -1),
2645         new OneTestCase("o", "p" , -1),
2646
2647         new OneTestCase("y", "e" , -1),
2648         new OneTestCase("i", "u" , -1),
2649
2650         new OneTestCase("quest", "were" , -1),
2651         new OneTestCase("quack", "quest", -1)
2652     };
2653
2654     // Tests the compact list with ASCII codepoints.
2655     public void TestSameStrengthList() {
2656         String[] rules = new String[] {
2657             // Normal
2658             "&a<b<c<d &b<<k<<l<<m &k<<<x<<<y<<<z &y<f<g<h<e &a=1=2=3",
2659
2660             // Lists
2661             "&a<*bcd &b<<*klm &k<<<*xyz &y<*fghe &a=*123",
2662
2663             // Lists with quoted characters
2664             "&'\u0061'<*bcd &b<<*klm &k<<<*xyz &y<*f'\u0067\u0068'e &a=*123",
2665         };
2666         doTestCollation(m_rangeTestCases_, rules);
2667     }
2668     
2669     public void TestSameStrengthListQuoted() {
2670         String[] rules = new String[] {
2671             "&'\u0061'<*bcd &b<<*klm &k<<<*xyz &y<*f'\u0067\u0068'e &a=1=2=3",
2672             "&'\u0061'<*b'\u0063'd &b<<*klm &k<<<*xyz &'\u0079'<*fgh'\u0065' " +
2673             "&a=*'\u0031\u0032\u0033'",
2674
2675             "&'\u0061'<*'\u0062'c'\u0064' &b<<*klm &k<<<*xyz  &y<*fghe " +
2676             "&a=*'\u0031\u0032\u0033'",
2677         };
2678         doTestCollation(m_rangeTestCases_, rules);
2679     }
2680
2681     // Tests the compact list with ASCII codepoints in non-codepoint order.
2682     public void TestSameStrengthListQwerty() {
2683         String[] rules = new String[] {
2684             "&q<w<e<r &w<<t<<y<<u &t<<<i<<<o<<<p &o=a=s=d",   // Normal
2685             "&q<*wer &w<<*tyu &t<<<*iop &o=*asd",             // Lists
2686         };
2687
2688         doTestCollation(m_qwertCollationTestCases_, rules);
2689     }
2690
2691     // Tests the compact list with supplemental codepoints.
2692     public void TestSameStrengthListWithSupplementalCharacters() {
2693         String[] rules = new String[] {
2694             // ** Rule without compact list syntax **
2695             // \ufffe < \uffff < \U00010000    < \U00010001  < \U00010002
2696             "&'\ufffe'<'\uffff'<'\ud800\udc00'<'\ud800\udc01'<'\ud800\udc02' " +
2697             // \U00010000    << \U00020001   << \U00020002       \U00020002
2698             "&'\ud800\udc00'<<'\ud840\udc01'<<'\ud840\udc02'<<'\ud840\udc02'  " +
2699             // \U00020001   = \U0003001    = \U0004001    = \U0004002
2700             "&'\ud840\udc01'='\ud880\udc01'='\ud8c0\udc01'='\ud8c0\udc02'" +
2701             // \U00040008   < \U00030008   < \U00020008
2702             "&'\ud8c0\udc08'<'\ud880\udc08'<'\ud840\udc08'",
2703
2704             // ** Rule with compact list syntax **
2705             // \ufffe <* \uffff\U00010000  \U00010001
2706             "&'\ufffe'<*'\uffff\ud800\udc00\ud800\udc01\ud800\udc02' " +
2707             // \U00010000   <<* \U00020001  \U00020002
2708             "&'\ud800\udc00'<<*'\ud840\udc01\ud840\udc02\ud840\udc03'  " +
2709             // \U00020001   =* \U0003001   \U0003002   \U0003003   \U0004001
2710             "&'\ud840\udc01'=*'\ud880\udc01\ud880\udc02\ud880\udc03\ud8c0\udc01' " +
2711             // \U00040008   <* \U00030008  \U00030009  \U0003000a  \U00020008
2712             "&'\ud8c0\udc08'<*'\ud880\udc08\ud880\udc09\ud880\udc0a\ud840\udc08'",
2713
2714         };
2715         doTestCollation(m_rangeTestCasesSupplemental_, rules);
2716     }
2717
2718
2719     // Tests the compact range syntax with ASCII codepoints.
2720     public void TestSameStrengthListRanges() {
2721         String[] rules = new String[] {
2722             // Ranges
2723             "&a<*b-d &b<<*k-m &k<<<*x-z &y<*f-he &a=*1-3",
2724
2725             // Ranges with quoted characters
2726             "&'\u0061'<*'\u0062'-'\u0064' &b<<*klm &k<<<*xyz " +
2727             "&'\u0079'<*'\u0066'-'\u0068e' &a=*123",
2728             "&'\u0061'<*'\u0062'-'\u0064' " +
2729             "&b<<*'\u006B'-m &k<<<*x-'\u007a' " +
2730             "&'\u0079'<*'\u0066'-h'\u0065' &a=*'\u0031\u0032\u0033'",
2731         };
2732
2733         doTestCollation(m_rangeTestCases_, rules);
2734     }
2735
2736     // Tests the compact range syntax with supplemental codepoints.
2737     public void TestSameStrengthListRangesWithSupplementalCharacters() {
2738         String[] rules = new String[] {
2739             // \ufffe <* \uffff\U00010000  \U00010001
2740             "&'\ufffe'<*'\uffff'-'\ud800\udc02' " +
2741             // \U00010000   <<* \U00020001   - \U00020003
2742             "&'\ud800\udc00'<<*'\ud840\udc01'-'\ud840\udc03'  " +
2743             // \U00020001   =* \U0003001   \U0004001
2744             "&'\ud840\udc01'=*'\ud880\udc01'-'\ud880\udc03\ud8c0\udc01' " +
2745             // \U00040008   <* \U00030008  \U00020008
2746             "&'\ud8c0\udc08'<*'\ud880\udc08'-'\ud880\udc0a\ud840\udc08'",
2747         };
2748         doTestCollation(m_rangeTestCasesSupplemental_, rules);
2749     }
2750
2751     // Tests the compact range syntax with special characters used as syntax characters in rules.
2752     public void TestSpecialCharacters() {
2753         String rules[] = new String[] {
2754                 // Normal
2755                 "&';'<'+'<','<'-'<'&'<'*'",
2756
2757                 // List
2758                 "&';'<*'+,-&*'",
2759
2760                 // Range
2761                 "&';'<*'+'-'-&*'",
2762
2763                 "&'\u003b'<'\u002b'<'\u002c'<'\u002d'<'\u0026'<'\u002a'",
2764
2765                 "&'\u003b'<*'\u002b\u002c\u002d\u0026\u002a'",
2766                 "&'\u003b'<*'\u002b\u002c\u002d\u0026\u002a'",
2767                 "&'\u003b'<*'\u002b'-'\u002d\u0026\u002a'",
2768                 "&'\u003b'<*'\u002b'-'\u002d\u0026\u002a'",
2769         };
2770         OneTestCase[] testCases = new OneTestCase[] {
2771             new OneTestCase("\u003b", "\u002b", -1), // ; < +
2772             new OneTestCase("\u002b", "\u002c", -1), // + < ,
2773             new OneTestCase("\u002c", "\u002d", -1), // , < -
2774             new OneTestCase("\u002d", "\u0026", -1), // - < &
2775         };
2776         doTestCollation(testCases, rules);
2777     }
2778     
2779     public void TestInvalidListsAndRanges() {
2780         String[] invalidRules = new String[] {
2781             // Range not in starred expression
2782             "&'\ufffe'<'\uffff'-'\ud800\udc02'",
2783             
2784             // Range without start
2785             "&a<*-c",
2786             
2787             // Range without end
2788             "&a<*b-",
2789                        
2790             // More than one hyphen
2791             "&a<*b-g-l",
2792             
2793             // Range in the wrong order
2794             "&a<*k-b",
2795         };
2796         for (String rule : invalidRules) {
2797             try {
2798                 Collator myCollation = new RuleBasedCollator(rule);
2799                 warnln("ERROR: Creation of collator didn't fail for " + rule + " when it should.");
2800                 CollationTest.doTest(this, (RuleBasedCollator)myCollation,
2801                         "x",
2802                         "y",
2803                         -1);
2804                
2805            } catch (Exception e) {
2806                 continue;
2807             }
2808            throw new IllegalArgumentException("ERROR: Invalid collator with rule " + rule + " worked fine.");
2809         }
2810     }
2811
2812     // This is the same example above with ' and space added.
2813     // They work a little different than expected.  Desired rules are commented out.
2814     public void TestQuoteAndSpace() {
2815         String rules[] = new String[] {
2816                 // These are working as expected.
2817                 "&';'<'+'<','<'-'<'&'<''<'*'<' '",
2818
2819                 // List.  Desired rule is 
2820                 // "&';'<*'+,-&''* '",
2821                 // but it doesn't work.  Instead, '' should be outside quotes as below.
2822                 "&';'<*'+,-&''''* '",
2823
2824                 // Range.  Similar issues here as well.  The following are working.
2825                 //"&';'<*'+'-'-&''* '",
2826                 //"&';'<*'+'-'-&'\\u0027'* '",
2827                 "&';'<*'+'-'-&''''* '",
2828                 //"&';'<*'+'-'-&'\\u0027'* '",
2829
2830                 // The following rules are not working.
2831                 // "&';'<'+'<','<'-'<'&'<\\u0027<'*'<' '", 
2832                 //"&'\u003b'<'\u002b'<'\u002c'<'\u002d'<'\u0026'<'\u0027'<\u002a'<'\u0020'",
2833                 //"&'\u003b'<'\u002b'<'\u002c'<'\u002d'<'\u0026'<\\u0027<\u002a'<'\u0020'",
2834         };
2835
2836         OneTestCase[] testCases = new OneTestCase[] {
2837             new OneTestCase("\u003b", "\u002b", -1), // ; < ,
2838             new OneTestCase("\u002b", "\u002c", -1), // ; < ,
2839             new OneTestCase("\u002c", "\u002d", -1), // , < -
2840             new OneTestCase("\u002d", "\u0026", -1), // - < &
2841             new OneTestCase("\u0026", "\u0027", -1), // & < '
2842             new OneTestCase("\u0027", "\u002a", -1), // ' < *
2843             // new OneTestCase("\u002a", "\u0020", -1), // * < <space>
2844         };
2845         doTestCollation(testCases, rules);
2846     }
2847
2848     /*
2849      * Tests the method public boolean equals(Object target) in CollationKey
2850      */
2851     public void TestCollationKeyEquals() {
2852         CollationKey ck = new CollationKey("", (byte[]) null);
2853
2854         // Tests when "if (!(target instanceof CollationKey))" is true
2855         if (ck.equals(new Object())) {
2856             errln("CollationKey.equals() was not suppose to return false "
2857                     + "since it is comparing to a non Collation Key object.");
2858         }
2859         if (ck.equals("")) {
2860             errln("CollationKey.equals() was not suppose to return false "
2861                     + "since it is comparing to a non Collation Key object.");
2862         }
2863         if (ck.equals(0)) {
2864             errln("CollationKey.equals() was not suppose to return false "
2865                     + "since it is comparing to a non Collation Key object.");
2866         }
2867         if (ck.equals(0.0)) {
2868             errln("CollationKey.equals() was not suppose to return false "
2869                     + "since it is comparing to a non Collation Key object.");
2870         }
2871
2872         // Tests when "if (target == null)" is true
2873         if (ck.equals((CollationKey) null)) {
2874             errln("CollationKey.equals() was not suppose to return false "
2875                     + "since it is comparing to a null Collation Key object.");
2876         }
2877     }
2878
2879     /*
2880      * Tests the method public int hashCode() in CollationKey
2881      */
2882     public void TestCollationKeyHashCode() {
2883         CollationKey ck = new CollationKey("", (byte[]) null);
2884
2885         // Tests when "if (m_key_ == null)" is true
2886         if (ck.hashCode() != 1) {
2887             errln("CollationKey.hashCode() was suppose to return 1 "
2888                     + "when m_key is null due a null parameter in the " + "constructor.");
2889         }
2890     }
2891
2892     /*
2893      * Tests the method public CollationKey getBound(int boundType, int noOfLevels)
2894      */
2895     public void TestGetBound() {
2896         CollationKey ck = new CollationKey("", (byte[]) null);
2897
2898         // Tests when "if (noOfLevels > Collator.PRIMARY)" is false
2899         // Tests when "default: " is true for "switch (boundType)"
2900         try {
2901             ck.getBound(BoundMode.COUNT, -1);
2902             errln("CollationKey.getBound(int,int) was suppose to return an "
2903                     + "exception for an invalid boundType value.");
2904         } catch (Exception e) {
2905         }
2906
2907         // Tests when "if (noOfLevels > 0)"
2908         byte b[] = {};
2909         CollationKey ck1 = new CollationKey("", b);
2910         try {
2911             ck1.getBound(0, 1);
2912             errln("CollationKey.getBound(int,int) was suppose to return an "
2913                     + "exception a value of noOfLevels that exceeds expected.");
2914         } catch (Exception e) {
2915         }
2916     }
2917
2918     /*
2919      * Tests the method public CollationKey merge(CollationKey source)
2920      */
2921     public void TestMerge() {
2922         byte b[] = {};
2923         CollationKey ck = new CollationKey("", b);
2924
2925         // Tests when "if (source == null || source.getLength() == 0)" is true
2926         try {
2927             ck.merge(null);
2928             errln("Collationkey.merge(CollationKey) was suppose to return " + "an exception for a null parameter.");
2929         } catch (Exception e) {
2930         }
2931         try {
2932             ck.merge(ck);
2933             errln("Collationkey.merge(CollationKey) was suppose to return " + "an exception for a null parameter.");
2934         } catch (Exception e) {
2935         }
2936     }
2937
2938     /* Test the method public int compareTo(RawCollationKey rhs) */
2939     public void TestRawCollationKeyCompareTo(){
2940         RawCollationKey rck = new RawCollationKey();
2941         byte[] b = {(byte) 10, (byte) 20};
2942         RawCollationKey rck100 = new RawCollationKey(b, 2);
2943
2944         if(rck.compareTo(rck) != 0){
2945             errln("RawCollatonKey.compareTo(RawCollationKey) was suppose to return 0 " +
2946                     "for two idential RawCollationKey objects.");
2947         }
2948
2949         if(rck.compareTo(rck100) == 0){
2950             errln("RawCollatonKey.compareTo(RawCollationKey) was not suppose to return 0 " +
2951                     "for two different RawCollationKey objects.");
2952         }
2953     }
2954
2955     /* Track7223: CollationElementIterator does not return correct order for Hungarian */
2956     public void TestHungarianTailoring(){
2957         String rules = new String("&DZ<dzs<<<Dzs<<<DZS" +
2958                                   "&G<gy<<<Gy<<<GY" +
2959                                   "&L<ly<<<Ly<<<LY" +
2960                                   "&N<ny<<<Ny<<<NY" +
2961                                   "&S<sz<<<Sz<<<SZ" +
2962                                   "&T<ty<<<Ty<<<TY" +
2963                                   "&Z<zs<<<Zs<<<ZS" +
2964                                   "&O<\u00f6<<<\u00d6<<\u0151<<<\u0150" +
2965                                   "&U<\u00fc<<<\u00dc<<\u0171<<<\u0171" +
2966                                   "&cs<<<ccs/cs" +
2967                                   "&Cs<<<Ccs/cs" +
2968                                   "&CS<<<CCS/CS" +
2969                                   "&dz<<<ddz/dz" +
2970                                   "&Dz<<<Ddz/dz" +
2971                                   "&DZ<<<DDZ/DZ" +
2972                                   "&dzs<<<ddzs/dzs" +
2973                                   "&Dzs<<<Ddzs/dzs" +
2974                                   "&DZS<<<DDZS/DZS" +
2975                                   "&gy<<<ggy/gy" +
2976                                   "&Gy<<<Ggy/gy" +
2977                                   "&GY<<<GGY/GY");
2978         RuleBasedCollator coll;
2979         try {
2980             String str1 = "ggy";
2981             String str2 = "GGY";
2982             coll = new RuleBasedCollator(rules);
2983             if (coll.compare("ggy", "GGY") >= 0) {
2984                   errln("TestHungarianTailoring.compare(" + str1 + ","+ str2 +
2985                         ") was suppose to return -1 ");
2986             }
2987             CollationKey sortKey1 = coll.getCollationKey(str1);
2988             CollationKey sortKey2 = coll.getCollationKey(str2);
2989             if (sortKey1.compareTo(sortKey2) >= 0) {
2990                   errln("TestHungarianTailoring getCollationKey(\"" + str1 +"\") was suppose "+
2991                         "less than getCollationKey(\""+ str2 + "\").");
2992                   errln("  getCollationKey(\"ggy\"):" + prettify(sortKey1) +
2993                         "  getCollationKey(\"GGY\"):" + prettify(sortKey2));
2994             }
2995
2996             CollationElementIterator iter1 = coll.getCollationElementIterator(str1);
2997             CollationElementIterator iter2 = coll.getCollationElementIterator(str2);
2998             int ce1, ce2;
2999             while((ce1 = iter1.next()) != CollationElementIterator.NULLORDER &&
3000                   (ce2 = iter2.next()) != CollationElementIterator.NULLORDER) {
3001                 if (ce1 > ce2) {
3002                   errln("TestHungarianTailoring.CollationElementIterator(" + str1 +
3003                       ","+ str2 + ") was suppose to return -1 ");
3004                 }
3005             }
3006           } catch (Exception e) {
3007               e.printStackTrace();
3008           }
3009      }
3010
3011     public void TestImport(){
3012         try{
3013             RuleBasedCollator vicoll = (RuleBasedCollator)Collator.getInstance(new ULocale("vi"));
3014             RuleBasedCollator escoll = (RuleBasedCollator)Collator.getInstance(new ULocale("es"));
3015             RuleBasedCollator viescoll = new RuleBasedCollator(vicoll.getRules() + escoll.getRules());
3016             RuleBasedCollator importviescoll = new RuleBasedCollator("[import vi][import es]");
3017
3018             UnicodeSet tailoredSet = viescoll.getTailoredSet();
3019             UnicodeSet importTailoredSet = importviescoll.getTailoredSet();
3020
3021             if(!tailoredSet.equals(importTailoredSet)){
3022                 warnln("Tailored set not equal");
3023             }
3024
3025             for (UnicodeSetIterator it = new UnicodeSetIterator(tailoredSet); it.next();) {
3026                 String t = it.getString();
3027                 CollationKey sk1 = viescoll.getCollationKey(t);
3028                 CollationKey sk2 = importviescoll.getCollationKey(t);
3029                 if(!sk1.equals(sk2)){
3030                     warnln("Collation key's not equal for " + t);
3031                 }
3032             }
3033
3034         }catch(Exception e){
3035             warnln("ERROR: in creation of rule based collator");
3036         }
3037     }
3038
3039     public void TestImportWithType(){
3040         try{
3041             RuleBasedCollator vicoll = (RuleBasedCollator)Collator.getInstance(new ULocale("vi"));
3042             RuleBasedCollator decoll = (RuleBasedCollator)Collator.getInstance(ULocale.forLanguageTag("de-u-co-phonebk"));
3043             RuleBasedCollator videcoll = new RuleBasedCollator(vicoll.getRules() + decoll.getRules());
3044             RuleBasedCollator importvidecoll = new RuleBasedCollator("[import vi][import de-u-co-phonebk]");
3045
3046             UnicodeSet tailoredSet = videcoll.getTailoredSet();
3047             UnicodeSet importTailoredSet = importvidecoll.getTailoredSet();
3048
3049             if(!tailoredSet.equals(importTailoredSet)){
3050                 warnln("Tailored set not equal");
3051             }
3052
3053             for (UnicodeSetIterator it = new UnicodeSetIterator(tailoredSet); it.next();) {
3054                 String t = it.getString();
3055                 CollationKey sk1 = videcoll.getCollationKey(t);
3056                 CollationKey sk2 = importvidecoll.getCollationKey(t);
3057                 if(!sk1.equals(sk2)){
3058                     warnln("Collation key's not equal for " + t);
3059                 }
3060             }
3061
3062         }catch(Exception e){
3063             warnln("ERROR: in creation of rule based collator");
3064         }
3065     }
3066
3067     /*
3068      * This test ensures that characters placed before a character in a different script have the same lead byte
3069      * in their collation key before and after script reordering.
3070      */
3071     public void TestBeforeRuleWithScriptReordering() throws Exception
3072     {
3073         /* build collator */
3074         String rules = "&[before 1]\u03b1 < \u0e01";
3075         int[] reorderCodes = {UScript.GREEK};
3076         int result;
3077         
3078         Collator myCollation = new RuleBasedCollator(rules);
3079         myCollation.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
3080         myCollation.setStrength(Collator.TERTIARY);
3081         
3082         String base = "\u03b1"; /* base */
3083         String before = "\u0e01"; /* ko kai */
3084
3085         /* check collation results - before rule applied but not script reordering */
3086         result = myCollation.compare(base, before);
3087         if (!(result > 0)) {
3088             errln("Collation result not correct before script reordering.");
3089         }
3090
3091         /* check the lead byte of the collation keys before script reordering */
3092         CollationKey baseKey = myCollation.getCollationKey(base);
3093         CollationKey beforeKey = myCollation.getCollationKey(before);
3094         byte[] baseKeyBytes = baseKey.toByteArray();
3095         byte[] beforeKeyBytes = beforeKey.toByteArray();
3096         if (baseKeyBytes[0] != beforeKeyBytes[0]) {
3097             errln("Different lead byte for sort keys using before rule and before script reordering. base character lead byte = " 
3098                     + baseKeyBytes[0] + ", before character lead byte = " + beforeKeyBytes[0]);
3099        }
3100
3101         /* reorder the scripts */
3102         myCollation.setReorderCodes(reorderCodes);
3103
3104         /* check collation results - before rule applied and after script reordering */
3105         result = myCollation.compare(base, before);
3106         if (!(result > 0)) {
3107             errln("Collation result not correct after script reordering.");
3108         }
3109         
3110         /* check the lead byte of the collation keys after script reordering */
3111         baseKey = myCollation.getCollationKey(base);
3112         beforeKey = myCollation.getCollationKey(before);
3113         baseKeyBytes = baseKey.toByteArray();
3114         beforeKeyBytes = beforeKey.toByteArray();
3115         if (baseKeyBytes[0] != beforeKeyBytes[0]) {
3116             errln("Different lead byte for sort keys using before rule and before script reordering. base character lead byte = " 
3117                     + baseKeyBytes[0] + ", before character lead byte = " + beforeKeyBytes[0]);
3118        }
3119     }
3120
3121     /*
3122      * Test that in a primary-compressed sort key all bytes except the first one are unchanged under script reordering.
3123      */
3124     public void TestNonLeadBytesDuringCollationReordering() throws Exception
3125     {
3126         Collator myCollation;
3127         byte[] baseKey;
3128         byte[] reorderKey;
3129         int[] reorderCodes = {UScript.GREEK};
3130         String testString = "\u03b1\u03b2\u03b3";
3131
3132         /* build collator tertiary */
3133         myCollation = new RuleBasedCollator("");
3134         myCollation.setStrength(Collator.TERTIARY);
3135         baseKey = myCollation.getCollationKey(testString).toByteArray();
3136
3137         myCollation.setReorderCodes(reorderCodes);
3138         reorderKey = myCollation.getCollationKey(testString).toByteArray();
3139         
3140         if (baseKey.length != reorderKey.length) {
3141             errln("Key lengths not the same during reordering.\n");
3142         }
3143         
3144         for (int i = 1; i < baseKey.length; i++) {
3145             if (baseKey[i] != reorderKey[i]) {
3146                 errln("Collation key bytes not the same at position " + i);
3147             }
3148         } 
3149
3150         /* build collator tertiary */
3151         myCollation = new RuleBasedCollator("");
3152         myCollation.setStrength(Collator.QUATERNARY);
3153         baseKey = myCollation.getCollationKey(testString).toByteArray();
3154
3155         myCollation.setReorderCodes(reorderCodes);
3156         reorderKey = myCollation.getCollationKey(testString).toByteArray();
3157         
3158         if (baseKey.length != reorderKey.length) {
3159             errln("Key lengths not the same during reordering.\n");
3160         }
3161         
3162         for (int i = 1; i < baseKey.length; i++) {
3163             if (baseKey[i] != reorderKey[i]) {
3164                 errln("Collation key bytes not the same at position " + i);
3165             }
3166         } 
3167     }
3168
3169     /*
3170      * Test reordering API.
3171      */
3172     public void TestReorderingAPI() throws Exception
3173     {
3174         Collator myCollation;
3175         int[] reorderCodes = {UScript.GREEK, UScript.HAN, ReorderCodes.PUNCTUATION};
3176         int[] duplicateReorderCodes = {UScript.CUNEIFORM, UScript.GREEK, ReorderCodes.CURRENCY, UScript.EGYPTIAN_HIEROGLYPHS};
3177         int[] reorderCodesStartingWithDefault = {ReorderCodes.DEFAULT, UScript.GREEK, UScript.HAN, ReorderCodes.PUNCTUATION};
3178         int[] retrievedReorderCodes;
3179         String greekString = "\u03b1";
3180         String punctuationString = "\u203e";
3181
3182         /* build collator tertiary */
3183         myCollation = new RuleBasedCollator("");
3184         myCollation.setStrength(Collator.TERTIARY);
3185
3186         /* set the reorderding */
3187         myCollation.setReorderCodes(reorderCodes);
3188         
3189         retrievedReorderCodes = myCollation.getReorderCodes();
3190         if (!Arrays.equals(reorderCodes, retrievedReorderCodes)) {
3191             errln("ERROR: retrieved reorder codes do not match set reorder codes.");
3192         }
3193         if (!(myCollation.compare(greekString, punctuationString) < 0)) {
3194             errln("ERROR: collation result should have been less.");
3195         }
3196         
3197         /* clear the reordering */
3198         myCollation.setReorderCodes(null);    
3199         retrievedReorderCodes = myCollation.getReorderCodes();
3200         if (retrievedReorderCodes.length != 0) {
3201             errln("ERROR: retrieved reorder codes was not null.");
3202         }
3203
3204         if (!(myCollation.compare(greekString, punctuationString) > 0)) {
3205             errln("ERROR: collation result should have been greater.");
3206         }
3207         
3208         // do it again with an empty but non-null array
3209         
3210         /* set the reorderding */
3211         myCollation.setReorderCodes(reorderCodes);
3212         
3213         retrievedReorderCodes = myCollation.getReorderCodes();
3214         if (!Arrays.equals(reorderCodes, retrievedReorderCodes)) {
3215             errln("ERROR: retrieved reorder codes do not match set reorder codes.");
3216         }
3217         if (!(myCollation.compare(greekString, punctuationString) < 0)) {
3218             errln("ERROR: collation result should have been less.");
3219         }
3220         
3221         /* clear the reordering */
3222         myCollation.setReorderCodes(new int[]{});    
3223         retrievedReorderCodes = myCollation.getReorderCodes();
3224         if (retrievedReorderCodes.length != 0) {
3225             errln("ERROR: retrieved reorder codes was not null.");
3226         }
3227
3228         if (!(myCollation.compare(greekString, punctuationString) > 0)) {
3229             errln("ERROR: collation result should have been greater.");
3230         }
3231         
3232         boolean gotException = false;
3233         /* set duplicates in the reorder codes */
3234         try {
3235             myCollation.setReorderCodes(duplicateReorderCodes);
3236         } catch (IllegalArgumentException e) {
3237             // expect exception on illegal arguments
3238             gotException = true;
3239         }
3240         if (!gotException) {
3241             errln("ERROR: exception was not thrown for illegal reorder codes argument.");            
3242         }
3243         
3244         /* set duplicate reorder codes */
3245         gotException = false;
3246         try {
3247             myCollation.setReorderCodes(reorderCodesStartingWithDefault);
3248         } catch (IllegalArgumentException e) {
3249             gotException = true;
3250         }
3251         if (!gotException) {
3252             errln("ERROR: reorder codes following a 'default' code should have thrown an exception but did not.");            
3253         }
3254     }
3255     
3256     /*
3257      * Test reordering API.
3258      */
3259     public void TestReorderingAPIWithRuleCreatedCollator() throws Exception
3260     {
3261         Collator myCollation;
3262         String rules = "[reorder Hani Grek]";
3263         int[] rulesReorderCodes = {UScript.HAN, UScript.GREEK};
3264         int[] reorderCodes = {UScript.GREEK, UScript.HAN, ReorderCodes.PUNCTUATION};
3265         int[] retrievedReorderCodes;
3266
3267         
3268         /* build collator tertiary */
3269         myCollation = new RuleBasedCollator(rules);
3270         myCollation.setStrength(Collator.TERTIARY);
3271
3272         retrievedReorderCodes = myCollation.getReorderCodes();
3273         if (!Arrays.equals(rulesReorderCodes, retrievedReorderCodes)) {
3274             errln("ERROR: retrieved reorder codes do not match set reorder codes.");
3275         }
3276         
3277         /* clear the reordering */
3278         myCollation.setReorderCodes(null);    
3279         retrievedReorderCodes = myCollation.getReorderCodes();
3280         if (retrievedReorderCodes.length != 0) {
3281             errln("ERROR: retrieved reorder codes was not null.");
3282         }
3283
3284         /* set the reorderding */
3285         myCollation.setReorderCodes(reorderCodes);
3286         
3287         retrievedReorderCodes = myCollation.getReorderCodes();
3288         if (!Arrays.equals(reorderCodes, retrievedReorderCodes)) {
3289             errln("ERROR: retrieved reorder codes do not match set reorder codes.");
3290         }
3291         
3292         /* reset the reordering */
3293         myCollation.setReorderCodes(ReorderCodes.DEFAULT);    
3294         retrievedReorderCodes = myCollation.getReorderCodes();
3295         if (!Arrays.equals(rulesReorderCodes, retrievedReorderCodes)) {
3296             errln("ERROR: retrieved reorder codes do not match set reorder codes.");
3297         }
3298     }
3299     
3300     public void TestSameLeadBytScriptReorder(){
3301         String[] testSourceCases = {
3302                 "\ud800\udf31", // Gothic
3303                 "\ud801\udc50", // Shavian
3304         };
3305
3306         String[] testTargetCases = {
3307                 "\u0100",   // Latin Extended-A
3308                 "\u2c74",   // Latin Extended-C
3309         };
3310
3311         int[] results = {
3312                 -1,
3313                 -1,
3314         };
3315
3316         Collator  myCollation;
3317         String rules = "[reorder Goth Latn]";
3318         try {
3319             myCollation = new RuleBasedCollator(rules);
3320         } catch (Exception e) {
3321             warnln("ERROR: in creation of rule based collator");
3322             return;
3323         }
3324         myCollation.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
3325         myCollation.setStrength(Collator.TERTIARY);
3326         for (int i = 0; i < testSourceCases.length ; i++)
3327         {
3328             CollationTest.doTest(this, (RuleBasedCollator)myCollation, 
3329                     testSourceCases[i], testTargetCases[i], 
3330                     results[i]);
3331         }
3332
3333         // ensure that the non-reordered and reordered collation is the same
3334         Collator nonReorderdCollator = RuleBasedCollator.getInstance();
3335         int nonReorderedResults = nonReorderdCollator.compare(testSourceCases[0], testSourceCases[1]);
3336         CollationTest.doTest(this, (RuleBasedCollator)myCollation, 
3337                 testSourceCases[0], testSourceCases[1], nonReorderedResults);   
3338      }
3339     
3340     public void TestEquivalentReorderingScripts() {
3341         int[] equivalentScriptsResult = {
3342                 UScript.BOPOMOFO,               //Bopo
3343                 UScript.LISU,                   //Lisu
3344                 UScript.LYCIAN,                 //Lyci
3345                 UScript.CARIAN,                 //Cari
3346                 UScript.LYDIAN,                 //Lydi
3347                 UScript.YI,                     //Yiii
3348                 UScript.OLD_ITALIC,             //Ital
3349                 UScript.GOTHIC,                 //Goth
3350                 UScript.DESERET,                //Dsrt
3351                 UScript.SHAVIAN,                //Shaw
3352                 UScript.OSMANYA,                //Osma
3353                 UScript.LINEAR_B,               //Linb
3354                 UScript.CYPRIOT,                //Cprt
3355                 UScript.OLD_SOUTH_ARABIAN,      //Sarb
3356                 UScript.AVESTAN,                //Avst
3357                 UScript.IMPERIAL_ARAMAIC,       //Armi
3358                 UScript.INSCRIPTIONAL_PARTHIAN, //Prti
3359                 UScript.INSCRIPTIONAL_PAHLAVI,  //Phli
3360                 UScript.UGARITIC,               //Ugar
3361                 UScript.OLD_PERSIAN,            //Xpeo
3362                 UScript.CUNEIFORM,              //Xsux
3363                 UScript.EGYPTIAN_HIEROGLYPHS    //Egyp
3364         };
3365         Arrays.sort(equivalentScriptsResult);
3366         
3367         int[] equivalentScripts = RuleBasedCollator.getEquivalentReorderCodes(UScript.GOTHIC);
3368         Arrays.sort(equivalentScripts);
3369         assertTrue("Script Equivalents for Reordering", Arrays.equals(equivalentScripts, equivalentScriptsResult));
3370
3371         equivalentScripts = RuleBasedCollator.getEquivalentReorderCodes(UScript.SHAVIAN);
3372         Arrays.sort(equivalentScripts);
3373         assertTrue("Script Equivalents for Reordering", Arrays.equals(equivalentScripts, equivalentScriptsResult));
3374     }
3375     
3376     public void TestGreekFirstReorderCloning() {
3377         String[] testSourceCases = {
3378             "\u0041",
3379             "\u03b1\u0041",
3380             "\u0061",
3381             "\u0041\u0061",
3382             "\u0391",
3383         };
3384
3385         String[] testTargetCases = {
3386             "\u03b1",
3387             "\u0041\u03b1",
3388             "\u0391",
3389             "\u0391\u03b1",
3390             "\u0391",
3391         };
3392
3393         int[] results = {
3394             1,
3395             -1,
3396             1,
3397             1,
3398             0
3399         };
3400
3401         Collator  originalCollation;
3402         Collator  myCollation;
3403         String rules = "[reorder Grek]";
3404         try {
3405             originalCollation = new RuleBasedCollator(rules);
3406         } catch (Exception e) {
3407             warnln("ERROR: in creation of rule based collator");
3408             return;
3409         }
3410         try {
3411             myCollation = (Collator) originalCollation.clone();
3412         } catch (Exception e) {
3413             warnln("ERROR: in creation of rule based collator");
3414             return;
3415         }
3416         myCollation.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
3417         myCollation.setStrength(Collator.TERTIARY);
3418         for (int i = 0; i < testSourceCases.length ; i++)
3419         {
3420             CollationTest.doTest(this, (RuleBasedCollator)myCollation, 
3421                                  testSourceCases[i], testTargetCases[i], 
3422                                  results[i]);
3423         }
3424     }
3425
3426     /*
3427      * Utility function to test one collation reordering test case.
3428      * @param testcases Array of test cases.
3429      * @param n_testcases Size of the array testcases.
3430      * @param str_rules Array of rules.  These rules should be specifying the same rule in different formats.
3431      * @param n_rules Size of the array str_rules.
3432      */
3433     private void doTestOneReorderingAPITestCase(OneTestCase testCases[], int reorderTokens[])
3434     {
3435         Collator myCollation = Collator.getInstance(ULocale.ENGLISH);
3436         myCollation.setReorderCodes(reorderTokens);
3437         
3438         for (OneTestCase testCase : testCases) {
3439             CollationTest.doTest(this, (RuleBasedCollator)myCollation,
3440                     testCase.m_source_,
3441                     testCase.m_target_,
3442                     testCase.m_result_);
3443         }
3444     }
3445
3446     public void TestGreekFirstReorder()
3447     {
3448         String[] strRules = {
3449             "[reorder Grek]"
3450         };
3451
3452         int[] apiRules = {
3453             UScript.GREEK
3454         };
3455         
3456         OneTestCase[] privateUseCharacterStrings = {
3457             new OneTestCase("\u0391", "\u0391", 0),
3458             new OneTestCase("\u0041", "\u0391", 1),
3459             new OneTestCase("\u03B1\u0041", "\u03B1\u0391", 1),
3460             new OneTestCase("\u0060", "\u0391", -1),
3461             new OneTestCase("\u0391", "\ue2dc", -1),
3462             new OneTestCase("\u0391", "\u0060", 1),
3463         };
3464
3465         /* Test rules creation */
3466         doTestCollation(privateUseCharacterStrings, strRules);
3467
3468         /* Test collation reordering API */
3469         doTestOneReorderingAPITestCase(privateUseCharacterStrings, apiRules);
3470     }
3471
3472     public void TestGreekLastReorder()
3473     {
3474         String[] strRules = {
3475             "[reorder Zzzz Grek]"
3476         };
3477
3478         int[] apiRules = {
3479             UScript.UNKNOWN, UScript.GREEK
3480         };
3481         
3482         OneTestCase[] privateUseCharacterStrings = {
3483             new OneTestCase("\u0391", "\u0391", 0),
3484             new OneTestCase("\u0041", "\u0391", -1),
3485             new OneTestCase("\u03B1\u0041", "\u03B1\u0391", -1),
3486             new OneTestCase("\u0060", "\u0391", -1),
3487             new OneTestCase("\u0391", "\ue2dc", 1),
3488         };
3489         
3490         /* Test rules creation */
3491         doTestCollation(privateUseCharacterStrings, strRules);
3492
3493         /* Test collation reordering API */
3494         doTestOneReorderingAPITestCase(privateUseCharacterStrings, apiRules);
3495     }
3496
3497     public void TestNonScriptReorder()
3498     {
3499         String[] strRules = {
3500             "[reorder Grek Symbol DIGIT Latn Punct space Zzzz cURRENCy]"
3501         };
3502
3503         int[] apiRules = {
3504             UScript.GREEK, ReorderCodes.SYMBOL, ReorderCodes.DIGIT, UScript.LATIN,
3505             ReorderCodes.PUNCTUATION, ReorderCodes.SPACE, UScript.UNKNOWN,
3506             ReorderCodes.CURRENCY
3507         };
3508
3509         OneTestCase[] privateUseCharacterStrings = {
3510             new OneTestCase("\u0391", "\u0041", -1),
3511             new OneTestCase("\u0041", "\u0391", 1),
3512             new OneTestCase("\u0060", "\u0041", -1),
3513             new OneTestCase("\u0060", "\u0391", 1),
3514             new OneTestCase("\u0024", "\u0041", 1),
3515         };
3516         
3517         /* Test rules creation */
3518         doTestCollation(privateUseCharacterStrings, strRules);
3519
3520         /* Test collation reordering API */
3521         doTestOneReorderingAPITestCase(privateUseCharacterStrings, apiRules);
3522     }
3523
3524     public void TestHaniReorder()
3525     {
3526         String[] strRules = {
3527             "[reorder Hani]"
3528         };
3529         int[] apiRules = {
3530             UScript.HAN
3531         };
3532
3533         OneTestCase[] privateUseCharacterStrings = {
3534             new OneTestCase("\u4e00", "\u0041", -1),
3535             new OneTestCase("\u4e00", "\u0060", 1),
3536             new OneTestCase("\uD86D, 0xDF40", "\u0041", -1),
3537             new OneTestCase("\uD86D, 0xDF40", "\u0060", 1),
3538             new OneTestCase("\u4e00", "\uD86D\uDF40", -1),
3539             new OneTestCase("\ufa27", "\u0041", -1),
3540             new OneTestCase("\uD869\uDF00", "\u0041", -1),
3541         };
3542         
3543         /* Test rules creation */
3544         doTestCollation(privateUseCharacterStrings, strRules);
3545
3546         /* Test collation reordering API */
3547         doTestOneReorderingAPITestCase(privateUseCharacterStrings, apiRules);
3548     }
3549     
3550     public void TestMultipleReorder()
3551     {
3552         String[] strRules = {
3553             "[reorder Grek Zzzz DIGIT Latn Hani]"
3554         };
3555
3556         int[] apiRules = {
3557             UScript.GREEK, UScript.UNKNOWN, ReorderCodes.DIGIT, UScript.LATIN, UScript.HAN
3558         };
3559         
3560         OneTestCase[] collationTestCases = {
3561             new OneTestCase("\u0391", "\u0041", -1),
3562             new OneTestCase("\u0031", "\u0041", -1),
3563             new OneTestCase("u0041", "\u4e00", -1),
3564         };
3565
3566         /* Test rules creation */
3567         doTestCollation(collationTestCases, strRules);
3568
3569         /* Test collation reordering API */
3570         doTestOneReorderingAPITestCase(collationTestCases, apiRules);
3571     }
3572     
3573     public void TestFrozeness()
3574     {
3575         Collator myCollation = Collator.getInstance(ULocale.CANADA);
3576         boolean exceptionCaught = false;
3577         
3578         myCollation.freeze();
3579         assertTrue("Collator not frozen.", myCollation.isFrozen());
3580
3581         try {
3582             myCollation.setStrength(Collator.SECONDARY);
3583         } catch (UnsupportedOperationException e) {
3584             // expected
3585             exceptionCaught = true;
3586         }
3587         assertTrue("Frozen collator allowed change.", exceptionCaught);
3588         exceptionCaught = false;
3589         
3590         try {
3591             myCollation.setReorderCodes(ReorderCodes.DEFAULT);
3592         } catch (UnsupportedOperationException e) {
3593             // expected
3594             exceptionCaught = true;
3595         }
3596         assertTrue("Frozen collator allowed change.", exceptionCaught);
3597         exceptionCaught = false;
3598         
3599         try {
3600             myCollation.setVariableTop(12);
3601         } catch (UnsupportedOperationException e) {
3602             // expected
3603             exceptionCaught = true;
3604         }
3605         assertTrue("Frozen collator allowed change.", exceptionCaught);
3606         exceptionCaught = false;
3607         
3608         Collator myClone = null;
3609         try {
3610             myClone = (Collator) myCollation.clone();
3611         } catch (CloneNotSupportedException e) {
3612             // should not happen - clone is implemented in Collator
3613             errln("ERROR: unable to clone collator.");
3614         }
3615         assertTrue("Clone not frozen as expected.", myClone.isFrozen());
3616         
3617         myClone = myClone.cloneAsThawed();
3618         assertFalse("Clone not thawed as expected.", myClone.isFrozen());        
3619     }
3620 }