// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 *******************************************************************************
 * Copyright (C) 2002-2014, International Business Machines Corporation and
 * others. All Rights Reserved.
 *******************************************************************************
 */

/**
 * Port From:   ICU4C v2.1 : collate/CollationIteratorTest
 * Source File: $ICU4CRoot/source/test/intltest/itercoll.cpp
 **/

package com.ibm.icu.dev.test.collator;

import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import java.util.Arrays;
import java.util.Locale;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.text.CollationElementIterator;
import com.ibm.icu.text.Collator;
import com.ibm.icu.text.RuleBasedCollator;
import com.ibm.icu.text.UCharacterIterator;
import com.ibm.icu.util.ULocale;

@RunWith(JUnit4.class)
public class CollationIteratorTest extends TestFmwk {

    String test1 = "What subset of all possible test cases?";
    String test2 = "has the highest probability of detecting";

    /*
     * @bug 4157299
     */
    @Test
    public void TestClearBuffers(/* char* par */) {
        RuleBasedCollator c = null;
        try {
            c = new RuleBasedCollator("&a < b < c & ab = d");
        } catch (Exception e) {
            warnln("Couldn't create a RuleBasedCollator.");
            return;
        }

        String source = "abcd";
        CollationElementIterator i = c.getCollationElementIterator(source);
        int e0 = 0;
        try {
            e0 = i.next();    // save the first collation element
        } catch (Exception e) {
            errln("call to i.next() failed.");
            return;
        }

        try {
            i.setOffset(3);        // go to the expanding character
        } catch (Exception e) {
            errln("call to i.setOffset(3) failed.");
            return;
        }

        try {
            i.next();                // but only use up half of it
        } catch (Exception e) {
            errln("call to i.next() failed.");
            return;
        }

        try {
            i.setOffset(0);        // go back to the beginning
        } catch (Exception e) {
            errln("call to i.setOffset(0) failed. ");
        }

        int e = 0;
        try {
            e = i.next();    // and get this one again
        } catch (Exception ee) {
            errln("call to i.next() failed. ");
            return;
        }

        if (e != e0) {
            errln("got 0x" + Integer.toHexString(e) + ", expected 0x" + Integer.toHexString(e0));
        }
    }

    /** @bug 4108762
     * Test for getMaxExpansion()
     */
    @Test
    public void TestMaxExpansion(/* char* par */) {
        int unassigned = 0xEFFFD;
        String rule = "&a < ab < c/aba < d < z < ch";
        RuleBasedCollator coll = null;
        try {
            coll = new RuleBasedCollator(rule);
        } catch (Exception e) {
            warnln("Fail to create RuleBasedCollator");
            return;
        }
        char ch = 0;
        String str = String.valueOf(ch);

        CollationElementIterator iter = coll.getCollationElementIterator(str);

        while (ch < 0xFFFF) {
            int count = 1;
            ch ++;
            str = String.valueOf(ch);
            iter.setText(str);
            int order = iter.previous();

            // thai management
            if (order == 0) {
                order = iter.previous();
            }

            while (iter.previous() != CollationElementIterator.NULLORDER) {
                count ++;
            }

            if (iter.getMaxExpansion(order) < count) {
                errln("Failure at codepoint " + ch + ", maximum expansion count < " + count);
            }
        }

        // testing for exact max expansion
        ch = 0;
        while (ch < 0x61) {
            str = String.valueOf(ch);
            iter.setText(str);
            int order = iter.previous();

            if (iter.getMaxExpansion(order) != 1) {
                errln("Failure at codepoint 0x" + Integer.toHexString(ch)
                      + " maximum expansion count == 1");
            }
            ch ++;
        }

        ch = 0x63;
        str = String.valueOf(ch);
        iter.setText(str);
        int temporder = iter.previous();

        if (iter.getMaxExpansion(temporder) != 3) {
            errln("Failure at codepoint 0x" + Integer.toHexString(ch)
                                  + " maximum expansion count == 3");
        }

        ch = 0x64;
        str = String.valueOf(ch);
        iter.setText(str);
        temporder = iter.previous();

        if (iter.getMaxExpansion(temporder) != 1) {
            errln("Failure at codepoint 0x" + Integer.toHexString(ch)
                                  + " maximum expansion count == 1");
        }

        str = UCharacter.toString(unassigned);
        iter.setText(str);
        temporder = iter.previous();

        if (iter.getMaxExpansion(temporder) != 2) {
            errln("Failure at codepoint 0x" + Integer.toHexString(ch)
                                  + " maximum expansion count == 2");
        }


        // testing jamo
        ch = 0x1165;
        str = String.valueOf(ch);
        iter.setText(str);
        temporder = iter.previous();

        if (iter.getMaxExpansion(temporder) > 3) {
            errln("Failure at codepoint 0x" + Integer.toHexString(ch)
                                          + " maximum expansion count < 3");
        }

        // testing special jamo &a<\u1165
        rule = "\u0026\u0071\u003c\u1165\u002f\u0071\u0071\u0071\u0071";

        try {
            coll = new RuleBasedCollator(rule);
        } catch (Exception e) {
            errln("Fail to create RuleBasedCollator");
            return;
        }
        iter = coll.getCollationElementIterator(str);

        temporder = iter.previous();

        if (iter.getMaxExpansion(temporder) != 6) {
            errln("Failure at codepoint 0x" + Integer.toHexString(ch)
                                         + " maximum expansion count == 6");
        }
    }

