// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 *******************************************************************************
 * Copyright (C) 2007-2015, International Business Machines Corporation and
 * others. All Rights Reserved.
 *******************************************************************************
 */
package com.ibm.icu.dev.test.format;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

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.dev.test.serializable.SerializableTestUtility;
import com.ibm.icu.dev.util.CollectionUtilities;
import com.ibm.icu.impl.Relation;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.number.FormattedNumber;
import com.ibm.icu.number.FormattedNumberRange;
import com.ibm.icu.number.LocalizedNumberFormatter;
import com.ibm.icu.number.NumberFormatter;
import com.ibm.icu.number.NumberRangeFormatter;
import com.ibm.icu.number.Precision;
import com.ibm.icu.number.UnlocalizedNumberFormatter;
import com.ibm.icu.text.NumberFormat;
import com.ibm.icu.text.PluralRules;
import com.ibm.icu.text.PluralRules.FixedDecimal;
import com.ibm.icu.text.PluralRules.FixedDecimalRange;
import com.ibm.icu.text.PluralRules.FixedDecimalSamples;
import com.ibm.icu.text.PluralRules.KeywordStatus;
import com.ibm.icu.text.PluralRules.PluralType;
import com.ibm.icu.text.PluralRules.SampleType;
import com.ibm.icu.text.UFieldPosition;
import com.ibm.icu.util.Output;
import com.ibm.icu.util.ULocale;

/**
 * @author dougfelt (Doug Felt)
 * @author markdavis (Mark Davis) [for fractional support]
 */
@RunWith(JUnit4.class)
public class PluralRulesTest extends TestFmwk {

    PluralRulesFactory factory = PluralRulesFactory.NORMAL;

    @Test
    public void testOverUnderflow() {
        logln(String.valueOf(Long.MAX_VALUE + 1d));
        for (double[] testDouble : new double[][] {
                { 1E18, 0, 0, 1E18 }, // check overflow
                { 10000000000000.1d, 1, 1, 10000000000000d }, { -0.00001d, 1, 5, 0 }, { 1d, 0, 0, 1 },
                { 1.1d, 1, 1, 1 }, { 12345d, 0, 0, 12345 }, { 12345.678912d, 678912, 6, 12345 },
                { 12345.6789123d, 678912, 6, 12345 }, // we only go out 6 digits
                { 1E18, 0, 0, 1E18 }, // check overflow
                { 1E19, 0, 0, 1E18 }, // check overflow
        }) {
            FixedDecimal fd = new FixedDecimal(testDouble[0]);
            assertEquals(testDouble[0] + "=doubleValue()", testDouble[0], fd.doubleValue());
            assertEquals(testDouble[0] + " decimalDigits", (int) testDouble[1], fd.getDecimalDigits());
            assertEquals(testDouble[0] + " visibleDecimalDigitCount", (int) testDouble[2], fd.getVisibleDecimalDigitCount());
            assertEquals(testDouble[0] + " decimalDigitsWithoutTrailingZeros", (int) testDouble[1],
                    fd.getDecimalDigitsWithoutTrailingZeros());
            assertEquals(testDouble[0] + " visibleDecimalDigitCountWithoutTrailingZeros", (int) testDouble[2],
                    fd.getVisibleDecimalDigitCountWithoutTrailingZeros());
            assertEquals(testDouble[0] + " integerValue", (long) testDouble[3], fd.getIntegerValue());
        }

        for (ULocale locale : new ULocale[] { ULocale.ENGLISH, new ULocale("cy"), new ULocale("ar") }) {
            PluralRules rules = factory.forLocale(locale);

            assertEquals(locale + " NaN", "other", rules.select(Double.NaN));
            assertEquals(locale + " ∞", "other", rules.select(Double.POSITIVE_INFINITY));
            assertEquals(locale + " -∞", "other", rules.select(Double.NEGATIVE_INFINITY));
        }
    }

    @Test
    public void testSyntaxRestrictions() {
        Object[][] shouldFail = {
                { "a:n in 3..10,13..19" },

                // = and != always work
                { "a:n=1" },
                { "a:n=1,3" },
                { "a:n!=1" },
                { "a:n!=1,3" },

                // with spacing
                { "a: n = 1" },
                { "a: n = 1, 3" },
                { "a: n != 1" },
                { "a: n != 1, 3" },
                { "a: n ! = 1" },
                { "a: n ! = 1, 3" },
                { "a: n = 1 , 3" },
                { "a: n != 1 , 3" },
                { "a: n ! = 1 , 3" },
                { "a: n = 1 .. 3" },
                { "a: n != 1 .. 3" },
                { "a: n ! = 1 .. 3" },

                // more complicated
                { "a:n in 3 .. 10 , 13 .. 19" },

                // singles have special exceptions
                { "a: n is 1" },
                { "a: n is not 1" },
                { "a: n not is 1", ParseException.class }, // hacked to fail
                { "a: n in 1" },
                { "a: n not in 1" },

                // multiples also have special exceptions
                // TODO enable the following once there is an update to CLDR
                // {"a: n is 1,3", ParseException.class},
                { "a: n is not 1,3", ParseException.class }, // hacked to fail
                { "a: n not is 1,3", ParseException.class }, // hacked to fail
                { "a: n in 1,3" },
                { "a: n not in 1,3" },

                // disallow not with =
                { "a: n not= 1", ParseException.class }, // hacked to fail
                { "a: n not= 1,3", ParseException.class }, // hacked to fail

                // disallow double negatives
                { "a: n ! is not 1", ParseException.class },
                { "a: n ! is not 1", ParseException.class },
                { "a: n not not in 1", ParseException.class },
                { "a: n is not not 1", NumberFormatException.class },

                // disallow screwy cases
                { null, NullPointerException.class }, { "djkl;", ParseException.class },
                { "a: n = 1 .", ParseException.class }, { "a: n = 1 ..", ParseException.class },
                { "a: n = 1 2", ParseException.class }, { "a: n = 1 ,", ParseException.class },
                { "a:n in 3 .. 10 , 13 .. 19 ,", ParseException.class }, };
        for (Object[] shouldFailTest : shouldFail) {
            String rules = (String) shouldFailTest[0];
            Class exception = shouldFailTest.length < 2 ? null : (Class) shouldFailTest[1];
            Class actualException = null;
            try {
                PluralRules.parseDescription(rules);
            } catch (Exception e) {
                actualException = e.getClass();
            }
            assertEquals("Exception " + rules, exception, actualException);
        }
    }

    @Test
    public void testSamples() {
        String description = "one: n is 3 or f is 5 @integer  3,19, @decimal 3.50 ~ 3.53,   …; other:  @decimal 99.0~99.2, 999.0, …";
        PluralRules test = PluralRules.createRules(description);

        checkNewSamples(description, test, "one", PluralRules.SampleType.INTEGER, "@integer 3, 19", true,
                new FixedDecimal(3));
        checkNewSamples(description, test, "one", PluralRules.SampleType.DECIMAL, "@decimal 3.50~3.53, …", false,
                new FixedDecimal(3.5, 2));
        checkOldSamples(description, test, "one", SampleType.INTEGER, 3d, 19d);
        checkOldSamples(description, test, "one", SampleType.DECIMAL, 3.5d, 3.51d, 3.52d, 3.53d);

        checkNewSamples(description, test, "other", PluralRules.SampleType.INTEGER, "", true, null);
        checkNewSamples(description, test, "other", PluralRules.SampleType.DECIMAL, "@decimal 99.0~99.2, 999.0, …",
                false, new FixedDecimal(99d, 1));
        checkOldSamples(description, test, "other", SampleType.INTEGER);
        checkOldSamples(description, test, "other", SampleType.DECIMAL, 99d, 99.1, 99.2d, 999d);
    }

