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

#include "unicode/bytestream.h"
#include "unicode/utypes.h"
#include "unicode/ures.h"
#include "unicode/localpointer.h"
#include "unicode/putil.h"
#include "unicode/uenum.h"
#include "unicode/uloc.h"
#include "ustr_imp.h"
#include "bytesinkutil.h"
#include "charstr.h"
#include "cmemory.h"
#include "cstring.h"
#include "putilimp.h"
#include "uinvchar.h"
#include "ulocimp.h"
#include "uassert.h"


/* struct holding a single variant */
typedef struct VariantListEntry {
    const char              *variant;
    struct VariantListEntry *next;
} VariantListEntry;

/* struct holding a single attribute value */
struct AttributeListEntry : public icu::UMemory {
    const char              *attribute;
    struct AttributeListEntry *next;
};

/* struct holding a single extension */
struct ExtensionListEntry : public icu::UMemory {
    const char                  *key;
    const char                  *value;
    struct ExtensionListEntry   *next;
};

#define MAXEXTLANG 3
typedef struct ULanguageTag {
    char                *buf;   /* holding parsed subtags */
    const char          *language;
    const char          *extlang[MAXEXTLANG];
    const char          *script;
    const char          *region;
    VariantListEntry    *variants;
    ExtensionListEntry  *extensions;
    const char          *privateuse;
    const char          *legacy;
} ULanguageTag;

#define MINLEN 2
#define SEP '-'
#define PRIVATEUSE 'x'
#define LDMLEXT 'u'

#define LOCALE_SEP '_'
#define LOCALE_EXT_SEP '@'
#define LOCALE_KEYWORD_SEP ';'
#define LOCALE_KEY_TYPE_SEP '='

#define ISALPHA(c) uprv_isASCIILetter(c)
#define ISNUMERIC(c) ((c)>='0' && (c)<='9')

static const char EMPTY[] = "";
static const char LANG_UND[] = "und";
static const char PRIVATEUSE_KEY[] = "x";
static const char _POSIX[] = "_POSIX";
static const char POSIX_KEY[] = "va";
static const char POSIX_VALUE[] = "posix";
static const char LOCALE_ATTRIBUTE_KEY[] = "attribute";
static const char PRIVUSE_VARIANT_PREFIX[] = "lvariant";
static const char LOCALE_TYPE_YES[] = "yes";

#define LANG_UND_LEN 3

/*
 Updated on 2018-09-12 from
 https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry .

 This table has 2 parts. The part for
 legacy language tags (marked as “Type: grandfathered” in BCP 47)
 is generated by the following scripts from the IANA language tag registry.

 curl  https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry |\
 egrep -A 7 'Type: grandfathered' | \
 egrep 'Tag|Prefe' | grep -B1 'Preferred' | grep -v '^--' | \
 awk -n '/Tag/ {printf("    \"%s\", ", $2);} /Preferred/ {printf("\"%s\",\n", $2);}' |\
 tr 'A-Z' 'a-z'


 The 2nd part is made of five ICU-specific entries. They're kept for
 the backward compatibility for now, even though there are no preferred
 values. They may have to be removed for the strict BCP 47 compliance.

*/
static const char* const LEGACY[] = {
/*  legacy          preferred */
    "art-lojban",   "jbo",
    "en-gb-oed",    "en-gb-oxendict",
    "i-ami",        "ami",
    "i-bnn",        "bnn",
    "i-hak",        "hak",
    "i-klingon",    "tlh",
    "i-lux",        "lb",
    "i-navajo",     "nv",
    "i-pwn",        "pwn",
    "i-tao",        "tao",
    "i-tay",        "tay",
    "i-tsu",        "tsu",
    "no-bok",       "nb",
    "no-nyn",       "nn",
    "sgn-be-fr",    "sfb",
    "sgn-be-nl",    "vgt",
    "sgn-ch-de",    "sgg",
    "zh-guoyu",     "cmn",
    "zh-hakka",     "hak",
    "zh-min-nan",   "nan",
    "zh-xiang",     "hsn",

    // Legacy tags with no preferred value in the IANA
    // registry. Kept for now for the backward compatibility
    // because ICU has mapped them this way.
    "i-default",    "en-x-i-default",
    "i-enochian",   "und-x-i-enochian",
    "i-mingo",      "see-x-i-mingo",
    "zh-min",       "nan-x-zh-min",
};

/*
 Updated on 2018-09-12 from
 https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry .

 The table lists redundant tags with preferred value in the IANA languate tag registry.
 It's generated with the following command:

 curl  https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry |\
 grep 'Type: redundant' -A 5 | egrep '^(Tag:|Prefer)' | grep -B1 'Preferred' | \
 awk -n '/Tag/ {printf("    \"%s\",       ", $2);} /Preferred/ {printf("\"%s\",\n", $2);}' | \
 tr 'A-Z' 'a-z'

 In addition, ja-latn-hepburn-heploc is mapped to ja-latn-alalc97 because
 a variant tag 'hepburn-heploc' has the preferred subtag, 'alaic97'.
*/

static const char* const REDUNDANT[] = {
//  redundant       preferred
    "sgn-br",       "bzs",
    "sgn-co",       "csn",
    "sgn-de",       "gsg",
    "sgn-dk",       "dsl",
    "sgn-es",       "ssp",
    "sgn-fr",       "fsl",
    "sgn-gb",       "bfi",
    "sgn-gr",       "gss",
    "sgn-ie",       "isg",
    "sgn-it",       "ise",
    "sgn-jp",       "jsl",
    "sgn-mx",       "mfs",
    "sgn-ni",       "ncs",
    "sgn-nl",       "dse",
    "sgn-no",       "nsl",
    "sgn-pt",       "psr",
    "sgn-se",       "swl",
    "sgn-us",       "ase",
    "sgn-za",       "sfs",
    "zh-cmn",       "cmn",
    "zh-cmn-hans",  "cmn-hans",
    "zh-cmn-hant",  "cmn-hant",
    "zh-gan",       "gan",
    "zh-wuu",       "wuu",
    "zh-yue",       "yue",

    // variant tag with preferred value
    "ja-latn-hepburn-heploc", "ja-latn-alalc97",
};

/*
  Updated on 2018-09-12 from
  https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry .

  grep 'Type: language' -A 7 language-subtag-registry  | egrep 'Subtag|Prefe' | \
  grep -B1 'Preferred' | grep -v '^--' | \
  awk -n '/Subtag/ {printf("    \"%s\",       ", $2);} /Preferred/ {printf("\"%s\",\n", $2);}'

  Make sure that 2-letter language subtags come before 3-letter subtags.
*/
static const char DEPRECATEDLANGS[][4] = {
/*  deprecated  new */
    "in",       "id",
    "iw",       "he",
    "ji",       "yi",
    "jw",       "jv",
    "mo",       "ro",
    "aam",       "aas",
    "adp",       "dz",
    "aue",       "ktz",
    "ayx",       "nun",
    "bgm",       "bcg",
    "bjd",       "drl",
    "ccq",       "rki",
    "cjr",       "mom",
    "cka",       "cmr",
    "cmk",       "xch",
    "coy",       "pij",
    "cqu",       "quh",
    "drh",       "khk",
    "drw",       "prs",
    "gav",       "dev",
    "gfx",       "vaj",
    "ggn",       "gvr",
    "gti",       "nyc",
    "guv",       "duz",
    "hrr",       "jal",
    "ibi",       "opa",
    "ilw",       "gal",
    "jeg",       "oyb",
    "kgc",       "tdf",
    "kgh",       "kml",
    "koj",       "kwv",
    "krm",       "bmf",
    "ktr",       "dtp",
    "kvs",       "gdj",
    "kwq",       "yam",
    "kxe",       "tvd",
    "kzj",       "dtp",
    "kzt",       "dtp",
    "lii",       "raq",
    "lmm",       "rmx",
    "meg",       "cir",
    "mst",       "mry",
    "mwj",       "vaj",
    "myt",       "mry",
    "nad",       "xny",
    "ncp",       "kdz",
    "nnx",       "ngv",
    "nts",       "pij",
    "oun",       "vaj",
    "pcr",       "adx",
    "pmc",       "huw",
    "pmu",       "phr",
    "ppa",       "bfy",
    "ppr",       "lcq",
    "pry",       "prt",
    "puz",       "pub",
    "sca",       "hle",
    "skk",       "oyb",
    "tdu",       "dtp",
    "thc",       "tpo",
    "thx",       "oyb",
    "tie",       "ras",
    "tkk",       "twm",
    "tlw",       "weo",
    "tmp",       "tyj",
    "tne",       "kak",
    "tnf",       "prs",
    "tsf",       "taj",
    "uok",       "ema",
    "xba",       "cax",
    "xia",       "acn",
    "xkh",       "waw",
    "xsj",       "suj",
    "ybd",       "rki",
    "yma",       "lrr",
    "ymt",       "mtm",
    "yos",       "zom",
    "yuu",       "yug",
};

/*
  Updated on 2018-04-24 from

  curl  https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry | \
  grep 'Type: region' -A 7 | egrep 'Subtag|Prefe' | \
  grep -B1 'Preferred' | \
  awk -n '/Subtag/ {printf("    \"%s\",       ", $2);} /Preferred/ {printf("\"%s\",\n", $2);}'
*/
static const char DEPRECATEDREGIONS[][3] = {
/*  deprecated  new */
    "BU",       "MM",
    "DD",       "DE",
    "FX",       "FR",
    "TP",       "TL",
    "YD",       "YE",
    "ZR",       "CD",
};

/*
* -------------------------------------------------
*
* These ultag_ functions may be exposed as APIs later
*
* -------------------------------------------------
*/

static ULanguageTag*
ultag_parse(const char* tag, int32_t tagLen, int32_t* parsedLen, UErrorCode* status);

static void
ultag_close(ULanguageTag* langtag);

static const char*
ultag_getLanguage(const ULanguageTag* langtag);

#if 0
static const char*
ultag_getJDKLanguage(const ULanguageTag* langtag);
#endif

static const char*
ultag_getExtlang(const ULanguageTag* langtag, int32_t idx);

static int32_t
ultag_getExtlangSize(const ULanguageTag* langtag);

static const char*
ultag_getScript(const ULanguageTag* langtag);

static const char*
ultag_getRegion(const ULanguageTag* langtag);

static const char*
ultag_getVariant(const ULanguageTag* langtag, int32_t idx);

static int32_t
ultag_getVariantsSize(const ULanguageTag* langtag);

static const char*
ultag_getExtensionKey(const ULanguageTag* langtag, int32_t idx);

static const char*
ultag_getExtensionValue(const ULanguageTag* langtag, int32_t idx);

static int32_t
ultag_getExtensionsSize(const ULanguageTag* langtag);

static const char*
ultag_getPrivateUse(const ULanguageTag* langtag);