    /**
     * Test for getOffset() and setOffset()
     */
    @Test
    public void TestOffset(/* char* par */) {
        RuleBasedCollator en_us;
        try {
            en_us = (RuleBasedCollator)Collator.getInstance(Locale.US);
        } catch (Exception e) {
            warnln("ERROR: in creation of collator of ENGLISH locale");
            return;
        }

        CollationElementIterator iter = en_us.getCollationElementIterator(test1);
        // testing boundaries
        iter.setOffset(0);
        if (iter.previous() != CollationElementIterator.NULLORDER) {
            errln("Error: After setting offset to 0, we should be at the end "
                  + "of the backwards iteration");
        }
        iter.setOffset(test1.length());
        if (iter.next() != CollationElementIterator.NULLORDER) {
            errln("Error: After setting offset to the end of the string, we "
                  + "should be at the end of the forwards iteration");
        }

        // Run all the way through the iterator, then get the offset
        int[] orders = CollationTest.getOrders(iter);
        logln("orders.length = " + orders.length);

        int offset = iter.getOffset();

        if (offset != test1.length()) {
            String msg1 = "offset at end != length: ";
            String msg2 = " vs ";
            errln(msg1 + offset + msg2 + test1.length());
        }

        // Now set the offset back to the beginning and see if it works
        CollationElementIterator pristine = en_us.getCollationElementIterator(test1);

        try {
            iter.setOffset(0);
        } catch(Exception e) {
            errln("setOffset failed.");
        }
        assertEqual(iter, pristine);

        // setting offset in the middle of a contraction
        String contraction = "change";
        RuleBasedCollator tailored = null;
        try {
            tailored = new RuleBasedCollator("& a < ch");
        } catch (Exception e) {
            errln("Error: in creation of Spanish collator");
            return;
        }
        iter = tailored.getCollationElementIterator(contraction);
        int order[] = CollationTest.getOrders(iter);
        iter.setOffset(1); // sets offset in the middle of ch
        int order2[] = CollationTest.getOrders(iter);
        if (!Arrays.equals(order, order2)) {
            errln("Error: setting offset in the middle of a contraction should be the same as setting it to the start of the contraction");
        }
        contraction = "peache";
        iter = tailored.getCollationElementIterator(contraction);
        iter.setOffset(3);
        order = CollationTest.getOrders(iter);
        iter.setOffset(4); // sets offset in the middle of ch
        order2 = CollationTest.getOrders(iter);
        if (!Arrays.equals(order, order2)) {
            errln("Error: setting offset in the middle of a contraction should be the same as setting it to the start of the contraction");
        }
        // setting offset in the middle of a surrogate pair
        String surrogate = "\ud800\udc00str";
        iter = tailored.getCollationElementIterator(surrogate);
        order = CollationTest.getOrders(iter);
        iter.setOffset(1); // sets offset in the middle of surrogate
        order2 = CollationTest.getOrders(iter);
        if (!Arrays.equals(order, order2)) {
            errln("Error: setting offset in the middle of a surrogate pair should be the same as setting it to the start of the surrogate pair");
        }
        surrogate = "simple\ud800\udc00str";
        iter = tailored.getCollationElementIterator(surrogate);
        iter.setOffset(6);
        order = CollationTest.getOrders(iter);
        iter.setOffset(7); // sets offset in the middle of surrogate
        order2 = CollationTest.getOrders(iter);
        if (!Arrays.equals(order, order2)) {
            errln("Error: setting offset in the middle of a surrogate pair should be the same as setting it to the start of the surrogate pair");
        }
        // TODO: try iterating halfway through a messy string.
    }