    /**
     * This test is for the support of X.YeZ scientific notation of numbers in
     * the plural sample string.
     */
    @Test
    public void testSamplesWithExponent() {
        String description = "one: i = 0,1 @integer 0, 1, 1e5 @decimal 0.0~1.5, 1.1e5; "
                + "many: e = 0 and i != 0 and i % 1000000 = 0 and v = 0 or e != 0..5"
                + " @integer 1000000, 2e6, 3e6, 4e6, 5e6, 6e6, 7e6, … @decimal 2.1e6, 3.1e6, 4.1e6, 5.1e6, 6.1e6, 7.1e6, …; "
                + "other:  @integer 2~17, 100, 1000, 10000, 100000, 2e5, 3e5, 4e5, 5e5, 6e5, 7e5, …"
                + " @decimal 2.0~3.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 2.1e5, 3.1e5, 4.1e5, 5.1e5, 6.1e5, 7.1e5, …"
                ;
        // Creating the PluralRules object means being able to parse numbers
        // like 1e5 and 1.1e5
        PluralRules test = PluralRules.createRules(description);
        checkNewSamples(description, test, "one", PluralRules.SampleType.INTEGER, "@integer 0, 1, 1e5", true,
                new FixedDecimal(0));
        checkNewSamples(description, test, "one", PluralRules.SampleType.DECIMAL, "@decimal 0.0~1.5, 1.1e5", true,
                new FixedDecimal(0, 1));
        checkNewSamples(description, test, "many", PluralRules.SampleType.INTEGER, "@integer 1000000, 2e6, 3e6, 4e6, 5e6, 6e6, 7e6, …", false,
                new FixedDecimal(1000000));
        checkNewSamples(description, test, "many", PluralRules.SampleType.DECIMAL, "@decimal 2.1e6, 3.1e6, 4.1e6, 5.1e6, 6.1e6, 7.1e6, …", false,
                FixedDecimal.createWithExponent(2.1, 1, 6));
        checkNewSamples(description, test, "other", PluralRules.SampleType.INTEGER, "@integer 2~17, 100, 1000, 10000, 100000, 2e5, 3e5, 4e5, 5e5, 6e5, 7e5, …", false,
                new FixedDecimal(2));
        checkNewSamples(description, test, "other", PluralRules.SampleType.DECIMAL, "@decimal 2.0~3.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 2.1e5, 3.1e5, 4.1e5, 5.1e5, 6.1e5, 7.1e5, …", false,
                new FixedDecimal(2.0, 1));
    }

    /**
     * This test is for the support of X.YcZ compactnotation of numbers in
     * the plural sample string.
     */
    @Test
    public void testSamplesWithCompactNotation() {
        String description = "one: i = 0,1 @integer 0, 1, 1c5 @decimal 0.0~1.5, 1.1c5; "
                + "many: c = 0 and i != 0 and i % 1000000 = 0 and v = 0 or c != 0..5"
                + " @integer 1000000, 2c6, 3c6, 4c6, 5c6, 6c6, 7c6, … @decimal 2.1c6, 3.1c6, 4.1c6, 5.1c6, 6.1c6, 7.1c6, …; "
                + "other:  @integer 2~17, 100, 1000, 10000, 100000, 2c5, 3c5, 4c5, 5c5, 6c5, 7c5, …"
                + " @decimal 2.0~3.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 2.1c5, 3.1c5, 4.1c5, 5.1c5, 6.1c5, 7.1c5, …"
                ;
        // Creating the PluralRules object means being able to parse numbers
        // like 1c5 and 1.1c5.
        // Note: Since `c` is currently an alias to `e`, the toString() of
        // FixedDecimal will return "1e5" even when input is "1c5".
        PluralRules test = PluralRules.createRules(description);
        checkNewSamples(description, test, "one", PluralRules.SampleType.INTEGER, "@integer 0, 1, 1e5", true,
                new FixedDecimal(0));
        checkNewSamples(description, test, "one", PluralRules.SampleType.DECIMAL, "@decimal 0.0~1.5, 1.1e5", true,
                new FixedDecimal(0, 1));
        checkNewSamples(description, test, "many", PluralRules.SampleType.INTEGER, "@integer 1000000, 2e6, 3e6, 4e6, 5e6, 6e6, 7e6, …", false,
                new FixedDecimal(1000000));
        checkNewSamples(description, test, "many", PluralRules.SampleType.DECIMAL, "@decimal 2.1e6, 3.1e6, 4.1e6, 5.1e6, 6.1e6, 7.1e6, …", false,
                FixedDecimal.createWithExponent(2.1, 1, 6));
        checkNewSamples(description, test, "other", PluralRules.SampleType.INTEGER, "@integer 2~17, 100, 1000, 10000, 100000, 2e5, 3e5, 4e5, 5e5, 6e5, 7e5, …", false,
                new FixedDecimal(2));
        checkNewSamples(description, test, "other", PluralRules.SampleType.DECIMAL, "@decimal 2.0~3.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 2.1e5, 3.1e5, 4.1e5, 5.1e5, 6.1e5, 7.1e5, …", false,
                new FixedDecimal(2.0, 1));
    }

    public void checkOldSamples(String description, PluralRules rules, String keyword, SampleType sampleType,
            Double... expected) {
        Collection<Double> oldSamples = rules.getSamples(keyword, sampleType);
        if (!assertEquals("getOldSamples; " + keyword + "; " + description, new HashSet(Arrays.asList(expected)),
                oldSamples)) {
            rules.getSamples(keyword, sampleType);
        }
    }

    public void checkNewSamples(String description, PluralRules test, String keyword, SampleType sampleType,
            String samplesString, boolean isBounded, FixedDecimal firstInRange) {
        String title = description + ", " + sampleType;
        FixedDecimalSamples samples = test.getDecimalSamples(keyword, sampleType);
        if (samples != null) {
            assertEquals("samples; " + title, samplesString, samples.toString());
            assertEquals("bounded; " + title, isBounded, samples.bounded);
            assertEquals("first; " + title, firstInRange, samples.samples.iterator().next().start);
        }
        assertEquals("limited: " + title, isBounded, test.isLimited(keyword, sampleType));
    }

    private static final String[] parseTestData = { "a: n is 1", "a:1", "a: n mod 10 is 2", "a:2,12,22",
            "a: n is not 1", "a:0,2,3,4,5", "a: n mod 3 is not 1", "a:0,2,3,5,6,8,9", "a: n in 2..5", "a:2,3,4,5",
            "a: n within 2..5", "a:2,3,4,5", "a: n not in 2..5", "a:0,1,6,7,8", "a: n not within 2..5", "a:0,1,6,7,8",
            "a: n mod 10 in 2..5", "a:2,3,4,5,12,13,14,15,22,23,24,25", "a: n mod 10 within 2..5",
            "a:2,3,4,5,12,13,14,15,22,23,24,25", "a: n mod 10 is 2 and n is not 12", "a:2,22,32,42",
            "a: n mod 10 in 2..3 or n mod 10 is 5", "a:2,3,5,12,13,15,22,23,25",
            "a: n mod 10 within 2..3 or n mod 10 is 5", "a:2,3,5,12,13,15,22,23,25", "a: n is 1 or n is 4 or n is 23",
            "a:1,4,23", "a: n mod 2 is 1 and n is not 3 and n in 1..11", "a:1,5,7,9,11",
            "a: n mod 2 is 1 and n is not 3 and n within 1..11", "a:1,5,7,9,11",
            "a: n mod 2 is 1 or n mod 5 is 1 and n is not 6", "a:1,3,5,7,9,11,13,15,16",
            "a: n in 2..5; b: n in 5..8; c: n mod 2 is 1", "a:2,3,4,5;b:6,7,8;c:1,9,11",
            "a: n within 2..5; b: n within 5..8; c: n mod 2 is 1", "a:2,3,4,5;b:6,7,8;c:1,9,11",
            "a: n in 2,4..6; b: n within 7..9,11..12,20", "a:2,4,5,6;b:7,8,9,11,12,20",
            "a: n in 2..8,12 and n not in 4..6", "a:2,3,7,8,12", "a: n mod 10 in 2,3,5..7 and n is not 12",
            "a:2,3,5,6,7,13,15,16,17", "a: n in 2..6,3..7", "a:2,3,4,5,6,7", };

    private String[] getTargetStrings(String targets) {
        List list = new ArrayList(50);
        String[] valSets = Utility.split(targets, ';');
        for (int i = 0; i < valSets.length; ++i) {
            String[] temp = Utility.split(valSets[i], ':');
            String key = temp[0].trim();
            String[] vals = Utility.split(temp[1], ',');
            for (int j = 0; j < vals.length; ++j) {
                String valString = vals[j].trim();
                int val = Integer.parseInt(valString);
                while (list.size() <= val) {
                    list.add(null);
                }
                if (list.get(val) != null) {
                    fail("test data error, key: " + list.get(val) + " already set for: " + val);
                }
                list.set(val, key);
            }
        }

        String[] result = (String[]) list.toArray(new String[list.size()]);
        for (int i = 0; i < result.length; ++i) {
            if (result[i] == null) {
                result[i] = "other";
            }
        }
        return result;
    }

    private void checkTargets(PluralRules rules, String[] targets) {
        for (int i = 0; i < targets.length; ++i) {
            assertEquals("value " + i, targets[i], rules.select(i));
        }
    }

    @Test
    public void testParseEmpty() throws ParseException {
        PluralRules rules = PluralRules.parseDescription("a:n");
        assertEquals("empty", "a", rules.select(0));
    }

