17935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*
27935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert*******************************************************************************
37935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert* Copyright (C) 2010-2014, International Business Machines
47935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert* Corporation and others.  All Rights Reserved.
57935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert*******************************************************************************
67935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert*/
77935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpackage com.ibm.icu.dev.test.normalizer;
87935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
97935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Collections;
107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.EnumSet;
117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Map;
127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Set;
137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.TreeMap;
147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.dev.test.TestFmwk;
167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.Normalizer2Impl.UTF16Plus;
177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.text.IDNA;
187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/**
207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * UTS #46 (IDNA2008) test.
217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @author Markus Scherer
227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @since 2010jul10
237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */
247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpublic class UTS46Test extends TestFmwk {
257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static void main(String[] args) throws Exception {
267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new UTS46Test().run(args);
277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public UTS46Test() {
297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int commonOptions=
307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            IDNA.USE_STD3_RULES|IDNA.CHECK_BIDI|
317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            IDNA.CHECK_CONTEXTJ|IDNA.CHECK_CONTEXTO;
327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        trans=IDNA.getUTS46Instance(commonOptions);
337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        nontrans=IDNA.getUTS46Instance(commonOptions|
347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                       IDNA.NONTRANSITIONAL_TO_ASCII|IDNA.NONTRANSITIONAL_TO_UNICODE);
357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestAPI() {
387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        StringBuilder result=new StringBuilder();
397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        IDNA.Info info=new IDNA.Info();
407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String input="www.eXample.cOm";
417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String expected="www.example.com";
427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        trans.nameToASCII(input, result, info);
437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if(info.hasErrors() || !UTF16Plus.equal(result, expected)) {
447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln(String.format("T.nameToASCII(www.example.com) info.errors=%s result matches=%b",
457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                info.getErrors(), UTF16Plus.equal(result, expected)));
467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        input="xn--bcher.de-65a";
487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        expected="xn--bcher\uFFFDde-65a";
497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        nontrans.labelToASCII(input, result, info);
507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if( !info.getErrors().equals(EnumSet.of(IDNA.Error.LABEL_HAS_DOT, IDNA.Error.INVALID_ACE_LABEL)) ||
517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            !UTF16Plus.equal(result, expected)
527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ) {
537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln(String.format("N.labelToASCII(label-with-dot) failed with errors %s",
547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                info.getErrors()));
557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Java API tests that are not parallel to C++ tests
577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // because the C++ specifics (error codes etc.) do not apply here.
587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String resultString=trans.nameToUnicode("fA\u00DF.de", result, info).toString();
597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if(info.hasErrors() || !resultString.equals("fass.de")) {
607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln(String.format("T.nameToUnicode(fA\u00DF.de) info.errors=%s result matches=%b",
617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                info.getErrors(), resultString.equals("fass.de")));
627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        try {
647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            nontrans.labelToUnicode(result, result, info);
657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("N.labelToUnicode(result, result) did not throw an Exception");
667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } catch(Exception e) {
677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // as expected (should be an IllegalArgumentException, or an ICU version of it)
687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestNotSTD3() {
727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        IDNA not3=IDNA.getUTS46Instance(IDNA.CHECK_BIDI);
737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String input="\u0000A_2+2=4\n.e\u00DFen.net";
747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        StringBuilder result=new StringBuilder();
757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        IDNA.Info info=new IDNA.Info();
767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if( !not3.nameToUnicode(input, result, info).toString().equals("\u0000a_2+2=4\n.essen.net") ||
777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            info.hasErrors()
787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ) {
797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln(String.format("notSTD3.nameToUnicode(non-LDH ASCII) unexpected errors %s string %s",
807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                info.getErrors(), prettify(result.toString())));
817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // A space (BiDi class WS) is not allowed in a BiDi domain name.
837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        input="a z.xn--4db.edu";
847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        not3.nameToASCII(input, result, info);
857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if(!UTF16Plus.equal(result, input) || !info.getErrors().equals(EnumSet.of(IDNA.Error.BIDI))) {
867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("notSTD3.nameToASCII(ASCII-with-space.alef.edu) failed");
877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Characters that are canonically equivalent to sequences with non-LDH ASCII.
897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        input="a\u2260b\u226Ec\u226Fd";
907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        not3.nameToUnicode(input, result, info);
917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if(!UTF16Plus.equal(result, input) || info.hasErrors()) {
927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln(String.format("notSTD3.nameToUnicode(equiv to non-LDH ASCII) unexpected errors %s string %s",
937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                info.getErrors().toString(), prettify(result.toString())));
947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final Map<String, IDNA.Error> errorNamesToErrors;
987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    static {
997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        errorNamesToErrors=new TreeMap<String, IDNA.Error>();
1007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        errorNamesToErrors.put("UIDNA_ERROR_EMPTY_LABEL", IDNA.Error.EMPTY_LABEL);
1017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        errorNamesToErrors.put("UIDNA_ERROR_LABEL_TOO_LONG", IDNA.Error.LABEL_TOO_LONG);
1027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        errorNamesToErrors.put("UIDNA_ERROR_DOMAIN_NAME_TOO_LONG", IDNA.Error.DOMAIN_NAME_TOO_LONG);
1037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        errorNamesToErrors.put("UIDNA_ERROR_LEADING_HYPHEN", IDNA.Error.LEADING_HYPHEN);
1047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        errorNamesToErrors.put("UIDNA_ERROR_TRAILING_HYPHEN", IDNA.Error.TRAILING_HYPHEN);
1057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        errorNamesToErrors.put("UIDNA_ERROR_HYPHEN_3_4", IDNA.Error.HYPHEN_3_4);
1067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        errorNamesToErrors.put("UIDNA_ERROR_LEADING_COMBINING_MARK", IDNA.Error.LEADING_COMBINING_MARK);
1077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        errorNamesToErrors.put("UIDNA_ERROR_DISALLOWED", IDNA.Error.DISALLOWED);
1087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        errorNamesToErrors.put("UIDNA_ERROR_PUNYCODE", IDNA.Error.PUNYCODE);
1097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        errorNamesToErrors.put("UIDNA_ERROR_LABEL_HAS_DOT", IDNA.Error.LABEL_HAS_DOT);
1107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        errorNamesToErrors.put("UIDNA_ERROR_INVALID_ACE_LABEL", IDNA.Error.INVALID_ACE_LABEL);
1117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        errorNamesToErrors.put("UIDNA_ERROR_BIDI", IDNA.Error.BIDI);
1127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        errorNamesToErrors.put("UIDNA_ERROR_CONTEXTJ", IDNA.Error.CONTEXTJ);
1137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        errorNamesToErrors.put("UIDNA_ERROR_CONTEXTO_PUNCTUATION", IDNA.Error.CONTEXTO_PUNCTUATION);
1147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        errorNamesToErrors.put("UIDNA_ERROR_CONTEXTO_DIGITS", IDNA.Error.CONTEXTO_DIGITS);
1157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final class TestCase {
1187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        private TestCase() {
1197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errors=EnumSet.noneOf(IDNA.Error.class);
1207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
1217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        private void set(String[] data) {
1227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            s=data[0];
1237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            o=data[1];
1247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            u=data[2];
1257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errors.clear();
1267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(data[3].length()!=0) {
1277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                for(String e: data[3].split("\\|")) {
1287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errors.add(errorNamesToErrors.get(e));
1297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
1307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
1317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
1327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Input string and options string (Nontransitional/Transitional/Both).
1337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        private String s, o;
1347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Expected Unicode result string.
1357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        private String u;
1367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        private EnumSet<IDNA.Error> errors;
1377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    };
1387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final String testCases[][]={
1407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "www.eXample.cOm", "B",  // all ASCII
1417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "www.example.com", "" },
1427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "B\u00FCcher.de", "B",  // u-umlaut
1437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "b\u00FCcher.de", "" },
1447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u00D6BB", "B",  // O-umlaut
1457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u00F6bb", "" },
1467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "fa\u00DF.de", "N",  // sharp s
1477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "fa\u00DF.de", "" },
1487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "fa\u00DF.de", "T",  // sharp s
1497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "fass.de", "" },
1507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "XN--fA-hia.dE", "B",  // sharp s in Punycode
1517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "fa\u00DF.de", "" },
1527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u03B2\u03CC\u03BB\u03BF\u03C2.com", "N",  // Greek with final sigma
1537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u03B2\u03CC\u03BB\u03BF\u03C2.com", "" },
1547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u03B2\u03CC\u03BB\u03BF\u03C2.com", "T",  // Greek with final sigma
1557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u03B2\u03CC\u03BB\u03BF\u03C3.com", "" },
1567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "xn--nxasmm1c", "B",  // Greek with final sigma in Punycode
1577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u03B2\u03CC\u03BB\u03BF\u03C2", "" },
1587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "www.\u0DC1\u0DCA\u200D\u0DBB\u0DD3.com", "N",  // "Sri" in "Sri Lanka" has a ZWJ
1597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "www.\u0DC1\u0DCA\u200D\u0DBB\u0DD3.com", "" },
1607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "www.\u0DC1\u0DCA\u200D\u0DBB\u0DD3.com", "T",  // "Sri" in "Sri Lanka" has a ZWJ
1617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "www.\u0DC1\u0DCA\u0DBB\u0DD3.com", "" },
1627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "www.xn--10cl1a0b660p.com", "B",  // "Sri" in Punycode
1637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "www.\u0DC1\u0DCA\u200D\u0DBB\u0DD3.com", "" },
1647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u0646\u0627\u0645\u0647\u200C\u0627\u06CC", "N",  // ZWNJ
1657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u0646\u0627\u0645\u0647\u200C\u0627\u06CC", "" },
1667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u0646\u0627\u0645\u0647\u200C\u0627\u06CC", "T",  // ZWNJ
1677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u0646\u0627\u0645\u0647\u0627\u06CC", "" },
1687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "xn--mgba3gch31f060k.com", "B",  // ZWNJ in Punycode
1697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u0646\u0627\u0645\u0647\u200C\u0627\u06CC.com", "" },
1707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "a.b\uFF0Ec\u3002d\uFF61", "B",
1717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "a.b.c.d.", "" },
1727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "U\u0308.xn--tda", "B",  // U+umlaut.u-umlaut
1737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u00FC.\u00FC", "" },
1747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "xn--u-ccb", "B",  // u+umlaut in Punycode
1757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "xn--u-ccb\uFFFD", "UIDNA_ERROR_INVALID_ACE_LABEL" },
1767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "a\u2488com", "B",  // contains 1-dot
1777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "a\uFFFDcom", "UIDNA_ERROR_DISALLOWED" },
1787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "xn--a-ecp.ru", "B",  // contains 1-dot in Punycode
1797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "xn--a-ecp\uFFFD.ru", "UIDNA_ERROR_INVALID_ACE_LABEL" },
1807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "xn--0.pt", "B",  // invalid Punycode
1817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "xn--0\uFFFD.pt", "UIDNA_ERROR_PUNYCODE" },
1827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "xn--a.pt", "B",  // U+0080
1837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "xn--a\uFFFD.pt", "UIDNA_ERROR_INVALID_ACE_LABEL" },
1847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "xn--a-\u00C4.pt", "B",  // invalid Punycode
1857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "xn--a-\u00E4.pt", "UIDNA_ERROR_PUNYCODE" },
1867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u65E5\u672C\u8A9E\u3002\uFF2A\uFF30", "B",  // Japanese with fullwidth ".jp"
1877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u65E5\u672C\u8A9E.jp", "" },
1887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u2615", "B", "\u2615", "" },  // Unicode 4.0 HOT BEVERAGE
1897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // some characters are disallowed because they are canonically equivalent
1907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // to sequences with non-LDH ASCII
1917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "a\u2260b\u226Ec\u226Fd", "B",
1927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "a\uFFFDb\uFFFDc\uFFFDd", "UIDNA_ERROR_DISALLOWED" },
1937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // many deviation characters, test the special mapping code
1947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "1.a\u00DF\u200C\u200Db\u200C\u200Dc\u00DF\u00DF\u00DF\u00DFd"+
1957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u03C2\u03C3\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DFe"+
1967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DFx"+
1977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DFy"+
1987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u0302\u00DFz", "N",
1997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1.a\u00DF\u200C\u200Db\u200C\u200Dc\u00DF\u00DF\u00DF\u00DFd"+
2007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u03C2\u03C3\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DFe"+
2017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DFx"+
2027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DFy"+
2037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u0302\u00DFz",
2047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "UIDNA_ERROR_LABEL_TOO_LONG|UIDNA_ERROR_CONTEXTJ" },
2057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "1.a\u00DF\u200C\u200Db\u200C\u200Dc\u00DF\u00DF\u00DF\u00DFd"+
2067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u03C2\u03C3\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DFe"+
2077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DFx"+
2087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DFy"+
2097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u00DF\u0302\u00DFz", "T",
2107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1.assbcssssssssd"+
2117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u03C3\u03C3sssssssssssssssse"+
2127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "ssssssssssssssssssssx"+
2137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "ssssssssssssssssssssy"+
2147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "sssssssssssssss\u015Dssz", "UIDNA_ERROR_LABEL_TOO_LONG" },
2157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // "xn--bss" with deviation characters
2167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u200Cx\u200Dn\u200C-\u200D-b\u00DF", "N",
2177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u200Cx\u200Dn\u200C-\u200D-b\u00DF", "UIDNA_ERROR_CONTEXTJ" },
2187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u200Cx\u200Dn\u200C-\u200D-b\u00DF", "T",
2197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u5919", "" },
2207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // "xn--bssffl" written as:
2217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // 02E3 MODIFIER LETTER SMALL X
2227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // 034F COMBINING GRAPHEME JOINER (ignored)
2237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // 2115 DOUBLE-STRUCK CAPITAL N
2247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // 200B ZERO WIDTH SPACE (ignored)
2257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // FE63 SMALL HYPHEN-MINUS
2267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // 00AD SOFT HYPHEN (ignored)
2277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // FF0D FULLWIDTH HYPHEN-MINUS
2287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // 180C MONGOLIAN FREE VARIATION SELECTOR TWO (ignored)
2297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // 212C SCRIPT CAPITAL B
2307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // FE00 VARIATION SELECTOR-1 (ignored)
2317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // 017F LATIN SMALL LETTER LONG S
2327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // 2064 INVISIBLE PLUS (ignored)
2337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // 1D530 MATHEMATICAL FRAKTUR SMALL S
2347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // E01EF VARIATION SELECTOR-256 (ignored)
2357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // FB04 LATIN SMALL LIGATURE FFL
2367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u02E3\u034F\u2115\u200B\uFE63\u00AD\uFF0D\u180C"+
2377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u212C\uFE00\u017F\u2064"+"\uD835\uDD30\uDB40\uDDEF"/*1D530 E01EF*/+"\uFB04", "B",
2387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u5921\u591E\u591C\u5919", "" },
2397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "123456789012345678901234567890123456789012345678901234567890123."+
2407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890123456789012345678901234567890123456789012345678901", "B",
2437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890123456789012345678901234567890123456789012345678901", "" },
2477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "123456789012345678901234567890123456789012345678901234567890123."+
2487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890123456789012345678901234567890123456789012345678901.", "B",
2517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890123456789012345678901234567890123456789012345678901.", "" },
2557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Domain name >256 characters, forces slow path in UTF-8 processing.
2567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "123456789012345678901234567890123456789012345678901234567890123."+
2577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "12345678901234567890123456789012345678901234567890123456789012", "B",
2617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "12345678901234567890123456789012345678901234567890123456789012",
2667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "UIDNA_ERROR_DOMAIN_NAME_TOO_LONG" },
2677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "123456789012345678901234567890123456789012345678901234567890123."+
2687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890123456789012345678901234567890123456789\u05D0", "B",
2727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890123456789012345678901234567890123456789\u05D0",
2777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "UIDNA_ERROR_DOMAIN_NAME_TOO_LONG|UIDNA_ERROR_BIDI" },
2787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "123456789012345678901234567890123456789012345678901234567890123."+
2797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890123456789012345678901234567890123456789012345678901234."+
2807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890", "B",
2827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890123456789012345678901234567890123456789012345678901234."+
2847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890",
2867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "UIDNA_ERROR_LABEL_TOO_LONG" },
2877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "123456789012345678901234567890123456789012345678901234567890123."+
2887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890123456789012345678901234567890123456789012345678901234."+
2897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890.", "B",
2917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890123456789012345678901234567890123456789012345678901234."+
2937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890.",
2957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "UIDNA_ERROR_LABEL_TOO_LONG" },
2967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "123456789012345678901234567890123456789012345678901234567890123."+
2977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890123456789012345678901234567890123456789012345678901234."+
2987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
2997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890123456789012345678901234567890123456789012345678901", "B",
3007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
3017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890123456789012345678901234567890123456789012345678901234."+
3027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
3037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890123456789012345678901234567890123456789012345678901",
3047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "UIDNA_ERROR_LABEL_TOO_LONG|UIDNA_ERROR_DOMAIN_NAME_TOO_LONG" },
3057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // label length 63: xn--1234567890123456789012345678901234567890123456789012345-9te
3067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u00E41234567890123456789012345678901234567890123456789012345", "B",
3077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u00E41234567890123456789012345678901234567890123456789012345", "" },
3087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "1234567890\u00E41234567890123456789012345678901234567890123456", "B",
3097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890\u00E41234567890123456789012345678901234567890123456", "UIDNA_ERROR_LABEL_TOO_LONG" },
3107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "123456789012345678901234567890123456789012345678901234567890123."+
3117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890\u00E4123456789012345678901234567890123456789012345."+
3127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
3137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890123456789012345678901234567890123456789012345678901", "B",
3147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
3157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890\u00E4123456789012345678901234567890123456789012345."+
3167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
3177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890123456789012345678901234567890123456789012345678901", "" },
3187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "123456789012345678901234567890123456789012345678901234567890123."+
3197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890\u00E4123456789012345678901234567890123456789012345."+
3207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
3217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890123456789012345678901234567890123456789012345678901.", "B",
3227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
3237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890\u00E4123456789012345678901234567890123456789012345."+
3247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
3257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890123456789012345678901234567890123456789012345678901.", "" },
3267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "123456789012345678901234567890123456789012345678901234567890123."+
3277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890\u00E4123456789012345678901234567890123456789012345."+
3287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
3297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "12345678901234567890123456789012345678901234567890123456789012", "B",
3307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
3317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890\u00E4123456789012345678901234567890123456789012345."+
3327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
3337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "12345678901234567890123456789012345678901234567890123456789012",
3347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "UIDNA_ERROR_DOMAIN_NAME_TOO_LONG" },
3357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "123456789012345678901234567890123456789012345678901234567890123."+
3367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890\u00E41234567890123456789012345678901234567890123456."+
3377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
3387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890", "B",
3397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
3407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890\u00E41234567890123456789012345678901234567890123456."+
3417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
3427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890",
3437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "UIDNA_ERROR_LABEL_TOO_LONG" },
3447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "123456789012345678901234567890123456789012345678901234567890123."+
3457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890\u00E41234567890123456789012345678901234567890123456."+
3467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
3477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890.", "B",
3487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
3497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890\u00E41234567890123456789012345678901234567890123456."+
3507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
3517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890.",
3527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "UIDNA_ERROR_LABEL_TOO_LONG" },
3537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "123456789012345678901234567890123456789012345678901234567890123."+
3547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890\u00E41234567890123456789012345678901234567890123456."+
3557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
3567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890123456789012345678901234567890123456789012345678901", "B",
3577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
3587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890\u00E41234567890123456789012345678901234567890123456."+
3597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "123456789012345678901234567890123456789012345678901234567890123."+
3607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "1234567890123456789012345678901234567890123456789012345678901",
3617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "UIDNA_ERROR_LABEL_TOO_LONG|UIDNA_ERROR_DOMAIN_NAME_TOO_LONG" },
3627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // hyphen errors and empty-label errors
3637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Ticket #10883: ToUnicode also checks for empty labels.
3647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { ".", "B", ".", "UIDNA_ERROR_EMPTY_LABEL" },
3657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\uFF0E", "B", ".", "UIDNA_ERROR_EMPTY_LABEL" },
3667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // "xn---q----jra"=="-q--a-umlaut-"
3677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "a.b..-q--a-.e", "B", "a.b..-q--a-.e",
3687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "UIDNA_ERROR_EMPTY_LABEL|UIDNA_ERROR_LEADING_HYPHEN|UIDNA_ERROR_TRAILING_HYPHEN|"+
3697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "UIDNA_ERROR_HYPHEN_3_4" },
3707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "a.b..-q--\u00E4-.e", "B", "a.b..-q--\u00E4-.e",
3717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "UIDNA_ERROR_EMPTY_LABEL|UIDNA_ERROR_LEADING_HYPHEN|UIDNA_ERROR_TRAILING_HYPHEN|"+
3727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "UIDNA_ERROR_HYPHEN_3_4" },
3737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "a.b..xn---q----jra.e", "B", "a.b..-q--\u00E4-.e",
3747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "UIDNA_ERROR_EMPTY_LABEL|UIDNA_ERROR_LEADING_HYPHEN|UIDNA_ERROR_TRAILING_HYPHEN|"+
3757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "UIDNA_ERROR_HYPHEN_3_4" },
3767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "a..c", "B", "a..c", "UIDNA_ERROR_EMPTY_LABEL" },
3777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "a.xn--.c", "B", "a..c", "UIDNA_ERROR_EMPTY_LABEL" },
3787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "a.-b.", "B", "a.-b.", "UIDNA_ERROR_LEADING_HYPHEN" },
3797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "a.b-.c", "B", "a.b-.c", "UIDNA_ERROR_TRAILING_HYPHEN" },
3807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "a.-.c", "B", "a.-.c", "UIDNA_ERROR_LEADING_HYPHEN|UIDNA_ERROR_TRAILING_HYPHEN" },
3817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "a.bc--de.f", "B", "a.bc--de.f", "UIDNA_ERROR_HYPHEN_3_4" },
3827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u00E4.\u00AD.c", "B", "\u00E4..c", "UIDNA_ERROR_EMPTY_LABEL" },
3837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u00E4.xn--.c", "B", "\u00E4..c", "UIDNA_ERROR_EMPTY_LABEL" },
3847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u00E4.-b.", "B", "\u00E4.-b.", "UIDNA_ERROR_LEADING_HYPHEN" },
3857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u00E4.b-.c", "B", "\u00E4.b-.c", "UIDNA_ERROR_TRAILING_HYPHEN" },
3867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u00E4.-.c", "B", "\u00E4.-.c", "UIDNA_ERROR_LEADING_HYPHEN|UIDNA_ERROR_TRAILING_HYPHEN" },
3877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u00E4.bc--de.f", "B", "\u00E4.bc--de.f", "UIDNA_ERROR_HYPHEN_3_4" },
3887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "a.b.\u0308c.d", "B", "a.b.\uFFFDc.d", "UIDNA_ERROR_LEADING_COMBINING_MARK" },
3897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "a.b.xn--c-bcb.d", "B",
3907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "a.b.xn--c-bcb\uFFFD.d", "UIDNA_ERROR_LEADING_COMBINING_MARK|UIDNA_ERROR_INVALID_ACE_LABEL" },
3917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // BiDi
3927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "A0", "B", "a0", "" },
3937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "0A", "B", "0a", "" },  // all-LTR is ok to start with a digit (EN)
3947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "0A.\u05D0", "B",  // ASCII label does not start with L/R/AL
3957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "0a.\u05D0", "UIDNA_ERROR_BIDI" },
3967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "c.xn--0-eha.xn--4db", "B",  // 2nd label does not start with L/R/AL
3977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "c.0\u00FC.\u05D0", "UIDNA_ERROR_BIDI" },
3987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "b-.\u05D0", "B",  // label does not end with L/EN
3997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "b-.\u05D0", "UIDNA_ERROR_TRAILING_HYPHEN|UIDNA_ERROR_BIDI" },
4007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "d.xn----dha.xn--4db", "B",  // 2nd label does not end with L/EN
4017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "d.\u00FC-.\u05D0", "UIDNA_ERROR_TRAILING_HYPHEN|UIDNA_ERROR_BIDI" },
4027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "a\u05D0", "B", "a\u05D0", "UIDNA_ERROR_BIDI" },  // first dir != last dir
4037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u05D0\u05C7", "B", "\u05D0\u05C7", "" },
4047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u05D09\u05C7", "B", "\u05D09\u05C7", "" },
4057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u05D0a\u05C7", "B", "\u05D0a\u05C7", "UIDNA_ERROR_BIDI" },  // first dir != last dir
4067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u05D0\u05EA", "B", "\u05D0\u05EA", "" },
4077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u05D0\u05F3\u05EA", "B", "\u05D0\u05F3\u05EA", "" },
4087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "a\u05D0Tz", "B", "a\u05D0tz", "UIDNA_ERROR_BIDI" },  // mixed dir
4097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u05D0T\u05EA", "B", "\u05D0t\u05EA", "UIDNA_ERROR_BIDI" },  // mixed dir
4107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u05D07\u05EA", "B", "\u05D07\u05EA", "" },
4117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u05D0\u0667\u05EA", "B", "\u05D0\u0667\u05EA", "" },  // Arabic 7 in the middle
4127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "a7\u0667z", "B", "a7\u0667z", "UIDNA_ERROR_BIDI" },  // AN digit in LTR
4137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u05D07\u0667\u05EA", "B",  // mixed EN/AN digits in RTL
4147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u05D07\u0667\u05EA", "UIDNA_ERROR_BIDI" },
4157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // ZWJ
4167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u0BB9\u0BCD\u200D", "N", "\u0BB9\u0BCD\u200D", "" },  // Virama+ZWJ
4177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u0BB9\u200D", "N", "\u0BB9\u200D", "UIDNA_ERROR_CONTEXTJ" },  // no Virama
4187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u200D", "N", "\u200D", "UIDNA_ERROR_CONTEXTJ" },  // no Virama
4197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // ZWNJ
4207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u0BB9\u0BCD\u200C", "N", "\u0BB9\u0BCD\u200C", "" },  // Virama+ZWNJ
4217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u0BB9\u200C", "N", "\u0BB9\u200C", "UIDNA_ERROR_CONTEXTJ" },  // no Virama
4227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u200C", "N", "\u200C", "UIDNA_ERROR_CONTEXTJ" },  // no Virama
4237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u0644\u0670\u200C\u06ED\u06EF", "N",  // Joining types D T ZWNJ T R
4247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u0644\u0670\u200C\u06ED\u06EF", "" },
4257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u0644\u0670\u200C\u06EF", "N",  // D T ZWNJ R
4267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u0644\u0670\u200C\u06EF", "" },
4277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u0644\u200C\u06ED\u06EF", "N",  // D ZWNJ T R
4287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u0644\u200C\u06ED\u06EF", "" },
4297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u0644\u200C\u06EF", "N",  // D ZWNJ R
4307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u0644\u200C\u06EF", "" },
4317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u0644\u0670\u200C\u06ED", "N",  // D T ZWNJ T
4327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u0644\u0670\u200C\u06ED", "UIDNA_ERROR_BIDI|UIDNA_ERROR_CONTEXTJ" },
4337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u06EF\u200C\u06EF", "N",  // R ZWNJ R
4347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u06EF\u200C\u06EF", "UIDNA_ERROR_CONTEXTJ" },
4357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u0644\u200C", "N",  // D ZWNJ
4367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u0644\u200C", "UIDNA_ERROR_BIDI|UIDNA_ERROR_CONTEXTJ" },
4377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u0660\u0661", "B",  // Arabic-Indic Digits alone
4387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u0660\u0661", "UIDNA_ERROR_BIDI" },
4397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u06F0\u06F1", "B",  // Extended Arabic-Indic Digits alone
4407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u06F0\u06F1", "" },
4417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u0660\u06F1", "B",  // Mixed Arabic-Indic Digits
4427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u0660\u06F1", "UIDNA_ERROR_CONTEXTO_DIGITS|UIDNA_ERROR_BIDI" },
4437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // All of the CONTEXTO "Would otherwise have been DISALLOWED" characters
4447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // in their correct contexts,
4457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // then each in incorrect context.
4467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "l\u00B7l\u4E00\u0375\u03B1\u05D0\u05F3\u05F4\u30FB", "B",
4477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "l\u00B7l\u4E00\u0375\u03B1\u05D0\u05F3\u05F4\u30FB", "UIDNA_ERROR_BIDI" },
4487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "l\u00B7", "B",
4497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "l\u00B7", "UIDNA_ERROR_CONTEXTO_PUNCTUATION" },
4507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u00B7l", "B",
4517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u00B7l", "UIDNA_ERROR_CONTEXTO_PUNCTUATION" },
4527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u0375", "B",
4537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u0375", "UIDNA_ERROR_CONTEXTO_PUNCTUATION" },
4547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u03B1\u05F3", "B",
4557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u03B1\u05F3", "UIDNA_ERROR_CONTEXTO_PUNCTUATION|UIDNA_ERROR_BIDI" },
4567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "\u05F4", "B",
4577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "\u05F4", "UIDNA_ERROR_CONTEXTO_PUNCTUATION" },
4587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        { "l\u30FB", "B",
4597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          "l\u30FB", "UIDNA_ERROR_CONTEXTO_PUNCTUATION" },
4607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // { "", "B",
4617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        //   "", "" },
4627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    };
4637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestSomeCases() {
4657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        StringBuilder aT=new StringBuilder(), uT=new StringBuilder();
4667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        StringBuilder aN=new StringBuilder(), uN=new StringBuilder();
4677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        IDNA.Info aTInfo=new IDNA.Info(), uTInfo=new IDNA.Info();
4687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        IDNA.Info aNInfo=new IDNA.Info(), uNInfo=new IDNA.Info();
4697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        StringBuilder aTuN=new StringBuilder(), uTaN=new StringBuilder();
4717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        StringBuilder aNuN=new StringBuilder(), uNaN=new StringBuilder();
4727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        IDNA.Info aTuNInfo=new IDNA.Info(), uTaNInfo=new IDNA.Info();
4737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        IDNA.Info aNuNInfo=new IDNA.Info(), uNaNInfo=new IDNA.Info();
4747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        StringBuilder aTL=new StringBuilder(), uTL=new StringBuilder();
4767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        StringBuilder aNL=new StringBuilder(), uNL=new StringBuilder();
4777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        IDNA.Info aTLInfo=new IDNA.Info(), uTLInfo=new IDNA.Info();
4787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        IDNA.Info aNLInfo=new IDNA.Info(), uNLInfo=new IDNA.Info();
4797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        EnumSet<IDNA.Error> uniErrors=EnumSet.noneOf(IDNA.Error.class);
4817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        TestCase testCase=new TestCase();
4837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int i;
4847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for(i=0; i<testCases.length; ++i) {
4857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            testCase.set(testCases[i]);
4867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String input=testCase.s;
4877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String expected=testCase.u;
4887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // ToASCII/ToUnicode, transitional/nontransitional
4897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            try {
4907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                trans.nameToASCII(input, aT, aTInfo);
4917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                trans.nameToUnicode(input, uT, uTInfo);
4927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                nontrans.nameToASCII(input, aN, aNInfo);
4937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                nontrans.nameToUnicode(input, uN, uNInfo);
4947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } catch(Exception e) {
4957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln(String.format("first-level processing [%d/%s] %s - %s",
4967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    i, testCase.o, testCase.s, e));
4977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                continue;
4987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
4997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // ToUnicode does not set length-overflow errors.
5007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            uniErrors.clear();
5017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            uniErrors.addAll(testCase.errors);
5027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            uniErrors.removeAll(lengthOverflowErrors);
5037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            char mode=testCase.o.charAt(0);
5047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(mode=='B' || mode=='N') {
5057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if(!sameErrors(uNInfo, uniErrors)) {
5067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln(String.format("N.nameToUnicode([%d] %s) unexpected errors %s",
5077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        i, testCase.s, uNInfo.getErrors()));
5087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    continue;
5097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
5107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if(!UTF16Plus.equal(uN, expected)) {
5117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln(String.format("N.nameToUnicode([%d] %s) unexpected string %s",
5127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        i, testCase.s, prettify(uN.toString())));
5137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    continue;
5147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
5157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if(!sameErrors(aNInfo, testCase.errors)) {
5167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln(String.format("N.nameToASCII([%d] %s) unexpected errors %s",
5177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        i, testCase.s, aNInfo.getErrors()));
5187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    continue;
5197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
5207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
5217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(mode=='B' || mode=='T') {
5227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if(!sameErrors(uTInfo, uniErrors)) {
5237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln(String.format("T.nameToUnicode([%d] %s) unexpected errors %s",
5247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        i, testCase.s, uTInfo.getErrors()));
5257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    continue;
5267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
5277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if(!UTF16Plus.equal(uT, expected)) {
5287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln(String.format("T.nameToUnicode([%d] %s) unexpected string %s",
5297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        i, testCase.s, prettify(uT.toString())));
5307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    continue;
5317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
5327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if(!sameErrors(aTInfo, testCase.errors)) {
5337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln(String.format("T.nameToASCII([%d] %s) unexpected errors %s",
5347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        i, testCase.s, aTInfo.getErrors()));
5357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    continue;
5367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
5377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
5387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // ToASCII is all-ASCII if no severe errors
5397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(!hasCertainErrors(aNInfo, severeErrors) && !isASCII(aN)) {
5407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln(String.format("N.nameToASCII([%d] %s) (errors %s) result is not ASCII %s",
5417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    i, testCase.s, aNInfo.getErrors(), prettify(aN.toString())));
5427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                continue;
5437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
5447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(!hasCertainErrors(aTInfo, severeErrors) && !isASCII(aT)) {
5457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln(String.format("T.nameToASCII([%d] %s) (errors %s) result is not ASCII %s",
5467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    i, testCase.s, aTInfo.getErrors(), prettify(aT.toString())));
5477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                continue;
5487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
5497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(isVerbose()) {
5507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                char m= mode=='B' ? mode : 'N';
5517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                logln(String.format("%c.nameToASCII([%d] %s) (errors %s) result string: %s",
5527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    m, i, testCase.s, aNInfo.getErrors(), prettify(aN.toString())));
5537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if(mode!='B') {
5547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    logln(String.format("T.nameToASCII([%d] %s) (errors %s) result string: %s",
5557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        i, testCase.s, aTInfo.getErrors(), prettify(aT.toString())));
5567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
5577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
5587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // second-level processing
5597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            try {
5607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                nontrans.nameToUnicode(aT, aTuN, aTuNInfo);
5617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                nontrans.nameToASCII(uT, uTaN, uTaNInfo);
5627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                nontrans.nameToUnicode(aN, aNuN, aNuNInfo);
5637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                nontrans.nameToASCII(uN, uNaN, uNaNInfo);
5647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } catch(Exception e) {
5657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln(String.format("second-level processing [%d/%s] %s - %s",
5667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    i, testCase.o, testCase.s, e));
5677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                continue;
5687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
5697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(!UTF16Plus.equal(aN, uNaN)) {
5707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln(String.format("N.nameToASCII([%d] %s)!=N.nameToUnicode().N.nameToASCII() "+
5717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    "(errors %s) %s vs. %s",
5727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    i, testCase.s, aNInfo.getErrors(),
5737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    prettify(aN.toString()), prettify(uNaN.toString())));
5747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                continue;
5757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
5767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(!UTF16Plus.equal(aT, uTaN)) {
5777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln(String.format("T.nameToASCII([%d] %s)!=T.nameToUnicode().N.nameToASCII() "+
5787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    "(errors %s) %s vs. %s",
5797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    i, testCase.s, aNInfo.getErrors(),
5807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    prettify(aT.toString()), prettify(uTaN.toString())));
5817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                continue;
5827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
5837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(!UTF16Plus.equal(uN, aNuN)) {
5847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln(String.format("N.nameToUnicode([%d] %s)!=N.nameToASCII().N.nameToUnicode() "+
5857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    "(errors %s) %s vs. %s",
5867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    i, testCase.s, uNInfo.getErrors(), prettify(uN.toString()), prettify(aNuN.toString())));
5877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                continue;
5887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
5897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(!UTF16Plus.equal(uT, aTuN)) {
5907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln(String.format("T.nameToUnicode([%d] %s)!=T.nameToASCII().N.nameToUnicode() "+
5917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    "(errors %s) %s vs. %s",
5927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    i, testCase.s, uNInfo.getErrors(),
5937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    prettify(uT.toString()), prettify(aTuN.toString())));
5947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                continue;
5957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
5967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // labelToUnicode
5977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            try {
5987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                trans.labelToASCII(input, aTL, aTLInfo);
5997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                trans.labelToUnicode(input, uTL, uTLInfo);
6007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                nontrans.labelToASCII(input, aNL, aNLInfo);
6017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                nontrans.labelToUnicode(input, uNL, uNLInfo);
6027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } catch(Exception e) {
6037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln(String.format("labelToXYZ processing [%d/%s] %s - %s",
6047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    i, testCase.o, testCase.s, e));
6057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                continue;
6067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
6077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(aN.indexOf(".")<0) {
6087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if(!UTF16Plus.equal(aN, aNL) || !sameErrors(aNInfo, aNLInfo)) {
6097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln(String.format("N.nameToASCII([%d] %s)!=N.labelToASCII() "+
6107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        "(errors %s vs %s) %s vs. %s",
6117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        i, testCase.s, aNInfo.getErrors().toString(), aNLInfo.getErrors().toString(),
6127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        prettify(aN.toString()), prettify(aNL.toString())));
6137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    continue;
6147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
6157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else {
6167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if(!hasError(aNLInfo, IDNA.Error.LABEL_HAS_DOT)) {
6177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln(String.format("N.labelToASCII([%d] %s) errors %s missing UIDNA_ERROR_LABEL_HAS_DOT",
6187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        i, testCase.s, aNLInfo.getErrors()));
6197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    continue;
6207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
6217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
6227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(aT.indexOf(".")<0) {
6237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if(!UTF16Plus.equal(aT, aTL) || !sameErrors(aTInfo, aTLInfo)) {
6247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln(String.format("T.nameToASCII([%d] %s)!=T.labelToASCII() "+
6257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        "(errors %s vs %s) %s vs. %s",
6267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        i, testCase.s, aTInfo.getErrors().toString(), aTLInfo.getErrors().toString(),
6277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        prettify(aT.toString()), prettify(aTL.toString())));
6287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    continue;
6297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
6307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else {
6317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if(!hasError(aTLInfo, IDNA.Error.LABEL_HAS_DOT)) {
6327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln(String.format("T.labelToASCII([%d] %s) errors %s missing UIDNA_ERROR_LABEL_HAS_DOT",
6337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        i, testCase.s, aTLInfo.getErrors()));
6347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    continue;
6357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
6367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
6377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(uN.indexOf(".")<0) {
6387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if(!UTF16Plus.equal(uN, uNL) || !sameErrors(uNInfo, uNLInfo)) {
6397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln(String.format("N.nameToUnicode([%d] %s)!=N.labelToUnicode() "+
6407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        "(errors %s vs %s) %s vs. %s",
6417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        i, testCase.s, uNInfo.getErrors().toString(), uNLInfo.getErrors().toString(),
6427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        prettify(uN.toString()), prettify(uNL.toString())));
6437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    continue;
6447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
6457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else {
6467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if(!hasError(uNLInfo, IDNA.Error.LABEL_HAS_DOT)) {
6477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln(String.format("N.labelToUnicode([%d] %s) errors %s missing UIDNA_ERROR_LABEL_HAS_DOT",
6487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        i, testCase.s, uNLInfo.getErrors()));
6497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    continue;
6507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
6517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
6527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(uT.indexOf(".")<0) {
6537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if(!UTF16Plus.equal(uT, uTL) || !sameErrors(uTInfo, uTLInfo)) {
6547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln(String.format("T.nameToUnicode([%d] %s)!=T.labelToUnicode() "+
6557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        "(errors %s vs %s) %s vs. %s",
6567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        i, testCase.s, uTInfo.getErrors().toString(), uTLInfo.getErrors().toString(),
6577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        prettify(uT.toString()), prettify(uTL.toString())));
6587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    continue;
6597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
6607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else {
6617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if(!hasError(uTLInfo, IDNA.Error.LABEL_HAS_DOT)) {
6627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln(String.format("T.labelToUnicode([%d] %s) errors %s missing UIDNA_ERROR_LABEL_HAS_DOT",
6637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        i, testCase.s, uTLInfo.getErrors()));
6647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    continue;
6657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
6667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
6677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // Differences between transitional and nontransitional processing
6687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(mode=='B') {
6697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if( aNInfo.isTransitionalDifferent() ||
6707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    aTInfo.isTransitionalDifferent() ||
6717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    uNInfo.isTransitionalDifferent() ||
6727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    uTInfo.isTransitionalDifferent() ||
6737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    aNLInfo.isTransitionalDifferent() ||
6747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    aTLInfo.isTransitionalDifferent() ||
6757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    uNLInfo.isTransitionalDifferent() ||
6767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    uTLInfo.isTransitionalDifferent()
6777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                ) {
6787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln(String.format("B.process([%d] %s) isTransitionalDifferent()", i, testCase.s));
6797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    continue;
6807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
6817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if( !UTF16Plus.equal(aN, aT) || !UTF16Plus.equal(uN, uT) ||
6827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    !UTF16Plus.equal(aNL, aTL) || !UTF16Plus.equal(uNL, uTL) ||
6837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    !sameErrors(aNInfo, aTInfo) || !sameErrors(uNInfo, uTInfo) ||
6847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    !sameErrors(aNLInfo, aTLInfo) || !sameErrors(uNLInfo, uTLInfo)
6857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                ) {
6867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln(String.format("N.process([%d] %s) vs. T.process() different errors or result strings",
6877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        i, testCase.s));
6887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    continue;
6897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
6907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else {
6917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if( !aNInfo.isTransitionalDifferent() ||
6927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    !aTInfo.isTransitionalDifferent() ||
6937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    !uNInfo.isTransitionalDifferent() ||
6947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    !uTInfo.isTransitionalDifferent() ||
6957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    !aNLInfo.isTransitionalDifferent() ||
6967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    !aTLInfo.isTransitionalDifferent() ||
6977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    !uNLInfo.isTransitionalDifferent() ||
6987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    !uTLInfo.isTransitionalDifferent()
6997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                ) {
7007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln(String.format("%s.process([%d] %s) !isTransitionalDifferent()",
7017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        testCase.o, i, testCase.s));
7027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    continue;
7037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
7047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if( UTF16Plus.equal(aN, aT) || UTF16Plus.equal(uN, uT) ||
7057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    UTF16Plus.equal(aNL, aTL) || UTF16Plus.equal(uNL, uTL)
7067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                ) {
7077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln(String.format("N.process([%d] %s) vs. T.process() same result strings",
7087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        i, testCase.s));
7097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    continue;
7107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
7117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
7127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
7137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
7147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private final IDNA trans, nontrans;
7167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final EnumSet<IDNA.Error> severeErrors=EnumSet.of(
7187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        IDNA.Error.LEADING_COMBINING_MARK,
7197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        IDNA.Error.DISALLOWED,
7207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        IDNA.Error.PUNYCODE,
7217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        IDNA.Error.LABEL_HAS_DOT,
7227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        IDNA.Error.INVALID_ACE_LABEL);
7237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final EnumSet<IDNA.Error> lengthOverflowErrors=EnumSet.of(
7247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            IDNA.Error.LABEL_TOO_LONG,
7257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            IDNA.Error.DOMAIN_NAME_TOO_LONG);
7267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private boolean hasError(IDNA.Info info, IDNA.Error error) {
7287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return info.getErrors().contains(error);
7297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
7307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // assumes that certainErrors is not empty
7317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private boolean hasCertainErrors(Set<IDNA.Error> errors, Set<IDNA.Error> certainErrors) {
7327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return !errors.isEmpty() && !Collections.disjoint(errors, certainErrors);
7337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
7347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private boolean hasCertainErrors(IDNA.Info info, Set<IDNA.Error> certainErrors) {
7357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return hasCertainErrors(info.getErrors(), certainErrors);
7367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
7377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private boolean sameErrors(Set<IDNA.Error> a, Set<IDNA.Error> b) {
7387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return a.equals(b);
7397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
7407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private boolean sameErrors(IDNA.Info a, IDNA.Info b) {
7417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return sameErrors(a.getErrors(), b.getErrors());
7427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
7437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private boolean sameErrors(IDNA.Info a, Set<IDNA.Error> b) {
7447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return sameErrors(a.getErrors(), b);
7457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
7467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static boolean
7487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    isASCII(CharSequence str) {
7497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int length=str.length();
7507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for(int i=0; i<length; ++i) {
7517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(str.charAt(i)>=0x80) {
7527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return false;
7537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
7547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
7557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return true;
7567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
7577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert}
758