#if 0
static const char*
ultag_getLegacy(const ULanguageTag* langtag);
#endif

U_NAMESPACE_BEGIN

/**
 * \class LocalULanguageTagPointer
 * "Smart pointer" class, closes a ULanguageTag via ultag_close().
 * For most methods see the LocalPointerBase base class.
 *
 * @see LocalPointerBase
 * @see LocalPointer
 * @internal
 */
U_DEFINE_LOCAL_OPEN_POINTER(LocalULanguageTagPointer, ULanguageTag, ultag_close);

U_NAMESPACE_END

/*
* -------------------------------------------------
*
* Language subtag syntax validation functions
*
* -------------------------------------------------
*/

static UBool
_isAlphaString(const char* s, int32_t len) {
    int32_t i;
    for (i = 0; i < len; i++) {
        if (!ISALPHA(*(s + i))) {
            return FALSE;
        }
    }
    return TRUE;
}

static UBool
_isNumericString(const char* s, int32_t len) {
    int32_t i;
    for (i = 0; i < len; i++) {
        if (!ISNUMERIC(*(s + i))) {
            return FALSE;
        }
    }
    return TRUE;
}

static UBool
_isAlphaNumericString(const char* s, int32_t len) {
    int32_t i;
    for (i = 0; i < len; i++) {
        if (!ISALPHA(*(s + i)) && !ISNUMERIC(*(s + i))) {
            return FALSE;
        }
    }
    return TRUE;
}

static UBool
_isAlphaNumericStringLimitedLength(const char* s, int32_t len, int32_t min, int32_t max) {
    if (len < 0) {
        len = (int32_t)uprv_strlen(s);
    }
    if (len >= min && len <= max && _isAlphaNumericString(s, len)) {
        return TRUE;
    }
    return FALSE;
}

U_CFUNC UBool
ultag_isLanguageSubtag(const char* s, int32_t len) {
    /*
     * unicode_language_subtag = alpha{2,3} | alpha{5,8};
     * NOTE: Per ICUTC 2019/01/23- accepting alpha 4
     * See ICU-20372
     */
    if (len < 0) {
        len = (int32_t)uprv_strlen(s);
    }
    if (len >= 2 && len <= 8 && _isAlphaString(s, len)) {
        return TRUE;
    }
    return FALSE;
}

static UBool
_isExtlangSubtag(const char* s, int32_t len) {
    /*
     * extlang       = 3ALPHA              ; selected ISO 639 codes
     *                 *2("-" 3ALPHA)      ; permanently reserved
     */
    if (len < 0) {
        len = (int32_t)uprv_strlen(s);
    }
    if (len == 3 && _isAlphaString(s, len)) {
        return TRUE;
    }
    return FALSE;
}

U_CFUNC UBool
ultag_isScriptSubtag(const char* s, int32_t len) {
    /*
     * script        = 4ALPHA              ; ISO 15924 code
     */
    if (len < 0) {
        len = (int32_t)uprv_strlen(s);
    }
    if (len == 4 && _isAlphaString(s, len)) {
        return TRUE;
    }
    return FALSE;
}

U_CFUNC UBool
ultag_isRegionSubtag(const char* s, int32_t len) {
    /*
     * region        = 2ALPHA              ; ISO 3166-1 code
     *               / 3DIGIT              ; UN M.49 code
     */
    if (len < 0) {
        len = (int32_t)uprv_strlen(s);
    }
    if (len == 2 && _isAlphaString(s, len)) {
        return TRUE;
    }
    if (len == 3 && _isNumericString(s, len)) {
        return TRUE;
    }
    return FALSE;
}

static UBool
_isVariantSubtag(const char* s, int32_t len) {
    /*
     * variant       = 5*8alphanum         ; registered variants
     *               / (DIGIT 3alphanum)
     */
    if (len < 0) {
        len = (int32_t)uprv_strlen(s);
    }
    if (_isAlphaNumericStringLimitedLength(s, len, 5, 8)) {
        return TRUE;
    }
    if (len == 4 && ISNUMERIC(*s) && _isAlphaNumericString(s + 1, 3)) {
        return TRUE;
    }
    return FALSE;
}

static UBool
_isSepListOf(UBool (*test)(const char*, int32_t), const char* s, int32_t len) {
    const char *p = s;
    const char *pSubtag = NULL;

    if (len < 0) {
        len = (int32_t)uprv_strlen(s);
    }

    while ((p - s) < len) {
        if (*p == SEP) {
            if (pSubtag == NULL) {
                return FALSE;
            }
            if (!test(pSubtag, (int32_t)(p - pSubtag))) {
                return FALSE;
            }
            pSubtag = NULL;
        } else if (pSubtag == NULL) {
            pSubtag = p;
        }
        p++;
    }
    if (pSubtag == NULL) {
        return FALSE;
    }
    return test(pSubtag, (int32_t)(p - pSubtag));
}

U_CFUNC UBool
ultag_isVariantSubtags(const char* s, int32_t len) {
    return _isSepListOf(&_isVariantSubtag, s, len);
}

// This is for the ICU-specific "lvariant" handling.
static UBool
_isPrivateuseVariantSubtag(const char* s, int32_t len) {
    /*
     * variant       = 1*8alphanum         ; registered variants
     *               / (DIGIT 3alphanum)
     */
    return _isAlphaNumericStringLimitedLength(s, len , 1, 8);
}

static UBool
_isExtensionSingleton(const char* s, int32_t len) {
    /*
     * extension     = singleton 1*("-" (2*8alphanum))
     *
     * singleton     = DIGIT               ; 0 - 9
     *               / %x41-57             ; A - W
     *               / %x59-5A             ; Y - Z
     *               / %x61-77             ; a - w
     *               / %x79-7A             ; y - z
     */
    if (len < 0) {
        len = (int32_t)uprv_strlen(s);
    }
    if (len == 1 && (ISALPHA(*s) || ISNUMERIC(*s)) && (uprv_tolower(*s) != PRIVATEUSE)) {
        return TRUE;
    }
    return FALSE;
}

static UBool
_isExtensionSubtag(const char* s, int32_t len) {
    /*
     * extension     = singleton 1*("-" (2*8alphanum))
     */
    return _isAlphaNumericStringLimitedLength(s, len, 2, 8);
}

U_CFUNC UBool
ultag_isExtensionSubtags(const char* s, int32_t len) {
    return _isSepListOf(&_isExtensionSubtag, s, len);
}

static UBool
_isPrivateuseValueSubtag(const char* s, int32_t len) {
    /*
     * privateuse    = "x" 1*("-" (1*8alphanum))
     */
    return _isAlphaNumericStringLimitedLength(s, len, 1, 8);
}

U_CFUNC UBool
ultag_isPrivateuseValueSubtags(const char* s, int32_t len) {
    return _isSepListOf(&_isPrivateuseValueSubtag, s, len);
}

U_CFUNC UBool
ultag_isUnicodeLocaleAttribute(const char* s, int32_t len) {
    /*
     * attribute = alphanum{3,8} ;
     */
    return _isAlphaNumericStringLimitedLength(s, len , 3, 8);
}

U_CFUNC UBool
ultag_isUnicodeLocaleAttributes(const char* s, int32_t len) {
    return _isSepListOf(&ultag_isUnicodeLocaleAttribute, s, len);
}

U_CFUNC UBool
ultag_isUnicodeLocaleKey(const char* s, int32_t len) {
    /*
     * key = alphanum alpha ;
     */
    if (len < 0) {
        len = (int32_t)uprv_strlen(s);
    }
    if (len == 2 && (ISALPHA(*s) || ISNUMERIC(*s)) && ISALPHA(s[1])) {
        return TRUE;
    }
    return FALSE;
}

U_CFUNC UBool
_isUnicodeLocaleTypeSubtag(const char*s, int32_t len) {
    /*
     * alphanum{3,8}
     */
    return _isAlphaNumericStringLimitedLength(s, len , 3, 8);
}

U_CFUNC UBool
ultag_isUnicodeLocaleType(const char*s, int32_t len) {
    /*
     * type = alphanum{3,8} (sep alphanum{3,8})* ;
     */
    return _isSepListOf(&_isUnicodeLocaleTypeSubtag, s, len);
}

static UBool
_isTKey(const char* s, int32_t len)
{
    /*
     * tkey = alpha digit ;
     */
    if (len < 0) {
        len = (int32_t)uprv_strlen(s);
    }
    if (len == 2 && ISALPHA(*s) && ISNUMERIC(*(s + 1))) {
        return TRUE;
    }
    return FALSE;
}

static UBool
_isTValue(const char* s, int32_t len)
{
    /*
     * tvalue = (sep alphanum{3,8})+ ;
     */
    return _isAlphaNumericStringLimitedLength(s, len , 3, 8);
}

static UBool
_isTransformedExtensionSubtag(int32_t& state, const char* s, int32_t len)
{
    const int32_t kStart = 0;       // Start, wait for unicode_language_subtag, tkey or end
    const int32_t kGotLanguage = 1; // Got unicode_language_subtag, wait for unicode_script_subtag,
                                    // unicode_region_subtag, unicode_variant_subtag, tkey or end
    const int32_t kGotScript = 2;   // Got unicode_script_subtag, wait for unicode_region_subtag,
                                    // unicode_variant_subtag, tkey, or end
    const int32_t kGotRegion = 3;   // Got unicode_region_subtag, wait for unicode_variant_subtag,
                                    // tkey, or end.
    const int32_t kGotVariant = 4;  // Got unicode_variant_subtag, wait for unicode_variant_subtag
                                    // tkey or end.
    const int32_t kGotTKey = -1;    // Got tkey, wait for tvalue. ERROR if stop here.
    const int32_t kGotTValue = 6;   // Got tvalue, wait for tkey, tvalue or end

    switch (state) {
        case kStart:
            if (ultag_isLanguageSubtag(s, len)) {
                state = kGotLanguage;
                return TRUE;
            }
            if (_isTKey(s, len)) {
                state = kGotTKey;
                return TRUE;
            }
            return FALSE;
        case kGotLanguage:
            if (ultag_isScriptSubtag(s, len)) {
                state = kGotScript;
                return TRUE;
            }
            U_FALLTHROUGH;
        case kGotScript:
            if (ultag_isRegionSubtag(s, len)) {
                state = kGotRegion;
                return TRUE;
            }
            U_FALLTHROUGH;
        case kGotRegion:
            U_FALLTHROUGH;
        case kGotVariant:
            if (_isVariantSubtag(s, len)) {
                state = kGotVariant;
                return TRUE;
            }
            if (_isTKey(s, len)) {
                state = kGotTKey;
                return TRUE;
            }
            return FALSE;
        case kGotTKey:
            if (_isTValue(s, len)) {
                state = kGotTValue;
                return TRUE;
            }
            return FALSE;
        case kGotTValue:
            if (_isTKey(s, len)) {
                state = kGotTKey;
                return TRUE;
            }
            if (_isTValue(s, len)) {
                return TRUE;
            }
            return FALSE;
    }
    return FALSE;
}

