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