    void assertEqual(CollationElementIterator i1, CollationElementIterator i2) {
        int c1, c2, count = 0;
        do {
            c1 = i1.next();
            c2 = i2.next();
            if (c1 != c2) {
                errln("    " + count + ": strength(0x" +
                    Integer.toHexString(c1) + ") != strength(0x" + Integer.toHexString(c2) + ")");
                break;
            }
            count += 1;
        } while (c1 != CollationElementIterator.NULLORDER);
        CollationTest.backAndForth(this, i1);
        CollationTest.backAndForth(this, i2);
    }

    /**
     * Test for CollationElementIterator.previous()
     *
     * @bug 4108758 - Make sure it works with contracting characters
     *
     */
    @Test
    public void TestPrevious(/* char* par */) {
        RuleBasedCollator en_us = (RuleBasedCollator)Collator.getInstance(Locale.US);
        CollationElementIterator iter = en_us.getCollationElementIterator(test1);

        // A basic test to see if it's working at all
        CollationTest.backAndForth(this, iter);

        // Test with a contracting character sequence
        String source;
        RuleBasedCollator c1 = null;
        try {
            c1 = new RuleBasedCollator("&a,A < b,B < c,C, d,D < z,Z < ch,cH,Ch,CH");
        } catch (Exception e) {
            errln("Couldn't create a RuleBasedCollator with a contracting sequence.");
            return;
        }

        source = "abchdcba";
        iter = c1.getCollationElementIterator(source);
        CollationTest.backAndForth(this, iter);

        // Test with an expanding character sequence
        RuleBasedCollator c2 = null;
        try {
            c2 = new RuleBasedCollator("&a < b < c/abd < d");
        } catch (Exception e ) {
            errln("Couldn't create a RuleBasedCollator with an expanding sequence.");
            return;
        }

        source = "abcd";
        iter = c2.getCollationElementIterator(source);
        CollationTest.backAndForth(this, iter);

        // Now try both
        RuleBasedCollator c3 = null;
        try {
            c3 = new RuleBasedCollator("&a < b < c/aba < d < z < ch");
        } catch (Exception e) {
            errln("Couldn't create a RuleBasedCollator with both an expanding and a contracting sequence.");
            return;
        }

        source = "abcdbchdc";
        iter = c3.getCollationElementIterator(source);
        CollationTest.backAndForth(this, iter);

        source= "\u0e41\u0e02\u0e41\u0e02\u0e27abc";
        Collator c4 = null;
        try {
            c4 = Collator.getInstance(new Locale("th", "TH", ""));
        } catch (Exception e) {
            errln("Couldn't create a collator");
            return;
        }

        iter = ((RuleBasedCollator)c4).getCollationElementIterator(source);
        CollationTest.backAndForth(this, iter);

        source= "\u0061\u30CF\u3099\u30FC";
        Collator c5 = null;
        try {
            c5 = Collator.getInstance(new Locale("ja", "JP", ""));
        } catch (Exception e) {
            errln("Couldn't create Japanese collator\n");
            return;
        }
        iter = ((RuleBasedCollator)c5).getCollationElementIterator(source);

        CollationTest.backAndForth(this, iter);
    }



    /**
     * Test for setText()
     */
    @Test
    public void TestSetText(/* char* par */) {
        RuleBasedCollator en_us = (RuleBasedCollator)Collator.getInstance(Locale.US);
        CollationElementIterator iter1 = en_us.getCollationElementIterator(test1);
        CollationElementIterator iter2 = en_us.getCollationElementIterator(test2);

        // Run through the second iterator just to exercise it
        int c = iter2.next();
        int i = 0;

        while ( ++i < 10 && c != CollationElementIterator.NULLORDER) {
            try {
                c = iter2.next();
            } catch (Exception e) {
                errln("iter2.next() returned an error.");
                break;
            }
        }

        // Now set it to point to the same string as the first iterator
        try {
            iter2.setText(test1);
        } catch (Exception e) {
            errln("call to iter2->setText(test1) failed.");
            return;
        }
        assertEqual(iter1, iter2);

        iter1.reset();
        //now use the overloaded setText(ChracterIterator&, UErrorCode) function to set the text
        CharacterIterator chariter = new StringCharacterIterator(test1);
        try {
            iter2.setText(chariter);
        } catch (Exception e ) {
            errln("call to iter2->setText(chariter(test1)) failed.");
            return;
        }
        assertEqual(iter1, iter2);

        iter1.reset();
        //now use the overloaded setText(ChracterIterator&, UErrorCode) function to set the text
        UCharacterIterator uchariter = UCharacterIterator.getInstance(test1);
        try {
            iter2.setText(uchariter);
        } catch (Exception e ) {
            errln("call to iter2->setText(uchariter(test1)) failed.");
            return;
        }
        assertEqual(iter1, iter2);
    }