static UBool
_isUnicodeExtensionSubtag(int32_t& state, const char* s, int32_t len)
{
    const int32_t kStart = 0;         // Start, wait for a key or attribute or end
    const int32_t kGotKey = 1;        // Got a key, wait for type or key or end
    const int32_t kGotType = 2;       // Got a type, wait for key or end

    switch (state) {
        case kStart:
            if (ultag_isUnicodeLocaleKey(s, len)) {
                state = kGotKey;
                return TRUE;
            }
            if (ultag_isUnicodeLocaleAttribute(s, len)) {
                return TRUE;
            }
            return FALSE;
        case kGotKey:
            if (ultag_isUnicodeLocaleKey(s, len)) {
                return TRUE;
            }
            if (_isUnicodeLocaleTypeSubtag(s, len)) {
                state = kGotType;
                return TRUE;
            }
            return FALSE;
        case kGotType:
            if (ultag_isUnicodeLocaleKey(s, len)) {
                state = kGotKey;
                return TRUE;
            }
            if (_isUnicodeLocaleTypeSubtag(s, len)) {
                return TRUE;
            }
            return FALSE;
    }
    return FALSE;
}

static UBool
_isStatefulSepListOf(UBool (*test)(int32_t&, const char*, int32_t), const char* s, int32_t len)
{
    int32_t state = 0;
    const char* p;
    const char* start = s;
    int32_t subtagLen = 0;

    if (len < 0) {
        len = (int32_t)uprv_strlen(s);
    }

    for (p = s; len > 0; p++, len--) {
        if (*p == SEP) {
            if (!test(state, start, subtagLen)) {
                return FALSE;
            }
            subtagLen = 0;
            start = p + 1;
        } else {
            subtagLen++;
        }
    }

    if (test(state, start, subtagLen) && state >= 0) {
        return TRUE;
    }
    return FALSE;
}

U_CFUNC UBool
ultag_isTransformedExtensionSubtags(const char* s, int32_t len)
{
    return _isStatefulSepListOf(&_isTransformedExtensionSubtag, s, len);
}

U_CFUNC UBool
ultag_isUnicodeExtensionSubtags(const char* s, int32_t len) {
    return _isStatefulSepListOf(&_isUnicodeExtensionSubtag, s, len);
}


/*
* -------------------------------------------------
*
* Helper functions
*
* -------------------------------------------------
*/

static UBool
_addVariantToList(VariantListEntry **first, VariantListEntry *var) {
    UBool bAdded = TRUE;

    if (*first == NULL) {
        var->next = NULL;
        *first = var;
    } else {
        VariantListEntry *prev, *cur;
        int32_t cmp;

        /* variants order should be preserved */
        prev = NULL;
        cur = *first;
        while (TRUE) {
            if (cur == NULL) {
                prev->next = var;
                var->next = NULL;
                break;
            }

            /* Checking for duplicate variant */
            cmp = uprv_compareInvCharsAsAscii(var->variant, cur->variant);
            if (cmp == 0) {
                /* duplicated variant */
                bAdded = FALSE;
                break;
            }
            prev = cur;
            cur = cur->next;
        }
    }

    return bAdded;
}

static UBool
_addAttributeToList(AttributeListEntry **first, AttributeListEntry *attr) {
    UBool bAdded = TRUE;

    if (*first == NULL) {
        attr->next = NULL;
        *first = attr;
    } else {
        AttributeListEntry *prev, *cur;
        int32_t cmp;

        /* reorder variants in alphabetical order */
        prev = NULL;
        cur = *first;
        while (TRUE) {
            if (cur == NULL) {
                prev->next = attr;
                attr->next = NULL;
                break;
            }
            cmp = uprv_compareInvCharsAsAscii(attr->attribute, cur->attribute);
            if (cmp < 0) {
                if (prev == NULL) {
                    *first = attr;
                } else {
                    prev->next = attr;
                }
                attr->next = cur;
                break;
            }
            if (cmp == 0) {
                /* duplicated variant */
                bAdded = FALSE;
                break;
            }
            prev = cur;
            cur = cur->next;
        }
    }

    return bAdded;
}


static UBool
_addExtensionToList(ExtensionListEntry **first, ExtensionListEntry *ext, UBool localeToBCP) {
    UBool bAdded = TRUE;

    if (*first == NULL) {
        ext->next = NULL;
        *first = ext;
    } else {
        ExtensionListEntry *prev, *cur;
        int32_t cmp;

        /* reorder variants in alphabetical order */
        prev = NULL;
        cur = *first;
        while (TRUE) {
            if (cur == NULL) {
                prev->next = ext;
                ext->next = NULL;
                break;
            }
            if (localeToBCP) {
                /* special handling for locale to bcp conversion */
                int32_t len, curlen;

                len = (int32_t)uprv_strlen(ext->key);
                curlen = (int32_t)uprv_strlen(cur->key);

                if (len == 1 && curlen == 1) {
                    if (*(ext->key) == *(cur->key)) {
                        cmp = 0;
                    } else if (*(ext->key) == PRIVATEUSE) {
                        cmp = 1;
                    } else if (*(cur->key) == PRIVATEUSE) {
                        cmp = -1;
                    } else {
                        cmp = *(ext->key) - *(cur->key);
                    }
                } else if (len == 1) {
                    cmp = *(ext->key) - LDMLEXT; 
                } else if (curlen == 1) {
                    cmp = LDMLEXT - *(cur->key);
                } else {
                    cmp = uprv_compareInvCharsAsAscii(ext->key, cur->key);
                    /* Both are u extension keys - we need special handling for 'attribute' */
                    if (cmp != 0) {
                        if (uprv_strcmp(cur->key, LOCALE_ATTRIBUTE_KEY) == 0) {
                            cmp = 1;
                        } else if (uprv_strcmp(ext->key, LOCALE_ATTRIBUTE_KEY) == 0) {
                            cmp = -1;
                        }
                    }
                }
            } else {
                cmp = uprv_compareInvCharsAsAscii(ext->key, cur->key);
            }
            if (cmp < 0) {
                if (prev == NULL) {
                    *first = ext;
                } else {
                    prev->next = ext;
                }
                ext->next = cur;
                break;
            }
            if (cmp == 0) {
                /* duplicated extension key */
                bAdded = FALSE;
                break;
            }
            prev = cur;
            cur = cur->next;
        }
    }

    return bAdded;
}

static void
_initializeULanguageTag(ULanguageTag* langtag) {
    int32_t i;

    langtag->buf = NULL;

    langtag->language = EMPTY;
    for (i = 0; i < MAXEXTLANG; i++) {
        langtag->extlang[i] = NULL;
    }

    langtag->script = EMPTY;
    langtag->region = EMPTY;

    langtag->variants = NULL;
    langtag->extensions = NULL;

    langtag->legacy = EMPTY;
    langtag->privateuse = EMPTY;
}

static void
_appendLanguageToLanguageTag(const char* localeID, icu::ByteSink& sink, UBool strict, UErrorCode* status) {
    char buf[ULOC_LANG_CAPACITY];
    UErrorCode tmpStatus = U_ZERO_ERROR;
    int32_t len, i;

    if (U_FAILURE(*status)) {
        return;
    }

    len = uloc_getLanguage(localeID, buf, sizeof(buf), &tmpStatus);
    if (U_FAILURE(tmpStatus) || tmpStatus == U_STRING_NOT_TERMINATED_WARNING) {
        if (strict) {
            *status = U_ILLEGAL_ARGUMENT_ERROR;
            return;
        }
        len = 0;
    }

    /* Note: returned language code is in lower case letters */

    if (len == 0) {
        sink.Append(LANG_UND, LANG_UND_LEN);
    } else if (!ultag_isLanguageSubtag(buf, len)) {
            /* invalid language code */
        if (strict) {
            *status = U_ILLEGAL_ARGUMENT_ERROR;
            return;
        }
        sink.Append(LANG_UND, LANG_UND_LEN);
    } else {
        /* resolve deprecated */
        for (i = 0; i < UPRV_LENGTHOF(DEPRECATEDLANGS); i += 2) {
            // 2-letter deprecated subtags are listede before 3-letter
            // ones in DEPRECATEDLANGS[]. Get out of loop on coming
            // across the 1st 3-letter subtag, if the input is a 2-letter code.
            // to avoid continuing to try when there's no match.
            if (uprv_strlen(buf) < uprv_strlen(DEPRECATEDLANGS[i])) break;
            if (uprv_compareInvCharsAsAscii(buf, DEPRECATEDLANGS[i]) == 0) {
                uprv_strcpy(buf, DEPRECATEDLANGS[i + 1]);
                len = (int32_t)uprv_strlen(buf);
                break;
            }
        }
        sink.Append(buf, len);
    }
}

static void
_appendScriptToLanguageTag(const char* localeID, icu::ByteSink& sink, UBool strict, UErrorCode* status) {
    char buf[ULOC_SCRIPT_CAPACITY];
    UErrorCode tmpStatus = U_ZERO_ERROR;
    int32_t len;

    if (U_FAILURE(*status)) {
        return;
    }

    len = uloc_getScript(localeID, buf, sizeof(buf), &tmpStatus);
    if (U_FAILURE(tmpStatus) || tmpStatus == U_STRING_NOT_TERMINATED_WARNING) {
        if (strict) {
            *status = U_ILLEGAL_ARGUMENT_ERROR;
        }
        return;
    }

    if (len > 0) {
        if (!ultag_isScriptSubtag(buf, len)) {
            /* invalid script code */
            if (strict) {
                *status = U_ILLEGAL_ARGUMENT_ERROR;
            }
            return;
        } else {
            sink.Append("-", 1);
            sink.Append(buf, len);
        }
    }
}

static void
_appendRegionToLanguageTag(const char* localeID, icu::ByteSink& sink, UBool strict, UErrorCode* status) {
    char buf[ULOC_COUNTRY_CAPACITY];
    UErrorCode tmpStatus = U_ZERO_ERROR;
    int32_t len;

    if (U_FAILURE(*status)) {
        return;
    }

    len = uloc_getCountry(localeID, buf, sizeof(buf), &tmpStatus);
    if (U_FAILURE(tmpStatus) || tmpStatus == U_STRING_NOT_TERMINATED_WARNING) {
        if (strict) {
            *status = U_ILLEGAL_ARGUMENT_ERROR;
        }
        return;
    }

    if (len > 0) {
        if (!ultag_isRegionSubtag(buf, len)) {
            /* invalid region code */
            if (strict) {
                *status = U_ILLEGAL_ARGUMENT_ERROR;
            }
            return;
        } else {
            sink.Append("-", 1);
            /* resolve deprecated */
            for (int i = 0; i < UPRV_LENGTHOF(DEPRECATEDREGIONS); i += 2) {
                if (uprv_compareInvCharsAsAscii(buf, DEPRECATEDREGIONS[i]) == 0) {
                    uprv_strcpy(buf, DEPRECATEDREGIONS[i + 1]);
                    len = (int32_t)uprv_strlen(buf);
                    break;
                }
            }
            sink.Append(buf, len);
        }
    }
}

