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