    /**
     * Test for CollationElementIterator previous and next for the whole set of
     * unicode characters.
     */
    @Test
    public void TestUnicodeChar() {
        RuleBasedCollator en_us = (RuleBasedCollator)Collator.getInstance(Locale.US);
        CollationElementIterator iter;
        char codepoint;
        StringBuffer source = new StringBuffer();
        source.append("\u0e4d\u0e4e\u0e4f");
        // source.append("\u04e8\u04e9");
        iter = en_us.getCollationElementIterator(source.toString());
        // A basic test to see if it's working at all
        CollationTest.backAndForth(this, iter);
        for (codepoint = 1; codepoint < 0xFFFE;) {
            source.delete(0, source.length());
            while (codepoint % 0xFF != 0) {
                if (UCharacter.isDefined(codepoint)) {
                    source.append(codepoint);
                }
                codepoint ++;
            }

            if (UCharacter.isDefined(codepoint)) {
                source.append(codepoint);
            }

            if (codepoint != 0xFFFF) {
                codepoint ++;
            }
            /*if (codepoint >= 0x04fc) {
                System.out.println("codepoint " + Integer.toHexString(codepoint));
                String str = source.substring(230, 232);
                System.out.println(com.ibm.icu.impl.Utility.escape(str));
                System.out.println("codepoint " + Integer.toHexString(codepoint)
                                   + "length " + str.length());
                iter = en_us.getCollationElementIterator(str);
                CollationTest.backAndForth(this, iter);
            }
            */
            iter = en_us.getCollationElementIterator(source.toString());
            // A basic test to see if it's working at all
            CollationTest.backAndForth(this, iter);
        }
    }

    /**
     * Test for CollationElementIterator previous and next for the whole set of
     * unicode characters with normalization on.
     */
    @Test
    public void TestNormalizedUnicodeChar()
    {
        // thai should have normalization on
        RuleBasedCollator th_th = null;
        try {
            th_th = (RuleBasedCollator)Collator.getInstance(
                                                       new Locale("th", "TH"));
        } catch (Exception e) {
            warnln("Error creating Thai collator");
            return;
        }
        StringBuffer source = new StringBuffer();
        source.append('\uFDFA');
        CollationElementIterator iter
                        = th_th.getCollationElementIterator(source.toString());
        CollationTest.backAndForth(this, iter);
        for (char codepoint = 0x1; codepoint < 0xfffe;) {
            source.delete(0, source.length());
            while (codepoint % 0xFF != 0) {
                if (UCharacter.isDefined(codepoint)) {
                    source.append(codepoint);
                }
                codepoint ++;
            }

            if (UCharacter.isDefined(codepoint)) {
                source.append(codepoint);
            }

            if (codepoint != 0xFFFF) {
                codepoint ++;
            }

            /*if (((int)codepoint) >= 0xfe00) {
                String str = source.substring(185, 190);
                System.out.println(com.ibm.icu.impl.Utility.escape(str));
                System.out.println("codepoint "
                                   + Integer.toHexString(codepoint)
                                   + "length " + str.length());
                iter = th_th.getCollationElementIterator(str);
                CollationTest.backAndForth(this, iter);
            */
            iter = th_th.getCollationElementIterator(source.toString());
            // A basic test to see if it's working at all
            CollationTest.backAndForth(this, iter);
        }
    }