static void _sortVariants(VariantListEntry* first) {
    for (VariantListEntry* var1 = first; var1 != NULL; var1 = var1->next) {
        for (VariantListEntry* var2 = var1->next; var2 != NULL; var2 = var2->next) {
            // Swap var1->variant and var2->variant.
            if (uprv_compareInvCharsAsAscii(var1->variant, var2->variant) > 0) {
                const char* temp = var1->variant;
                var1->variant = var2->variant;
                var2->variant = temp;
            }
        }
    }
}

static void
_appendVariantsToLanguageTag(const char* localeID, icu::ByteSink& sink, UBool strict, UBool *hadPosix, UErrorCode* status) {
    char buf[ULOC_FULLNAME_CAPACITY];
    UErrorCode tmpStatus = U_ZERO_ERROR;
    int32_t len, i;

    if (U_FAILURE(*status)) {
        return;
    }

    len = uloc_getVariant(localeID, buf, sizeof(buf), &tmpStatus);
    if (U_FAILURE(tmpStatus) || tmpStatus == U_STRING_NOT_TERMINATED_WARNING) {
        if (strict) {
            *status = U_ILLEGAL_ARGUMENT_ERROR;
        }
        return;
    }

    if (len > 0) {
        char *p, *pVar;
        UBool bNext = TRUE;
        VariantListEntry *var;
        VariantListEntry *varFirst = NULL;

        pVar = NULL;
        p = buf;
        while (bNext) {
            if (*p == SEP || *p == LOCALE_SEP || *p == 0) {
                if (*p == 0) {
                    bNext = FALSE;
                } else {
                    *p = 0; /* terminate */
                }
                if (pVar == NULL) {
                    if (strict) {
                        *status = U_ILLEGAL_ARGUMENT_ERROR;
                        break;
                    }
                    /* ignore empty variant */
                } else {
                    /* ICU uses upper case letters for variants, but
                       the canonical format is lowercase in BCP47 */
                    for (i = 0; *(pVar + i) != 0; i++) {
                        *(pVar + i) = uprv_tolower(*(pVar + i));
                    }

                    /* validate */
                    if (_isVariantSubtag(pVar, -1)) {
                        if (uprv_strcmp(pVar,POSIX_VALUE) || len != (int32_t)uprv_strlen(POSIX_VALUE)) {
                            /* emit the variant to the list */
                            var = (VariantListEntry*)uprv_malloc(sizeof(VariantListEntry));
                            if (var == NULL) {
                                *status = U_MEMORY_ALLOCATION_ERROR;
                                break;
                            }
                            var->variant = pVar;
                            if (!_addVariantToList(&varFirst, var)) {
                                /* duplicated variant */
                                uprv_free(var);
                                if (strict) {
                                    *status = U_ILLEGAL_ARGUMENT_ERROR;
                                    break;
                                }
                            }
                        } else {
                            /* Special handling for POSIX variant, need to remember that we had it and then */
                            /* treat it like an extension later. */
                            *hadPosix = TRUE;
                        }
                    } else if (strict) {
                        *status = U_ILLEGAL_ARGUMENT_ERROR;
                        break;
                    } else if (_isPrivateuseValueSubtag(pVar, -1)) {
                        /* Handle private use subtags separately */
                        break;
                    }
                }
                /* reset variant starting position */
                pVar = NULL;
            } else if (pVar == NULL) {
                pVar = p;
            }
            p++;
        }

        if (U_SUCCESS(*status)) {
            if (varFirst != NULL) {
                int32_t varLen;

                /* per UTS35, we should sort the variants */
                _sortVariants(varFirst);

                /* write out validated/normalized variants to the target */
                var = varFirst;
                while (var != NULL) {
                    sink.Append("-", 1);
                    varLen = (int32_t)uprv_strlen(var->variant);
                    sink.Append(var->variant, varLen);
                    var = var->next;
                }
            }
        }

        /* clean up */
        var = varFirst;
        while (var != NULL) {
            VariantListEntry *tmpVar = var->next;
            uprv_free(var);
            var = tmpVar;
        }

        if (U_FAILURE(*status)) {
            return;
        }
    }
}

static void
_appendKeywordsToLanguageTag(const char* localeID, icu::ByteSink& sink, UBool strict, UBool hadPosix, UErrorCode* status) {
    char attrBuf[ULOC_KEYWORD_AND_VALUES_CAPACITY] = { 0 };
    int32_t attrBufLength = 0;

    icu::MemoryPool<AttributeListEntry> attrPool;
    icu::MemoryPool<ExtensionListEntry> extPool;
    icu::MemoryPool<icu::CharString> strPool;

    icu::LocalUEnumerationPointer keywordEnum(uloc_openKeywords(localeID, status));
    if (U_FAILURE(*status) && !hadPosix) {
        return;
    }
    if (keywordEnum.isValid() || hadPosix) {
        /* reorder extensions */
        int32_t len;
        const char *key;
        ExtensionListEntry *firstExt = NULL;
        ExtensionListEntry *ext;
        AttributeListEntry *firstAttr = NULL;
        AttributeListEntry *attr;
        icu::MemoryPool<icu::CharString> extBufPool;
        const char *bcpKey=nullptr, *bcpValue=nullptr;
        UErrorCode tmpStatus = U_ZERO_ERROR;
        int32_t keylen;
        UBool isBcpUExt;

        while (TRUE) {
            key = uenum_next(keywordEnum.getAlias(), NULL, status);
            if (key == NULL) {
                break;
            }

            icu::CharString buf;
            {
                icu::CharStringByteSink sink(&buf);
                ulocimp_getKeywordValue(localeID, key, sink, &tmpStatus);
            }
            len = buf.length();

            if (U_FAILURE(tmpStatus)) {
                if (tmpStatus == U_MEMORY_ALLOCATION_ERROR) {
                    *status = U_MEMORY_ALLOCATION_ERROR;
                    break;
                }
                if (strict) {
                    *status = U_ILLEGAL_ARGUMENT_ERROR;
                    break;
                }
                /* ignore this keyword */
                tmpStatus = U_ZERO_ERROR;
                continue;
            }

            keylen = (int32_t)uprv_strlen(key);
            isBcpUExt = (keylen > 1);

            /* special keyword used for representing Unicode locale attributes */
            if (uprv_strcmp(key, LOCALE_ATTRIBUTE_KEY) == 0) {
                if (len > 0) {
                    int32_t i = 0;
                    while (TRUE) {
                        attrBufLength = 0;
                        for (; i < len; i++) {
                            if (buf[i] != '-') {
                                attrBuf[attrBufLength++] = buf[i];
                            } else {
                                i++;
                                break;
                            }
                        }
                        if (attrBufLength > 0) {
                            attrBuf[attrBufLength] = 0;

                        } else if (i >= len){
                            break;
                        }

                        /* create AttributeListEntry */
                        attr = attrPool.create();
                        if (attr == NULL) {
                            *status = U_MEMORY_ALLOCATION_ERROR;
                            break;
                        }
                        icu::CharString* attrValue =
                                strPool.create(attrBuf, attrBufLength, *status);
                        if (attrValue == NULL) {
                            *status = U_MEMORY_ALLOCATION_ERROR;
                            break;
                        }
                        if (U_FAILURE(*status)) {
                            break;
                        }
                        attr->attribute = attrValue->data();

                        if (!_addAttributeToList(&firstAttr, attr)) {
                            if (strict) {
                                *status = U_ILLEGAL_ARGUMENT_ERROR;
                                break;
                            }
                        }
                    }
                    /* for a place holder ExtensionListEntry */
                    bcpKey = LOCALE_ATTRIBUTE_KEY;
                    bcpValue = NULL;
                }
            } else if (isBcpUExt) {
                bcpKey = uloc_toUnicodeLocaleKey(key);
                if (bcpKey == NULL) {
                    if (strict) {
                        *status = U_ILLEGAL_ARGUMENT_ERROR;
                        break;
                    }
                    continue;
                }

                /* we've checked buf is null-terminated above */
                bcpValue = uloc_toUnicodeLocaleType(key, buf.data());
                if (bcpValue == NULL) {
                    if (strict) {
                        *status = U_ILLEGAL_ARGUMENT_ERROR;
                        break;
                    }
                    continue;
                }
                if (bcpValue == buf.data()) {
                    /*
                    When uloc_toUnicodeLocaleType(key, buf) returns the
                    input value as is, the value is well-formed, but has
                    no known mapping. This implementation normalizes the
                    value to lower case
                    */
                    icu::CharString* extBuf = extBufPool.create(buf, tmpStatus);

                    if (extBuf == nullptr) {
                        *status = U_MEMORY_ALLOCATION_ERROR;
                        break;
                    }
                    if (U_FAILURE(tmpStatus)) {
                        *status = tmpStatus;
                        break;
                    }

                    T_CString_toLowerCase(extBuf->data());
                    bcpValue = extBuf->data();
                }
            } else {
                if (*key == PRIVATEUSE) {
                    if (!ultag_isPrivateuseValueSubtags(buf.data(), len)) {
                        if (strict) {
                            *status = U_ILLEGAL_ARGUMENT_ERROR;
                            break;
                        }
                        continue;
                    }
                } else {
                    if (!_isExtensionSingleton(key, keylen) || !ultag_isExtensionSubtags(buf.data(), len)) {
                        if (strict) {
                            *status = U_ILLEGAL_ARGUMENT_ERROR;
                            break;
                        }
                        continue;
                    }
                }
                bcpKey = key;
                icu::CharString* extBuf =
                    extBufPool.create(buf.data(), len, tmpStatus);
                if (extBuf == nullptr) {
                    *status = U_MEMORY_ALLOCATION_ERROR;
                    break;
                }
                if (U_FAILURE(tmpStatus)) {
                    *status = tmpStatus;
                    break;
                }
                bcpValue = extBuf->data();
            }

            /* create ExtensionListEntry */
            ext = extPool.create();
            if (ext == NULL) {
                *status = U_MEMORY_ALLOCATION_ERROR;
                break;
            }
            ext->key = bcpKey;
            ext->value = bcpValue;

            if (!_addExtensionToList(&firstExt, ext, TRUE)) {
                if (strict) {
                    *status = U_ILLEGAL_ARGUMENT_ERROR;
                    break;
                }
            }
        }

        /* Special handling for POSIX variant - add the keywords for POSIX */
        if (hadPosix) {
            /* create ExtensionListEntry for POSIX */
            ext = extPool.create();
            if (ext == NULL) {
                *status = U_MEMORY_ALLOCATION_ERROR;
                return;
            }
            ext->key = POSIX_KEY;
            ext->value = POSIX_VALUE;

            if (!_addExtensionToList(&firstExt, ext, TRUE)) {
                // Silently ignore errors.
            }
        }

        if (U_SUCCESS(*status) && (firstExt != NULL || firstAttr != NULL)) {
            UBool startLDMLExtension = FALSE;
            for (ext = firstExt; ext; ext = ext->next) {
                if (!startLDMLExtension && uprv_strlen(ext->key) > 1) {
                    /* first LDML u singlton extension */
                   sink.Append("-u", 2);
                   startLDMLExtension = TRUE;
                }

                /* write out the sorted BCP47 attributes, extensions and private use */
                if (uprv_strcmp(ext->key, LOCALE_ATTRIBUTE_KEY) == 0) {
                    /* write the value for the attributes */
                    for (attr = firstAttr; attr; attr = attr->next) {
                        sink.Append("-", 1);
                        sink.Append(
                                attr->attribute, static_cast<int32_t>(uprv_strlen(attr->attribute)));
                    }
                } else {
                    sink.Append("-", 1);
                    sink.Append(ext->key, static_cast<int32_t>(uprv_strlen(ext->key)));
                    if (uprv_strcmp(ext->value, "true") != 0 &&
                        uprv_strcmp(ext->value, "yes") != 0) {
                      sink.Append("-", 1);
                      sink.Append(ext->value, static_cast<int32_t>(uprv_strlen(ext->value)));
                    }
                }
            }
        }
    }
}