    @Test
    public void testParsing() {
        for (int i = 0; i < parseTestData.length; i += 2) {
            String pattern = parseTestData[i];
            String expected = parseTestData[i + 1];

            logln("pattern[" + i + "] " + pattern);
            try {
                PluralRules rules = PluralRules.createRules(pattern);
                String[] targets = getTargetStrings(expected);
                checkTargets(rules, targets);
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e.getMessage());
            }
        }
    }

    private static String[][] operandTestData = { { "a: n 3", "FAIL" },
            { "a: n=1,2; b: n != 3..5; c:n!=5", "a:1,2; b:6,7; c:3,4" },
            { "a: n=1,2; b: n!=3..5; c:n!=5", "a:1,2; b:6,7; c:3,4" },
            { "a: t is 1", "a:1.1,1.1000,99.100; other:1.2,1.0" }, { "a: f is 1", "a:1.1; other:1.1000,99.100" },
            { "a: i is 2; b:i is 3", "b: 3.5; a: 2.5" }, { "a: f is 0; b:f is 50", "a: 1.00; b: 1.50" },
            { "a: v is 1; b:v is 2", "a: 1.0; b: 1.00" }, { "one: n is 1 AND v is 0", "one: 1 ; other: 1.00,1.0" }, // English
                                                                                                                    // rules
            { "one: v is 0 and i mod 10 is 1 or f mod 10 is 1", "one: 1, 1.1, 3.1; other: 1.0, 3.2, 5" }, // Last
                                                                                                          // visible
                                                                                                          // digit
            { "one: j is 0", "one: 0; other: 0.0, 1.0, 3" }, // Last visible digit
    // one → n is 1; few → n in 2..4;
    };

    @Test
    public void testOperands() {
        for (String[] pair : operandTestData) {
            String pattern = pair[0].trim();
            String categoriesAndExpected = pair[1].trim();

            // logln("pattern[" + i + "] " + pattern);
            boolean FAIL_EXPECTED = categoriesAndExpected.equalsIgnoreCase("fail");
            try {
                logln(pattern);
                PluralRules rules = PluralRules.createRules(pattern);
                if (FAIL_EXPECTED) {
                    assertNull("Should fail with 'null' return.", rules);
                } else {
                    logln(rules == null ? "null rules" : rules.toString());
                    checkCategoriesAndExpected(pattern, categoriesAndExpected, rules);
                }
            } catch (Exception e) {
                if (!FAIL_EXPECTED) {
                    e.printStackTrace();
                    throw new RuntimeException(e.getMessage());
                }
            }
        }
    }

    @Test
    public void testUniqueRules() {
        main: for (ULocale locale : factory.getAvailableULocales()) {
            PluralRules rules = factory.forLocale(locale);
            Map<String, PluralRules> keywordToRule = new HashMap<>();
            Collection<FixedDecimalSamples> samples = new LinkedHashSet<>();

            for (String keyword : rules.getKeywords()) {
                for (SampleType sampleType : SampleType.values()) {
                    FixedDecimalSamples samples2 = rules.getDecimalSamples(keyword, sampleType);
                    if (samples2 != null) {
                        samples.add(samples2);
                    }
                }
                if (keyword.equals("other")) {
                    continue;
                }
                String rules2 = keyword + ":" + rules.getRules(keyword);
                PluralRules singleRule = PluralRules.createRules(rules2);
                if (singleRule == null) {
                    errln("Can't generate single rule for " + rules2);
                    PluralRules.createRules(rules2); // for debugging
                    continue main;
                }
                keywordToRule.put(keyword, singleRule);
            }
            Map<FixedDecimal, String> collisionTest = new TreeMap();
            for (FixedDecimalSamples sample3 : samples) {
                Set<FixedDecimalRange> samples2 = sample3.getSamples();
                if (samples2 == null) {
                    continue;
                }
                for (FixedDecimalRange sample : samples2) {
                    for (int i = 0; i < 1; ++i) {
                        FixedDecimal item = i == 0 ? sample.start : sample.end;
                        collisionTest.clear();
                        for (Entry<String, PluralRules> entry : keywordToRule.entrySet()) {
                            PluralRules rule = entry.getValue();
                            String foundKeyword = rule.select(item);
                            if (foundKeyword.equals("other")) {
                                continue;
                            }
                            String old = collisionTest.get(item);
                            if (old != null) {
                                if (!locale.getLanguage().equals("fr") ||
                                        !logKnownIssue("21328", "fr Non-unique rules: 1e6 => one & many")) {
                                    errln(locale + "\tNon-unique rules: " + item + " => " + old + " & " + foundKeyword);
                                }
                                rule.select(item);
                            } else {
                                collisionTest.put(item, foundKeyword);
                            }
                        }
                    }
                }
            }
        }
    }

    private void checkCategoriesAndExpected(String title1, String categoriesAndExpected, PluralRules rules) {
        for (String categoryAndExpected : categoriesAndExpected.split("\\s*;\\s*")) {
            String[] categoryFromExpected = categoryAndExpected.split("\\s*:\\s*");
            String expected = categoryFromExpected[0];
            for (String value : categoryFromExpected[1].split("\\s*,\\s*")) {
                if (value.startsWith("@") || value.equals("…") || value.equals("null")) {
                    continue;
                }
                String[] values = value.split("\\s*~\\s*");
                checkValue(title1, rules, expected, values[0]);
                if (values.length > 1) {
                    checkValue(title1, rules, expected, values[1]);
                }
            }
        }
    }

    public void checkValue(String title1, PluralRules rules, String expected, String value) {
        double number = Double.parseDouble(value);
        int decimalPos = value.indexOf('.') + 1;
        int countVisibleFractionDigits;
        int fractionaldigits;
        if (decimalPos == 0) {
            countVisibleFractionDigits = fractionaldigits = 0;
        } else {
            countVisibleFractionDigits = value.length() - decimalPos;
            fractionaldigits = Integer.parseInt(value.substring(decimalPos));
        }
        String result = rules.select(number, countVisibleFractionDigits, fractionaldigits);
        ULocale locale = null;
        assertEquals(getAssertMessage(title1, locale, rules, expected) + "; value: " + value, expected, result);
    }

    private static String[][] equalityTestData = {
            // once we add fractions, we had to retract the "test all possibilities" for equality,
            // so we only have a limited set of equality tests now.
            { "c: n%11!=5", "c: n mod 11 is not 5" }, { "c: n is not 7", "c: n != 7" }, { "a:n in 2;", "a: n = 2" },
            { "b:n not in 5;", "b: n != 5" },

    // { "a: n is 5",
    // "a: n in 2..6 and n not in 2..4 and n is not 6" },
    // { "a: n in 2..3",
    // "a: n is 2 or n is 3",
    // "a: n is 3 and n in 2..5 or n is 2" },
    // { "a: n is 12; b:n mod 10 in 2..3",
    // "b: n mod 10 in 2..3 and n is not 12; a: n in 12..12",
    // "b: n is 13; a: n is 12; b: n mod 10 is 2 or n mod 10 is 3" },
    };

    private static String[][] inequalityTestData = { { "a: n mod 8 is 3", "a: n mod 7 is 3" },
            { "a: n mod 3 is 2 and n is not 5", "a: n mod 6 is 2 or n is 8 or n is 11" },
            // the following are currently inequal, but we may make them equal in the future.
            { "a: n in 2..5", "a: n in 2..4,5" }, };

    private void compareEquality(String id, Object[] objects, boolean shouldBeEqual) {
        for (int i = 0; i < objects.length; ++i) {
            Object lhs = objects[i];
            int start = shouldBeEqual ? i : i + 1;
            for (int j = start; j < objects.length; ++j) {
                Object rhs = objects[j];
                if (rhs == null || shouldBeEqual != lhs.equals(rhs)) {
                    String msg = shouldBeEqual ? "should be equal" : "should not be equal";
                    fail(id + " " + msg + " (" + i + ", " + j + "):\n    " + lhs + "\n    " + rhs);
                }
                // assertEquals("obj " + i + " and " + j, lhs, rhs);
            }
        }
    }

    private void compareEqualityTestSets(String[][] sets, boolean shouldBeEqual) {
        for (int i = 0; i < sets.length; ++i) {
            String[] patterns = sets[i];
            PluralRules[] rules = new PluralRules[patterns.length];
            for (int j = 0; j < patterns.length; ++j) {
                rules[j] = PluralRules.createRules(patterns[j]);
            }
            compareEquality("test " + i, rules, shouldBeEqual);
        }
    }

    @Test
    public void testEquality() {
        compareEqualityTestSets(equalityTestData, true);
    }

    @Test
    public void testInequality() {
        compareEqualityTestSets(inequalityTestData, false);
    }

    @Test
    public void testBuiltInRules() {
        Object[][] cases = {
                {"en-US", PluralRules.KEYWORD_OTHER, 0},
                {"en-US", PluralRules.KEYWORD_ONE, 1},
                {"en-US", PluralRules.KEYWORD_OTHER, 2},
                {"ja-JP", PluralRules.KEYWORD_OTHER, 0},
                {"ja-JP", PluralRules.KEYWORD_OTHER, 1},
                {"ja-JP", PluralRules.KEYWORD_OTHER, 2},
                {"ru", PluralRules.KEYWORD_MANY, 0},
                {"ru", PluralRules.KEYWORD_ONE, 1},
                {"ru", PluralRules.KEYWORD_FEW, 2}
        };
        for (Object[] cas : cases) {
            ULocale locale = new ULocale((String) cas[0]);
            PluralRules rules = factory.forLocale(locale);
            String expectedKeyword = (String) cas[1];
            double number = (Integer) cas[2];
            String message = locale + " " + number;
            // Check both as double and as FormattedNumber.
            assertEquals(message, expectedKeyword, rules.select(number));
            FormattedNumber fn = NumberFormatter.withLocale(locale).format(number);
            assertEquals(message, expectedKeyword, rules.select(fn));
        }
    }

    @Test
    public void testSelectTrailingZeros() {
        UnlocalizedNumberFormatter unf = NumberFormatter.with()
                .precision(Precision.fixedFraction(2));
        Object[][] cases = {
                // 1) locale
                // 2) double expected keyword
                // 3) formatted number expected keyword (2 fraction digits)
                // 4) input number
                {"bs",  PluralRules.KEYWORD_FEW,   PluralRules.KEYWORD_OTHER, 5.2},  // 5.2 => two, but 5.20 => other
                {"si",  PluralRules.KEYWORD_ONE,   PluralRules.KEYWORD_ONE,   0.0},
                {"si",  PluralRules.KEYWORD_ONE,   PluralRules.KEYWORD_ONE,   1.0},
                {"si",  PluralRules.KEYWORD_ONE,   PluralRules.KEYWORD_OTHER, 0.1},  // 0.1 => one, but 0.10 => other
                {"si",  PluralRules.KEYWORD_ONE,   PluralRules.KEYWORD_ONE,   0.01}, // 0.01 => one
                {"hsb", PluralRules.KEYWORD_FEW,   PluralRules.KEYWORD_FEW,   1.03}, // (f % 100 == 3) => few
                {"hsb", PluralRules.KEYWORD_FEW,   PluralRules.KEYWORD_OTHER, 1.3},  // 1.3 => few, but 1.30 => other
        };
        for (Object[] cas : cases) {
            ULocale locale = new ULocale((String) cas[0]);
            PluralRules rules = factory.forLocale(locale);
            String expectedDoubleKeyword = (String) cas[1];
            String expectedFormattedKeyword = (String) cas[2];
            double number = (Double) cas[3];
            String message = locale + " " + number;
            // Check both as double and as FormattedNumber.
            assertEquals(message, expectedDoubleKeyword, rules.select(number));
            FormattedNumber fn = unf.locale(locale).format(number);
            assertEquals(message, expectedFormattedKeyword, rules.select(fn));
        }
    }

    private void compareLocaleResults(String loc1, String loc2, String loc3) {
        PluralRules rules1 = PluralRules.forLocale(new ULocale(loc1));
        PluralRules rules2 = PluralRules.forLocale(new ULocale(loc2));
        PluralRules rules3 = PluralRules.forLocale(new ULocale(loc3));
        for (int value = 0; value <= 12; value++) {
            String result1 = rules1.select(value);
            String result2 = rules2.select(value);
            String result3 = rules3.select(value);
            if (!result1.equals(result2) || !result1.equals(result3)) {
                errln("PluralRules.select(" + value + ") does not return the same values for "
                        + loc1 + ", " + loc2 + ", " + loc3);
            }
        }
    }

    @Test
    public void testLocaleExtension() {
        PluralRules rules = PluralRules.forLocale(new ULocale("pt@calendar=gregorian"));
        String key = rules.select(1);
        assertEquals("pt@calendar=gregorian select(1)", "one", key);
        compareLocaleResults("ar", "ar_SA", "ar_SA@calendar=gregorian");
        compareLocaleResults("ru", "ru_UA", "ru-u-cu-RUB");
        compareLocaleResults("fr", "fr_CH", "fr@ms=uksystem");
    }

    @Test
    public void testFunctionalEquivalent() {
        // spot check
        ULocale unknown = ULocale.createCanonical("zz_ZZ");
        ULocale un_equiv = PluralRules.getFunctionalEquivalent(unknown, null);
        assertEquals("unknown locales have root", ULocale.ROOT, un_equiv);

        ULocale jp_equiv = PluralRules.getFunctionalEquivalent(ULocale.JAPAN, null);
        ULocale cn_equiv = PluralRules.getFunctionalEquivalent(ULocale.CHINA, null);
        assertEquals("japan and china equivalent locales", jp_equiv, cn_equiv);

        boolean[] available = new boolean[1];
        ULocale russia = ULocale.createCanonical("ru_RU");
        ULocale ru_ru_equiv = PluralRules.getFunctionalEquivalent(russia, available);
        assertFalse("ru_RU not listed", available[0]);

        ULocale russian = ULocale.createCanonical("ru");
        ULocale ru_equiv = PluralRules.getFunctionalEquivalent(russian, available);
        assertTrue("ru listed", available[0]);
        assertEquals("ru and ru_RU equivalent locales", ru_ru_equiv, ru_equiv);
    }

    @Test
    public void testAvailableULocales() {
        ULocale[] locales = factory.getAvailableULocales();
        Set localeSet = new HashSet();
        localeSet.addAll(Arrays.asList(locales));

        assertEquals("locales are unique in list", locales.length, localeSet.size());
    }

    /*
     * Test the method public static PluralRules parseDescription(String description)
     */
    @Test
    public void TestParseDescription() {
        try {
            if (PluralRules.DEFAULT != PluralRules.parseDescription("")) {
                errln("PluralRules.parseDescription(String) was suppose "
                        + "to return PluralRules.DEFAULT when String is of " + "length 0.");
            }
        } catch (ParseException e) {
            errln("PluralRules.parseDescription(String) was not suppose " + "to return an exception.");
        }
    }

    /*
     * Tests the method public static PluralRules createRules(String description)
     */
    @Test
    public void TestCreateRules() {
        try {
            if (PluralRules.createRules(null) != null) {
                errln("PluralRules.createRules(String) was suppose to "
                        + "return null for an invalid String descrtiption.");
            }
        } catch (Exception e) {
        }
    }

    /*
     * Tests the method public int hashCode()
     */
    @Test
    public void TestHashCode() {
        // Bad test, breaks whenever PluralRules implementation changes.
        // PluralRules pr = PluralRules.DEFAULT;
        // if (106069776 != pr.hashCode()) {
        // errln("PluralRules.hashCode() was suppose to return 106069776 " + "when PluralRules.DEFAULT.");
        // }
    }

    /*
     * Tests the method public boolean equals(PluralRules rhs)
     */
    @Test
    public void TestEquals() {
        PluralRules pr = PluralRules.DEFAULT;

        if (pr.equals((PluralRules) null)) {
            errln("PluralRules.equals(PluralRules) was supposed to return false " + "when passing null.");
        }
    }

    private void assertRuleValue(String rule, double value) {
        assertRuleKeyValue("a:" + rule, "a", value);
    }

    private void assertRuleKeyValue(String rule, String key, double value) {
        PluralRules pr = PluralRules.createRules(rule);
        assertEquals(rule, value, pr.getUniqueKeywordValue(key));
    }

    /*
     * Tests getUniqueKeywordValue()
     */
    @Test
    public void TestGetUniqueKeywordValue() {
        assertRuleKeyValue("a: n is 1", "not_defined", PluralRules.NO_UNIQUE_VALUE); // key not defined
        assertRuleValue("n within 2..2", 2);
        assertRuleValue("n is 1", 1);
        assertRuleValue("n in 2..2", 2);
        assertRuleValue("n in 3..4", PluralRules.NO_UNIQUE_VALUE);
        assertRuleValue("n within 3..4", PluralRules.NO_UNIQUE_VALUE);
        assertRuleValue("n is 2 or n is 2", 2);
        assertRuleValue("n is 2 and n is 2", 2);
        assertRuleValue("n is 2 or n is 3", PluralRules.NO_UNIQUE_VALUE);
        assertRuleValue("n is 2 and n is 3", PluralRules.NO_UNIQUE_VALUE);
        assertRuleValue("n is 2 or n in 2..3", PluralRules.NO_UNIQUE_VALUE);
        assertRuleValue("n is 2 and n in 2..3", 2);
        assertRuleKeyValue("a: n is 1", "other", PluralRules.NO_UNIQUE_VALUE); // key matches default rule
        assertRuleValue("n in 2,3", PluralRules.NO_UNIQUE_VALUE);
        assertRuleValue("n in 2,3..6 and n not in 2..3,5..6", 4);
    }

    /**
     * The version in PluralFormatUnitTest is not really a test, and it's in the wrong place anyway, so I'm putting a
     * variant of it here.
     */
    @Test
    public void TestGetSamples() {
        Set<ULocale> uniqueRuleSet = new HashSet<>();
        for (ULocale locale : factory.getAvailableULocales()) {
            uniqueRuleSet.add(PluralRules.getFunctionalEquivalent(locale, null));
        }
        for (ULocale locale : uniqueRuleSet) {
            if (locale.getLanguage().equals("fr") &&
                    logKnownIssue("21322", "PluralRules::getSamples cannot distinguish 1e5 from 100000")) {
                continue;
            }
            PluralRules rules = factory.forLocale(locale);
            logln("\nlocale: " + (locale == ULocale.ROOT ? "root" : locale.toString()) + ", rules: " + rules);
            Set<String> keywords = rules.getKeywords();
            for (String keyword : keywords) {
                Collection<Double> list = rules.getSamples(keyword);
                logln("keyword: " + keyword + ", samples: " + list);
                // with fractions, the samples can be empty and thus the list null. In that case, however, there will be
                // FixedDecimal values.
                // So patch the test for that.
                if (list.size() == 0) {
                    // when the samples (meaning integer samples) are null, then then integerSamples must be, and the
                    // decimalSamples must not be
                    FixedDecimalSamples integerSamples = rules.getDecimalSamples(keyword, SampleType.INTEGER);
                    FixedDecimalSamples decimalSamples = rules.getDecimalSamples(keyword, SampleType.DECIMAL);
                    assertTrue(getAssertMessage("List is not null", locale, rules, keyword), integerSamples == null
                            && decimalSamples != null && decimalSamples.samples.size() != 0);
                } else {
                    if (!assertTrue(getAssertMessage("Test getSamples.isEmpty", locale, rules, keyword),
                            !list.isEmpty())) {
                        rules.getSamples(keyword);
                    }
                    if (rules.toString().contains(": j")) {
                        // hack until we remove j
                    } else {
                        for (double value : list) {
                            assertEquals(getAssertMessage("Match keyword", locale, rules, keyword) + "; value '"
                                    + value + "'", keyword, rules.select(value));
                        }
                    }
                }
            }

            assertNull(locale + ", list is null", rules.getSamples("@#$%^&*"));
            assertNull(locale + ", list is null", rules.getSamples("@#$%^&*", SampleType.DECIMAL));
        }
    }

    public String getAssertMessage(String message, ULocale locale, PluralRules rules, String keyword) {
        String ruleString = "";
        if (keyword != null) {
            if (keyword.equals("other")) {
                for (String keyword2 : rules.getKeywords()) {
                    ruleString += " NOR " + rules.getRules(keyword2).split("@")[0];
                }
            } else {
                String rule = rules.getRules(keyword);
                ruleString = rule == null ? null : rule.split("@")[0];
            }
            ruleString = "; rule: '" + keyword + ": " + ruleString + "'";
            // !keyword.equals("other") ? "'; keyword: '" + keyword + "'; rule: '" + rules.getRules(keyword) + "'"
            // : "'; keyword: '" + keyword + "'; rules: '" + rules.toString() + "'";
        }
        return message + (locale == null ? "" : "; locale: '" + locale + "'") + ruleString;
    }

    /**
     * Returns the empty set if the keyword is not defined, null if there are an unlimited number of values for the
     * keyword, or the set of values that trigger the keyword.
     */
    @Test
    public void TestGetAllKeywordValues() {
        // data is pairs of strings, the rule, and the expected values as arguments
        String[] data = {
                "other: ; a: n mod 3 is 0",
                "a: null",
                "a: n in 2..5 and n within 5..8",
                "a: 5",
                "a: n in 2..5",
                "a: 2,3,4,5; other: null",
                "a: n not in 2..5",
                "a: null; other: null",
                "a: n within 2..5",
                "a: 2,3,4,5; other: null",
                "a: n not within 2..5",
                "a: null; other: null",
                "a: n in 2..5 or n within 6..8",
                "a: 2,3,4,5,6,7,8", // ignore 'other' here on out, always null
                "a: n in 2..5 and n within 6..8",
                "a: null",
                // we no longer support 'degenerate' rules
                // "a: n within 2..5 and n within 6..8", "a:", // our sampling catches these
                // "a: n within 2..5 and n within 5..8", "a: 5", // ''
                // "a: n within 1..2 and n within 2..3 or n within 3..4 and n within 4..5", "a: 2,4",
                // "a: n mod 3 is 0 and n within 0..5", "a: 0,3",
                "a: n within 1..2 and n within 2..3 or n within 3..4 and n within 4..5 or n within 5..6 and n within 6..7",
                "a: 2,4,6", // but not this...
                "a: n mod 3 is 0 and n within 1..2", "a: null", "a: n mod 3 is 0 and n within 0..6", "a: 0,3,6",
                "a: n mod 3 is 0 and n in 3..12", "a: 3,6,9,12", "a: n in 2,4..6 and n is not 5", "a: 2,4,6", };
        for (int i = 0; i < data.length; i += 2) {
            String ruleDescription = data[i];
            String result = data[i + 1];

            PluralRules p = PluralRules.createRules(ruleDescription);
            if (p == null) { // for debugging
                PluralRules.createRules(ruleDescription);
            }
            for (String ruleResult : result.split(";")) {
                String[] ruleAndValues = ruleResult.split(":");
                String keyword = ruleAndValues[0].trim();
                String valueList = ruleAndValues.length < 2 ? null : ruleAndValues[1];
                if (valueList != null) {
                    valueList = valueList.trim();
                }
                Collection<Double> values;
                if (valueList == null || valueList.length() == 0) {
                    values = Collections.EMPTY_SET;
                } else if ("null".equals(valueList)) {
                    values = null;
                } else {
                    values = new TreeSet<>();
                    for (String value : valueList.split(",")) {
                        values.add(Double.parseDouble(value));
                    }
                }

                Collection<Double> results = p.getAllKeywordValues(keyword);
                assertEquals(keyword + " in " + ruleDescription, values, results == null ? null : new HashSet(results));

                if (results != null) {
                    try {
                        results.add(PluralRules.NO_UNIQUE_VALUE);
                        fail("returned set is modifiable");
                    } catch (UnsupportedOperationException e) {
                        // pass
                    }
                }
            }
        }
    }

    @Test
    public void TestOrdinal() {
        PluralRules pr = factory.forLocale(ULocale.ENGLISH, PluralType.ORDINAL);
        assertEquals("PluralRules(en-ordinal).select(2)", "two", pr.select(2));
    }

    @Test
    public void TestBasicFraction() {
        String[][] tests = { { "en", "one: j is 1" }, { "1", "0", "1", "one" }, { "1", "2", "1.00", "other" }, };
        ULocale locale = null;
        NumberFormat nf = null;
        PluralRules pr = null;

        for (String[] row : tests) {
            switch (row.length) {
            case 2:
                locale = ULocale.forLanguageTag(row[0]);
                nf = NumberFormat.getInstance(locale);
                pr = PluralRules.createRules(row[1]);
                break;
            case 4:
                double n = Double.parseDouble(row[0]);
                int minFracDigits = Integer.parseInt(row[1]);
                nf.setMinimumFractionDigits(minFracDigits);
                String expectedFormat = row[2];
                String expectedKeyword = row[3];

                UFieldPosition pos = new UFieldPosition();
                String formatted = nf.format(1.0, new StringBuffer(), pos).toString();
                int countVisibleFractionDigits = pos.getCountVisibleFractionDigits();
                long fractionDigits = pos.getFractionDigits();
                String keyword = pr.select(n, countVisibleFractionDigits, fractionDigits);
                assertEquals("Formatted " + n + "\t" + minFracDigits, expectedFormat, formatted);
                assertEquals("Keyword " + n + "\t" + minFracDigits, expectedKeyword, keyword);
                break;
            default:
                throw new RuntimeException();
            }
        }
    }

    @Test
    public void TestLimitedAndSamplesConsistency() {
        for (ULocale locale : PluralRules.getAvailableULocales()) {
            ULocale loc2 = PluralRules.getFunctionalEquivalent(locale, null);
            if (!loc2.equals(locale)) {
                continue; // only need "unique" rules
            }
            for (PluralType type : PluralType.values()) {
                PluralRules rules = PluralRules.forLocale(locale, type);
                for (SampleType sampleType : SampleType.values()) {
                    if (type == PluralType.ORDINAL) {
                        logKnownIssue("10783", "Fix issues with isLimited vs computeLimited on ordinals");
                        continue;
                    }
                    for (String keyword : rules.getKeywords()) {
                        boolean isLimited = rules.isLimited(keyword, sampleType);
                        boolean computeLimited = rules.computeLimited(keyword, sampleType);
                        if (!keyword.equals("other") && !(locale.getLanguage().equals("fr") && logKnownIssue("ICU-21270", "fr plurals many case computeLimited == isLimited"))) {
                            assertEquals(getAssertMessage("computeLimited == isLimited", locale, rules, keyword),
                                    computeLimited, isLimited);
                        }
                        Collection<Double> samples = rules.getSamples(keyword, sampleType);
                        assertNotNull(getAssertMessage("Samples must not be null", locale, rules, keyword), samples);
                        /* FixedDecimalSamples decimalSamples = */rules.getDecimalSamples(keyword, sampleType);
                        // assertNotNull(getAssertMessage("Decimal samples must be null if unlimited", locale, rules,
                        // keyword), decimalSamples);
                    }
                }
            }
        }
    }

    @Test
    public void TestKeywords() {
        Set<String> possibleKeywords = new LinkedHashSet(Arrays.asList("zero", "one", "two", "few", "many", "other"));
        Object[][][] tests = {
                // format is locale, explicits, then triples of keyword, status, unique value.
                { { "en", null }, { "one", KeywordStatus.UNIQUE, 1.0d }, { "other", KeywordStatus.UNBOUNDED, null } },
                { { "pl", null }, { "one", KeywordStatus.UNIQUE, 1.0d }, { "few", KeywordStatus.UNBOUNDED, null },
                        { "many", KeywordStatus.UNBOUNDED, null },
                        { "other", KeywordStatus.SUPPRESSED, null, KeywordStatus.UNBOUNDED, null } // note that it is
                                                                                                   // suppressed in
                                                                                                   // INTEGER but not
                                                                                                   // DECIMAL
                }, { { "en", new HashSet<>(Arrays.asList(1.0d)) }, // check that 1 is suppressed
                        { "one", KeywordStatus.SUPPRESSED, null }, { "other", KeywordStatus.UNBOUNDED, null } }, };
        Output<Double> uniqueValue = new Output<>();
        for (Object[][] test : tests) {
            ULocale locale = new ULocale((String) test[0][0]);
            // NumberType numberType = (NumberType) test[1];
            Set<Double> explicits = (Set<Double>) test[0][1];
            PluralRules pluralRules = factory.forLocale(locale);
            LinkedHashSet<String> remaining = new LinkedHashSet(possibleKeywords);
            for (int i = 1; i < test.length; ++i) {
                Object[] row = test[i];
                String keyword = (String) row[0];
                KeywordStatus statusExpected = (KeywordStatus) row[1];
                Double uniqueExpected = (Double) row[2];
                remaining.remove(keyword);
                KeywordStatus status = pluralRules.getKeywordStatus(keyword, 0, explicits, uniqueValue);
                assertEquals(getAssertMessage("Unique Value", locale, pluralRules, keyword), uniqueExpected,
                        uniqueValue.value);
                assertEquals(getAssertMessage("Keyword Status", locale, pluralRules, keyword), statusExpected, status);
                if (row.length > 3) {
                    statusExpected = (KeywordStatus) row[3];
                    uniqueExpected = (Double) row[4];
                    status = pluralRules.getKeywordStatus(keyword, 0, explicits, uniqueValue, SampleType.DECIMAL);
                    assertEquals(getAssertMessage("Unique Value - decimal", locale, pluralRules, keyword),
                            uniqueExpected, uniqueValue.value);
                    assertEquals(getAssertMessage("Keyword Status - decimal", locale, pluralRules, keyword),
                            statusExpected, status);
                }
            }
            for (String keyword : remaining) {
                KeywordStatus status = pluralRules.getKeywordStatus(keyword, 0, null, uniqueValue);
                assertEquals("Invalid keyword " + keyword, status, KeywordStatus.INVALID);
                assertNull("Invalid keyword " + keyword, uniqueValue.value);
            }
        }
    }

    // For the time being, the compact notation exponent operand `c` is an alias
    // for the scientific exponent operand `e` and compact notation.
    @Test
    public void testScientificPluralKeyword() {
        PluralRules rules = PluralRules.createRules("one: i = 0,1 @integer 0, 1 @decimal 0.0~1.5;  many: e = 0 and i % 1000000 = 0 and v = 0 or " +
                "e != 0 .. 5;  other:  @integer 2~17, 100, 1000, 10000, 100000, 1000000, @decimal 2.0~3.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …");
        ULocale locale = new ULocale("fr-FR");

        Object[][] casesData = {
                // unlocalized formatter skeleton, input, string output, plural rule keyword
                {"",           0, "0", "one"},
                {"scientific", 0, "0", "one"},

                {"",           1, "1", "one"},
                {"scientific", 1, "1", "one"},

                {"",           2, "2", "other"},
                {"scientific", 2, "2", "other"},

                {"",           1000000, "1 000 000", "many"},
                {"scientific", 1000000, "1 million", "many"},

                {"",           1000001, "1 000 001", "other"},
                {"scientific", 1000001, "1 million", "many"},

                {"",           120000, "1 200 000", "other"},
                {"scientific", 1200000, "1,2 millions", "many"},

                {"",           1200001, "1 200 001", "other"},
                {"scientific", 1200001, "1,2 millions", "many"},

                {"",           2000000, "2 000 000", "many"},
                {"scientific", 2000000, "2 millions", "many"},
        };

        for (Object[] caseDatum : casesData) {
            String skeleton = (String) caseDatum[0];
            int input = (int) caseDatum[1];
            // String expectedString = (String) caseDatum[2];
            String expectPluralRuleKeyword = (String) caseDatum[3];

            String actualPluralRuleKeyword =
                    getPluralKeyword(rules, locale, input, skeleton);

            assertEquals(
                    String.format("PluralRules select %s: %d", skeleton, input),
                    expectPluralRuleKeyword,
                    actualPluralRuleKeyword);
        }
    }

    @Test
    public void testCompactDecimalPluralKeyword() {
        PluralRules rules = PluralRules.createRules("one: i = 0,1 @integer 0, 1 @decimal 0.0~1.5;  many: c = 0 and i % 1000000 = 0 and v = 0 or " +
                "c != 0 .. 5;  other:  @integer 2~17, 100, 1000, 10000, 100000, 1000000, @decimal 2.0~3.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …");
        ULocale locale = new ULocale("fr-FR");

        Object[][] casesData = {
                // unlocalized formatter skeleton, input, string output, plural rule keyword
                {"",             0, "0", "one"},
                {"compact-long", 0, "0", "one"},

                {"",             1, "1", "one"},
                {"compact-long", 1, "1", "one"},

                {"",             2, "2", "other"},
                {"compact-long", 2, "2", "other"},

                {"",             1000000, "1 000 000", "many"},
                {"compact-long", 1000000, "1 million", "many"},

                {"",             1000001, "1 000 001", "other"},
                {"compact-long", 1000001, "1 million", "many"},

                {"",             120000, "1 200 000", "other"},
                {"compact-long", 1200000, "1,2 millions", "many"},

                {"",             1200001, "1 200 001", "other"},
                {"compact-long", 1200001, "1,2 millions", "many"},

                {"",             2000000, "2 000 000", "many"},
                {"compact-long", 2000000, "2 millions", "many"},
        };

        for (Object[] caseDatum : casesData) {
            String skeleton = (String) caseDatum[0];
            int input = (int) caseDatum[1];
            // String expectedString = (String) caseDatum[2];
            String expectPluralRuleKeyword = (String) caseDatum[3];

            String actualPluralRuleKeyword =
                    getPluralKeyword(rules, locale, input, skeleton);

            assertEquals(
                    String.format("PluralRules select %s: %d", skeleton, input),
                    expectPluralRuleKeyword,
                    actualPluralRuleKeyword);
        }
    }

    private String getPluralKeyword(PluralRules rules, ULocale locale, double number, String skeleton) {
        LocalizedNumberFormatter formatter =
                NumberFormatter.forSkeleton(skeleton)
                    .locale(locale);
        FormattedNumber fn = formatter.format(number);
        String pluralKeyword = rules.select(fn);
        return pluralKeyword;
    }

    enum StandardPluralCategories {
        zero, one, two, few, many, other;
        /**
         *
         */
        private static final Set<StandardPluralCategories> ALL = Collections.unmodifiableSet(EnumSet
                .allOf(StandardPluralCategories.class));

        /**
         * Return a mutable set
         *
         * @param source
         * @return
         */
        static final EnumSet<StandardPluralCategories> getSet(Collection<String> source) {
            EnumSet<StandardPluralCategories> result = EnumSet.noneOf(StandardPluralCategories.class);
            for (String s : source) {
                result.add(StandardPluralCategories.valueOf(s));
            }
            return result;
        }

        static final Comparator<Set<StandardPluralCategories>> SHORTEST_FIRST = new Comparator<Set<StandardPluralCategories>>() {
            @Override
            public int compare(Set<StandardPluralCategories> arg0, Set<StandardPluralCategories> arg1) {
                int diff = arg0.size() - arg1.size();
                if (diff != 0) {
                    return diff;
                }
                // otherwise first...
                // could be optimized, but we don't care here.
                for (StandardPluralCategories value : ALL) {
                    if (arg0.contains(value)) {
                        if (!arg1.contains(value)) {
                            return 1;
                        }
                    } else if (arg1.contains(value)) {
                        return -1;
                    }

                }
                return 0;
            }

        };
    }

    @Test
    public void TestLocales() {
        if (false) {
            generateLOCALE_SNAPSHOT();
        }
        for (String test : LOCALE_SNAPSHOT) {
            test = test.trim();
            String[] parts = test.split("\\s*;\\s*");
            for (String localeString : parts[0].split("\\s*,\\s*")) {
                ULocale locale = new ULocale(localeString);
                if (factory.hasOverride(locale)) {
                    continue; // skip for now
                }
                PluralRules rules = factory.forLocale(locale);
                for (int i = 1; i < parts.length; ++i) {
                    checkCategoriesAndExpected(localeString, parts[i], rules);
                }
            }
        }
    }

    private static final Comparator<PluralRules> PLURAL_RULE_COMPARATOR = new Comparator<PluralRules>() {
        @Override
        public int compare(PluralRules o1, PluralRules o2) {
            return o1.compareTo(o2);
        }
    };

    private void generateLOCALE_SNAPSHOT() {
        Comparator c = new CollectionUtilities.CollectionComparator<>();
        Relation<Set<StandardPluralCategories>, PluralRules> setsToRules = Relation.of(
                new TreeMap<Set<StandardPluralCategories>, Set<PluralRules>>(c), TreeSet.class, PLURAL_RULE_COMPARATOR);
        Relation<PluralRules, ULocale> data = Relation.of(
                new TreeMap<PluralRules, Set<ULocale>>(PLURAL_RULE_COMPARATOR), TreeSet.class);
        for (ULocale locale : PluralRules.getAvailableULocales()) {
            PluralRules pr = PluralRules.forLocale(locale);
            EnumSet<StandardPluralCategories> set = getCanonicalSet(pr.getKeywords());
            setsToRules.put(set, pr);
            data.put(pr, locale);
        }
        for (Entry<Set<StandardPluralCategories>, Set<PluralRules>> entry1 : setsToRules.keyValuesSet()) {
            Set<StandardPluralCategories> set = entry1.getKey();
            Set<PluralRules> rules = entry1.getValue();
            System.out.println("\n        // " + set);
            for (PluralRules rule : rules) {
                Set<ULocale> locales = data.get(rule);
                System.out.print("        \"" + CollectionUtilities.join(locales, ","));
                for (StandardPluralCategories spc : set) {
                    String keyword = spc.toString();
                    FixedDecimalSamples samples = rule.getDecimalSamples(keyword, SampleType.INTEGER);
                    System.out.print("; " + spc + ": " + samples);
                }
                System.out.println("\",");
            }
        }
    }

    /**
     * @param keywords
     * @return
     */
    private EnumSet<StandardPluralCategories> getCanonicalSet(Set<String> keywords) {
        EnumSet<StandardPluralCategories> result = EnumSet.noneOf(StandardPluralCategories.class);
        for (String s : keywords) {
            result.add(StandardPluralCategories.valueOf(s));
        }
        return result;
    }

    static final String[] LOCALE_SNAPSHOT = {
            // [other]
            "bm,bo,dz,id,ig,ii,in,ja,jbo,jv,jw,kde,kea,km,ko,lkt,lo,ms,my,nqo,root,sah,ses,sg,th,to,vi,wo,yo,zh; other: @integer 0~15, 100, 1000, 10000, 100000, 1000000, …",

            // [one, other]
            "am,bn,fa,gu,hi,kn,mr,zu; one: @integer 0, 1; other: @integer 2~17, 100, 1000, 10000, 100000, 1000000, …",
            "ff,hy,kab; one: @integer 0, 1; other: @integer 2~17, 100, 1000, 10000, 100000, 1000000, …",
            "ast,ca,de,en,et,fi,fy,gl,it,ji,nl,sv,sw,ur,yi; one: @integer 1; other: @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, …",
            "pt; one: @integer 1; other: @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, …",
            "si; one: @integer 0, 1; other: @integer 2~17, 100, 1000, 10000, 100000, 1000000, …",
            "ak,bho,guw,ln,mg,nso,pa,ti,wa; one: @integer 0, 1; other: @integer 2~17, 100, 1000, 10000, 100000, 1000000, …",
            "tzm; one: @integer 0, 1, 11~24; other: @integer 2~10, 100~106, 1000, 10000, 100000, 1000000, …",
            "af,asa,az,bem,bez,bg,brx,cgg,chr,ckb,dv,ee,el,eo,es,eu,fo,fur,gsw,ha,haw,hu,jgo,jmc,ka,kaj,kcg,kk,kkj,kl,ks,ksb,ku,ky,lb,lg,mas,mgo,ml,mn,nah,nb,nd,ne,nn,nnh,no,nr,ny,nyn,om,or,os,pap,ps,rm,rof,rwk,saq,seh,sn,so,sq,ss,ssy,st,syr,ta,te,teo,tig,tk,tn,tr,ts,ug,uz,ve,vo,vun,wae,xh,xog; one: @integer 1; other: @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, …",
            "pt_PT; one: @integer 1; other: @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, …",
            "da; one: @integer 1; other: @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, …",
            "is; one: @integer 1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, …; other: @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, …",
            "mk; one: @integer 1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, …; other: @integer 0, 2~16, 100, 1000, 10000, 100000, 1000000, …",
            "fil,tl; one: @integer 0~3, 5, 7, 8, 10~13, 15, 17, 18, 20, 21, 100, 1000, 10000, 100000, 1000000, …; other: @integer 4, 6, 9, 14, 16, 19, 24, 26, 104, 1004, …",

            // [zero, one, other]
            "lag; zero: @integer 0; one: @integer 1; other: @integer 2~17, 100, 1000, 10000, 100000, 1000000, …",
            "lv,prg; zero: @integer 0, 10~20, 30, 40, 50, 60, 100, 1000, 10000, 100000, 1000000, …; one: @integer 1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, …; other: @integer 2~9, 22~29, 102, 1002, …",
            "ksh; zero: @integer 0; one: @integer 1; other: @integer 2~17, 100, 1000, 10000, 100000, 1000000, …",

            // [one, two, other]
            "iu,naq,se,sma,smi,smj,smn,sms; one: @integer 1; two: @integer 2; other: @integer 0, 3~17, 100, 1000, 10000, 100000, 1000000, …",

            // [one, many, other]
            "fr; one: @integer 0, 1; many: @integer 1000000; other: @integer 2~17, 100, 1000, 10000, 100000, …",

            // [one, few, other]
            "shi; one: @integer 0, 1; few: @integer 2~10; other: @integer 11~26, 100, 1000, 10000, 100000, 1000000, …",
            "mo,ro; one: @integer 1; few: @integer 0, 2~16, 102, 1002, …; other: @integer 20~35, 100, 1000, 10000, 100000, 1000000, …",
            "bs,hr,sh,sr; one: @integer 1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, …; few: @integer 2~4, 22~24, 32~34, 42~44, 52~54, 62, 102, 1002, …; other: @integer 0, 5~19, 100, 1000, 10000, 100000, 1000000, …",

            // [one, two, few, other]
            "gd; one: @integer 1, 11; two: @integer 2, 12; few: @integer 3~10, 13~19; other: @integer 0, 20~34, 100, 1000, 10000, 100000, 1000000, …",
            "sl; one: @integer 1, 101, 201, 301, 401, 501, 601, 701, 1001, …; two: @integer 2, 102, 202, 302, 402, 502, 602, 702, 1002, …; few: @integer 3, 4, 103, 104, 203, 204, 303, 304, 403, 404, 503, 504, 603, 604, 703, 704, 1003, …; other: @integer 0, 5~19, 100, 1000, 10000, 100000, 1000000, …",

            // [one, two, many, other]
            "he,iw; one: @integer 1; two: @integer 2; many: @integer 20, 30, 40, 50, 60, 70, 80, 90, 100, 1000, 10000, 100000, 1000000, …; other: @integer 0, 3~17, 101, 1001, …",

            // [one, few, many, other]
            "cs,sk; one: @integer 1; few: @integer 2~4; many: null; other: @integer 0, 5~19, 100, 1000, 10000, 100000, 1000000, …",
            "be; one: @integer 1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, …; few: @integer 2~4, 22~24, 32~34, 42~44, 52~54, 62, 102, 1002, …; many: @integer 0, 5~19, 100, 1000, 10000, 100000, 1000000, …; other: null",
            "lt; one: @integer 1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, …; few: @integer 2~9, 22~29, 102, 1002, …; many: null; other: @integer 0, 10~20, 30, 40, 50, 60, 100, 1000, 10000, 100000, 1000000, …",
            "mt; one: @integer 1; few: @integer 0, 2~10, 102~107, 1002, …; many: @integer 11~19, 111~117, 1011, …; other: @integer 20~35, 100, 1000, 10000, 100000, 1000000, …",
            "pl; one: @integer 1; few: @integer 2~4, 22~24, 32~34, 42~44, 52~54, 62, 102, 1002, …; many: @integer 0, 5~19, 100, 1000, 10000, 100000, 1000000, …; other: null",
            "ru,uk; one: @integer 1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, …; few: @integer 2~4, 22~24, 32~34, 42~44, 52~54, 62, 102, 1002, …; many: @integer 0, 5~19, 100, 1000, 10000, 100000, 1000000, …; other: null",

            // [one, two, few, many, other]
            "br; one: @integer 1, 21, 31, 41, 51, 61, 81, 101, 1001, …; two: @integer 2, 22, 32, 42, 52, 62, 82, 102, 1002, …; few: @integer 3, 4, 9, 23, 24, 29, 33, 34, 39, 43, 44, 49, 103, 1003, …; many: @integer 1000000, …; other: @integer 0, 5~8, 10~20, 100, 1000, 10000, 100000, …",
            "ga; one: @integer 1; two: @integer 2; few: @integer 3~6; many: @integer 7~10; other: @integer 0, 11~25, 100, 1000, 10000, 100000, 1000000, …",
            "gv; one: @integer 1, 11, 21, 31, 41, 51, 61, 71, 101, 1001, …; two: @integer 2, 12, 22, 32, 42, 52, 62, 72, 102, 1002, …; few: @integer 0, 20, 40, 60, 80, 100, 120, 140, 1000, 10000, 100000, 1000000, …; many: null; other: @integer 3~10, 13~19, 23, 103, 1003, …",

            // [zero, one, two, few, many, other]
            "ar; zero: @integer 0; one: @integer 1; two: @integer 2; few: @integer 3~10, 103~110, 1003, …; many: @integer 11~26, 111, 1011, …; other: @integer 100~102, 200~202, 300~302, 400~402, 500~502, 600, 1000, 10000, 100000, 1000000, …",
            "cy; zero: @integer 0; one: @integer 1; two: @integer 2; few: @integer 3; many: @integer 6; other: @integer 4, 5, 7~20, 100, 1000, 10000, 100000, 1000000, …",
            "kw; zero: @integer 0; one: @integer 1; two: @integer 2, 22, 42, 62, 82, 102, 122, 142, 1002, …; few: @integer 3, 23, 43, 63, 83, 103, 123, 143, 1003, …; many: @integer 21, 41, 61, 81, 101, 121, 141, 161, 1001, …; other: @integer 4~19, 100, 1000000, …", };

    private <T extends Serializable> T serializeAndDeserialize(T original, Output<Integer> size) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream ostream = new ObjectOutputStream(baos);
            ostream.writeObject(original);
            ostream.flush();
            byte bytes[] = baos.toByteArray();
            size.value = bytes.length;
            ObjectInputStream istream = new ObjectInputStream(new ByteArrayInputStream(bytes));
            T reconstituted = (T) istream.readObject();
            return reconstituted;
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    @Test
    public void TestSerialization() {
        Output<Integer> size = new Output<>();
        int max = 0;
        for (ULocale locale : PluralRules.getAvailableULocales()) {
            PluralRules item = PluralRules.forLocale(locale);
            PluralRules item2 = serializeAndDeserialize(item, size);
            logln(locale + "\tsize:\t" + size.value);
            max = Math.max(max, size.value);
            if (!assertEquals(locale + "\tPlural rules before and after serialization", item, item2)) {
                // for debugging
                PluralRules item3 = serializeAndDeserialize(item, size);
                item.equals(item3);
            }
        }
        logln("max \tsize:\t" + max);
    }

    public static class FixedDecimalHandler implements SerializableTestUtility.Handler {
        @Override
        public Object[] getTestObjects() {
            FixedDecimal items[] = { new FixedDecimal(3d), new FixedDecimal(3d, 2), new FixedDecimal(3.1d, 1),
                    new FixedDecimal(3.1d, 2), };
            return items;
        }

        @Override
        public boolean hasSameBehavior(Object a, Object b) {
            FixedDecimal a1 = (FixedDecimal) a;
            FixedDecimal b1 = (FixedDecimal) b;
            return a1.equals(b1);
        }
    }

    @Test
    public void TestSerial() {
        PluralRules s = PluralRules.forLocale(ULocale.ENGLISH);
        checkStreamingEquality(s);
    }

    public void checkStreamingEquality(PluralRules s) {
        try {
            ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteOut);
            objectOutputStream.writeObject(s);
            objectOutputStream.close();
            byte[] contents = byteOut.toByteArray();
            logln(s.getClass() + ": " + showBytes(contents));
            ByteArrayInputStream byteIn = new ByteArrayInputStream(contents);
            ObjectInputStream objectInputStream = new ObjectInputStream(byteIn);
            Object obj = objectInputStream.readObject();
            assertEquals("Streamed Object equals ", s, obj);
        } catch (Exception e) {
            assertNull("TestSerial", e);
        }
    }

    /**
     * @param contents
     * @return
     */
    private String showBytes(byte[] contents) {
        StringBuilder b = new StringBuilder("[");
        for (int i = 0; i < contents.length; ++i) {
            int item = contents[i] & 0xFF;
            if (item >= 0x20 && item <= 0x7F) {
                b.append((char) item);
            } else {
                b.append('(').append(Utility.hex(item, 2)).append(')');
            }
        }
        return b.append(']').toString();
    }

    @Test
    public void testJavaLocaleFactory() {
        PluralRules rulesU0 = PluralRules.forLocale(ULocale.FRANCE);
        PluralRules rulesJ0 = PluralRules.forLocale(Locale.FRANCE);
        assertEquals("forLocale()", rulesU0, rulesJ0);

        PluralRules rulesU1 = PluralRules.forLocale(ULocale.FRANCE, PluralType.ORDINAL);
        PluralRules rulesJ1 = PluralRules.forLocale(Locale.FRANCE, PluralType.ORDINAL);
        assertEquals("forLocale() with type", rulesU1, rulesJ1);
    }

    @Test
    public void testBug20264() {
        String expected = "1.23400";
        FixedDecimal fd = new FixedDecimal(1.234, 5, 2);
        assertEquals("FixedDecimal toString", expected, fd.toString());
        Locale.setDefault(Locale.FRENCH);
        assertEquals("FixedDecimal toString", expected, fd.toString());
        Locale.setDefault(Locale.GERMAN);
        assertEquals("FixedDecimal toString", expected, fd.toString());
    }

    @Test
    public void testSelectRange() {
        int d1 = 102;
        int d2 = 201;
        ULocale locale = new ULocale("sl");

        // Locale sl has interesting data: one + two => few
        FormattedNumberRange range = NumberRangeFormatter.withLocale(locale).formatRange(d1, d2);
        PluralRules rules = PluralRules.forLocale(locale);

        // For testing: get plural form of first and second numbers
        FormattedNumber a = NumberFormatter.withLocale(locale).format(d1);
        FormattedNumber b = NumberFormatter.withLocale(locale).format(d2);
        assertEquals("First plural", "two", rules.select(a));
        assertEquals("Second plural", "one", rules.select(b));

        // Check the range plural now:
        String form = rules.select(range);
        assertEquals("Range plural", "few", form);

        // Test when plural ranges data is unavailable:
        PluralRules bare = PluralRules.createRules("a: i = 0,1");
        try {
            form = bare.select(range);
            fail("Expected exception");
        } catch (UnsupportedOperationException e) {}

        // However, they should not throw when no data is available for a language.
        PluralRules xyz = PluralRules.forLocale(new ULocale("xyz"));
        form = xyz.select(range);
        assertEquals("Fallback form", "other", form);
    }
}