    /**
    * Testing the discontiguous contractions
    */
    @Test
    public void TestDiscontiguous()
    {
        String rulestr ="&z < AB < X\u0300 < ABC < X\u0300\u0315";
        String src[] = {"ADB", "ADBC", "A\u0315B", "A\u0315BC",
                        // base character blocked
                        "XD\u0300", "XD\u0300\u0315",
                        // non blocking combining character
                        "X\u0319\u0300", "X\u0319\u0300\u0315",
                        // blocking combining character
                        "X\u0314\u0300", "X\u0314\u0300\u0315",
                        // contraction prefix
                        "ABDC", "AB\u0315C","X\u0300D\u0315",
                        "X\u0300\u0319\u0315", "X\u0300\u031A\u0315",
                        // ends not with a contraction character
                        "X\u0319\u0300D", "X\u0319\u0300\u0315D",
                        "X\u0300D\u0315D", "X\u0300\u0319\u0315D",
                        "X\u0300\u031A\u0315D"
        };
        String tgt[] = {// non blocking combining character
                        "A D B", "A D BC", "A \u0315 B", "A \u0315 BC",
                        // base character blocked
                        "X D \u0300", "X D \u0300\u0315",
                        // non blocking combining character
                        "X\u0300 \u0319", "X\u0300\u0315 \u0319",
                        // blocking combining character
                        "X \u0314 \u0300", "X \u0314 \u0300\u0315",
                        // contraction prefix
                        "AB DC", "AB \u0315 C","X\u0300 D \u0315",
                        "X\u0300\u0315 \u0319", "X\u0300 \u031A \u0315",
                        // ends not with a contraction character
                        "X\u0300 \u0319D", "X\u0300\u0315 \u0319D",
                        "X\u0300 D\u0315D", "X\u0300\u0315 \u0319D",
                        "X\u0300 \u031A\u0315D"
        };
        int count = 0;
        try {
            RuleBasedCollator coll = new RuleBasedCollator(rulestr);
            CollationElementIterator iter
                                        = coll.getCollationElementIterator("");
            CollationElementIterator resultiter
                                        = coll.getCollationElementIterator("");
            while (count < src.length) {
                iter.setText(src[count]);
                int s = 0;
                while (s < tgt[count].length()) {
                    int e = tgt[count].indexOf(' ', s);
                    if (e < 0) {
                        e = tgt[count].length();
                    }
                    String resultstr = tgt[count].substring(s, e);
                    resultiter.setText(resultstr);
                    int ce = resultiter.next();
                    while (ce != CollationElementIterator.NULLORDER) {
                        if (ce != iter.next()) {
                            errln("Discontiguos contraction test mismatch at"
                                  + count);
                            return;
                        }
                        ce = resultiter.next();
                    }
                    s = e + 1;
                }
                iter.reset();
                CollationTest.backAndForth(this, iter);
                count ++;
            }
        }
        catch (Exception e) {
            warnln("Error running discontiguous tests " + e.toString());
        }
    }

    /**
    * Test the incremental normalization
    */
    @Test
    public void TestNormalization()
    {
        String rules = "&a < \u0300\u0315 < A\u0300\u0315 < \u0316\u0315B < \u0316\u0300\u0315";
        String testdata[] = {"\u1ED9", "o\u0323\u0302",
                            "\u0300\u0315", "\u0315\u0300",
                            "A\u0300\u0315B", "A\u0315\u0300B",
                            "A\u0316\u0315B", "A\u0315\u0316B",
                            "\u0316\u0300\u0315", "\u0315\u0300\u0316",
                            "A\u0316\u0300\u0315B", "A\u0315\u0300\u0316B",
                            "\u0316\u0315\u0300", "A\u0316\u0315\u0300B"};
        RuleBasedCollator coll = null;
        try {
            coll = new RuleBasedCollator(rules);
            coll.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
        } catch (Exception e) {
            warnln("ERROR: in creation of collator using rules " + rules);
            return;
        }

        CollationElementIterator iter = coll.getCollationElementIterator("testing");
        for (int count = 0; count < testdata.length; count ++) {
            iter.setText(testdata[count]);
            CollationTest.backAndForth(this, iter);
        }
    }