/**
 * Append keywords parsed from LDML extension value
 * e.g. "u-ca-gregory-co-trad" -> {calendar = gregorian} {collation = traditional}
 * Note: char* buf is used for storing keywords
 */
static void
_appendLDMLExtensionAsKeywords(const char* ldmlext, ExtensionListEntry** appendTo, icu::MemoryPool<ExtensionListEntry>& extPool, icu::MemoryPool<icu::CharString>& kwdBuf, UBool *posixVariant, UErrorCode *status) {
    const char *pTag;   /* beginning of current subtag */
    const char *pKwds;  /* beginning of key-type pairs */
    UBool variantExists = *posixVariant;

    ExtensionListEntry *kwdFirst = NULL;    /* first LDML keyword */
    ExtensionListEntry *kwd, *nextKwd;

    int32_t len;

    /* Reset the posixVariant value */
    *posixVariant = FALSE;

    pTag = ldmlext;
    pKwds = NULL;

    {
        AttributeListEntry *attrFirst = NULL;   /* first attribute */
        AttributeListEntry *attr, *nextAttr;

        char attrBuf[ULOC_KEYWORD_AND_VALUES_CAPACITY];
        int32_t attrBufIdx = 0;

        icu::MemoryPool<AttributeListEntry> attrPool;

        /* Iterate through u extension attributes */
        while (*pTag) {
            /* locate next separator char */
            for (len = 0; *(pTag + len) && *(pTag + len) != SEP; len++);

            if (ultag_isUnicodeLocaleKey(pTag, len)) {
                pKwds = pTag;
                break;
            }

            /* add this attribute to the list */
            attr = attrPool.create();
            if (attr == NULL) {
                *status = U_MEMORY_ALLOCATION_ERROR;
                return;
            }

            if (len < (int32_t)sizeof(attrBuf) - attrBufIdx) {
                uprv_memcpy(&attrBuf[attrBufIdx], pTag, len);
                attrBuf[attrBufIdx + len] = 0;
                attr->attribute = &attrBuf[attrBufIdx];
                attrBufIdx += (len + 1);
            } else {
                *status = U_ILLEGAL_ARGUMENT_ERROR;
                return;
            }

            // duplicate attribute is ignored, causes no error.
            _addAttributeToList(&attrFirst, attr);

            /* next tag */
            pTag += len;
            if (*pTag) {
                /* next to the separator */
                pTag++;
            }
        }

        if (attrFirst) {
            /* emit attributes as an LDML keyword, e.g. attribute=attr1-attr2 */

            kwd = extPool.create();
            if (kwd == NULL) {
                *status = U_MEMORY_ALLOCATION_ERROR;
                return;
            }

            icu::CharString* value = kwdBuf.create();
            if (value == NULL) {
                *status = U_MEMORY_ALLOCATION_ERROR;
                return;
            }

            /* attribute subtags sorted in alphabetical order as type */
            attr = attrFirst;
            while (attr != NULL) {
                nextAttr = attr->next;
                if (attr != attrFirst) {
                    value->append('-', *status);
                }
                value->append(attr->attribute, *status);
                attr = nextAttr;
            }
            if (U_FAILURE(*status)) {
                return;
            }

            kwd->key = LOCALE_ATTRIBUTE_KEY;
            kwd->value = value->data();

            if (!_addExtensionToList(&kwdFirst, kwd, FALSE)) {
                *status = U_ILLEGAL_ARGUMENT_ERROR;
                return;
            }
        }
    }

    if (pKwds) {
        const char *pBcpKey = NULL;     /* u extenstion key subtag */
        const char *pBcpType = NULL;    /* beginning of u extension type subtag(s) */
        int32_t bcpKeyLen = 0;
        int32_t bcpTypeLen = 0;
        UBool isDone = FALSE;

        pTag = pKwds;
        /* BCP47 representation of LDML key/type pairs */
        while (!isDone) {
            const char *pNextBcpKey = NULL;
            int32_t nextBcpKeyLen = 0;
            UBool emitKeyword = FALSE;

            if (*pTag) {
                /* locate next separator char */
                for (len = 0; *(pTag + len) && *(pTag + len) != SEP; len++);

                if (ultag_isUnicodeLocaleKey(pTag, len)) {
                    if (pBcpKey) {
                        emitKeyword = TRUE;
                        pNextBcpKey = pTag;
                        nextBcpKeyLen = len;
                    } else {
                        pBcpKey = pTag;
                        bcpKeyLen = len;
                    }
                } else {
                    U_ASSERT(pBcpKey != NULL);
                    /* within LDML type subtags */
                    if (pBcpType) {
                        bcpTypeLen += (len + 1);
                    } else {
                        pBcpType = pTag;
                        bcpTypeLen = len;
                    }
                }

                /* next tag */
                pTag += len;
                if (*pTag) {
                    /* next to the separator */
                    pTag++;
                }
            } else {
                /* processing last one */
                emitKeyword = TRUE;
                isDone = TRUE;
            }

            if (emitKeyword) {
                const char *pKey = NULL;    /* LDML key */
                const char *pType = NULL;   /* LDML type */

                char bcpKeyBuf[3];          /* BCP key length is always 2 for now */

                U_ASSERT(pBcpKey != NULL);

                if (bcpKeyLen >= (int32_t)sizeof(bcpKeyBuf)) {
                    /* the BCP key is invalid */
                    *status = U_ILLEGAL_ARGUMENT_ERROR;
                    return;
                }
                U_ASSERT(bcpKeyLen <= 2);

                uprv_strncpy(bcpKeyBuf, pBcpKey, bcpKeyLen);
                bcpKeyBuf[bcpKeyLen] = 0;

                /* u extension key to LDML key */
                pKey = uloc_toLegacyKey(bcpKeyBuf);
                if (pKey == NULL) {
                    *status = U_ILLEGAL_ARGUMENT_ERROR;
                    return;
                }
                if (pKey == bcpKeyBuf) {
                    /*
                    The key returned by toLegacyKey points to the input buffer.
                    We normalize the result key to lower case.
                    */
                    T_CString_toLowerCase(bcpKeyBuf);
                    icu::CharString* key = kwdBuf.create(bcpKeyBuf, bcpKeyLen, *status);
                    if (key == NULL) {
                        *status = U_MEMORY_ALLOCATION_ERROR;
                        return;
                    }
                    if (U_FAILURE(*status)) {
                        return;
                    }
                    pKey = key->data();
                }

                if (pBcpType) {
                    char bcpTypeBuf[128];       /* practically long enough even considering multiple subtag type */
                    if (bcpTypeLen >= (int32_t)sizeof(bcpTypeBuf)) {
                        /* the BCP type is too long */
                        *status = U_ILLEGAL_ARGUMENT_ERROR;
                        return;
                    }

                    uprv_strncpy(bcpTypeBuf, pBcpType, bcpTypeLen);
                    bcpTypeBuf[bcpTypeLen] = 0;

                    /* BCP type to locale type */
                    pType = uloc_toLegacyType(pKey, bcpTypeBuf);
                    if (pType == NULL) {
                        *status = U_ILLEGAL_ARGUMENT_ERROR;
                        return;
                    }
                    if (pType == bcpTypeBuf) {
                        /*
                        The type returned by toLegacyType points to the input buffer.
                        We normalize the result type to lower case.
                        */
                        /* normalize to lower case */
                        T_CString_toLowerCase(bcpTypeBuf);
                        icu::CharString* type = kwdBuf.create(bcpTypeBuf, bcpTypeLen, *status);
                        if (type == NULL) {
                            *status = U_MEMORY_ALLOCATION_ERROR;
                            return;
                        }
                        if (U_FAILURE(*status)) {
                            return;
                        }
                        pType = type->data();
                    }
                } else {
                    /* typeless - default type value is "yes" */
                    pType = LOCALE_TYPE_YES;
                }

                /* Special handling for u-va-posix, since we want to treat this as a variant, 
                   not as a keyword */
                if (!variantExists && !uprv_strcmp(pKey, POSIX_KEY) && !uprv_strcmp(pType, POSIX_VALUE) ) {
                    *posixVariant = TRUE;
                } else {
                    /* create an ExtensionListEntry for this keyword */
                    kwd = extPool.create();
                    if (kwd == NULL) {
                        *status = U_MEMORY_ALLOCATION_ERROR;
                        return;
                    }

                    kwd->key = pKey;
                    kwd->value = pType;

                    if (!_addExtensionToList(&kwdFirst, kwd, FALSE)) {
                        // duplicate keyword is allowed, Only the first
                        // is honored.
                    }
                }

                pBcpKey = pNextBcpKey;
                bcpKeyLen = pNextBcpKey != NULL ? nextBcpKeyLen : 0;
                pBcpType = NULL;
                bcpTypeLen = 0;
            }
        }
    }

    kwd = kwdFirst;
    while (kwd != NULL) {
        nextKwd = kwd->next;
        _addExtensionToList(appendTo, kwd, FALSE);
        kwd = nextKwd;
    }
}


