1/*
2 * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @bug 6850113 8032446
27 * @summary confirm the behavior of new Bidi implementation. (Backward compatibility)
28 * @modules java.desktop
29 */
30
31import java.awt.font.NumericShaper;
32import java.awt.font.TextAttribute;
33import java.text.AttributedString;
34import java.text.Bidi;
35import java.util.Arrays;
36
37public class BidiConformance {
38
39    /* internal flags */
40    private static boolean error = false;
41    private static boolean verbose = false;
42    private static boolean abort = false;
43
44    private static final byte MAX_EXPLICIT_LEVEL = 125;
45
46    public static void main(String[] args) {
47        for (int i = 0; i < args.length; i++) {
48            String arg = args[i];
49            if (arg.equals("-verbose")) {
50                verbose = true;
51            } else if (arg.equals("-abort")) {
52                abort = true;
53            }
54        }
55
56        BidiConformance bc = new BidiConformance();
57        bc.test();
58
59        if (error) {
60            throw new RuntimeException("Failed.");
61        } else {
62            System.out.println("Passed.");
63        }
64    }
65
66    private void test() {
67        testConstants();
68        testConstructors();
69        testMethods();
70
71        testMethods4Constructor1();  // Bidi(AttributedCharacterIterator)
72        testMethods4Constructor2();  // Bidi(String, int)
73        testMethods4Constructor3();  // Bidi(char[], ...)
74    }
75
76    private void testConstants() {
77        System.out.println("*** Test constants");
78
79        checkResult("Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT",
80                     -2, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
81        checkResult("Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT",
82                     -1, Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
83        checkResult("Bidi.DIRECTION_LEFT_TO_RIGHT",
84                     0, Bidi.DIRECTION_LEFT_TO_RIGHT);
85        checkResult("Bidi.DIRECTION_RIGHT_TO_LEFT",
86                     1, Bidi.DIRECTION_RIGHT_TO_LEFT);
87    }
88
89    private void testConstructors() {
90        System.out.println("*** Test constructors");
91
92        testConstructor1();  // Bidi(AttributedCharacterIterator)
93        testConstructor2();  // Bidi(String, int)
94        testConstructor3();  // Bidi(char[], ...)
95    }
96
97    private void testMethods() {
98        System.out.println("*** Test methods");
99
100        testMethod_createLineBidi1();
101        testMethod_createLineBidi2();
102        testMethod_getLevelAt();
103        testMethod_getRunLevel();
104        testMethod_getRunLimit();
105        testMethod_getRunStart();
106        testMethod_reorderVisually1();
107        testMethod_reorderVisually2();
108        testMethod_requiresBidi();
109    }
110
111    private void testMethods4Constructor1() {
112        System.out.println("*** Test methods for constructor 1");
113
114        String paragraph;
115        Bidi bidi;
116        NumericShaper ns = NumericShaper.getShaper(NumericShaper.ARABIC);
117
118        for (int textNo = 0; textNo < data4Constructor1.length; textNo++) {
119            paragraph = data4Constructor1[textNo][0];
120            int start = paragraph.indexOf('<')+1;
121            int limit = paragraph.indexOf('>');
122            int testNo;
123
124            System.out.println("*** Test textNo=" + textNo +
125                ": Bidi(AttributedCharacterIterator\"" +
126                toReadableString(paragraph) + "\") " +
127                "  start=" + start + ", limit=" + limit);
128
129            // Test 0
130            testNo = 0;
131            System.out.println(" Test#" + testNo +": RUN_DIRECTION_LTR");
132            AttributedString astr = new AttributedString(paragraph);
133            astr.addAttribute(TextAttribute.RUN_DIRECTION,
134                              TextAttribute.RUN_DIRECTION_LTR);
135            bidi = new Bidi(astr.getIterator());
136
137            callTestEachMethod4Constructor1(textNo, testNo, bidi);
138
139            // Test 1
140            ++testNo;
141            System.out.println(" Test#" + testNo +
142                ": RUN_DIRECTION_LTR, BIDI_EMBEDDING(1)");
143            astr = new AttributedString(paragraph);
144            astr.addAttribute(TextAttribute.RUN_DIRECTION,
145                              TextAttribute.RUN_DIRECTION_LTR);
146            astr.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(1),
147                              start, limit);
148            bidi = new Bidi(astr.getIterator());
149            callTestEachMethod4Constructor1(textNo, testNo, bidi);
150
151            // Test 2
152            ++testNo;
153            System.out.println(" Test#" + testNo +
154                ": RUN_DIERCTION_LTR, BIDI_EMBEDDING(2)");
155            astr = new AttributedString(paragraph);
156            astr.addAttribute(TextAttribute.RUN_DIRECTION,
157                              TextAttribute.RUN_DIRECTION_LTR);
158            astr.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(2),
159                              start, limit);
160            bidi = new Bidi(astr.getIterator());
161            callTestEachMethod4Constructor1(textNo, testNo, bidi);
162
163            // Test 3
164            ++testNo;
165            System.out.println(" Test#" + testNo +
166                ": RUN_DIRECTIOIN_LTR, BIDI_EMBEDDING(-3)");
167            astr = new AttributedString(paragraph);
168            astr.addAttribute(TextAttribute.RUN_DIRECTION,
169                              TextAttribute.RUN_DIRECTION_LTR);
170            astr.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(-3),
171                              start, limit);
172            bidi = new Bidi(astr.getIterator());
173            callTestEachMethod4Constructor1(textNo, testNo, bidi);
174
175            // Test 4
176            ++testNo;
177            System.out.println(" Test#" + testNo +
178                ": RUN_DIRECTION_LTR, BIDI_EMBEDDING(-4)");
179            astr = new AttributedString(paragraph);
180            astr.addAttribute(TextAttribute.RUN_DIRECTION,
181                              TextAttribute.RUN_DIRECTION_LTR);
182            astr.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(-4),
183                              start, limit);
184            bidi = new Bidi(astr.getIterator());
185            callTestEachMethod4Constructor1(textNo, testNo, bidi);
186
187            // Test 5
188            ++testNo;
189            System.out.println(" Test#" + testNo + ": RUN_DIRECTION_RTL");
190            astr = new AttributedString(paragraph);
191            astr.addAttribute(TextAttribute.RUN_DIRECTION,
192                              TextAttribute.RUN_DIRECTION_RTL);
193            bidi = new Bidi(astr.getIterator());
194            callTestEachMethod4Constructor1(textNo, testNo, bidi);
195
196            // Test 6
197            ++testNo;
198            System.out.println(" Test#" + testNo +
199                ": RUN_DIRECTION_RTL, BIDI_EMBEDDING(1)");
200            astr = new AttributedString(paragraph);
201            astr.addAttribute(TextAttribute.RUN_DIRECTION,
202                              TextAttribute.RUN_DIRECTION_RTL);
203            astr.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(1),
204                              start, limit);
205            try {
206                bidi = new Bidi(astr.getIterator());
207                callTestEachMethod4Constructor1(textNo, testNo, bidi);
208            }
209            catch (IllegalArgumentException e) {
210                errorHandling("  Unexpected exception: " + e);
211            }
212
213            // Test 7
214            ++testNo;
215            System.out.println(" Test#" + testNo +
216                ": RUN_DIRECTION_RTL, BIDI_EMBEDDING(2)");
217            astr = new AttributedString(paragraph);
218            astr.addAttribute(TextAttribute.RUN_DIRECTION,
219                              TextAttribute.RUN_DIRECTION_RTL);
220            astr.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(2),
221                              start, limit);
222            try {
223                bidi = new Bidi(astr.getIterator());
224                callTestEachMethod4Constructor1(textNo, testNo, bidi);
225            }
226            catch (IllegalArgumentException e) {
227                errorHandling("  Unexpected exception: " + e);
228            }
229
230            // Test 8
231            ++testNo;
232            System.out.println(" Test#" + testNo +
233                ": RUN_DIRECTION_RTL, BIDI_EMBEDDING(-3)");
234            astr = new AttributedString(paragraph);
235            astr.addAttribute(TextAttribute.RUN_DIRECTION,
236                              TextAttribute.RUN_DIRECTION_RTL);
237            astr.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(-3),
238                              start, limit);
239            try {
240                bidi = new Bidi(astr.getIterator());
241                callTestEachMethod4Constructor1(textNo, testNo, bidi);
242            }
243            catch (IllegalArgumentException e) {
244                errorHandling("  Unexpected exception: " + e);
245            }
246
247            // Test 9
248            ++testNo;
249            System.out.println(" Test#" + testNo +
250                ": RUN_DIRECTION_RTL, BIDI_EMBEDDING(-4)");
251            astr = new AttributedString(paragraph);
252            astr.addAttribute(TextAttribute.RUN_DIRECTION,
253                              TextAttribute.RUN_DIRECTION_RTL);
254            astr.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(-4),
255                              start, limit);
256            try {
257                bidi = new Bidi(astr.getIterator());
258                callTestEachMethod4Constructor1(textNo, testNo, bidi);
259            }
260            catch (IllegalArgumentException e) {
261                errorHandling("  Unexpected exception: " + e);
262            }
263
264            // Test 10
265            ++testNo;
266            System.out.println(" Test#" + testNo +
267                ": TextAttribute not specified");
268            astr = new AttributedString(paragraph);
269            bidi = new Bidi(astr.getIterator());
270            callTestEachMethod4Constructor1(textNo, testNo, bidi);
271
272            // Test 11
273            ++testNo;
274            System.out.println(" Test#" + testNo +
275                ": RUN_DIRECTION_LTR, NUMERIC_SHAPING(ARABIC)");
276            astr = new AttributedString(paragraph);
277            astr.addAttribute(TextAttribute.RUN_DIRECTION,
278                              TextAttribute.RUN_DIRECTION_LTR);
279            astr.addAttribute(TextAttribute.NUMERIC_SHAPING, ns);
280            bidi = new Bidi(astr.getIterator());
281            callTestEachMethod4Constructor1(textNo, testNo, bidi);
282
283            // Test 12
284            ++testNo;
285            System.out.println(" Test#" + testNo +
286                 ": RUN_DIRECTION_RTL, NUMERIC_SHAPING(ARABIC)");
287            astr = new AttributedString(paragraph);
288            astr.addAttribute(TextAttribute.RUN_DIRECTION,
289                              TextAttribute.RUN_DIRECTION_RTL);
290            astr.addAttribute(TextAttribute.NUMERIC_SHAPING, ns);
291            bidi = new Bidi(astr.getIterator());
292            callTestEachMethod4Constructor1(textNo, testNo, bidi);
293        }
294    }
295
296    private void testMethods4Constructor2() {
297        System.out.println("*** Test methods for constructor 2");
298
299        String paragraph;
300        Bidi bidi;
301
302        for (int textNo = 0; textNo < data4Constructor2.length; textNo++) {
303            paragraph = data4Constructor2[textNo][0];
304            for (int flagNo = 0; flagNo < FLAGS.length; flagNo++) {
305                int flag = FLAGS[flagNo];
306
307                System.out.println("*** Test textNo=" + textNo +
308                    ": Bidi(\"" + toReadableString(paragraph) +
309                    "\", " + getFlagName(flag) + ")");
310
311                bidi = new Bidi(paragraph, flag);
312                callTestEachMethod4Constructor2(textNo, flagNo, bidi);
313            }
314        }
315    }
316
317    private void testMethods4Constructor3() {
318        System.out.println("*** Test methods for constructor 3");
319
320        String paragraph;
321        Bidi bidi;
322
323        for (int textNo = 0; textNo < data4Constructor3.length; textNo++) {
324            paragraph = data4Constructor3[textNo][0];
325            char[] c = paragraph.toCharArray();
326            int start = paragraph.indexOf('<')+1;
327            byte[][] embeddings = (c.length < emb4Constructor3[1][0].length) ?
328                                  emb4Constructor3[0] : emb4Constructor3[1];
329            for (int flagNo = 0; flagNo < FLAGS.length; flagNo++) {
330                int flag = FLAGS[flagNo];
331                for (int embNo = 0; embNo < embeddings.length; embNo++) {
332                    int dataNo = flagNo * FLAGS.length + embNo;
333
334                    System.out.println("*** Test textNo=" + textNo +
335                        ": Bidi(char[]\"" + toReadableString(paragraph) +
336                        "\", 0, embeddings={" + toString(embeddings[embNo]) +
337                        "}, " + c.length + ", " +
338                       getFlagName(flag) + ")" + "  dataNo=" + dataNo);
339
340                    try {
341                        bidi = new Bidi(c, 0, embeddings[embNo], 0,
342                                        c.length, flag);
343                        callTestEachMethod4Constructor3(textNo, dataNo, bidi);
344                    }
345                    catch (Exception e) {
346                        errorHandling("  Unexpected exception: " + e);
347                    }
348                }
349            }
350        }
351    }
352
353    private void testConstructor1() {
354        Bidi bidi;
355
356        try {
357            bidi = new Bidi(null);
358            errorHandling("Bidi((AttributedCharacterIterator)null) " +
359                "should throw an IAE.");
360        }
361        catch (IllegalArgumentException e) {
362        }
363        catch (NullPointerException e) {
364            errorHandling("Bidi((AttributedCharacterIterator)null) " +
365                "should not throw an NPE but an IAE.");
366        }
367
368        String paragraph = data4Constructor1[1][0];
369        int start = paragraph.indexOf('<')+1;
370        int limit = paragraph.indexOf('>');
371        AttributedString astr = new AttributedString(paragraph);
372        astr.addAttribute(TextAttribute.RUN_DIRECTION,
373                          TextAttribute.RUN_DIRECTION_RTL);
374        astr.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(-MAX_EXPLICIT_LEVEL),
375                          start, limit);
376        try {
377            bidi = new Bidi(astr.getIterator());
378            for (int i = start; i < limit; i++) {
379                if (bidi.getLevelAt(i) != MAX_EXPLICIT_LEVEL) {
380                    errorHandling("Bidi(AttributedCharacterIterator).getLevelAt(" +
381                        i + ") should not be " + bidi.getLevelAt(i) +
382                        " but MAX_EXPLICIT_LEVEL-1 when BIDI_EMBEDDING is -MAX_EXPLICIT_LEVEL.");
383                }
384            }
385        }
386        catch (Exception e) {
387            errorHandling("  Unexpected exception: " + e);
388        }
389
390        astr = new AttributedString(paragraph);
391        astr.addAttribute(TextAttribute.RUN_DIRECTION,
392                          TextAttribute.RUN_DIRECTION_RTL);
393        astr.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(-(MAX_EXPLICIT_LEVEL+1)),
394                          start, limit);
395        try {
396            bidi = new Bidi(astr.getIterator());
397            for (int i = start; i < limit; i++) {
398                if (bidi.getLevelAt(i) != 1) {
399                    errorHandling("Bidi(AttributedCharacterIterator).getLevelAt() " +
400                        "should be 1 when BIDI_EMBEDDING is -(MAX_EXPLICIT_LEVEL+1).");
401                }
402            }
403        }
404        catch (Exception e) {
405            errorHandling("  Unexpected exception: " + e);
406        }
407
408        astr = new AttributedString(paragraph);
409        astr.addAttribute(TextAttribute.RUN_DIRECTION,
410                          TextAttribute.RUN_DIRECTION_RTL);
411        astr.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(MAX_EXPLICIT_LEVEL-1),
412                          start, limit);
413        try {
414            bidi = new Bidi(astr.getIterator());
415            for (int i = start; i < limit; i++) {
416                if (bidi.getLevelAt(i) != MAX_EXPLICIT_LEVEL) {
417                    errorHandling("Bidi(AttributedCharacterIterator).getLevelAt() " +
418                        "should be MAX_EXPLICIT_LEVEL when BIDI_EMBEDDING is MAX_EXPLICIT_LEVEL-1.");
419                }
420            }
421        }
422        catch (Exception e) {
423            errorHandling("  Unexpected exception: " + e);
424        }
425
426        astr = new AttributedString(paragraph);
427        astr.addAttribute(TextAttribute.RUN_DIRECTION,
428                          TextAttribute.RUN_DIRECTION_RTL);
429        astr.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(MAX_EXPLICIT_LEVEL),
430                          start, limit);
431        try {
432            bidi = new Bidi(astr.getIterator());
433            for (int i = start; i < limit; i++) {
434                if (bidi.getLevelAt(i) != MAX_EXPLICIT_LEVEL) {
435                    errorHandling("Bidi(AttributedCharacterIterator).getLevelAt(" +
436                        i + ") should not be " + bidi.getLevelAt(i) +
437                        " but MAX_EXPLICIT_LEVEL when BIDI_EMBEDDING is MAX_EXPLICIT_LEVEL.");
438                }
439            }
440        }
441        catch (Exception e) {
442            errorHandling("  Unexpected exception: " + e);
443        }
444
445        astr = new AttributedString(paragraph);
446        astr.addAttribute(TextAttribute.RUN_DIRECTION,
447                          TextAttribute.RUN_DIRECTION_RTL);
448        astr.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(MAX_EXPLICIT_LEVEL+1),
449                          start, limit);
450        try {
451            bidi = new Bidi(astr.getIterator());
452            for (int i = start; i < limit; i++) {
453                if (bidi.getLevelAt(i) != 1) {
454                    errorHandling("Bidi(AttributedCharacterIterator).getLevelAt(" +
455                         i + ") should not be " + bidi.getLevelAt(i) +
456                        " but 1 when BIDI_EMBEDDING is MAX_EXPLICIT_LEVEL+1.");
457                }
458            }
459        }
460        catch (Exception e) {
461            errorHandling("  Unexpected exception: " + e);
462        }
463    }
464
465    private void testConstructor2() {
466        Bidi bidi;
467
468        try {
469            bidi = new Bidi(null, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
470            errorHandling("Bidi((String)null, DIRECTION_DEFAULT_LEFT_TO_RIGHT)" +
471                " should throw an IAE.");
472        }
473        catch (IllegalArgumentException e) {
474        }
475        catch (NullPointerException e) {
476            errorHandling("Bidi((String)null, DIRECTION_DEFAULT_LEFT_TO_RIGHT) " +
477                "should not throw an NPE but an IAE.");
478        }
479
480        try {
481            bidi = new Bidi("abc", -3);
482        }
483        catch (Exception e) {
484            errorHandling("Bidi(\"abc\", -3) should not throw an exception: " +
485                e);
486        }
487
488        try {
489            bidi = new Bidi("abc", 2);
490        }
491        catch (Exception e) {
492            errorHandling("Bidi(\"abc\", 2) should not throw an exception: " +
493                e);
494        }
495    }
496
497    private void testConstructor3() {
498        char[] text = {'a', 'b', 'c', 'd', 'e'};
499        byte[] embeddings = {0, 0, 0, 0, 0};
500        Bidi bidi;
501
502        try {
503            bidi = new Bidi(null, 0, embeddings, 0, 5,
504                            Bidi.DIRECTION_LEFT_TO_RIGHT);
505            errorHandling("Bidi(char[], ...) should throw an IAE " +
506                "when text=null.");
507        }
508        catch (IllegalArgumentException e) {
509        }
510        catch (NullPointerException e) {
511            errorHandling("Bidi(char[], ...) should not throw an NPE " +
512                "but an IAE when text=null.");
513        }
514
515        try {
516            bidi = new Bidi(text, -1, embeddings, 0, 5,
517                            Bidi.DIRECTION_LEFT_TO_RIGHT);
518            errorHandling("Bidi(char[], ...) should throw an IAE " +
519                "when textStart is incorrect(-1: too small).");
520        }
521        catch (IllegalArgumentException e) {
522        }
523        catch (ArrayIndexOutOfBoundsException e) {
524            errorHandling("Bidi(char[], ...) should not throw an NPE " +
525                "but an IAE when textStart is incorrect(-1: too small).");
526        }
527
528        try {
529            bidi = new Bidi(text, 4, embeddings, 0, 2,
530                            Bidi.DIRECTION_LEFT_TO_RIGHT);
531            errorHandling("Bidi(char[], ...) should throw an IAE " +
532                "when textStart is incorrect(4: too large).");
533        }
534        catch (IllegalArgumentException e) {
535        }
536        catch (ArrayIndexOutOfBoundsException e) {
537            errorHandling("Bidi(char[], ...) should not throw an NPE " +
538                "but an IAE when textStart is incorrect(4: too large).");
539        }
540
541        byte[] actualLevels = new byte[text.length];
542        byte[] validEmbeddings1 = {0, -MAX_EXPLICIT_LEVEL, -(MAX_EXPLICIT_LEVEL-1), -2, -1};
543        byte[] expectedLevels1  = {0,  MAX_EXPLICIT_LEVEL,  MAX_EXPLICIT_LEVEL-1,  2,  1};
544        try {
545            bidi = new Bidi(text, 0, validEmbeddings1, 0, 5,
546                            Bidi.DIRECTION_LEFT_TO_RIGHT);
547            for (int i = 0; i < text.length; i++) {
548                actualLevels[i] = (byte)bidi.getLevelAt(i);
549            }
550            if (!Arrays.equals(expectedLevels1, actualLevels)) {
551                errorHandling("Bidi(char[], ...).getLevelAt()" +
552                    " should be {" + toString(actualLevels) +
553                    "} when embeddings are {" +
554                    toString(expectedLevels1) + "}.");
555            }
556        }
557        catch (Exception e) {
558            errorHandling("Bidi(char[], ...) should not throw an exception " +
559                "when embeddings is valid(-MAX_EXPLICIT_LEVEL).");
560        }
561
562        byte[] validEmbeddings2 = {0,  MAX_EXPLICIT_LEVEL,  MAX_EXPLICIT_LEVEL-1,  2,  1};
563        byte[] expectedLevels2  = {0,  MAX_EXPLICIT_LEVEL+1,  MAX_EXPLICIT_LEVEL-1,  2,  2};
564        try {
565            bidi = new Bidi(text, 0, validEmbeddings2, 0, 5,
566                            Bidi.DIRECTION_LEFT_TO_RIGHT);
567            for (int i = 0; i < text.length; i++) {
568                actualLevels[i] = (byte)bidi.getLevelAt(i);
569            }
570            if (!Arrays.equals(expectedLevels2, actualLevels)) {
571                errorHandling("Bidi(char[], ...).getLevelAt()" +
572                    " should be {" + toString(actualLevels) +
573                    "} when embeddings are {" +
574                    toString(expectedLevels2) + "}.");
575            }
576        }
577        catch (Exception e) {
578            errorHandling("Bidi(char[], ...) should not throw an exception " +
579                "when embeddings is valid(MAX_EXPLICIT_LEVEL).");
580        }
581
582        byte[] invalidEmbeddings1 = {0, -(MAX_EXPLICIT_LEVEL+1), 0, 0, 0};
583        try {
584            bidi = new Bidi(text, 0, invalidEmbeddings1, 0, 5,
585                            Bidi.DIRECTION_LEFT_TO_RIGHT);
586            if (bidi.getLevelAt(1) != 0) {
587                errorHandling("Bidi(char[], ...).getLevelAt(1) should be 0 " +
588                    "when embeddings[1] is -(MAX_EXPLICIT_LEVEL+1).");
589            }
590        }
591        catch (Exception e) {
592            errorHandling("Bidi(char[], ...) should not throw an exception " +
593                "even when embeddings includes -(MAX_EXPLICIT_LEVEL+1).");
594        }
595
596        byte[] invalidEmbeddings2 = {0, MAX_EXPLICIT_LEVEL+1, 0, 0, 0};
597        try {
598            bidi = new Bidi(text, 0, invalidEmbeddings2, 0, 5,
599                            Bidi.DIRECTION_LEFT_TO_RIGHT);
600            if (bidi.getLevelAt(1) != 0) {
601                errorHandling("Bidi(char[], ...).getLevelAt(1) should be 0 " +
602                    "when embeddings[1] is MAX_EXPLICIT_LEVEL+1.");
603            }
604        }
605        catch (Exception e) {
606            errorHandling("Bidi(char[], ...) should not throw an exception " +
607                "even when embeddings includes MAX_EXPLICIT_LEVEL+1.");
608        }
609
610        try {
611            bidi = new Bidi(text, 0, embeddings, 0, -1,
612                            Bidi.DIRECTION_LEFT_TO_RIGHT);
613            errorHandling("Bidi(char[], ...) should throw an IAE " +
614                "when paragraphLength=-1(too small).");
615        }
616        catch (IllegalArgumentException e) {
617        }
618        catch (NegativeArraySizeException e) {
619            errorHandling("Bidi(char[], ...) should not throw an NASE " +
620                "but an IAE when paragraphLength=-1(too small).");
621        }
622
623        try {
624            bidi = new Bidi(text, 0, embeddings, 0, 6,
625                            Bidi.DIRECTION_LEFT_TO_RIGHT);
626            errorHandling("Bidi(char[], ...) should throw an IAE " +
627                "when paragraphLength=6(too large).");
628        }
629        catch (IllegalArgumentException e) {
630        }
631        catch (ArrayIndexOutOfBoundsException e) {
632            errorHandling("Bidi(char[], ...) should not throw an AIOoBE " +
633                "but an IAE when paragraphLength=6(too large).");
634        }
635
636        try {
637            bidi = new Bidi(text, 0, embeddings, 0, 4, -3);
638        }
639        catch (Exception e) {
640            errorHandling("Bidi(char[], ...) should not throw an exception " +
641                "even when flag=-3(too small).");
642        }
643
644        try {
645            bidi = new Bidi(text, 0, embeddings, 0, 5, 2);
646        }
647        catch (Exception e) {
648            errorHandling("Bidi(char[], ...) should not throw an exception " +
649                "even when flag=2(too large).");
650        }
651    }
652
653    private void callTestEachMethod4Constructor1(int textNo,
654                                                 int testNo,
655                                                 Bidi bidi) {
656        testEachMethod(bidi,
657                       data4Constructor1[textNo][0],
658                       data4Constructor1[textNo][testNo+1],
659                       baseIsLTR4Constructor1[textNo][testNo],
660                       isLTR_isRTL4Constructor1[textNo][0][testNo],
661                       isLTR_isRTL4Constructor1[textNo][1][testNo]);
662    }
663
664    private void callTestEachMethod4Constructor2(int textNo,
665                                                 int flagNo,
666                                                 Bidi bidi) {
667        testEachMethod(bidi,
668                       data4Constructor2[textNo][0],
669                       data4Constructor2[textNo][flagNo+1],
670                       baseIsLTR4Constructor2[textNo][flagNo],
671                       isLTR_isRTL4Constructor2[textNo][0][flagNo],
672                       isLTR_isRTL4Constructor2[textNo][1][flagNo]);
673    }
674
675    private void callTestEachMethod4Constructor3(int textNo,
676                                                 int dataNo,
677                                                 Bidi bidi) {
678        testEachMethod(bidi,
679                       data4Constructor3[textNo][0],
680                       data4Constructor3[textNo][dataNo+1],
681                       baseIsLTR4Constructor3[textNo][dataNo],
682                       isLTR_isRTL4Constructor3[textNo][0][dataNo],
683                       isLTR_isRTL4Constructor3[textNo][1][dataNo]);
684    }
685
686    private StringBuilder sb = new StringBuilder();
687    private void testEachMethod(Bidi bidi,
688                                String text,
689                                String expectedLevels,
690                                boolean expectedBaseIsLTR,
691                                boolean expectedIsLTR,
692                                boolean expectedIsRTL
693                               ) {
694        /* Test baseIsLeftToRight() */
695        boolean actualBoolean = bidi.baseIsLeftToRight();
696        checkResult("baseIsLeftToRight()", expectedBaseIsLTR, actualBoolean);
697
698        /* Test getBaseLevel() */
699        int expectedInt = (expectedBaseIsLTR) ? 0 : 1;
700        int actualInt = bidi.getBaseLevel();
701        checkResult("getBaseLevel()", expectedInt, actualInt);
702
703        /* Test getLength() */
704        expectedInt = text.length();
705        actualInt = bidi.getLength();
706        checkResult("getLength()", expectedInt, actualInt);
707
708        /* Test getLevelAt() */
709        sb.setLength(0);
710        for (int i = 0; i < text.length(); i++) {
711            sb.append(bidi.getLevelAt(i));
712        }
713        checkResult("getLevelAt()", expectedLevels, sb.toString());
714
715        /* Test getRunCount() */
716        expectedInt = getRunCount(expectedLevels);
717        actualInt = bidi.getRunCount();
718        checkResult("getRunCount()", expectedInt, actualInt);
719
720        /* Test getRunLevel(), getRunLimit() and getRunStart() */
721        if (expectedInt == actualInt) {
722            int runCount = expectedInt;
723            int[] expectedRunLevels = getRunLevels_int(runCount, expectedLevels);
724            int[] expectedRunLimits = getRunLimits(runCount, expectedLevels);
725            int[] expectedRunStarts = getRunStarts(runCount, expectedLevels);
726            int[] actualRunLevels = new int[runCount];
727            int[] actualRunLimits = new int[runCount];
728            int[] actualRunStarts = new int[runCount];
729
730            for (int k = 0; k < runCount; k++) {
731                actualRunLevels[k] = bidi.getRunLevel(k);
732                actualRunLimits[k] = bidi.getRunLimit(k);
733                actualRunStarts[k] = bidi.getRunStart(k);
734            }
735
736            checkResult("getRunLevel()", expectedRunLevels, actualRunLevels);
737            checkResult("getRunStart()", expectedRunStarts, actualRunStarts);
738            checkResult("getRunLimit()", expectedRunLimits, actualRunLimits);
739        }
740
741        /* Test isLeftToRight() */
742        boolean expectedBoolean = expectedIsLTR;
743        actualBoolean = bidi.isLeftToRight();
744        checkResult("isLeftToRight()", expectedBoolean, actualBoolean);
745
746        /* Test isMixed() */
747        expectedBoolean = !(expectedIsLTR || expectedIsRTL);
748        actualBoolean = bidi.isMixed();
749        checkResult("isMixed()", expectedBoolean, actualBoolean);
750
751        /* Test isRightToLeft() */
752        expectedBoolean = expectedIsRTL;
753        actualBoolean = bidi.isRightToLeft();
754        checkResult("isRightToLeft()", expectedBoolean, actualBoolean);
755    }
756
757    private int getRunCount(String levels) {
758        int len = levels.length();
759        char c = levels.charAt(0);
760        int runCount = 1;
761
762        for (int index = 1; index < len; index++) {
763            if (levels.charAt(index) != c) {
764                runCount++;
765                c = levels.charAt(index);
766            }
767        }
768
769        return runCount;
770    }
771
772    private int[] getRunLevels_int(int runCount, String levels) {
773        int[] array = new int[runCount];
774        int len = levels.length();
775        char c = levels.charAt(0);
776        int i = 0;
777        array[i++] = c - '0';
778
779        for (int index = 1; index < len; index++) {
780            if (levels.charAt(index) != c) {
781                c = levels.charAt(index);
782                array[i++] = c - '0';
783            }
784        }
785
786        return array;
787    }
788
789    private byte[] getRunLevels_byte(int runCount, String levels) {
790        byte[] array = new byte[runCount];
791        int len = levels.length();
792        char c = levels.charAt(0);
793        int i = 0;
794        array[i++] = (byte)(c - '0');
795
796        for (int index = 1; index < len; index++) {
797            if (levels.charAt(index) != c) {
798                c = levels.charAt(index);
799                array[i++] = (byte)(c - '0');
800            }
801        }
802
803        return array;
804    }
805
806    private int[] getRunLimits(int runCount, String levels) {
807        int[] array = new int[runCount];
808        int len = levels.length();
809        char c = levels.charAt(0);
810        int i = 0;
811
812        for (int index = 1; index < len; index++) {
813            if (levels.charAt(index) != c) {
814                c = levels.charAt(index);
815                array[i++] = index;
816            }
817        }
818        array[i] = len;
819
820        return array;
821    }
822
823    private int[] getRunStarts(int runCount, String levels) {
824        int[] array = new int[runCount];
825        int len = levels.length();
826        char c = levels.charAt(0);
827        int i = 1;
828
829        for (int index = 1; index < len; index++) {
830            if (levels.charAt(index) != c) {
831                c = levels.charAt(index);
832                array[i++] = index;
833            }
834        }
835
836        return array;
837    }
838
839    private String[] getObjects(int runCount, String text, String levels) {
840        String[] array = new String[runCount];
841        int[] runLimits = getRunLimits(runCount, levels);
842        int runStart = 0;
843
844        for (int i = 0; i < runCount; i++) {
845            array[i] = text.substring(runStart, runLimits[i]);
846            runStart = runLimits[i];
847        }
848
849        return array;
850    }
851
852    private void testMethod_createLineBidi1() {
853        System.out.println("*** Test createLineBidi() 1");
854
855        String str = " ABC 123. " + HebrewABC + " " + NKo123 + ". ABC 123";
856
857        int lineStart = str.indexOf('.') + 2;
858        int lineLimit = str.lastIndexOf('.') + 2;
859        Bidi bidi = new Bidi(str, FLAGS[0]);
860        Bidi lineBidi = bidi.createLineBidi(lineStart, lineLimit);
861
862        checkResult("getBaseLevel()",
863            bidi.getBaseLevel(), lineBidi.getBaseLevel());
864        checkResult("getLevelAt(5)",
865            bidi.getLevelAt(lineStart+5), lineBidi.getLevelAt(5));
866    }
867
868    private void testMethod_createLineBidi2() {
869        System.out.println("*** Test createLineBidi() 2");
870
871        Bidi bidi = new Bidi(data4Constructor1[0][0], FLAGS[0]);
872        int len = data4Constructor1[0][0].length();
873
874        try {
875            Bidi lineBidi = bidi.createLineBidi(0, len);
876        }
877        catch (Exception e) {
878            errorHandling("createLineBidi(0, textLength)" +
879                " should not throw an exception.");
880        }
881
882        try {
883            Bidi lineBidi = bidi.createLineBidi(-1, len);
884            errorHandling("createLineBidi(-1, textLength)" +
885                " should throw an IAE.");
886        }
887        catch (IllegalArgumentException e) {
888        }
889
890        try {
891            Bidi lineBidi = bidi.createLineBidi(0, len+1);
892            errorHandling("createLineBidi(0, textLength+1)" +
893                " should throw an IAE.");
894        }
895        catch (IllegalArgumentException e) {
896        }
897    }
898
899    /*
900     * Confirm that getLevelAt() doesn't throw an exception for invalid offset
901     * unlike ICU4J.
902     */
903    private void testMethod_getLevelAt() {
904        System.out.println("*** Test getLevelAt()");
905
906        Bidi bidi = new Bidi(data4Constructor1[1][0], FLAGS[0]);
907        int len = data4Constructor1[1][0].length();
908
909        try {
910            int level = bidi.getLevelAt(-1);
911            if (level != bidi.getBaseLevel()) {
912                errorHandling("getLevelAt(-1) returned a wrong level." +
913                    " Expected=" + bidi.getBaseLevel() + ", got=" + level);
914            }
915        }
916        catch (Exception e) {
917            errorHandling("getLevelAt(-1) should not throw an exception.");
918        }
919
920        try {
921            int level = bidi.getLevelAt(len+1);
922            if (level != bidi.getBaseLevel()) {
923                errorHandling("getLevelAt(textLength+1)" +
924                    " returned a wrong level." +
925                    " Expected=" + bidi.getBaseLevel() + ", got=" + level);
926            }
927        }
928        catch (Exception e) {
929            errorHandling("getLevelAt(-1) should not throw an exception.");
930        }
931    }
932
933    private void testMethod_getRunLevel() {
934        System.out.println("*** Test getRunLevel()");
935
936        String str = "ABC 123";
937        Bidi bidi = new Bidi(str, Bidi.DIRECTION_LEFT_TO_RIGHT);
938        try {
939            if (bidi.getRunLevel(-1) != 0 ||  // runCount - 2 (out of range)
940                bidi.getRunLevel(0) != 0 ||   // runCount - 1
941                bidi.getRunLevel(1) != 0 ||   // runCount     (out of range)
942                bidi.getRunLevel(2) != 0) {   // runCount + 1 (out of range)
943                errorHandling("Incorrect getRunLevel() value(s).");
944            }
945        }
946        catch (Exception e) {
947            errorHandling("getRunLevel() should not throw an exception: " + e);
948        }
949
950        str = "ABC " + HebrewABC + " 123";
951        bidi = new Bidi(str, Bidi.DIRECTION_LEFT_TO_RIGHT);
952        try {
953            if (bidi.getRunLevel(-1) != 0 ||  // runCount - 4 (out of range)
954                bidi.getRunLevel(0) != 0 ||   // runCount - 3
955                bidi.getRunLevel(1) != 1 ||   // runCount - 2
956                bidi.getRunLevel(2) != 2 ||   // runCount - 1
957                bidi.getRunLevel(3) != 0 ||   // runCount     (out of range)
958                bidi.getRunLevel(4) != 0) {   // runCount + 1 (out of range)
959                errorHandling("Incorrect getRunLevel() value(s).");
960            }
961        }
962        catch (Exception e) {
963            errorHandling("getRunLevel() should not throw an exception: " + e);
964        }
965
966        str = "ABC";
967        bidi = new Bidi(str, Bidi.DIRECTION_LEFT_TO_RIGHT);
968        try {
969            if (bidi.getRunLevel(-1) != 0 ||  // runCount - 2 (out of range)
970                bidi.getRunLevel(0) != 0 ||   // runCount - 1
971                bidi.getRunLevel(1) != 0 ||   // runCount     (out of range)
972                bidi.getRunLevel(2) != 0) {   // runCount + 1 (out of range)
973                errorHandling("Incorrect getRunLevel() value(s).");
974            }
975        }
976        catch (Exception e) {
977            errorHandling("getRunLevel() should not throw an exception: " + e);
978        }
979
980        str = "ABC";
981        bidi = new Bidi(str, Bidi.DIRECTION_RIGHT_TO_LEFT);
982        try {
983            if (bidi.getRunLevel(-1) != 1 ||  // runCount - 2 (out of range)
984                bidi.getRunLevel(0) != 2 ||   // runCount - 1
985                bidi.getRunLevel(1) != 1 ||   // runCount     (out of range)
986                bidi.getRunLevel(2) != 1) {   // runCount + 1 (out of range)
987                errorHandling("Incorrect getRunLevel() value(s).");
988            }
989        }
990        catch (Exception e) {
991            errorHandling("getRunLevel() should not throw an exception: " + e);
992        }
993
994        str = "ABC";
995        bidi = new Bidi(str, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
996        try {
997            if (bidi.getRunLevel(-1) != 0 ||  // runCount - 2 (out of range)
998                bidi.getRunLevel(0) != 0 ||   // runCount - 1
999                bidi.getRunLevel(1) != 0 ||   // runCount     (out of range)
1000                bidi.getRunLevel(2) != 0) {   // runCount + 1 (out of range)
1001                errorHandling("Incorrect getRunLevel() value(s).");
1002            }
1003        }
1004        catch (Exception e) {
1005            errorHandling("getRunLevel() should not throw an exception: " + e);
1006        }
1007
1008        str = "ABC";
1009        bidi = new Bidi(str, Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
1010        try {
1011            if (bidi.getRunLevel(-1) != 0 ||  // runCount - 2 (out of range)
1012                bidi.getRunLevel(0) != 0 ||   // runCount - 1
1013                bidi.getRunLevel(1) != 0 ||   // runCount     (out of range)
1014                bidi.getRunLevel(2) != 0) {   // runCount + 1 (out of range)
1015                errorHandling("Incorrect getRunLevel() value(s).");
1016            }
1017        }
1018        catch (Exception e) {
1019            errorHandling("getRunLevel() should not throw an exception: " + e);
1020        }
1021
1022        str = HebrewABC;
1023        bidi = new Bidi(str, Bidi.DIRECTION_LEFT_TO_RIGHT);
1024        try {
1025            if (bidi.getRunLevel(-1) != 0 ||  // runCount - 2 (out of range)
1026                bidi.getRunLevel(0) != 1 ||   // runCount - 1
1027                bidi.getRunLevel(1) != 0 ||   // runCount     (out of range)
1028                bidi.getRunLevel(2) != 0) {   // runCount + 1 (out of range)
1029                errorHandling("Incorrect getRunLevel() value(s).");
1030            }
1031        }
1032        catch (Exception e) {
1033            errorHandling("getRunLevel() should not throw an exception: " + e);
1034        }
1035
1036        str = HebrewABC;
1037        bidi = new Bidi(str, Bidi.DIRECTION_RIGHT_TO_LEFT);
1038        try {
1039            if (bidi.getRunLevel(-1) != 1 ||  // runCount - 2 (out of range)
1040                bidi.getRunLevel(0) != 1 ||   // runCount - 1
1041                bidi.getRunLevel(1) != 1 ||   // runCount     (out of range)
1042                bidi.getRunLevel(2) != 1) {   // runCount + 1 (out of range)
1043                errorHandling("Incorrect getRunLevel() value(s).");
1044            }
1045        }
1046        catch (Exception e) {
1047            errorHandling("getRunLevel() should not throw an exception: " + e);
1048        }
1049
1050        str = HebrewABC;
1051        bidi = new Bidi(str, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
1052        try {
1053            if (bidi.getRunLevel(-1) != 1 ||  // runCount - 2 (out of range)
1054                bidi.getRunLevel(0) != 1 ||   // runCount - 1
1055                bidi.getRunLevel(1) != 1 ||   // runCount     (out of range)
1056                bidi.getRunLevel(2) != 1) {   // runCount + 1 (out of range)
1057                errorHandling("Incorrect getRunLevel() value(s).");
1058            }
1059        }
1060        catch (Exception e) {
1061            errorHandling("getRunLevel() should not throw an exception: " + e);
1062        }
1063
1064        str = HebrewABC;
1065        bidi = new Bidi(str, Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
1066        try {
1067            if (bidi.getRunLevel(-1) != 1 ||  // runCount - 2 (out of range)
1068                bidi.getRunLevel(0) != 1 ||   // runCount - 1
1069                bidi.getRunLevel(1) != 1 ||   // runCount     (out of range)
1070                bidi.getRunLevel(2) != 1) {   // runCount + 1 (out of range)
1071                errorHandling("Incorrect getRunLevel() value(s).");
1072            }
1073        }
1074        catch (Exception e) {
1075            errorHandling("getRunLevel() should not throw an exception: " + e);
1076        }
1077    }
1078
1079    private void testMethod_getRunLimit() {
1080        System.out.println("*** Test getRunLimit()");
1081
1082        String str = "ABC 123";
1083        int length = str.length();
1084        Bidi bidi = new Bidi(str, Bidi.DIRECTION_LEFT_TO_RIGHT);
1085
1086        try {
1087            if (bidi.getRunLimit(-1) != length ||  // runCount - 2
1088                bidi.getRunLimit(0) != length ||   // runCount - 1
1089                bidi.getRunLimit(1) != length ||   // runCount
1090                bidi.getRunLimit(2) != length) {   // runCount + 1
1091                errorHandling("getRunLimit() should return " + length +
1092                    " when getRunCount() is 1.");
1093            }
1094        }
1095        catch (Exception e) {
1096            errorHandling("getRunLimit() should not throw an exception " +
1097                "when getRunCount() is 1.");
1098        }
1099
1100        str = "ABC " + ArabicABC + " 123";
1101        length = str.length();
1102        bidi = new Bidi(str, Bidi.DIRECTION_LEFT_TO_RIGHT);
1103
1104        try {
1105            bidi.getRunLimit(-1);
1106            errorHandling("getRunLimit() should throw an AIOoBE " +
1107                "when run is -1(too small).");
1108        }
1109        catch (ArrayIndexOutOfBoundsException e) {
1110        }
1111        catch (IllegalArgumentException e) {
1112            errorHandling("getRunLimit() should not throw an IAE " +
1113                "but an AIOoBE when run is -1(too small).");
1114        }
1115
1116        try {
1117            bidi.getRunLimit(0);
1118            bidi.getRunLimit(1);
1119            bidi.getRunLimit(2);
1120        }
1121        catch (ArrayIndexOutOfBoundsException e) {
1122            errorHandling("getRunLimit() should not throw an AIOOBE " +
1123                "when run is from 0 to 2(runCount-1).");
1124        }
1125
1126        try {
1127            bidi.getRunLimit(3);
1128            errorHandling("getRunLimit() should throw an AIOoBE " +
1129                "when run is 3(same as runCount).");
1130        }
1131        catch (ArrayIndexOutOfBoundsException e) {
1132        }
1133        catch (IllegalArgumentException e) {
1134            errorHandling("getRunLimit() should not throw an IAE " +
1135                "but an AIOoBE when run is 3(same as runCount).");
1136        }
1137    }
1138
1139    private void testMethod_getRunStart() {
1140        System.out.println("*** Test getRunStart()");
1141
1142        String str = "ABC 123";
1143        int length = str.length();
1144        Bidi bidi = new Bidi(str, Bidi.DIRECTION_LEFT_TO_RIGHT);
1145
1146        try {
1147            if (bidi.getRunStart(-1) != 0 ||  // runCount - 2
1148                bidi.getRunStart(0) != 0 ||   // runCount - 1
1149                bidi.getRunStart(1) != 0 ||   // runCount
1150                bidi.getRunStart(2) != 0) {   // runCount + 1
1151                errorHandling("getRunStart() should return 0" +
1152                    " when getRunCount() is 1.");
1153            }
1154        }
1155        catch (Exception e) {
1156            errorHandling("getRunLimit() should not throw an exception" +
1157                " when getRunCount() is 1.");
1158        }
1159
1160        str = "ABC " + NKoABC + " 123";
1161        length = str.length();
1162        bidi = new Bidi(str, Bidi.DIRECTION_LEFT_TO_RIGHT);
1163
1164        try {
1165            bidi.getRunStart(-1);
1166            errorHandling("getRunStart() should throw an AIOoBE" +
1167                " when run is -1(too small).");
1168        }
1169        catch (ArrayIndexOutOfBoundsException e) {
1170        }
1171        catch (IllegalArgumentException e) {
1172            errorHandling("getRunStart() should not throw an IAE " +
1173                "but an AIOoBE when run is -1(too small).");
1174        }
1175
1176        try {
1177            bidi.getRunStart(0);
1178            bidi.getRunStart(1);
1179            bidi.getRunStart(2);
1180        }
1181        catch (ArrayIndexOutOfBoundsException e) {
1182            errorHandling("getRunStart() should not throw an AIOOBE " +
1183                "when run is from 0 to 2(runCount-1).");
1184        }
1185
1186        try {
1187            if (bidi.getRunStart(3) != length) {
1188                errorHandling("getRunStart() should return " + length +
1189                    " when run is 3(same as runCount).");
1190            }
1191        }
1192        catch (Exception e) {
1193            errorHandling("getRunStart() should not throw an exception " +
1194                "when run is 3(same as runCount).");
1195        }
1196
1197        try {
1198            bidi.getRunStart(4);
1199            errorHandling("getRunStart() should throw an AIOoBE " +
1200                "when run is runCount+1(too large).");
1201        }
1202        catch (ArrayIndexOutOfBoundsException e) {
1203        }
1204        catch (IllegalArgumentException e) {
1205            errorHandling("getRunStart() should not throw an IAE " +
1206                "but an AIOoBE when run is runCount+1(too large).");
1207        }
1208    }
1209
1210    private void testMethod_reorderVisually1() {
1211        System.out.println("*** Test reorderVisually() 1");
1212
1213        for (int textNo = 0; textNo < data4reorderVisually.length; textNo++) {
1214            Object[] objects = data4reorderVisually[textNo][0];
1215            byte[] levels = getLevels(data4reorderVisually[textNo]);
1216            Object[] expectedObjects = data4reorderVisually[textNo][2];
1217
1218            Bidi.reorderVisually(levels, 0, objects, 0, objects.length);
1219
1220            checkResult("textNo=" + textNo + ": reorderVisually(levels=[" +
1221                toString(levels) + "], objects=[" + toString(objects) + "])",
1222                expectedObjects, objects);
1223        }
1224    }
1225
1226    private void testMethod_reorderVisually2() {
1227        System.out.println("*** Test reorderVisually() 2");
1228
1229        Object[] objects = data4reorderVisually[0][0];
1230        byte[] levels = getLevels(data4reorderVisually[0]);
1231        int count = objects.length;
1232        int llen = levels.length;
1233        int olen = objects.length;
1234
1235        try {
1236            Bidi.reorderVisually(null, 0, objects, 0, count);
1237            errorHandling("reorderVisually() should throw a NPE " +
1238                "when levels is null.");
1239        }
1240        catch (NullPointerException e) {
1241        }
1242
1243        try {
1244            Bidi.reorderVisually(levels, -1, objects, 0, count);
1245            errorHandling("reorderVisually() should throw an IAE " +
1246                "when levelStart is -1.");
1247        }
1248        catch (IllegalArgumentException e) {
1249        }
1250        catch (ArrayIndexOutOfBoundsException e) {
1251            errorHandling("reorderVisually() should not throw an AIOoBE " +
1252                "but an IAE when levelStart is -1.");
1253        }
1254
1255        try {
1256            Bidi.reorderVisually(levels, llen, objects, 0, count);
1257            errorHandling("reorderVisually() should throw an IAE " +
1258                "when levelStart is 6(levels.length).");
1259        }
1260        catch (IllegalArgumentException e) {
1261        }
1262        catch (ArrayIndexOutOfBoundsException e) {
1263            errorHandling("reorderVisually() should not throw an AIOoBE " +
1264                "but an IAE when levelStart is 6(levels.length).");
1265        }
1266
1267        try {
1268            Bidi.reorderVisually(levels, 0, null, 0, count);
1269            errorHandling("reorderVisually() should throw a NPE" +
1270                " when objects is null.");
1271        }
1272        catch (NullPointerException e) {
1273        }
1274
1275        try {
1276            Bidi.reorderVisually(levels, 0, objects, -1, count);
1277            errorHandling("reorderVisually() should throw an IAE" +
1278                " when objectStart is -1.");
1279        }
1280        catch (IllegalArgumentException e) {
1281        }
1282        catch (ArrayIndexOutOfBoundsException e) {
1283            errorHandling("reorderVisually() should not throw an AIOoBE " +
1284                "but an IAE when objectStart is -1.");
1285        }
1286
1287        try {
1288            Bidi.reorderVisually(levels, 0, objects, 6, objects.length);
1289            errorHandling("reorderVisually() should throw an IAE " +
1290                "when objectStart is 6(objects.length).");
1291        }
1292        catch (IllegalArgumentException e) {
1293        }
1294
1295        try {
1296            Bidi.reorderVisually(levels, 0, objects, 0, -1);
1297            errorHandling("reorderVisually() should throw an IAE " +
1298                "when count is -1.");
1299        }
1300        catch (IllegalArgumentException e) {
1301        }
1302        catch (NegativeArraySizeException e) {
1303            errorHandling("reorderVisually() should not throw an NASE " +
1304                "but an IAE when count is -1.");
1305        }
1306
1307        try {
1308            Bidi.reorderVisually(levels, 0, objects, 0, count+1);
1309            errorHandling("reorderVisually() should throw an IAE " +
1310                "when count is 7(objects.length+1).");
1311        }
1312        catch (IllegalArgumentException e) {
1313        }
1314        catch (ArrayIndexOutOfBoundsException e) {
1315            errorHandling("reorderVisually() should not throw an AIOoBE " +
1316                "but an IAE when count is 7(objects.length+1).");
1317        }
1318
1319        try {
1320            Bidi.reorderVisually(levels, 0, objects, 0, 0);
1321            checkResult("reorderVisually(count=0)",
1322                data4reorderVisually[0][0], objects);
1323        }
1324        catch (Exception e) {
1325            errorHandling("reorderVisually() should not throw an exception" +
1326                " when count is 0.");
1327        }
1328    }
1329
1330    private void testMethod_requiresBidi() {
1331        System.out.println("*** Test requiresBidi()");
1332
1333        String paragraph;
1334        char[] text;
1335        Bidi bidi;
1336
1337        for (int textNo = 0; textNo < data4Constructor2.length; textNo++) {
1338            paragraph = data4Constructor2[textNo][0];
1339            text = paragraph.toCharArray();
1340            boolean rBidi = Bidi.requiresBidi(text, 0, text.length);
1341            if (rBidi != requiresBidi4Constructor2[textNo]) {
1342                error = true;
1343                System.err.println("Unexpected requiresBidi() value" +
1344                    " for requiresBidi(\"" + paragraph + "\", " + 0 + ", " +
1345                    text.length + ")." +
1346                    "\n    Expected: " + requiresBidi4Constructor2[textNo] +
1347                    "\n    Got     : " + rBidi);
1348            } else if (verbose) {
1349                System.out.println("  Okay : requiresBidi() for" +
1350                    " requiresBidi(\"" + paragraph + "\", " + 0 + ", " +
1351                    text.length + ")  Got: " + rBidi);
1352            }
1353        }
1354
1355        char[] txt = {'A', 'B', 'C', 'D', 'E'};
1356        int textLength = txt.length;
1357
1358        try {
1359            Bidi.requiresBidi(txt, -1, textLength);
1360            errorHandling("requiresBidi() should throw an IAE" +
1361                " when start is -1(too small).");
1362        }
1363        catch (IllegalArgumentException e) {
1364        }
1365        catch (ArrayIndexOutOfBoundsException e) {
1366            errorHandling("requiresBidi() should not throw an AIOoBE " +
1367                "but an IAE when start is -1(too small).");
1368        }
1369
1370        try {
1371            Bidi.requiresBidi(txt, textLength, textLength);
1372        }
1373        catch (Exception e) {
1374            errorHandling("requiresBidi() should not throw an exception " +
1375                "when start is textLength.");
1376        }
1377
1378        try {
1379            Bidi.requiresBidi(txt, textLength+1, textLength);
1380            errorHandling("requiresBidi() should throw an IAE" +
1381                " when start is textLength+1(too large).");
1382        }
1383        catch (IllegalArgumentException e) {
1384        }
1385
1386        try {
1387            Bidi.requiresBidi(txt, 0, -1);
1388            errorHandling("requiresBidi() should throw an IAE" +
1389                " when limit is -1(too small).");
1390        }
1391        catch (IllegalArgumentException e) {
1392        }
1393
1394        try {
1395            Bidi.requiresBidi(txt, 0, textLength+1);
1396            errorHandling("requiresBidi() should throw an IAE" +
1397                " when limit is textLength+1(too large).");
1398        }
1399        catch (IllegalArgumentException e) {
1400        }
1401        catch (ArrayIndexOutOfBoundsException e) {
1402            errorHandling("requiresBidi() should not throw an AIOoBE " +
1403                "but an IAE when limit is textLength+1(too large).");
1404        }
1405    }
1406
1407    private void checkResult(String name,
1408                             int expectedValue,
1409                             int actualValue) {
1410        if (expectedValue != actualValue) {
1411            errorHandling("Unexpected " + name + " value." +
1412                " Expected: " + expectedValue + " Got: " + actualValue);
1413        } else if (verbose) {
1414            System.out.println("  Okay : " + name + " = " + actualValue);
1415        }
1416    }
1417
1418    private void checkResult(String name,
1419                             boolean expectedValue,
1420                             boolean actualValue) {
1421        if (expectedValue != actualValue) {
1422            errorHandling("Unexpected " + name + " value." +
1423                " Expected: " + expectedValue + " Got: " + actualValue);
1424        } else if (verbose) {
1425            System.out.println("  Okay : " + name + " = " + actualValue);
1426        }
1427    }
1428
1429    private void checkResult(String name,
1430                             String expectedValue,
1431                             String actualValue) {
1432        if (!expectedValue.equals(actualValue)) {
1433            errorHandling("Unexpected " + name + " value." +
1434                "\n\tExpected: \"" + expectedValue + "\"" +
1435                "\n\tGot:      \"" + actualValue + "\"");
1436        } else if (verbose) {
1437            System.out.println("  Okay : " + name + " = \"" +
1438                actualValue + "\"");
1439        }
1440    }
1441
1442    private void checkResult(String name,
1443                             int[] expectedValues,
1444                             int[] actualValues) {
1445        if (!Arrays.equals(expectedValues, actualValues)) {
1446            errorHandling("Unexpected " + name + " value." +
1447                "\n\tExpected: " + toString(expectedValues) + "" +
1448                "\n\tGot:      " + toString(actualValues) + "");
1449        } else if (verbose) {
1450            System.out.println("  Okay : " + name + " = " +
1451                toString(actualValues));
1452        }
1453    }
1454
1455    private void checkResult(String name,
1456                             Object[] expectedValues,
1457                             Object[] actualValues) {
1458        if (!Arrays.equals(expectedValues, actualValues)) {
1459            errorHandling("Unexpected " + name + " value." +
1460                "\n\tExpected: [" + toString(expectedValues) +
1461                "]\n\tGot:      [" + toString(actualValues) + "]");
1462        } else if (verbose) {
1463            System.out.println("  Okay : " + name + " Reordered objects = [" +
1464                toString(actualValues) + "]");
1465        }
1466    }
1467
1468    private void errorHandling(String msg) {
1469        if (abort) {
1470            throw new RuntimeException("Error: " + msg);
1471        } else {
1472            error = true;
1473            System.err.println("**Error:" + msg);
1474        }
1475    }
1476
1477    private String toString(int[] values) {
1478        StringBuilder sb = new StringBuilder();
1479        for (int i = 0; i < values.length-1; i++) {
1480            sb.append((int)values[i]);
1481            sb.append(' ');
1482        }
1483        sb.append((int)values[values.length-1]);
1484
1485        return sb.toString();
1486    }
1487
1488    private String toString(byte[] values) {
1489        StringBuilder sb = new StringBuilder();
1490        for (int i = 0; i < values.length-1; i++) {
1491            sb.append((byte)values[i]);
1492            sb.append(' ');
1493        }
1494        sb.append((byte)values[values.length-1]);
1495
1496        return sb.toString();
1497    }
1498
1499    private String toString(Object[] values) {
1500        StringBuilder sb = new StringBuilder();
1501        String name;
1502
1503        for (int i = 0; i < values.length-1; i++) {
1504            if ((name = getStringName((String)values[i])) != null) {
1505                sb.append(name);
1506                sb.append(", ");
1507            } else {
1508                sb.append('"');
1509                sb.append((String)values[i]);
1510                sb.append("\", ");
1511            }
1512        }
1513        if ((name = getStringName((String)values[values.length-1])) != null) {
1514            sb.append(name);
1515        } else {
1516            sb.append('"');
1517            sb.append((String)values[values.length-1]);
1518            sb.append('\"');
1519        }
1520
1521        return sb.toString();
1522    }
1523
1524    private String getStringName(String str) {
1525        if (ArabicABC.equals(str)) return "ArabicABC";
1526        else if (Arabic123.equals(str)) return "Arabic123";
1527        else if (PArabicABC.equals(str)) return "ArabicABC(Presentation form)";
1528        else if (HebrewABC.equals(str)) return "HebrewABC";
1529        else if (KharoshthiABC.equals(str)) return "KharoshthiABC(RTL)";
1530        else if (Kharoshthi123.equals(str)) return "Kharoshthi123(RTL)";
1531        else if (NKoABC.equals(str)) return "NKoABC(RTL)";
1532        else if (NKo123.equals(str)) return "NKo123(RTL)";
1533        else if (OsmanyaABC.equals(str)) return "OsmanyaABC(LTR)";
1534        else if (Osmanya123.equals(str)) return "Osmanya123(LTR)";
1535        else return null;
1536    }
1537
1538    private String getFlagName(int flag) {
1539        if (flag == -2 || flag == 0x7e) return FLAGNAMES[0];
1540        else if (flag == -1 || flag == 0x7f) return FLAGNAMES[1];
1541        else if (flag == 0) return FLAGNAMES[2];
1542        else if (flag == 1) return FLAGNAMES[3];
1543        else return "Unknown(0x" + Integer.toHexString(flag) + ")";
1544    }
1545
1546    private String toReadableString(String str) {
1547         String s = str;
1548
1549         s = s.replaceAll(ArabicABC, "ArabicABC");
1550         s = s.replaceAll(Arabic123, "Arabic123");
1551         s = s.replaceAll(PArabicABC, "ArabicABC(Presentation form)");
1552         s = s.replaceAll(HebrewABC, "HebrewABC");
1553         s = s.replaceAll(KharoshthiABC, "KharoshthiABC");
1554         s = s.replaceAll(Kharoshthi123, "Kharoshthi123");
1555         s = s.replaceAll(NKoABC, "NKoABC");
1556         s = s.replaceAll(NKo123, "NKo123");
1557         s = s.replaceAll(OsmanyaABC, "OsmanyaABC");
1558         s = s.replaceAll(Osmanya123, "Osmanya123");
1559
1560         return s;
1561    }
1562
1563    private  byte[] getLevels(Object[][] data) {
1564        int levelLength = data[0].length;
1565        byte[] array = new byte[levelLength];
1566        int textIndex = 0;
1567
1568        for (int i = 0; i < levelLength; i++) {
1569            array[i] = (byte)(((String)data[1][0]).charAt(textIndex) - '0');
1570            textIndex += ((String)data[0][i]).length();
1571        }
1572
1573        return array;
1574    }
1575
1576
1577    /* Bidi pubilc constants */
1578    private static final int[] FLAGS = {
1579        Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT,  // -2 (0x7e in ICU4J)
1580        Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT,  // -1 (0x7f in ICU4J)
1581        Bidi.DIRECTION_LEFT_TO_RIGHT,          //  0
1582        Bidi.DIRECTION_RIGHT_TO_LEFT           //  1
1583    };
1584
1585    /* Bidi pubilc constants names */
1586    private static final String[] FLAGNAMES = {
1587        "DIRECTION_DEFAULT_LEFT_TO_RIGHT",  // -2
1588        "DIRECTION_DEFAULT_RIGHT_TO_LEFT",  // -1
1589        "DIRECTION_LEFT_TO_RIGHT",          //  0
1590        "DIRECTION_RIGHT_TO_LEFT",          //  1
1591    };
1592
1593    /* Bidirectional Character Types */
1594    private static final char L   = '\u200E';
1595    private static final char R   = '\u202F';
1596    private static final char LRE = '\u202A';
1597    private static final char RLE = '\u202B';
1598    private static final char PDF = '\u202C';
1599    private static final char LRO = '\u202D';
1600    private static final char RLO = '\u202E';
1601    private static final char LRI = '\u2066';
1602    private static final char RLI = '\u2067';
1603    private static final char FSI = '\u2068';
1604    private static final char PDI = '\u2069';
1605
1606    /*
1607     *  0x05D0-0x05EA:   [R]   Hewbrew letters (Strong)
1608     *  0x0627-0x063A:   [AL]  Arabic letters (Strong)
1609     *  0x0660-0x0669:   [AN]  Arabic-Indic digits (Weak)
1610     *  0x07CA-0x07E7:   [R]   NKo letters (Strong)
1611     *  0x07C0-0x07C9:   [R]   NKo digits (Strong)
1612     *  0xFE50-0xFEFF:   [AL]  Arabic presentaion form (Strong)
1613     *  0x10480-0x1049D: [L]   Osmanya letters (Strong)
1614     *  0x104A0-0x104A9: [L]   Osmanya digits (Strong)
1615     *  0x10A10-0x10A33: [R]   Kharoshthi letters (Strong)
1616     *  0x10A40-0x10A43: [R]   Kharoshthi digits (Strong)
1617     *
1618     *  0x200E:          [L]   Left-to-right mark (Implicit, Strong)
1619     *  0x200F:          [R]   Right-to-left mark (Implicit, Strong)
1620     *  0x202A:          [LRE] Left-to-right embedding (Explicit, Strong)
1621     *  0x202B:          [RLE] Right-to-left embedding (Explicit, Strong)
1622     *  0x202C:          [PDF] Pop directional formatting (Explicit, Weak)
1623     *  0x202D:          [LRO] Left-to-right override (Explicit, Strong)
1624     *  0x202E:          [RLO] Right-to-left override (Explicit, Strong)
1625     */
1626
1627    /* Right-to-left */
1628    private static String ArabicABC = "\u0627\u0628\u0629";
1629    private static String Arabic123 = "\u0661\u0662\u0663";
1630    private static String PArabicABC = "\uFE97\uFE92\uFE8E";
1631    private static String HebrewABC = "\u05D0\u05D1\u05D2";
1632    private static String KharoshthiABC =
1633        new String(Character.toChars(0x10A10)) +
1634        new String(Character.toChars(0x10A11)) +
1635        new String(Character.toChars(0x10A12));
1636    private static String Kharoshthi123 =
1637        new String(Character.toChars(0x10A40)) +
1638        new String(Character.toChars(0x10A41)) +
1639        new String(Character.toChars(0x10A42));
1640    private static String NKoABC = "\u07CA\u07CB\u07CC";
1641    private static String NKo123 = "\u07C1\u07C2\u07C3";
1642
1643    /* Left-to-right */
1644    private static String OsmanyaABC =
1645        new String(Character.toChars(0x10480)) +
1646        new String(Character.toChars(0x10481)) +
1647        new String(Character.toChars(0x10482));
1648    private static String Osmanya123 =
1649        new String(Character.toChars(0x104A0)) +
1650        new String(Character.toChars(0x104A1)) +
1651        new String(Character.toChars(0x104A2));
1652
1653    /* --------------------------------------------------------------------- */
1654
1655    /*
1656     * Test data for Bidi(char[], ...) constructor and methods
1657     */
1658
1659    /* Text for Bidi processing and its levels */
1660    private static String[][] data4Constructor1 = {
1661        /* For Text #0 */
1662        {"abc <ABC XYZ> xyz.",
1663             "000000000000000000", "000002222222000000", "000000000000000000",
1664             "000003333333000000", "000000000000000000",
1665             "222222222222222221", "222222222222222221", "222222222222222221",
1666             "222113333333112221", "222224444444222221",
1667             "000000000000000000", "000000000000000000", "222222222222222221"},
1668
1669        /* For Text #1 */
1670        {"ABC <" + HebrewABC + " " + NKo123 + "> XYZ.",
1671             "000001111111000000", "000001111111000000", "000003333333000000",
1672             "000003333333000000", "000000000000000000",
1673             "222111111111112221", "222111111111112221", "222223333333222221",
1674             "222113333333112221", "222224444444222221",
1675             "000001111111000000", "000001111111000000", "222111111111112221"},
1676
1677        /* For Text #2 */
1678        {NKoABC + " <ABC XYZ> " + NKo123 + ".",
1679             "111000000000001110", "111112222222111110", "111002222222001110",
1680             "111113333333111110", "111004444444001110",
1681             "111112222222111111", "111112222222111111", "111112222222111111",
1682             "111111111111111111", "111114444444111111",
1683             "111112222222111111", "111000000000001110", "111112222222111111"},
1684
1685        /* For Text #3 */
1686        {HebrewABC + " <" + ArabicABC + " " + Arabic123 + "> " + NKo123 + ".",
1687             "111111111222111110", "111111111222111110", "111003333444001110",
1688             "111113333333111110", "111004444444001110",
1689             "111111111222111111", "111111111222111111", "111113333444111111",
1690             "111111111111111111", "111114444444111111",
1691             "111111111222111111", "111111111222111110", "111111111222111111"},
1692
1693        /* For Text #4 */
1694        {"abc <" + NKoABC + " 123> xyz.",
1695             "000001111222000000", "000001111222000000", "000003333444000000",
1696             "000003333333000000", "000000000000000000",
1697             "222111111222112221", "222111111222112221", "222223333444222221",
1698             "222113333333112221", "222224444444222221",
1699             "000001111222000000", "000001111222000000", "222111111222112221"},
1700
1701        /* For Text #5 */
1702        {"abc <ABC " + NKo123 + "> xyz.",
1703             "000000000111000000", "000002221111000000", "000002222333000000",
1704             "000003333333000000", "000000000000000000",
1705             "222222221111112221", "222222221111112221", "222222222333222221",
1706             "222113333333112221", "222224444444222221",
1707             "000000000111000000", "000000000111000000", "222222221111112221"},
1708
1709        /* For Text #6 */
1710        {ArabicABC + " <" + NKoABC + " 123" + "> " + Arabic123 + ".",
1711             "111111111222112220", "111111111222112220", "111003333444002220",
1712             "111113333333112220", "111004444444002220",
1713             "111111111222112221", "111111111222112221", "111113333444112221",
1714             "111113333333112221", "111114444444112221",
1715             "111111111222112221", "111111111222112220", "111111111222112221"},
1716
1717        /* For Text #7 */
1718        {ArabicABC + " <XYZ " + NKoABC + "> " + Arabic123 + ".",
1719             "111000000111112220", "111112221111112220", "111002222333002220",
1720             "111113333333112220", "111004444444002220",
1721             "111112221111112221", "111112221111112221", "111112222333112221",
1722             "111113333333112221", "111114444444112221",
1723             "111112221111112221", "111000000111112220", "111112221111112221"},
1724
1725        /* For Text #8 */
1726        {OsmanyaABC + " <" + KharoshthiABC + " " + Kharoshthi123 + "> " +
1727         Osmanya123 + ".",
1728             "000000001111111111111000000000", "000000001111111111111000000000",
1729             "000000003333333333333000000000", "000000003333333333333000000000",
1730             "000000000000000000000000000000",
1731             "222222111111111111111112222221", "222222111111111111111112222221",
1732             "222222223333333333333222222221", "222222113333333333333112222221",
1733             "222222224444444444444222222221",
1734             "000000001111111111111000000000", "000000001111111111111000000000",
1735             "222222111111111111111112222221"},
1736
1737        /* For Text #9 */
1738        {KharoshthiABC + " <" + OsmanyaABC + " " + Osmanya123 + "> " +
1739         Kharoshthi123 + ".",
1740             "111111000000000000000001111110", "111111112222222222222111111110",
1741             "111111002222222222222001111110", "111111113333333333333111111110",
1742             "111111004444444444444001111110",
1743             "111111112222222222222111111111", "111111112222222222222111111111",
1744             "111111112222222222222111111111", "111111111111111111111111111111",
1745             "111111114444444444444111111111",
1746             "111111112222222222222111111111", "111111000000000000000001111110",
1747             "111111112222222222222111111111"},
1748    };
1749
1750    /* Golden data for baseIsLeftToRight() results */
1751    private static boolean[][] baseIsLTR4Constructor1 = {
1752        /* For Text #0 */
1753        {true,  true,  true,  true,  true,
1754         false, false, false, false, false,
1755         true,  true,  false},
1756
1757        /* For Text #1 */
1758        {true,  true,  true,  true,  true,
1759         false, false, false, false, false,
1760         true,  true,  false},
1761
1762        /* For Text #2 */
1763        {true,  true,  true,  true,  true,
1764         false, false, false, false, false,
1765         false, true,  false},
1766
1767        /* For Text #3 */
1768        {true,  true,  true,  true,  true,
1769         false, false, false, false, false,
1770         false, true,  false},
1771
1772        /* For Text #4 */
1773        {true,  true,  true,  true,  true,
1774         false, false, false, false, false,
1775         true,  true,  false},
1776
1777        /* For Text #5 */
1778        {true,  true,  true,  true,  true,
1779         false, false, false, false, false,
1780         true,  true,  false},
1781
1782        /* For Text #6 */
1783        {true,  true,  true,  true,  true,
1784         false, false, false, false, false,
1785         false, true,  false},
1786
1787        /* For Text #7 */
1788        {true,  true,  true,  true,  true,
1789         false, false, false, false, false,
1790         false, true,  false},
1791
1792        /* For Text #8 */
1793        {true,  true,  true,  true,  true,
1794         false, false, false, false, false,
1795         true,  true,  false},
1796
1797        /* For Text #9 */
1798        {true,  true,  true,  true,  true,
1799         false, false, false, false, false,
1800         false, true,  false},
1801    };
1802
1803    /* Golden data for isLeftToRight() & isRightToLeft() results */
1804    private static boolean[][][] isLTR_isRTL4Constructor1 = {
1805        /* For Text #0 */
1806         /* isLeftToRight() results */
1807        {{true,  false, true,  false, true,
1808          false, false, false, false, false,
1809          true,  true,  false},
1810         /* isRightToLeft() results   */
1811         {false, false, false, false, false,
1812          false, false, false, false, false,
1813          false, false, false}},
1814
1815        /* For Text #1 */
1816         /* isLeftToRight() results */
1817        {{false, false, false, false, true,
1818          false, false, false, false, false,
1819          false, false, false},
1820         /* isRightToLeft() results   */
1821         {false, false, false, false, false,
1822          false, false, false, false, false,
1823          false, false, false}},
1824
1825        /* For Text #2 */
1826         /* isLeftToRight() results */
1827        {{false, false, false, false, false,
1828          false, false, false, false, false,
1829          false, false, false},
1830         /* isRightToLeft() results   */
1831         {false, false, false, false, false,
1832          false, false, false, true,  false,
1833          false, false, false}},
1834
1835        /* For Text #3 */
1836         /* isLeftToRight() results */
1837        {{false, false, false, false, false,
1838          false, false, false, false, false,
1839          false, false, false},
1840         /* isRightToLeft() results   */
1841         {false, false, false, false, false,
1842          false, false, false, true,  false,
1843          false, false, false}},
1844
1845        /* For Text #4 */
1846         /* isLeftToRight() results */
1847        {{false, false, false, false, true,
1848          false, false, false, false, false,
1849          false, false, false},
1850         /* isRightToLeft() results   */
1851         {false, false, false, false, false,
1852          false, false, false, false, false,
1853          false, false, false}},
1854
1855        /* For Text #5 */
1856         /* isLeftToRight() results */
1857        {{false, false, false, false, true,
1858          false, false, false, false, false,
1859          false, false, false},
1860         /* isRightToLeft() results   */
1861         {false, false, false, false, false,
1862          false, false, false, false, false,
1863          false, false, false}},
1864
1865        /* For Text #6 */
1866         /* isLeftToRight() results */
1867        {{false, false, false, false, false,
1868          false, false, false, false, false,
1869          false, false, false},
1870         /* isRightToLeft() results   */
1871         {false, false, false, false, false,
1872          false, false, false, false, false,
1873          false, false, false}},
1874
1875        /* For Text #7 */
1876         /* isLeftToRight() results */
1877        {{false, false, false, false, false,
1878          false, false, false, false, false,
1879          false, false, false},
1880         /* isRightToLeft() results   */
1881         {false, false, false, false, false,
1882          false, false, false, false, false,
1883          false, false, false}},
1884
1885        /* For Text #8 */
1886         /* isLeftToRight() results */
1887        {{false, false, false, false, true,
1888          false, false, false, false, false,
1889          false, false, false},
1890         /* isRightToLeft() results   */
1891         {false, false, false, false, false,
1892          false, false, false, false, false,
1893          false, false, false}},
1894
1895        /* For Text #9 */
1896         /* isLeftToRight() results */
1897        {{false, false, false, false, false,
1898          false, false, false, false, false,
1899          false, false, false},
1900         /* isRightToLeft() results   */
1901         {false, false, false, false, false,
1902          false, false, false, true,  false,
1903          false, false, false}},
1904    };
1905
1906    /* --------------------------------------------------------------------- */
1907
1908    /*
1909     * Test data for Bidi(String, int) constructor and methods
1910     */
1911
1912    /* Text for Bidi processing and its levels */
1913    private static String[][] data4Constructor2 = {
1914        /* For Text #0 */
1915        {" ABC 123.",
1916             "000000000", "000000000", "000000000", "122222221"},
1917
1918        /* For Text #1 */
1919        {" ABC " + HebrewABC + " " + NKo123 + " 123.",
1920             "00000111111112220", "00000111111112220", "00000111111112220",
1921             "12221111111112221"},
1922
1923        /* For Text #2 */
1924        {" ABC " + ArabicABC + " " + Arabic123 + " 123.",
1925             "00000111122212220", "00000111122212220", "00000111122212220",
1926             "12221111122212221"},
1927
1928        /* For Text #3 */
1929        {" " + NKoABC + " ABC 123 " + NKo123 + ".",
1930             "11111222222211111", "11111222222211111", "01110000000001110",
1931             "11111222222211111"},
1932
1933        /* For Text #4 */
1934        {" " + ArabicABC + " ABC 123 " + Arabic123 + ".",
1935             "11111222222212221", "11111222222212221", "01110000000002220",
1936             "11111222222212221"},
1937
1938        /* For Text #5 */
1939        {" " + HebrewABC + " " + NKo123 + ".",
1940             "111111111", "111111111", "011111110", "111111111"},
1941
1942        /* For Text #6 */
1943        {" " + ArabicABC + " " + Arabic123 + ".",
1944             "111112221", "111112221", "011112220", "111112221"},
1945
1946        /* For Text #7 */
1947        {" " + KharoshthiABC + " " + Kharoshthi123 + ".",
1948             "111111111111111", "111111111111111", "011111111111110",
1949             "111111111111111"},
1950
1951        /* For Text #8 */
1952        {L + HebrewABC + " " + NKo123 + ".",
1953             "011111110", "011111110", "011111110", "211111111"},
1954
1955        /* For Text #9 */
1956        {R + "ABC " + Osmanya123 + ".",
1957             "000000000000", "000000000000", "000000000000", "122222222221"},
1958
1959        /* For Text #10 */
1960        {"ABC " + PArabicABC + " " + PArabicABC + " 123",
1961             "000011111111222", "000011111111222", "000011111111222",
1962             "222111111111222"},
1963
1964        /* For Text #11 */
1965        {RLE + "ABC " + HebrewABC + " " + NKo123 + "." + PDF,
1966             "22221111111110", "22221111111110", "22221111111110",
1967             "44443333333331"},
1968
1969        /* For Text #12 */
1970        {"He said \"" + RLE + "ABC " + HebrewABC + " " + NKo123 + PDF + ".\"",
1971             "000000000222211111111000", "000000000222211111111000",
1972             "000000000222211111111000", "222222211444433333333111"},
1973
1974        /* For Text #13 */
1975        {LRO + "He said \"" + RLE + "ABC " + NKoABC + " " + NKo123 + PDF +
1976         ".\"" + PDF,
1977             "22222222224444333333332220", "22222222224444333333332220",
1978             "22222222224444333333332220", "22222222224444333333332221"},
1979
1980        /* For Text #14 */
1981        {LRO + "He said \"" + RLE + "ABC " + HebrewABC + " " + NKo123 + PDF +
1982         ".\"",  // PDF missing
1983             "2222222222444433333333222", "2222222222444433333333222",
1984             "2222222222444433333333222", "2222222222444433333333222"},
1985
1986        /* For Text #15 */
1987        {"Did you say '" + LRE + "he said \"" + RLE + "ABC " + HebrewABC +
1988         " " + NKo123 + PDF + "\"" + PDF + "'?",
1989             "0000000000000222222222244443333333322000",
1990             "0000000000000222222222244443333333322000",
1991             "0000000000000222222222244443333333322000",
1992             "2222222222222222222222244443333333322111"},
1993
1994        /* For Text #16 */
1995        {RLO + "Did you say '" + LRE + "he said \"" + RLE + "ABC " +
1996         HebrewABC + " " + NKo123 + PDF + "\"" + PDF + "'?" + PDF,
1997             "111111111111112222222222444433333333221110",
1998             "111111111111112222222222444433333333221110",
1999             "111111111111112222222222444433333333221110",
2000             "333333333333334444444444666655555555443331"},
2001
2002        /* For Text #17 */
2003        {RLO + "Did you say '" + LRE + "he said \"" + RLE + "ABC " +
2004         HebrewABC + " " + NKo123 + PDF + "\"" + PDF + "'?",  // PDF missing
2005             "11111111111111222222222244443333333322111",
2006             "11111111111111222222222244443333333322111",
2007             "11111111111111222222222244443333333322111",
2008             "33333333333333444444444466665555555544333"},
2009
2010        /* For Text #18 */
2011        {" ABC (" + ArabicABC + " " + Arabic123 + ") 123.",
2012             "0000001111222002220", "0000001111222002220",
2013             "0000001111222002220", "1222111111222112221"},
2014
2015        /* For Text #19 */
2016        {" " + HebrewABC + " (ABC 123) " + NKo123 + ".",
2017             "1111112222222111111", "1111112222222111111",
2018             "0111000000000001110", "1111112222222111111"},
2019
2020        /* For Text #20 */
2021        {" He said \"" + RLE + "ABC " + NKoABC + " " + NKo123 + PDF + ".\" ",
2022             "00000000002222111111110000", "00000000002222111111110000",
2023             "00000000002222111111110000", "12222222114444333333331111"},
2024
2025        /* For Text #21 */
2026        {" Did you say '" + LRE + "he said \"" + RLE + "ABC " + HebrewABC +
2027         " " + NKo123 + PDF + "\"" + PDF + "'? ",
2028             "000000000000002222222222444433333333220000",
2029             "000000000000002222222222444433333333220000",
2030             "000000000000002222222222444433333333220000",
2031             "122222222222222222222222444433333333221111"},
2032
2033        /* For Text #22 */
2034        {RLE + OsmanyaABC + " " + KharoshthiABC + " " + Kharoshthi123 + "." +
2035         PDF,
2036             "22222221111111111111110", "22222221111111111111110",
2037             "22222221111111111111110", "44444443333333333333331"},
2038
2039        /* For Text #23 */
2040        {" ABC (" + Arabic123 + " " + ArabicABC + ") 123.",
2041             "0000002221111002220", "0000002221111002220",
2042             "0000002221111002220", "1222112221111112221"},
2043
2044        /* For Text #24 */
2045        {" 123 (" + ArabicABC + " " + Arabic123 + ") ABC.",
2046             "1222111111222112221", "1222111111222112221",
2047             "0000001111222000000", "1222111111222112221"},
2048
2049        /* For Text #25 */
2050        {" 123 (" + Arabic123 + " " + ArabicABC + ") ABC.",
2051             "1222112221111112221", "1222112221111112221",
2052             "0000002221111000000", "1222112221111112221"},
2053
2054        /* For Text #26 */
2055        {" " + ArabicABC + " (ABC 123) "  + Arabic123 + ".",
2056             "1111112222222112221", "1111112222222112221",
2057             "0111000000000002220", "1111112222222112221"},
2058
2059        /* For Text #27 */
2060        {" " + ArabicABC + " (123 ABC) "  + Arabic123 + ".",
2061             "1111112221222112221", "1111112221222112221",
2062             "0111002220000002220", "1111112221222112221"},
2063
2064        /* For Text #28 */
2065        {" " + Arabic123 + " (ABC 123) "  + ArabicABC + ".",
2066             "0222000000000001110", "0222000000000001110",
2067             "0222000000000001110", "1222112222222111111"},
2068
2069        /* For Text #29 */
2070        {" " + Arabic123 + " (123 ABC) "  + ArabicABC + ".",
2071             "0222000000000001110", "0222000000000001110",
2072             "0222000000000001110", "1222112221222111111"},
2073
2074        /* For Text #30 */
2075        {RLI + "ABC " + ArabicABC + " " + ArabicABC + "." + PDI,
2076             "02221111111110", "14443333333331",
2077             "02221111111110", "14443333333331"},
2078
2079        /* For Text #31 */
2080        {"ABC abc \"" + RLI + "IJK " + ArabicABC + " " + ArabicABC + PDI +
2081         ".\" \"" + RLI + ArabicABC + " " + ArabicABC + PDI + ",\" xyz XYZ.",
2082             "0000000000222111111110000001111111000000000000",
2083             "0000000000222111111110000001111111000000000000",
2084             "0000000000222111111110000001111111000000000000",
2085             "2222222222444333333332222223333333222222222221"},
2086
2087        /* For Text #32 */
2088        {ArabicABC + " " + ArabicABC + " '" + LRI + "abc def \"" + RLI +
2089         "xyz " + ArabicABC + " " + ArabicABC + PDI + "\"" + PDI + "'?",
2090             "111111111122222222224443333333322111",
2091             "111111111122222222224443333333322111",
2092             "111111100022222222224443333333322000",
2093             "111111111122222222224443333333322111"},
2094
2095        /* For Text #33 */
2096        {FSI + Arabic123 + " ABC " + ArabicABC + " " + ArabicABC + "." + PDI,
2097             "044422222333333320", "144422222333333321",
2098             "044422222333333320", "144422222333333321"},
2099
2100        /* For Text #34 */
2101        {FSI + "123 ABC " + ArabicABC + " " + ArabicABC + "." + PDI,
2102             "022222222333333320", "122222222333333321",
2103             "022222222333333320", "122222222333333321"},
2104
2105        /* For Text #35 */
2106        {FSI + "123 " + ArabicABC + " ABC " + ArabicABC + "." + PDI,
2107             "022211111222111110", "144433333444333331",
2108             "022211111222111110", "144433333444333331"},
2109
2110        /* For Text #36 */
2111        {FSI + Arabic123 + " " + ArabicABC + " ABC " + ArabicABC + "." + PDI,
2112             "022211111222111110", "144433333444333331",
2113             "022211111222111110", "144433333444333331"},
2114
2115        /* For Text #37 */
2116        {FSI + Arabic123 + " 123." + PDI,
2117             "0444222220", "1444222221", "0444222220", "1444222221"},
2118
2119        /* For Text #38 */
2120        {FSI + "123 " + Arabic123 + "." + PDI,
2121             "0222244420", "1222244421", "0222244420", "1222244421"},
2122    };
2123
2124    /* Golden data for baseIsLeftToRight() results */
2125    private static boolean[][] baseIsLTR4Constructor2 = {
2126        /* For Text #0 - $4  */
2127        {true,  true,  true,  false},
2128        {true,  true,  true,  false},
2129        {true,  true,  true,  false},
2130        {false, false, true,  false},
2131        {false, false, true,  false},
2132
2133        /* For Text #5 - $9  */
2134        {false, false, true,  false},
2135        {false, false, true,  false},
2136        {false, false, true,  false},
2137        {true,  true,  true,  false},
2138        {true,  true,  true,  false},
2139
2140        /* For Text #10 - $14  */
2141        {true,  true,  true,  false},
2142        {true,  true,  true,  false},
2143        {true,  true,  true,  false},
2144        {true,  true,  true,  false},
2145        {true,  true,  true,  false},
2146
2147        /* For Text #15 - $19  */
2148        {true,  true,  true,  false},
2149        {true,  true,  true,  false},
2150        {true,  true,  true,  false},
2151        {true,  true,  true,  false},
2152        {false, false, true,  false},
2153
2154        /* For Text #20 - $24  */
2155        {true,  true,  true,  false},
2156        {true,  true,  true,  false},
2157        {true,  true,  true,  false},
2158        {true,  true,  true,  false},
2159        {false, false, true,  false},
2160
2161        /* For Text #25 - $29  */
2162        {false, false, true,  false},
2163        {false, false, true,  false},
2164        {false, false, true,  false},
2165        {true,  true,  true,  false},
2166        {true,  true,  true,  false},
2167
2168        /* For Text #30 - $34  */
2169        {true,  false, true,  false},
2170        {true,  true,  true,  false},
2171        {false, false, true,  false},
2172        {true,  false, true,  false},
2173        {true , false, true,  false},
2174
2175        /* For Text #35 - $38  */
2176        {true,  false, true,  false},
2177        {true,  false, true,  false},
2178        {true,  false, true,  false},
2179        {true,  false, true,  false},
2180    };
2181
2182    /* Golden data for isLeftToRight() & isRightToLeft() results */
2183    private static boolean[][][] isLTR_isRTL4Constructor2 = {
2184        /* isLeftToRight() results   &   isRightToLeft() results   */
2185        /* For Text #0 - $4  */
2186        {{true,  true,  true,  false}, {false, false, false, false}},
2187        {{false, false, false, false}, {false, false, false, false}},
2188        {{false, false, false, false}, {false, false, false, false}},
2189        {{false, false, false, false}, {false, false, false, false}},
2190        {{false, false, false, false}, {false, false, false, false}},
2191
2192        /* For Text #5 - $9  */
2193        {{false, false, false, false}, {true,  true,  false, true }},
2194        {{false, false, false, false}, {false, false, false, false}},
2195        {{false, false, false, false}, {true,  true,  false, true }},
2196        {{false, false, false, false}, {false, false, false, false}},
2197        {{true,  true,  true,  false}, {false, false, false, false}},
2198
2199        /* For Text #10 - $14  */
2200        {{false, false, false, false}, {false, false, false, false}},
2201        {{false, false, false, false}, {false, false, false, false}},
2202        {{false, false, false, false}, {false, false, false, false}},
2203        {{false, false, false, false}, {false, false, false, false}},
2204        {{false, false, false, false}, {false, false, false, false}},
2205
2206        /* For Text #15 - $19  */
2207        {{false, false, false, false}, {false, false, false, false}},
2208        {{false, false, false, false}, {false, false, false, false}},
2209        {{false, false, false, false}, {false, false, false, false}},
2210        {{false, false, false, false}, {false, false, false, false}},
2211        {{false, false, false, false}, {false, false, false, false}},
2212
2213        /* For Text #20 - $24  */
2214        {{false, false, false, false}, {false, false, false, false}},
2215        {{false, false, false, false}, {false, false, false, false}},
2216        {{false, false, false, false}, {false, false, false, false}},
2217        {{false, false, false, false}, {false, false, false, false}},
2218        {{false, false, false, false}, {false, false, false, false}},
2219
2220        /* For Text #25 - $29  */
2221        {{false, false, false, false}, {false, false, false, false}},
2222        {{false, false, false, false}, {false, false, false, false}},
2223        {{false, false, false, false}, {false, false, false, false}},
2224        {{false, false, false, false}, {false, false, false, false}},
2225        {{false, false, false, false}, {false, false, false, false}},
2226
2227        /* For Text #30 - $34  */
2228        {{false, false, false, false}, {false, false, false, false}},
2229        {{false, false, false, false}, {false, false, false, false}},
2230        {{false, false, false, false}, {false, false, false, false}},
2231        {{false, false, false, false}, {false, false, false, false}},
2232        {{false, false, false, false}, {false, false, false, false}},
2233
2234        /* For Text #35 - $37  */
2235        {{false, false, false, false}, {false, false, false, false}},
2236        {{false, false, false, false}, {false, false, false, false}},
2237        {{false, false, false, false}, {false, false, false, false}},
2238        {{false, false, false, false}, {false, false, false, false}},
2239    };
2240
2241    /* Golden data for requiresBidi() results */
2242    private static boolean[] requiresBidi4Constructor2 = {
2243        /* For Text #0 - $9  */
2244        false, true,  true,  true,  true,
2245        true,  true,  true,  true,  false,
2246
2247        /* For Text #10 - $19  */
2248        true,  true,  true,  true,  true,
2249        true,  true,  true,  true,  true,
2250
2251        /* For Text #20 - $29  */
2252        true,  true,  true,  true,  true,
2253        true,  true,  true,  true,  true,
2254
2255        /* For Text #30 - $37  */
2256        true,  true,  true,  true,  true,
2257        true,  true,  true,  true,
2258    };
2259
2260    /* --------------------------------------------------------------------- */
2261
2262    /*
2263     * Test data for Bidi(char[], ...) constructor and methods
2264     */
2265
2266    /* Enbeddings */
2267    private static byte[][][] emb4Constructor3 = {
2268        /* Embeddings for paragraphs which don't include surrogate pairs. */
2269        {{0, 0, 0, 0, 0,  1,  1,  1,  1,  1,  1,  1, 0, 0, 0, 0, 0, 0},
2270         {0, 0, 0, 0, 0,  2,  2,  2,  2,  2,  2,  2, 0, 0, 0, 0, 0, 0},
2271         {0, 0, 0, 0, 0, -3, -3, -3, -3, -3, -3, -3, 0, 0, 0, 0, 0, 0},
2272         {0, 0, 0, 0, 0, -4, -4, -4, -4, -4, -4, -4, 0, 0, 0, 0, 0, 0}},
2273
2274        /* Embeddings for paragraphs which include surrogate pairs. */
2275        {{ 0,  0,  0,  0,  0,  0,  0,  0,
2276           1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
2277           0,  0,  0,  0,  0,  0,  0,  0,  0},
2278         { 0,  0,  0,  0,  0,  0,  0,  0,
2279           2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
2280           0,  0,  0,  0,  0,  0,  0,  0,  0},
2281         { 0,  0,  0,  0,  0,  0,  0,  0,
2282          -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,
2283           0,  0,  0,  0,  0,  0,  0,  0,  0},
2284         { 0,  0,  0,  0,  0,  0,  0,  0,
2285          -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4,
2286           0,  0,  0,  0,  0,  0,  0,  0,  0}},
2287    };
2288
2289    /* Text for Bidi processing and its levels */
2290    private static String[][] data4Constructor3 = {
2291        /* For Text #0 */
2292        {"abc <ABC XYZ> xyz.",
2293             /* DIRECTION_DEFAULT_LEFT_TO_RIGHT */
2294             "000002222222000000", "000000000000000000",
2295             "000003333333000000", "000000000000000000",
2296             /* DIRECTION_DEFAULT_RIGHT_TO_LEFT */
2297             "222222222222222221", "222222222222222221",
2298             "222113333333112221", "222224444444222221",
2299             /* DIRECTION_LEFT_TO_RIGHT */
2300             "000002222222000000", "000000000000000000",
2301             "000003333333000000", "000000000000000000",
2302             /* DIRECTION_RIGHT_TO_LEFT */
2303             "222222222222222221", "222222222222222221",
2304             "222113333333112221", "222224444444222221"},
2305
2306        /* For Text #1 */
2307        {"ABC <" + HebrewABC + " " + NKo123 + "> XYZ.",
2308             /* DIRECTION_DEFAULT_LEFT_TO_RIGHT */
2309             "000001111111000000", "000003333333000000",
2310             "000003333333000000", "000000000000000000",
2311             /* DIRECTION_DEFAULT_RIGHT_TO_LEFT */
2312             "222111111111112221", "222223333333222221",
2313             "222113333333112221", "222224444444222221",
2314             /* DIRECTION_LEFT_TO_RIGHT */
2315             "000001111111000000", "000003333333000000",
2316             "000003333333000000", "000000000000000000",
2317             /* DIRECTION_RIGHT_TO_LEFT */
2318             "222111111111112221", "222223333333222221",
2319             "222113333333112221", "222224444444222221"},
2320
2321        /* For Text #2 */
2322        {NKoABC + " <ABC XYZ> " + NKo123 + ".",
2323             /* DIRECTION_DEFAULT_LEFT_TO_RIGHT */
2324             "111112222222111111", "111112222222111111",
2325             "111111111111111111", "111114444444111111",
2326             /* DIRECTION_DEFAULT_RIGHT_TO_LEFT */
2327             "111112222222111111", "111112222222111111",
2328             "111111111111111111", "111114444444111111",
2329             /* DIRECTION_LEFT_TO_RIGHT */
2330             "111112222222111110", "111002222222001110",
2331             "111113333333111110", "111004444444001110",
2332             /* DIRECTION_RIGHT_TO_LEFT */
2333             "111112222222111111", "111112222222111111",
2334             "111111111111111111", "111114444444111111"},
2335
2336        /* For Text #3 */
2337        {HebrewABC + " <" + ArabicABC + " " + Arabic123 + "> " + NKo123 + ".",
2338             /* DIRECTION_DEFAULT_LEFT_TO_RIGHT */
2339             "111111111222111111", "111113333444111111",
2340             "111111111111111111", "111114444444111111",
2341             /* DIRECTION_DEFAULT_RIGHT_TO_LEFT */
2342             "111111111222111111", "111113333444111111",
2343             "111111111111111111", "111114444444111111",
2344             /* DIRECTION_LEFT_TO_RIGHT */
2345             "111111111222111110", "111003333444001110",
2346             "111113333333111110", "111004444444001110",
2347             /* DIRECTION_RIGHT_TO_LEFT */
2348             "111111111222111111", "111113333444111111",
2349             "111111111111111111", "111114444444111111"},
2350
2351        /* For Text #4 */
2352        {"abc <123 456> xyz.",
2353             /* DIRECTION_DEFAULT_LEFT_TO_RIGHT */
2354             "000002221222000000", "000000000000000000",
2355             "000003333333000000", "000000000000000000",
2356             /* DIRECTION_DEFAULT_RIGHT_TO_LEFT */
2357             "222222222222222221", "222222222222222221",
2358             "222113333333112221", "222224444444222221",
2359             /* DIRECTION_LEFT_TO_RIGHT */
2360             "000002221222000000", "000000000000000000",
2361             "000003333333000000", "000000000000000000",
2362             /* DIRECTION_RIGHT_TO_LEFT */
2363             "222222222222222221", "222222222222222221",
2364             "222113333333112221", "222224444444222221"},
2365
2366        /* For Text #5 */
2367        {OsmanyaABC + " <" + KharoshthiABC + " " + Kharoshthi123 + "> " +
2368         Osmanya123 + ".",
2369             /* DIRECTION_DEFAULT_LEFT_TO_RIGHT */
2370             "000000001111111111111000000000", "000000003333333333333000000000",
2371             "000000003333333333333000000000", "000000000000000000000000000000",
2372             /* DIRECTION_DEFAULT_RIGHT_TO_LEFT */
2373             "222222111111111111111112222221", "222222223333333333333222222221",
2374             "222222113333333333333112222221", "222222224444444444444222222221",
2375             /* DIRECTION_LEFT_TO_RIGHT */
2376             "000000001111111111111000000000", "000000003333333333333000000000",
2377             "000000003333333333333000000000", "000000000000000000000000000000",
2378             /* DIRECTION_RIGHT_TO_LEFT */
2379             "222222111111111111111112222221", "222222223333333333333222222221",
2380             "222222113333333333333112222221", "222222224444444444444222222221"},
2381
2382        /* For Text #6 */
2383        {KharoshthiABC + " <" + OsmanyaABC + " " + Osmanya123 + "> " +
2384         Kharoshthi123 + ".",
2385             /* DIRECTION_DEFAULT_LEFT_TO_RIGHT */
2386             "111111112222222222222111111111", "111111112222222222222111111111",
2387             "111111111111111111111111111111", "111111114444444444444111111111",
2388             /* DIRECTION_DEFAULT_RIGHT_TO_LEFT */
2389             "111111112222222222222111111111", "111111112222222222222111111111",
2390             "111111111111111111111111111111", "111111114444444444444111111111",
2391             /* DIRECTION_LEFT_TO_RIGHT */
2392             "111111112222222222222111111110", "111111002222222222222001111110",
2393             "111111113333333333333111111110", "111111004444444444444001111110",
2394             /* DIRECTION_RIGHT_TO_LEFT */
2395             "111111112222222222222111111111", "111111112222222222222111111111",
2396             "111111111111111111111111111111", "111111114444444444444111111111"},
2397    };
2398
2399    /* Golden data for baseIsLeftToRight() results */
2400    private static boolean[][] baseIsLTR4Constructor3 = {
2401        /* For Text #0 */
2402        {true,  true,  true,  true,    // DIRECTION_DEFAULT_LEFT_TO_RIGHT
2403         true,  true,  true,  true,    // DIRECTION_DEFAULT_RIGHT_TO_LEFT
2404         true,  true,  true,  true,    // DIRECTION_LEFT_TO_RIGHT
2405         false, false, false, false},  // DIRECTION_RIGHT_TO_LEFT
2406
2407        /* For Text #1 */
2408        {true,  true,  true,  true,
2409         true,  true,  true,  true,
2410         true,  true,  true,  true,
2411         false, false, false, false},
2412
2413        /* For Text #2 */
2414        {false, false, false, false,
2415         false, false, false, false,
2416         true,  true,  true,  true,
2417         false, false, false, false},
2418
2419        /* For Text #3 */
2420        {false, false, false, false,
2421         false, false, false, false,
2422         true,  true,  true,  true,
2423         false, false, false, false},
2424
2425        /* For Text #4 */
2426        {true,  true,  true,  true,
2427         true,  true,  true,  true,
2428         true,  true,  true,  true,
2429         false, false, false, false},
2430
2431        /* For Text #5 */
2432        {true,  true,  true,  true,
2433         true,  true,  true,  true,
2434         true,  true,  true,  true,
2435         false, false, false, false},
2436
2437        /* For Text #6 */
2438        {false, false, false, false,
2439         false, false, false, false,
2440         true,  true,  true,  true,
2441         false, false, false, false},
2442    };
2443
2444    /* Golden data for isLeftToRight() & isRightToLeft() results */
2445    private static boolean[][][] isLTR_isRTL4Constructor3 = {
2446        /* For Text #0 */
2447         /* isLeftToRight() results */
2448        {{false, true,  false, true,     // DIRECTION_DEFAULT_LEFT_TO_RIGHT
2449          false, false, false, false,    // DIRECTION_DEFAULT_RIGHT_TO_LEFT
2450          false, true,  false, true,     // DIRECTION_LEFT_TO_RIGHT
2451          false, false, false, false},   // DIRECTION_RIGHT_TO_LEFT
2452         /* isRightToLeft() results   */
2453         {false, false, false, false,    // DIRECTION_DEFAULT_LEFT_TO_RIGHT
2454          false, false, false, false,    // DIRECTION_DEFAULT_RIGHT_TO_LEFT
2455          false, false, false, false,    // DIRECTION_LEFT_TO_RIGHT
2456          false, false, false, false}},  // DIRECTION_RIGHT_TO_LEFTT
2457
2458        /* For Text #1 */
2459         /* isLeftToRight() results */
2460        {{false, false, false, true,
2461          false, false, false, false,
2462          false, false, false, true,
2463          false, false, false, false},
2464         /* isRightToLeft() results   */
2465         {false, false, false, false,
2466          false, false, false, false,
2467          false, false, false, false,
2468          false, false, false, false}},
2469
2470        /* For Text #2 */
2471         /* isLeftToRight() results */
2472        {{false, false, false, false,
2473          false, false, false, false,
2474          false, false, false, false,
2475          false, false, false, false},
2476         /* isRightToLeft() results   */
2477         {false, false, true,  false,
2478          false, false, true,  false,
2479          false, false, false, false,
2480          false, false, true,  false}},
2481
2482        /* For Text #3 */
2483         /* isLeftToRight() results */
2484        {{false, false, false, false,
2485          false, false, false, false,
2486          false, false, false, false,
2487          false, false, false, false},
2488         /* isRightToLeft() results   */
2489         {false, false, true,  false,
2490          false, false, true,  false,
2491          false, false, false, false,
2492          false, false, true,  false}},
2493
2494        /* For Text #4 */
2495         /* isLeftToRight() results */
2496        {{false, true,  false, true,
2497          false, false, false, false,
2498          false, true,  false, true,
2499          false, false, false, false },
2500         /* isRightToLeft() results   */
2501         {false, false, false, false,
2502          false, false, false, false,
2503          false, false, false, false,
2504          false, false, false, false}},
2505
2506        /* For Text #5 */
2507         /* isLeftToRight() results */
2508        {{false, false, false, true,
2509          false, false, false, false,
2510          false, false, false, true,
2511          false, false, false, false},
2512         /* isRightToLeft() results   */
2513         {false, false, false, false,
2514          false, false, false, false,
2515          false, false, false, false,
2516          false, false, false, false}},
2517
2518        /* For Text #6 */
2519         /* isLeftToRight() results */
2520        {{false, false, false, false,
2521          false, false, false, false,
2522          false, false, false, false,
2523          false, false, false, false},
2524         /* isRightToLeft() results   */
2525         {false, false, true,  false,
2526          false, false, true,  false,
2527          false, false, false, false,
2528          false, false, true,  false}},
2529    };
2530
2531    /* --------------------------------------------------------------------- */
2532
2533    /*
2534     * Test data for reorderVisually() methods
2535     */
2536
2537    private static Object[][][] data4reorderVisually = {
2538        {{"ABC", " ", "abc", " ", ArabicABC, "."},   // Original text
2539         {"000000001110"},                           // levels
2540         {"ABC", " ", "abc", " ", ArabicABC, "."}},  // Reordered text
2541
2542        {{"ABC", " ", HebrewABC, " ", NKoABC, "."},
2543         {"222111111111"},
2544         {".", NKoABC, " ", HebrewABC, " ", "ABC"}},
2545
2546        {{OsmanyaABC, " ", HebrewABC, " ", KharoshthiABC, "."},
2547         {"222222111111111111"},
2548         {".", KharoshthiABC, " ", HebrewABC, " ", OsmanyaABC,}},
2549
2550        {{"ABC", " ", Osmanya123, " ", "\"", OsmanyaABC, " ", Kharoshthi123,
2551          " ", KharoshthiABC, ".", "\""},
2552         {"0000000000002222221111111111111100"},
2553         {"ABC", " ", Osmanya123, " ", "\"", KharoshthiABC, " ", Kharoshthi123,
2554          " ", OsmanyaABC, ".", "\""}},
2555    };
2556
2557}
2558