    /**
     * TestSearchCollatorElements tests iterator behavior (forwards and backwards) with
     * normalization on AND jamo tailoring, among other things.
     *
     * Note: This test is sensitive to changes of the root collator,
     * for example whether the ae-ligature maps to three CEs (as in the DUCET)
     * or to two CEs (as in the CLDR 24 FractionalUCA.txt).
     * It is also sensitive to how those CEs map to the iterator's 32-bit CE encoding.
     * For example, the DUCET's artificial secondary CE in the ae-ligature
     * may map to two 32-bit iterator CEs (as it did until ICU 52).
     */
    @Test
    public void TestSearchCollatorElements()
    {
        String tsceText =
            " \uAC00" +              // simple LV Hangul
            " \uAC01" +              // simple LVT Hangul
            " \uAC0F" +              // LVTT, last jamo expands for search
            " \uAFFF" +              // LLVVVTT, every jamo expands for search
            " \u1100\u1161\u11A8" +  // 0xAC01 as conjoining jamo
            " \u3131\u314F\u3131" +  // 0xAC01 as compatibility jamo
            " \u1100\u1161\u11B6" +  // 0xAC0F as conjoining jamo; last expands for search
            " \u1101\u1170\u11B6" +  // 0xAFFF as conjoining jamo; all expand for search
            " \u00E6" +              // small letter ae, expands
            " \u1E4D" +              // small letter o with tilde and acute, decomposes
            " ";

        int[] rootStandardOffsets = {
            0,  1,2,
            2,  3,4,4,
            4,  5,6,6,
            6,  7,8,8,
            8,  9,10,11,
            12, 13,14,15,
            16, 17,18,19,
            20, 21,22,23,
            24, 25,26,  /* plus another 1-2 offset=26 if ae-ligature maps to three CEs */
            26, 27,28,28,
            28,
            29
        };

        int[] rootSearchOffsets = {
            0,  1,2,
            2,  3,4,4,
            4,  5,6,6,6,
            6,  7,8,8,8,8,8,8,
            8,  9,10,11,
            12, 13,14,15,
            16, 17,18,19,20,
            20, 21,22,22,23,23,23,24,
            24, 25,26,  /* plus another 1-2 offset=26 if ae-ligature maps to three CEs */
            26, 27,28,28,
            28,
            29
        };

        class TSCEItem {
            private String localeString;
            private int[] offsets;
            TSCEItem(String locStr, int[] offs) {
                localeString = locStr;
                offsets = offs;
            }
            public String getLocaleString() { return localeString; }
            public int[] getOffsets() { return offsets; }
        }
        final TSCEItem[] tsceItems = {
            new TSCEItem( "root",                  rootStandardOffsets ),
            new TSCEItem( "root@collation=search", rootSearchOffsets   ),
        };

        for (TSCEItem tsceItem: tsceItems) {
            String localeString = tsceItem.getLocaleString();
            ULocale uloc = new ULocale(localeString);
            RuleBasedCollator col = null;
            try {
                col = (RuleBasedCollator)Collator.getInstance(uloc);
            } catch (Exception e) {
                errln("Error: in locale " + localeString + ", err in Collator.getInstance");
                continue;
            }
            CollationElementIterator uce = col.getCollationElementIterator(tsceText);
            int[] offsets = tsceItem.getOffsets();
            int ioff, noff = offsets.length;
            int offset, element;

            ioff = 0;
            do {
                offset = uce.getOffset();
                element = uce.next();
                logln(String.format("(%s) offset=%2d  ce=%08x\n", tsceItem.localeString, offset, element));
                if (element == 0) {
                    errln("Error: in locale " + localeString + ", CEIterator next() returned element 0");
                }
                if ( ioff < noff ) {
                    if ( offset != offsets[ioff] ) {
                        errln("Error: in locale " + localeString + ", expected CEIterator next()->getOffset " + offsets[ioff] + ", got " + offset);
                        //ioff = noff;
                        //break;
                    }
                    ioff++;
                } else {
                    errln("Error: in locale " + localeString + ", CEIterator next() returned more elements than expected");
                }
            } while (element != CollationElementIterator.NULLORDER);
            if ( ioff < noff ) {
                errln("Error: in locale " + localeString + ", CEIterator next() returned fewer elements than expected");
            }

            // backwards test
            uce.setOffset(tsceText.length());
            ioff = noff;
            do {
                offset = uce.getOffset();
                element = uce.previous();
                if (element == 0) {
                    errln("Error: in locale " + localeString + ", CEIterator previous() returned element 0");
                }
                if ( ioff > 0 ) {
                    ioff--;
                    if ( offset != offsets[ioff] ) {
                        errln("Error: in locale " + localeString + ", expected CEIterator previous()->getOffset " + offsets[ioff] + ", got " + offset);
                        //ioff = 0;
                        //break;
                    }
                } else {
                    errln("Error: in locale " + localeString + ", CEIterator previous() returned more elements than expected");
                }
            } while (element != CollationElementIterator.NULLORDER);
            if ( ioff > 0 ) {
                errln("Error: in locale " + localeString + ", CEIterator previous() returned fewer elements than expected");
            }
        }
    }
}