static void
_appendKeywords(ULanguageTag* langtag, icu::ByteSink& sink, UErrorCode* status) {
    int32_t i, n;
    int32_t len;
    ExtensionListEntry *kwdFirst = NULL;
    ExtensionListEntry *kwd;
    const char *key, *type;
    icu::MemoryPool<ExtensionListEntry> extPool;
    icu::MemoryPool<icu::CharString> kwdBuf;
    UBool posixVariant = FALSE;

    if (U_FAILURE(*status)) {
        return;
    }

    /* Determine if variants already exists */
    if (ultag_getVariantsSize(langtag)) {
        posixVariant = TRUE;
    }

    n = ultag_getExtensionsSize(langtag);

    /* resolve locale keywords and reordering keys */
    for (i = 0; i < n; i++) {
        key = ultag_getExtensionKey(langtag, i);
        type = ultag_getExtensionValue(langtag, i);
        if (*key == LDMLEXT) {
            _appendLDMLExtensionAsKeywords(type, &kwdFirst, extPool, kwdBuf, &posixVariant, status);
            if (U_FAILURE(*status)) {
                break;
            }
        } else {
            kwd = extPool.create();
            if (kwd == NULL) {
                *status = U_MEMORY_ALLOCATION_ERROR;
                break;
            }
            kwd->key = key;
            kwd->value = type;
            if (!_addExtensionToList(&kwdFirst, kwd, FALSE)) {
                *status = U_ILLEGAL_ARGUMENT_ERROR;
                break;
            }
        }
    }

    if (U_SUCCESS(*status)) {
        type = ultag_getPrivateUse(langtag);
        if ((int32_t)uprv_strlen(type) > 0) {
            /* add private use as a keyword */
            kwd = extPool.create();
            if (kwd == NULL) {
                *status = U_MEMORY_ALLOCATION_ERROR;
            } else {
                kwd->key = PRIVATEUSE_KEY;
                kwd->value = type;
                if (!_addExtensionToList(&kwdFirst, kwd, FALSE)) {
                    *status = U_ILLEGAL_ARGUMENT_ERROR;
                }
            }
        }
    }

    /* If a POSIX variant was in the extensions, write it out before writing the keywords. */

    if (U_SUCCESS(*status) && posixVariant) {
        len = (int32_t) uprv_strlen(_POSIX);
        sink.Append(_POSIX, len);
    }

    if (U_SUCCESS(*status) && kwdFirst != NULL) {
        /* write out the sorted keywords */
        UBool firstValue = TRUE;
        kwd = kwdFirst;
        do {
            if (firstValue) {
                sink.Append("@", 1);
                firstValue = FALSE;
            } else {
                sink.Append(";", 1);
            }

            /* key */
            len = (int32_t)uprv_strlen(kwd->key);
            sink.Append(kwd->key, len);
            sink.Append("=", 1);

            /* type */
            len = (int32_t)uprv_strlen(kwd->value);
            sink.Append(kwd->value, len);

            kwd = kwd->next;
        } while (kwd);
    }
}

static void
_appendPrivateuseToLanguageTag(const char* localeID, icu::ByteSink& sink, UBool strict, UBool hadPosix, UErrorCode* status) {
    (void)hadPosix;
    char buf[ULOC_FULLNAME_CAPACITY];
    char tmpAppend[ULOC_FULLNAME_CAPACITY];
    UErrorCode tmpStatus = U_ZERO_ERROR;
    int32_t len, i;
    int32_t reslen = 0;
    int32_t capacity = sizeof tmpAppend;

    if (U_FAILURE(*status)) {
        return;
    }

    len = uloc_getVariant(localeID, buf, sizeof(buf), &tmpStatus);
    if (U_FAILURE(tmpStatus) || tmpStatus == U_STRING_NOT_TERMINATED_WARNING) {
        if (strict) {
            *status = U_ILLEGAL_ARGUMENT_ERROR;
        }
        return;
    }

    if (len > 0) {
        char *p, *pPriv;
        UBool bNext = TRUE;
        UBool firstValue = TRUE;
        UBool writeValue;

        pPriv = NULL;
        p = buf;
        while (bNext) {
            writeValue = FALSE;
            if (*p == SEP || *p == LOCALE_SEP || *p == 0) {
                if (*p == 0) {
                    bNext = FALSE;
                } else {
                    *p = 0; /* terminate */
                }
                if (pPriv != NULL) {
                    /* Private use in the canonical format is lowercase in BCP47 */
                    for (i = 0; *(pPriv + i) != 0; i++) {
                        *(pPriv + i) = uprv_tolower(*(pPriv + i));
                    }

                    /* validate */
                    if (_isPrivateuseValueSubtag(pPriv, -1)) {
                        if (firstValue) {
                            if (!_isVariantSubtag(pPriv, -1)) {
                                writeValue = TRUE;
                            }
                        } else {
                            writeValue = TRUE;
                        }
                    } else if (strict) {
                        *status = U_ILLEGAL_ARGUMENT_ERROR;
                        break;
                    } else {
                        break;
                    }

                    if (writeValue) {
                        if (reslen < capacity) {
                            tmpAppend[reslen++] = SEP;
                        }

                        if (firstValue) {
                            if (reslen < capacity) {
                                tmpAppend[reslen++] = *PRIVATEUSE_KEY;
                            }

                            if (reslen < capacity) {
                                tmpAppend[reslen++] = SEP;
                            }

                            len = (int32_t)uprv_strlen(PRIVUSE_VARIANT_PREFIX);
                            if (reslen < capacity) {
                                uprv_memcpy(tmpAppend + reslen, PRIVUSE_VARIANT_PREFIX, uprv_min(len, capacity - reslen));
                            }
                            reslen += len;

                            if (reslen < capacity) {
                                tmpAppend[reslen++] = SEP;
                            }

                            firstValue = FALSE;
                        }

                        len = (int32_t)uprv_strlen(pPriv);
                        if (reslen < capacity) {
                            uprv_memcpy(tmpAppend + reslen, pPriv, uprv_min(len, capacity - reslen));
                        }
                        reslen += len;
                    }
                }
                /* reset private use starting position */
                pPriv = NULL;
            } else if (pPriv == NULL) {
                pPriv = p;
            }
            p++;
        }

        if (U_FAILURE(*status)) {
            return;
        }
    }

    if (U_SUCCESS(*status)) {
        len = reslen;
        sink.Append(tmpAppend, len);
    }
}

/*
* -------------------------------------------------
*
* ultag_ functions
*
* -------------------------------------------------
*/

/* Bit flags used by the parser */
#define LANG 0x0001
#define EXTL 0x0002
#define SCRT 0x0004
#define REGN 0x0008
#define VART 0x0010
#define EXTS 0x0020
#define EXTV 0x0040
#define PRIV 0x0080

/**
 * Ticket #12705 - The optimizer in Visual Studio 2015 Update 3 has problems optimizing this function.
 * As a work-around, optimization is disabled for this function on VS2015 and VS2017.
 * This work-around should be removed once the following versions of Visual Studio are no
 * longer supported: All versions of VS2015/VS2017, and versions of VS2019 below 16.4.
 */
#if defined(_MSC_VER) && (_MSC_VER >= 1900) && (_MSC_VER < 1924)
#pragma optimize( "", off )
#endif

static ULanguageTag*
ultag_parse(const char* tag, int32_t tagLen, int32_t* parsedLen, UErrorCode* status) {
    char *tagBuf;
    int16_t next;
    char *pSubtag, *pNext, *pLastGoodPosition;
    int32_t subtagLen;
    int32_t extlangIdx;
    ExtensionListEntry *pExtension;
    char *pExtValueSubtag, *pExtValueSubtagEnd;
    int32_t i;
    UBool privateuseVar = FALSE;
    int32_t legacyLen = 0;

    if (parsedLen != NULL) {
        *parsedLen = 0;
    }

    if (U_FAILURE(*status)) {
        return NULL;
    }

    if (tagLen < 0) {
        tagLen = (int32_t)uprv_strlen(tag);
    }

    /* copy the entire string */
    tagBuf = (char*)uprv_malloc(tagLen + 1);
    if (tagBuf == NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }
    uprv_memcpy(tagBuf, tag, tagLen);
    *(tagBuf + tagLen) = 0;

    /* create a ULanguageTag */
    icu::LocalULanguageTagPointer t(
            (ULanguageTag*)uprv_malloc(sizeof(ULanguageTag)));
    if (t.isNull()) {
        uprv_free(tagBuf);
        *status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }
    _initializeULanguageTag(t.getAlias());
    t->buf = tagBuf;

    if (tagLen < MINLEN) {
        /* the input tag is too short - return empty ULanguageTag */
        return t.orphan();
    }

    size_t parsedLenDelta = 0;
    // Legacy tag will be consider together. Legacy tag with intervening
    // script and region such as art-DE-lojban or art-Latn-lojban won't be
    // matched.
    /* check if the tag is legacy */
    for (i = 0; i < UPRV_LENGTHOF(LEGACY); i += 2) {
        int32_t checkLegacyLen = static_cast<int32_t>(uprv_strlen(LEGACY[i]));
        if (tagLen < checkLegacyLen) {
            continue;
        }
        if (tagLen > checkLegacyLen && tagBuf[checkLegacyLen] != '-') {
            // make sure next char is '-'.
            continue;
        }
        if (uprv_strnicmp(LEGACY[i], tagBuf, checkLegacyLen) == 0) {
            int32_t newTagLength;

            legacyLen = checkLegacyLen;  /* back up for output parsedLen */
            int32_t replacementLen = static_cast<int32_t>(uprv_strlen(LEGACY[i+1]));
            newTagLength = replacementLen + tagLen - checkLegacyLen;
            if (tagLen < newTagLength) {
                uprv_free(tagBuf);
                tagBuf = (char*)uprv_malloc(newTagLength + 1);
                if (tagBuf == NULL) {
                    *status = U_MEMORY_ALLOCATION_ERROR;
                    return NULL;
                }
                t->buf = tagBuf;
                tagLen = newTagLength;
            }
            parsedLenDelta = checkLegacyLen - replacementLen;
            uprv_strcpy(t->buf, LEGACY[i + 1]);
            if (checkLegacyLen != tagLen) {
                uprv_strcpy(t->buf + replacementLen, tag + checkLegacyLen);
            }
            break;
        }
    }

    if (legacyLen == 0) {
        for (i = 0; i < UPRV_LENGTHOF(REDUNDANT); i += 2) {
            const char* redundantTag = REDUNDANT[i];
            size_t redundantTagLen = uprv_strlen(redundantTag);
            // The preferred tag for a redundant tag is always shorter than redundant
            // tag. A redundant tag may or may not be followed by other subtags.
            // (i.e. "zh-yue" or "zh-yue-u-co-pinyin").
            if (uprv_strnicmp(redundantTag, tagBuf, static_cast<uint32_t>(redundantTagLen)) == 0) {
                const char* redundantTagEnd = tagBuf + redundantTagLen;
                if (*redundantTagEnd  == '\0' || *redundantTagEnd == SEP) {
                    const char* preferredTag = REDUNDANT[i + 1];
                    size_t preferredTagLen = uprv_strlen(preferredTag);
                    uprv_strncpy(t->buf, preferredTag, preferredTagLen);
                    if (*redundantTagEnd == SEP) {
                        uprv_memmove(tagBuf + preferredTagLen,
                                     redundantTagEnd,
                                     tagLen - redundantTagLen + 1);
                    } else {
                        tagBuf[preferredTagLen] = '\0';
                    }
                    // parsedLen should be the length of the input
                    // before redundantTag is replaced by preferredTag.
                    // Save the delta to add it back later.
                    parsedLenDelta = redundantTagLen - preferredTagLen;
                    break;
                }
            }
        }
    }

    /*
     * langtag      =   language
     *                  ["-" script]
     *                  ["-" region]
     *                  *("-" variant)
     *                  *("-" extension)
     *                  ["-" privateuse]
     */

    next = LANG | PRIV;
    pNext = pLastGoodPosition = tagBuf;
    extlangIdx = 0;
    pExtension = NULL;
    pExtValueSubtag = NULL;
    pExtValueSubtagEnd = NULL;

    while (pNext) {
        char *pSep;

        pSubtag = pNext;

        /* locate next separator char */
        pSep = pSubtag;
        while (*pSep) {
            if (*pSep == SEP) {
                break;
            }
            pSep++;
        }
        if (*pSep == 0) {
            /* last subtag */
            pNext = NULL;
        } else {
            pNext = pSep + 1;
        }
        subtagLen = (int32_t)(pSep - pSubtag);

        if (next & LANG) {
            if (ultag_isLanguageSubtag(pSubtag, subtagLen)) {
                *pSep = 0;  /* terminate */
                // TODO: move deprecated language code handling here.
                t->language = T_CString_toLowerCase(pSubtag);

                pLastGoodPosition = pSep;
                next = SCRT | REGN | VART | EXTS | PRIV;
                if (subtagLen <= 3)
                  next |= EXTL;
                continue;
            }
        }
        if (next & EXTL) {
            if (_isExtlangSubtag(pSubtag, subtagLen)) {
                *pSep = 0;
                t->extlang[extlangIdx++] = T_CString_toLowerCase(pSubtag);

                pLastGoodPosition = pSep;
                if (extlangIdx < 3) {
                    next = EXTL | SCRT | REGN | VART | EXTS | PRIV;
                } else {
                    next = SCRT | REGN | VART | EXTS | PRIV;
                }
                continue;
            }
        }
        if (next & SCRT) {
            if (ultag_isScriptSubtag(pSubtag, subtagLen)) {
                char *p = pSubtag;

                *pSep = 0;

                /* to title case */
                *p = uprv_toupper(*p);
                p++;
                for (; *p; p++) {
                    *p = uprv_tolower(*p);
                }

                t->script = pSubtag;

                pLastGoodPosition = pSep;
                next = REGN | VART | EXTS | PRIV;
                continue;
            }
        }
        if (next & REGN) {
            if (ultag_isRegionSubtag(pSubtag, subtagLen)) {
                *pSep = 0;
                // TODO: move deprecated region code handling here.
                t->region = T_CString_toUpperCase(pSubtag);

                pLastGoodPosition = pSep;
                next = VART | EXTS | PRIV;
                continue;
            }
        }
        if (next & VART) {
            if (_isVariantSubtag(pSubtag, subtagLen) ||
               (privateuseVar && _isPrivateuseVariantSubtag(pSubtag, subtagLen))) {
                VariantListEntry *var;
                UBool isAdded;

                var = (VariantListEntry*)uprv_malloc(sizeof(VariantListEntry));
                if (var == NULL) {
                    *status = U_MEMORY_ALLOCATION_ERROR;
                    return NULL;
                }
                *pSep = 0;
                var->variant = T_CString_toUpperCase(pSubtag);
                isAdded = _addVariantToList(&(t->variants), var);
                if (!isAdded) {
                    /* duplicated variant entry */
                    uprv_free(var);
                    break;
                }
                pLastGoodPosition = pSep;
                next = VART | EXTS | PRIV;
                continue;
            }
        }
        if (next & EXTS) {
            if (_isExtensionSingleton(pSubtag, subtagLen)) {
                if (pExtension != NULL) {
                    if (pExtValueSubtag == NULL || pExtValueSubtagEnd == NULL) {
                        /* the previous extension is incomplete */
                        uprv_free(pExtension);
                        pExtension = NULL;
                        break;
                    }

                    /* terminate the previous extension value */
                    *pExtValueSubtagEnd = 0;
                    pExtension->value = T_CString_toLowerCase(pExtValueSubtag);

                    /* insert the extension to the list */
                    if (_addExtensionToList(&(t->extensions), pExtension, FALSE)) {
                        pLastGoodPosition = pExtValueSubtagEnd;
                    } else {
                        /* stop parsing here */
                        uprv_free(pExtension);
                        pExtension = NULL;
                        break;
                    }
                }

                /* create a new extension */
                pExtension = (ExtensionListEntry*)uprv_malloc(sizeof(ExtensionListEntry));
                if (pExtension == NULL) {
                    *status = U_MEMORY_ALLOCATION_ERROR;
                    return NULL;
                }
                *pSep = 0;
                pExtension->key = T_CString_toLowerCase(pSubtag);
                pExtension->value = NULL;   /* will be set later */

                /*
                 * reset the start and the end location of extension value
                 * subtags for this extension
                 */
                pExtValueSubtag = NULL;
                pExtValueSubtagEnd = NULL;

                next = EXTV;
                continue;
            }
        }
        if (next & EXTV) {
            if (_isExtensionSubtag(pSubtag, subtagLen)) {
                if (pExtValueSubtag == NULL) {
                    /* if the start postion of this extension's value is not yet,
                        this one is the first value subtag */
                    pExtValueSubtag = pSubtag;
                }

                /* Mark the end of this subtag */
                pExtValueSubtagEnd = pSep;
                next = EXTS | EXTV | PRIV;

                continue;
            }
        }
        if (next & PRIV) {
            if (uprv_tolower(*pSubtag) == PRIVATEUSE && subtagLen == 1) {
                char *pPrivuseVal;

                if (pExtension != NULL) {
                    /* Process the last extension */
                    if (pExtValueSubtag == NULL || pExtValueSubtagEnd == NULL) {
                        /* the previous extension is incomplete */
                        uprv_free(pExtension);
                        pExtension = NULL;
                        break;
                    } else {
                        /* terminate the previous extension value */
                        *pExtValueSubtagEnd = 0;
                        pExtension->value = T_CString_toLowerCase(pExtValueSubtag);

                        /* insert the extension to the list */
                        if (_addExtensionToList(&(t->extensions), pExtension, FALSE)) {
                            pLastGoodPosition = pExtValueSubtagEnd;
                            pExtension = NULL;
                        } else {
                        /* stop parsing here */
                            uprv_free(pExtension);
                            pExtension = NULL;
                            break;
                        }
                    }
                }

                /* The rest of part will be private use value subtags */
                if (pNext == NULL) {
                    /* empty private use subtag */
                    break;
                }
                /* back up the private use value start position */
                pPrivuseVal = pNext;

                /* validate private use value subtags */
                while (pNext) {
                    pSubtag = pNext;
                    pSep = pSubtag;
                    while (*pSep) {
                        if (*pSep == SEP) {
                            break;
                        }
                        pSep++;
                    }
                    if (*pSep == 0) {
                        /* last subtag */
                        pNext = NULL;
                    } else {
                        pNext = pSep + 1;
                    }
                    subtagLen = (int32_t)(pSep - pSubtag);

                    if (uprv_strncmp(pSubtag, PRIVUSE_VARIANT_PREFIX, uprv_strlen(PRIVUSE_VARIANT_PREFIX)) == 0) {
                        *pSep = 0;
                        next = VART;
                        privateuseVar = TRUE;
                        break;
                    } else if (_isPrivateuseValueSubtag(pSubtag, subtagLen)) {
                        pLastGoodPosition = pSep;
                    } else {
                        break;
                    }
                }

                if (next == VART) {
                    continue;
                }

                if (pLastGoodPosition - pPrivuseVal > 0) {
                    *pLastGoodPosition = 0;
                    t->privateuse = T_CString_toLowerCase(pPrivuseVal);
                }
                /* No more subtags, exiting the parse loop */
                break;
            }
            break;
        }

        /* If we fell through here, it means this subtag is illegal - quit parsing */
        break;
    }

    if (pExtension != NULL) {
        /* Process the last extension */
        if (pExtValueSubtag == NULL || pExtValueSubtagEnd == NULL) {
            /* the previous extension is incomplete */
            uprv_free(pExtension);
        } else {
            /* terminate the previous extension value */
            *pExtValueSubtagEnd = 0;
            pExtension->value = T_CString_toLowerCase(pExtValueSubtag);
            /* insert the extension to the list */
            if (_addExtensionToList(&(t->extensions), pExtension, FALSE)) {
                pLastGoodPosition = pExtValueSubtagEnd;
            } else {
                uprv_free(pExtension);
            }
        }
    }

    if (parsedLen != NULL) {
        *parsedLen = (int32_t)(pLastGoodPosition - t->buf + parsedLenDelta);
    }

    return t.orphan();
}

// Ticket #12705 - Turn optimization back on.
#if defined(_MSC_VER) && (_MSC_VER >= 1900) && (_MSC_VER < 1924)
#pragma optimize( "", on )
#endif

static void
ultag_close(ULanguageTag* langtag) {

    if (langtag == NULL) {
        return;
    }

    uprv_free(langtag->buf);

    if (langtag->variants) {
        VariantListEntry *curVar = langtag->variants;
        while (curVar) {
            VariantListEntry *nextVar = curVar->next;
            uprv_free(curVar);
            curVar = nextVar;
        }
    }

    if (langtag->extensions) {
        ExtensionListEntry *curExt = langtag->extensions;
        while (curExt) {
            ExtensionListEntry *nextExt = curExt->next;
            uprv_free(curExt);
            curExt = nextExt;
        }
    }

    uprv_free(langtag);
}

static const char*
ultag_getLanguage(const ULanguageTag* langtag) {
    return langtag->language;
}

#if 0
static const char*
ultag_getJDKLanguage(const ULanguageTag* langtag) {
    int32_t i;
    for (i = 0; DEPRECATEDLANGS[i] != NULL; i += 2) {
        if (uprv_compareInvCharsAsAscii(DEPRECATEDLANGS[i], langtag->language) == 0) {
            return DEPRECATEDLANGS[i + 1];
        }
    }
    return langtag->language;
}
#endif

static const char*
ultag_getExtlang(const ULanguageTag* langtag, int32_t idx) {
    if (idx >= 0 && idx < MAXEXTLANG) {
        return langtag->extlang[idx];
    }
    return NULL;
}

static int32_t
ultag_getExtlangSize(const ULanguageTag* langtag) {
    int32_t size = 0;
    int32_t i;
    for (i = 0; i < MAXEXTLANG; i++) {
        if (langtag->extlang[i]) {
            size++;
        }
    }
    return size;
}

static const char*
ultag_getScript(const ULanguageTag* langtag) {
    return langtag->script;
}

static const char*
ultag_getRegion(const ULanguageTag* langtag) {
    return langtag->region;
}

static const char*
ultag_getVariant(const ULanguageTag* langtag, int32_t idx) {
    const char *var = NULL;
    VariantListEntry *cur = langtag->variants;
    int32_t i = 0;
    while (cur) {
        if (i == idx) {
            var = cur->variant;
            break;
        }
        cur = cur->next;
        i++;
    }
    return var;
}

static int32_t
ultag_getVariantsSize(const ULanguageTag* langtag) {
    int32_t size = 0;
    VariantListEntry *cur = langtag->variants;
    while (TRUE) {
        if (cur == NULL) {
            break;
        }
        size++;
        cur = cur->next;
    }
    return size;
}

static const char*
ultag_getExtensionKey(const ULanguageTag* langtag, int32_t idx) {
    const char *key = NULL;
    ExtensionListEntry *cur = langtag->extensions;
    int32_t i = 0;
    while (cur) {
        if (i == idx) {
            key = cur->key;
            break;
        }
        cur = cur->next;
        i++;
    }
    return key;
}

static const char*
ultag_getExtensionValue(const ULanguageTag* langtag, int32_t idx) {
    const char *val = NULL;
    ExtensionListEntry *cur = langtag->extensions;
    int32_t i = 0;
    while (cur) {
        if (i == idx) {
            val = cur->value;
            break;
        }
        cur = cur->next;
        i++;
    }
    return val;
}

static int32_t
ultag_getExtensionsSize(const ULanguageTag* langtag) {
    int32_t size = 0;
    ExtensionListEntry *cur = langtag->extensions;
    while (TRUE) {
        if (cur == NULL) {
            break;
        }
        size++;
        cur = cur->next;
    }
    return size;
}

static const char*
ultag_getPrivateUse(const ULanguageTag* langtag) {
    return langtag->privateuse;
}

#if 0
static const char*
ultag_getLegacy(const ULanguageTag* langtag) {
    return langtag->legacy;
}
#endif


/*
* -------------------------------------------------
*
* Locale/BCP47 conversion APIs, exposed as uloc_*
*
* -------------------------------------------------
*/
U_CAPI int32_t U_EXPORT2
uloc_toLanguageTag(const char* localeID,
                   char* langtag,
                   int32_t langtagCapacity,
                   UBool strict,
                   UErrorCode* status) {
    if (U_FAILURE(*status)) {
        return 0;
    }

    icu::CheckedArrayByteSink sink(langtag, langtagCapacity);
    ulocimp_toLanguageTag(localeID, sink, strict, status);

    int32_t reslen = sink.NumberOfBytesAppended();

    if (U_FAILURE(*status)) {
        return reslen;
    }

    if (sink.Overflowed()) {
        *status = U_BUFFER_OVERFLOW_ERROR;
    } else {
        u_terminateChars(langtag, langtagCapacity, reslen, status);
    }

    return reslen;
}


U_CAPI void U_EXPORT2
ulocimp_toLanguageTag(const char* localeID,
                      icu::ByteSink& sink,
                      UBool strict,
                      UErrorCode* status) {
    icu::CharString canonical;
    int32_t reslen;
    UErrorCode tmpStatus = U_ZERO_ERROR;
    UBool hadPosix = FALSE;
    const char* pKeywordStart;

    /* Note: uloc_canonicalize returns "en_US_POSIX" for input locale ID "".  See #6835 */
    int32_t resultCapacity = static_cast<int32_t>(uprv_strlen(localeID));
    if (resultCapacity > 0) {
        char* buffer;

        for (;;) {
            buffer = canonical.getAppendBuffer(
                    /*minCapacity=*/resultCapacity,
                    /*desiredCapacityHint=*/resultCapacity,
                    resultCapacity,
                    tmpStatus);

            if (U_FAILURE(tmpStatus)) {
                *status = tmpStatus;
                return;
            }

            reslen =
                uloc_canonicalize(localeID, buffer, resultCapacity, &tmpStatus);

            if (tmpStatus != U_BUFFER_OVERFLOW_ERROR) {
                break;
            }

            resultCapacity = reslen;
            tmpStatus = U_ZERO_ERROR;
        }

        if (U_FAILURE(tmpStatus)) {
            *status = U_ILLEGAL_ARGUMENT_ERROR;
            return;
        }

        canonical.append(buffer, reslen, tmpStatus);
        if (tmpStatus == U_STRING_NOT_TERMINATED_WARNING) {
            tmpStatus = U_ZERO_ERROR;  // Terminators provided by CharString.
        }

        if (U_FAILURE(tmpStatus)) {
            *status = tmpStatus;
            return;
        }
    }

    /* For handling special case - private use only tag */
    pKeywordStart = locale_getKeywordsStart(canonical.data());
    if (pKeywordStart == canonical.data()) {
        int kwdCnt = 0;
        UBool done = FALSE;

        icu::LocalUEnumerationPointer kwdEnum(uloc_openKeywords(canonical.data(), &tmpStatus));
        if (U_SUCCESS(tmpStatus)) {
            kwdCnt = uenum_count(kwdEnum.getAlias(), &tmpStatus);
            if (kwdCnt == 1) {
                const char *key;
                int32_t len = 0;

                key = uenum_next(kwdEnum.getAlias(), &len, &tmpStatus);
                if (len == 1 && *key == PRIVATEUSE) {
                    icu::CharString buf;
                    {
                        icu::CharStringByteSink sink(&buf);
                        ulocimp_getKeywordValue(localeID, key, sink, &tmpStatus);
                    }
                    if (U_SUCCESS(tmpStatus)) {
                        if (ultag_isPrivateuseValueSubtags(buf.data(), buf.length())) {
                            /* return private use only tag */
                            static const char PREFIX[] = { PRIVATEUSE, SEP };
                            sink.Append(PREFIX, sizeof(PREFIX));
                            sink.Append(buf.data(), buf.length());
                            done = TRUE;
                        } else if (strict) {
                            *status = U_ILLEGAL_ARGUMENT_ERROR;
                            done = TRUE;
                        }
                        /* if not strict mode, then "und" will be returned */
                    } else {
                        *status = U_ILLEGAL_ARGUMENT_ERROR;
                        done = TRUE;
                    }
                }
            }
            if (done) {
                return;
            }
        }
    }

    _appendLanguageToLanguageTag(canonical.data(), sink, strict, status);
    _appendScriptToLanguageTag(canonical.data(), sink, strict, status);
    _appendRegionToLanguageTag(canonical.data(), sink, strict, status);
    _appendVariantsToLanguageTag(canonical.data(), sink, strict, &hadPosix, status);
    _appendKeywordsToLanguageTag(canonical.data(), sink, strict, hadPosix, status);
    _appendPrivateuseToLanguageTag(canonical.data(), sink, strict, hadPosix, status);
}


U_CAPI int32_t U_EXPORT2
uloc_forLanguageTag(const char* langtag,
                    char* localeID,
                    int32_t localeIDCapacity,
                    int32_t* parsedLength,
                    UErrorCode* status) {
    if (U_FAILURE(*status)) {
        return 0;
    }

    icu::CheckedArrayByteSink sink(localeID, localeIDCapacity);
    ulocimp_forLanguageTag(langtag, -1, sink, parsedLength, status);

    int32_t reslen = sink.NumberOfBytesAppended();

    if (U_FAILURE(*status)) {
        return reslen;
    }

    if (sink.Overflowed()) {
        *status = U_BUFFER_OVERFLOW_ERROR;
    } else {
        u_terminateChars(localeID, localeIDCapacity, reslen, status);
    }

    return reslen;
}


U_CAPI void U_EXPORT2
ulocimp_forLanguageTag(const char* langtag,
                       int32_t tagLen,
                       icu::ByteSink& sink,
                       int32_t* parsedLength,
                       UErrorCode* status) {
    UBool isEmpty = TRUE;
    const char *subtag, *p;
    int32_t len;
    int32_t i, n;
    UBool noRegion = TRUE;

    icu::LocalULanguageTagPointer lt(ultag_parse(langtag, tagLen, parsedLength, status));
    if (U_FAILURE(*status)) {
        return;
    }

    /* language */
    subtag = ultag_getExtlangSize(lt.getAlias()) > 0 ? ultag_getExtlang(lt.getAlias(), 0) : ultag_getLanguage(lt.getAlias());
    if (uprv_compareInvCharsAsAscii(subtag, LANG_UND) != 0) {
        len = (int32_t)uprv_strlen(subtag);
        if (len > 0) {
            sink.Append(subtag, len);
            isEmpty = FALSE;
        }
    }

    /* script */
    subtag = ultag_getScript(lt.getAlias());
    len = (int32_t)uprv_strlen(subtag);
    if (len > 0) {
        sink.Append("_", 1);
        isEmpty = FALSE;

        /* write out the script in title case */
        char c = uprv_toupper(*subtag);
        sink.Append(&c, 1);
        sink.Append(subtag + 1, len - 1);
    }

    /* region */
    subtag = ultag_getRegion(lt.getAlias());
    len = (int32_t)uprv_strlen(subtag);
    if (len > 0) {
        sink.Append("_", 1);
        isEmpty = FALSE;

        /* write out the region in upper case */
        p = subtag;
        while (*p) {
            char c = uprv_toupper(*p);
            sink.Append(&c, 1);
            p++;
        }
        noRegion = FALSE;
    }

    /* variants */
    _sortVariants(lt.getAlias()->variants);
    n = ultag_getVariantsSize(lt.getAlias());
    if (n > 0) {
        if (noRegion) {
            sink.Append("_", 1);
            isEmpty = FALSE;
        }

        for (i = 0; i < n; i++) {
            subtag = ultag_getVariant(lt.getAlias(), i);
            sink.Append("_", 1);

            /* write out the variant in upper case */
            p = subtag;
            while (*p) {
                char c = uprv_toupper(*p);
                sink.Append(&c, 1);
                p++;
            }
        }
    }

    /* keywords */
    n = ultag_getExtensionsSize(lt.getAlias());
    subtag = ultag_getPrivateUse(lt.getAlias());
    if (n > 0 || uprv_strlen(subtag) > 0) {
        if (isEmpty && n > 0) {
            /* need a language */
            sink.Append(LANG_UND, LANG_UND_LEN);
        }
        _appendKeywords(lt.getAlias(), sink, status);
    }
}
