Enable netstandard1.7 collations APIs (#7502)
authorTarek Mahmoud Sayed <tarekms@microsoft.com>
Fri, 7 Oct 2016 07:07:04 +0000 (00:07 -0700)
committerGitHub <noreply@github.com>
Fri, 7 Oct 2016 07:07:04 +0000 (00:07 -0700)
* Enable netstandard1.7 collations APIs

This change is adding the netstandard 1.7 APIs to CompareInfo class and adding support to SortKey and SortVersion classes
The change include some support in cultureinfo and culturedata for locale Id's too which is used by CompareInfo class

* optimize the globalization data so we'll have faster initialization

* Remove security attributes

12 files changed:
src/mscorlib/corefx/SR.cs
src/mscorlib/corefx/System/Globalization/CompareInfo.Unix.cs
src/mscorlib/corefx/System/Globalization/CompareInfo.Windows.cs
src/mscorlib/corefx/System/Globalization/CompareInfo.cs
src/mscorlib/corefx/System/Globalization/CultureData.Unix.cs
src/mscorlib/corefx/System/Globalization/CultureData.Windows.cs
src/mscorlib/corefx/System/Globalization/CultureData.cs
src/mscorlib/corefx/System/Globalization/CultureInfo.cs
src/mscorlib/corefx/System/Globalization/STUBS.cs
src/mscorlib/corefx/System/Globalization/SortKey.cs [new file with mode: 0644]
src/mscorlib/corefx/System/Globalization/SortVersion.cs [new file with mode: 0644]
src/mscorlib/mscorlib.shared.sources.props

index f162699..44c9b7d 100644 (file)
@@ -143,6 +143,11 @@ namespace System.Globalization
         {
             get { return Environment.GetResourceString("Argument_CultureNotSupported"); }
         }
+
+        public static string Argument_CustomCultureCannotBePassedByNumber
+        {
+            get { return Environment.GetResourceString("Argument_CustomCultureCannotBePassedByNumber"); }
+        }
        
         public static string Argument_EmptyDecString
         {
@@ -204,6 +209,11 @@ namespace System.Globalization
             get { return Environment.GetResourceString("Argument_NoRegionInvariantCulture"); }
         }
 
+        public static string Argument_OnlyMscorlib
+        {
+            get { return Environment.GetResourceString("Argument_OnlyMscorlib"); }
+        }
+
         public static string Argument_ResultCalendarRange
         {
             get { return Environment.GetResourceString("Argument_ResultCalendarRange"); }
index 2aaf5a2..eb7de2c 100644 (file)
@@ -17,7 +17,6 @@ namespace System.Globalization
         [NonSerialized]
         private bool _isAsciiEqualityOrdinal;
 
-        [SecuritySafeCritical]
         internal CompareInfo(CultureInfo culture)
         {
             _name = culture.m_name;
@@ -212,7 +211,6 @@ namespace System.Globalization
             }
         }
 
-        [SecuritySafeCritical]
         private bool StartsWith(string source, string prefix, CompareOptions options)
         {
             Contract.Assert(!string.IsNullOrEmpty(source));
@@ -227,7 +225,6 @@ namespace System.Globalization
             return Interop.GlobalizationInterop.StartsWith(_sortHandle, prefix, prefix.Length, source, source.Length, options);
         }
 
-        [SecuritySafeCritical]
         private bool EndsWith(string source, string suffix, CompareOptions options)
         {
             Contract.Assert(!string.IsNullOrEmpty(source));
@@ -241,12 +238,77 @@ namespace System.Globalization
 
             return Interop.GlobalizationInterop.EndsWith(_sortHandle, suffix, suffix.Length, source, source.Length, options);
         }
+        
+        private unsafe SortKey CreateSortKey(String source, CompareOptions options)
+        {
+            if (source==null) { throw new ArgumentNullException("source"); }
+            Contract.EndContractBlock();
+
+            if ((options & ValidSortkeyCtorMaskOffFlags) != 0)
+            {
+                throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), "options");
+            }
+            
+            byte [] keyData;
+            if (source.Length == 0)
+            { 
+                keyData = EmptyArray<Byte>.Value;
+            }
+            else
+            {
+                int sortKeyLength = Interop.GlobalizationInterop.GetSortKey(_sortHandle, source, source.Length, null, 0, options);
+                keyData = new byte[sortKeyLength];
+
+                fixed (byte* pSortKey = keyData)
+                {
+                    Interop.GlobalizationInterop.GetSortKey(_sortHandle, source, source.Length, pSortKey, sortKeyLength, options);
+                }
+            }
+
+            return new SortKey(Name, source, options, keyData);
+        }       
+
+        private unsafe static bool IsSortable(char *text, int length)
+        {
+            int index = 0;
+            UnicodeCategory uc;
+
+            while (index < length)
+            {
+                if (Char.IsHighSurrogate(text[index]))
+                {
+                    if (index == length - 1 || !Char.IsLowSurrogate(text[index+1]))
+                        return false; // unpaired surrogate
+
+                    uc = CharUnicodeInfo.InternalGetUnicodeCategory(Char.ConvertToUtf32(text[index], text[index+1]));
+                    if (uc == UnicodeCategory.PrivateUse || uc == UnicodeCategory.OtherNotAssigned)
+                        return false;
+
+                    index += 2;
+                    continue;
+                }
+
+                if (Char.IsLowSurrogate(text[index]))
+                {
+                    return false; // unpaired surrogate
+                }
+
+                uc = CharUnicodeInfo.GetUnicodeCategory(text[index]);
+                if (uc == UnicodeCategory.PrivateUse || uc == UnicodeCategory.OtherNotAssigned)
+                {
+                    return false;
+                }
+
+                index++;
+            }
+
+            return true;
+        }
 
         // -----------------------------
         // ---- PAL layer ends here ----
         // -----------------------------
 
-        [SecuritySafeCritical]
         internal unsafe int GetHashCodeOfStringCore(string source, CompareOptions options, bool forceRandomizedHashing, long additionalEntropy)
         {
             Contract.Assert(source != null);
index 744a48b..b10e1bd 100644 (file)
@@ -354,6 +354,26 @@ namespace System.Globalization
 #endif // TEST_CODEGEN_OPTIMIZATION
         }
 
+        private unsafe SortKey CreateSortKey(String source, CompareOptions options)
+        {
+            if (source==null) { throw new ArgumentNullException("source"); }
+            Contract.EndContractBlock();
+
+            if ((options & ValidSortkeyCtorMaskOffFlags) != 0)
+            {
+                throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), "options");
+            }
+
+            throw new NotImplementedException();
+        }
+
+        private unsafe static bool IsSortable(char *text, int length)
+        {
+            // CompareInfo c = CultureInfo.InvariantCulture.CompareInfo;
+            // return (InternalIsSortable(c.m_dataHandle, c.m_handleOrigin, c.m_sortName, text, text.Length));
+            throw new NotImplementedException();
+        }
+
         private const int COMPARE_OPTIONS_ORDINAL = 0x40000000;       // Ordinal
         private const int NORM_IGNORECASE = 0x00000001;       // Ignores case.  (use LINGUISTIC_IGNORECASE instead)
         private const int NORM_IGNOREKANATYPE = 0x00010000;       // Does not differentiate between Hiragana and Katakana characters. Corresponding Hiragana and Katakana will compare as equal.
index 77778af..a50107c 100644 (file)
@@ -13,6 +13,7 @@
 ////////////////////////////////////////////////////////////////////////////
 
 using System;
+using System.Reflection;
 using System.Collections;
 using System.Collections.Generic;
 using System.Diagnostics.Contracts;
@@ -58,6 +59,11 @@ namespace System.Globalization
             ~(CompareOptions.IgnoreCase | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace |
               CompareOptions.IgnoreWidth | CompareOptions.IgnoreKanaType);
 
+            // Mask used to check if we have the right flags.
+        private const CompareOptions ValidSortkeyCtorMaskOffFlags = 
+            ~(CompareOptions.IgnoreCase | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace |
+              CompareOptions.IgnoreWidth | CompareOptions.IgnoreKanaType | CompareOptions.StringSort);
+
         //
         // CompareInfos have an interesting identity.  They are attached to the locale that created them,
         // ie: en-US would have an en-US sort.  For haw-US (custom), then we serialize it as haw-US.
@@ -70,6 +76,83 @@ namespace System.Globalization
         private String _sortName; // The name that defines our behavior
 
         /*=================================GetCompareInfo==========================
+        **Action: Get the CompareInfo constructed from the data table in the specified assembly for the specified culture.
+        **       Warning: The assembly versioning mechanism is dead!
+        **Returns: The CompareInfo for the specified culture.
+        **Arguments:
+        **   culture    the ID of the culture
+        **   assembly   the assembly which contains the sorting table.
+        **Exceptions:
+        **  ArugmentNullException when the assembly is null
+        **  ArgumentException if culture is invalid.
+        ============================================================================*/
+        // Assembly constructor should be deprecated, we don't act on the assembly information any more
+        public static CompareInfo GetCompareInfo(int culture, Assembly assembly)
+        {
+            // Parameter checking.
+            if (assembly == null)
+            {
+                throw new ArgumentNullException("assembly");
+            }
+            if (assembly != typeof(Object).Module.Assembly) 
+            {
+                throw new ArgumentException(SR.Argument_OnlyMscorlib);
+            }
+            Contract.EndContractBlock();
+
+            return GetCompareInfo(culture);
+        }
+
+        /*=================================GetCompareInfo==========================
+        **Action: Get the CompareInfo constructed from the data table in the specified assembly for the specified culture.
+        **       The purpose of this method is to provide version for CompareInfo tables.
+        **Returns: The CompareInfo for the specified culture.
+        **Arguments:
+        **   name      the name of the culture
+        **   assembly  the assembly which contains the sorting table.
+        **Exceptions:
+        **  ArugmentNullException when the assembly is null
+        **  ArgumentException if name is invalid.
+        ============================================================================*/
+        // Assembly constructor should be deprecated, we don't act on the assembly information any more
+        public static CompareInfo GetCompareInfo(String name, Assembly assembly)
+        {
+            if (name == null || assembly == null)
+            {
+                throw new ArgumentNullException(name == null ? "name" : "assembly");
+            }
+            Contract.EndContractBlock();
+
+            if (assembly != typeof(Object).Module.Assembly)
+            {
+                throw new ArgumentException(SR.Argument_OnlyMscorlib);
+            }
+
+            return GetCompareInfo(name);
+        }
+
+        /*=================================GetCompareInfo==========================
+        **Action: Get the CompareInfo for the specified culture.
+        ** This method is provided for ease of integration with NLS-based software.
+        **Returns: The CompareInfo for the specified culture.
+        **Arguments:
+        **   culture    the ID of the culture.
+        **Exceptions:
+        **  ArgumentException if culture is invalid.
+        ============================================================================*/
+        // People really shouldn't be calling LCID versions, no custom support
+        public static CompareInfo GetCompareInfo(int culture)
+        {
+            if (CultureData.IsCustomCultureId(culture))
+            {
+                // Customized culture cannot be created by the LCID.
+                throw new ArgumentException(SR.Argument_CustomCultureCannotBePassedByNumber, "culture");
+            }
+
+            return CultureInfo.GetCultureInfo(culture).CompareInfo;
+        }
+
+        /*=================================GetCompareInfo==========================
         **Action: Get the CompareInfo for the specified culture.
         **Returns: The CompareInfo for the specified culture.
         **Arguments:
@@ -89,6 +172,35 @@ namespace System.Globalization
             return CultureInfo.GetCultureInfo(name).CompareInfo;
         }
 
+        [System.Runtime.InteropServices.ComVisible(false)]
+        public unsafe static bool IsSortable(char ch)
+        {
+            char *pChar = &ch;
+            return IsSortable(pChar, 1);
+        }
+
+        [System.Runtime.InteropServices.ComVisible(false)]
+        public unsafe static bool IsSortable(string text)
+        {
+            if (text == null) 
+            {
+                // A null param is invalid here.
+                throw new ArgumentNullException("text");
+            }
+
+            if (0 == text.Length)
+            {
+                // A zero length string is not invalid, but it is also not sortable.
+                return (false);
+            }
+            
+            fixed (char *pChar = text)
+            {
+                return IsSortable(pChar, text.Length);
+            }
+        }
+
+
         [OnDeserializing]
         private void OnDeserializing(StreamingContext ctx)
         {
@@ -517,6 +629,23 @@ namespace System.Globalization
             return IndexOf(source, value, 0, source.Length, options);
         }
 
+        public unsafe virtual int IndexOf(String source, char value, int startIndex)
+        {
+            if (source == null)
+                throw new ArgumentNullException("source");
+            Contract.EndContractBlock();
+
+            return IndexOf(source, value, startIndex, source.Length - startIndex, CompareOptions.None);
+        }
+
+        public unsafe virtual int IndexOf(String source, String value, int startIndex)
+        {
+            if (source == null)
+                throw new ArgumentNullException("source");
+            Contract.EndContractBlock();
+
+            return IndexOf(source, value, startIndex, source.Length - startIndex, CompareOptions.None);
+        }
 
         public unsafe virtual int IndexOf(String source, char value, int startIndex, CompareOptions options)
         {
@@ -682,6 +811,16 @@ namespace System.Globalization
                 source.Length, options);
         }
 
+        public unsafe virtual int LastIndexOf(String source, char value, int startIndex)
+        {
+            return LastIndexOf(source, value, startIndex, startIndex + 1, CompareOptions.None);
+        }
+
+
+        public unsafe virtual int LastIndexOf(String source, String value, int startIndex)
+        {
+            return LastIndexOf(source, value, startIndex, startIndex + 1, CompareOptions.None);
+        }
 
         public unsafe virtual int LastIndexOf(String source, char value, int startIndex, CompareOptions options)
         {
@@ -798,7 +937,23 @@ namespace System.Globalization
             return LastIndexOfCore(source, value, startIndex, count, options);
         }
 
+        ////////////////////////////////////////////////////////////////////////
+        //
+        //  GetSortKey
+        //
+        //  Gets the SortKey for the given string with the given options.
+        //
+        ////////////////////////////////////////////////////////////////////////
+        public unsafe virtual SortKey GetSortKey(String source, CompareOptions options)
+        {
+            return CreateSortKey(source, options);
+        }
+
 
+        public unsafe virtual SortKey GetSortKey(String source)
+        {
+            return CreateSortKey(source, CompareOptions.None);
+        }
 
         ////////////////////////////////////////////////////////////////////////
         //
@@ -921,5 +1076,13 @@ namespace System.Globalization
         {
             return ("CompareInfo - " + this.Name);
         }
+
+        public int LCID
+        {
+            get
+            {
+                return CultureInfo.GetCultureInfo(Name).LCID;
+            }
+        }
     }
 }
index 58aae2f..89b14ac 100644 (file)
@@ -17,7 +17,3513 @@ namespace System.Globalization
         const int ICU_ULOC_KEYWORD_AND_VALUES_CAPACITY = 100; // max size of keyword or value
         const int ICU_ULOC_FULLNAME_CAPACITY = 157;           // max size of locale name
         const string ICU_COLLATION_KEYWORD = "@collation=";
-
+        
+        // c_localeNames is the concatenation of all supported culture names.
+        // this is done rather than using a large readonly array of strings to avoid
+        // generating a large amount of code in the static constructor.
+        // Using indices from s_localeNamesIndices, we binary search this string when mapping
+        // an culture name to Lcid. Note that these names are all lowercase and are
+        // sorted alphabetically (ordinal).
+        private const string c_localeNames =
+        //  culture name                    Lcid    
+            "aa"                      + //  01000 - 0
+            "aa-dj"                   + //  01000 - 2
+            "aa-er"                   + //  01000 - 7
+            "aa-et"                   + //  01000 - 12
+            "af"                      + //  00036 - 17
+            "af-na"                   + //  01000 - 19
+            "af-za"                   + //  00436 - 24
+            "agq"                     + //  01000 - 29
+            "agq-cm"                  + //  01000 - 32
+            "ak"                      + //  01000 - 38
+            "ak-gh"                   + //  01000 - 40
+            "am"                      + //  0005e - 45
+            "am-et"                   + //  0045e - 47
+            "ar"                      + //  00001 - 52
+            "ar-001"                  + //  01000 - 54
+            "ar-ae"                   + //  03801 - 60
+            "ar-bh"                   + //  03c01 - 65
+            "ar-dj"                   + //  01000 - 70
+            "ar-dz"                   + //  01401 - 75
+            "ar-eg"                   + //  00c01 - 80
+            "ar-er"                   + //  01000 - 85
+            "ar-il"                   + //  01000 - 90
+            "ar-iq"                   + //  00801 - 95
+            "ar-jo"                   + //  02c01 - 100
+            "ar-km"                   + //  01000 - 105
+            "ar-kw"                   + //  03401 - 110
+            "ar-lb"                   + //  03001 - 115
+            "ar-ly"                   + //  01001 - 120
+            "ar-ma"                   + //  01801 - 125
+            "ar-mr"                   + //  01000 - 130
+            "ar-om"                   + //  02001 - 135
+            "ar-ps"                   + //  01000 - 140
+            "ar-qa"                   + //  04001 - 145
+            "ar-sa"                   + //  00401 - 150
+            "ar-sd"                   + //  01000 - 155
+            "ar-so"                   + //  01000 - 160
+            "ar-ss"                   + //  01000 - 165
+            "ar-sy"                   + //  02801 - 170
+            "ar-td"                   + //  01000 - 175
+            "ar-tn"                   + //  01c01 - 180
+            "ar-ye"                   + //  02401 - 185
+            "arn"                     + //  0007a - 190
+            "arn-cl"                  + //  0047a - 193
+            "as"                      + //  0004d - 199
+            "as-in"                   + //  0044d - 201
+            "asa"                     + //  01000 - 206
+            "asa-tz"                  + //  01000 - 209
+            "ast"                     + //  01000 - 215
+            "ast-es"                  + //  01000 - 218
+            "az"                      + //  0002c - 224
+            "az-cyrl"                 + //  0742c - 226
+            "az-cyrl-az"              + //  0082c - 233
+            "az-latn"                 + //  0782c - 243
+            "az-latn-az"              + //  0042c - 250
+            "ba"                      + //  0006d - 260
+            "ba-ru"                   + //  0046d - 262
+            "bas"                     + //  01000 - 267
+            "bas-cm"                  + //  01000 - 270
+            "be"                      + //  00023 - 276
+            "be-by"                   + //  00423 - 278
+            "bem"                     + //  01000 - 283
+            "bem-zm"                  + //  01000 - 286
+            "bez"                     + //  01000 - 292
+            "bez-tz"                  + //  01000 - 295
+            "bg"                      + //  00002 - 301
+            "bg-bg"                   + //  00402 - 303
+            "bin"                     + //  00066 - 308
+            "bin-ng"                  + //  00466 - 311
+            "bm"                      + //  01000 - 317
+            "bm-latn"                 + //  01000 - 319
+            "bm-latn-ml"              + //  01000 - 326
+            "bn"                      + //  00045 - 336
+            "bn-bd"                   + //  00845 - 338
+            "bn-in"                   + //  00445 - 343
+            "bo"                      + //  00051 - 348
+            "bo-cn"                   + //  00451 - 350
+            "bo-in"                   + //  01000 - 355
+            "br"                      + //  0007e - 360
+            "br-fr"                   + //  0047e - 362
+            "brx"                     + //  01000 - 367
+            "brx-in"                  + //  01000 - 370
+            "bs"                      + //  0781a - 376
+            "bs-cyrl"                 + //  0641a - 378
+            "bs-cyrl-ba"              + //  0201a - 385
+            "bs-latn"                 + //  0681a - 395
+            "bs-latn-ba"              + //  0141a - 402
+            "byn"                     + //  01000 - 412
+            "byn-er"                  + //  01000 - 415
+            "ca"                      + //  00003 - 421
+            "ca-ad"                   + //  01000 - 423
+            "ca-es"                   + //  00403 - 428
+            "ca-es-valencia"          + //  00803 - 433
+            "ca-fr"                   + //  01000 - 447
+            "ca-it"                   + //  01000 - 452
+            "ce-ru"                   + //  01000 - 457
+            "cgg"                     + //  01000 - 462
+            "cgg-ug"                  + //  01000 - 465
+            "chr"                     + //  0005c - 471
+            "chr-cher"                + //  07c5c - 474
+            "chr-cher-us"             + //  0045c - 482
+            "co"                      + //  00083 - 493
+            "co-fr"                   + //  00483 - 495
+            "cs"                      + //  00005 - 500
+            "cs-cz"                   + //  00405 - 502
+            "cu-ru"                   + //  01000 - 507
+            "cy"                      + //  00052 - 512
+            "cy-gb"                   + //  00452 - 514
+            "da"                      + //  00006 - 519
+            "da-dk"                   + //  00406 - 521
+            "da-gl"                   + //  01000 - 526
+            "dav"                     + //  01000 - 531
+            "dav-ke"                  + //  01000 - 534
+            "de"                      + //  00007 - 540
+            "de-at"                   + //  00c07 - 542
+            "de-be"                   + //  01000 - 547
+            "de-ch"                   + //  00807 - 552
+            "de-de"                   + //  00407 - 557
+            "de-de_phoneb"            + //  10407 - 562
+            "de-it"                   + //  01000 - 574
+            "de-li"                   + //  01407 - 579
+            "de-lu"                   + //  01007 - 584
+            "dje"                     + //  01000 - 589
+            "dje-ne"                  + //  01000 - 592
+            "dsb"                     + //  07c2e - 598
+            "dsb-de"                  + //  0082e - 601
+            "dua"                     + //  01000 - 607
+            "dua-cm"                  + //  01000 - 610
+            "dv"                      + //  00065 - 616
+            "dv-mv"                   + //  00465 - 618
+            "dyo"                     + //  01000 - 623
+            "dyo-sn"                  + //  01000 - 626
+            "dz"                      + //  01000 - 632
+            "dz-bt"                   + //  00c51 - 634
+            "ebu"                     + //  01000 - 639
+            "ebu-ke"                  + //  01000 - 642
+            "ee"                      + //  01000 - 648
+            "ee-gh"                   + //  01000 - 650
+            "ee-tg"                   + //  01000 - 655
+            "el"                      + //  00008 - 660
+            "el-cy"                   + //  01000 - 662
+            "el-gr"                   + //  00408 - 667
+            "en"                      + //  00009 - 672
+            "en-001"                  + //  01000 - 674
+            "en-029"                  + //  02409 - 680
+            "en-150"                  + //  01000 - 686
+            "en-ag"                   + //  01000 - 692
+            "en-ai"                   + //  01000 - 697
+            "en-as"                   + //  01000 - 702
+            "en-at"                   + //  01000 - 707
+            "en-au"                   + //  00c09 - 712
+            "en-bb"                   + //  01000 - 717
+            "en-be"                   + //  01000 - 722
+            "en-bi"                   + //  01000 - 727
+            "en-bm"                   + //  01000 - 732
+            "en-bs"                   + //  01000 - 737
+            "en-bw"                   + //  01000 - 742
+            "en-bz"                   + //  02809 - 747
+            "en-ca"                   + //  01009 - 752
+            "en-cc"                   + //  01000 - 757
+            "en-ch"                   + //  01000 - 762
+            "en-ck"                   + //  01000 - 767
+            "en-cm"                   + //  01000 - 772
+            "en-cx"                   + //  01000 - 777
+            "en-cy"                   + //  01000 - 782
+            "en-de"                   + //  01000 - 787
+            "en-dk"                   + //  01000 - 792
+            "en-dm"                   + //  01000 - 797
+            "en-er"                   + //  01000 - 802
+            "en-fi"                   + //  01000 - 807
+            "en-fj"                   + //  01000 - 812
+            "en-fk"                   + //  01000 - 817
+            "en-fm"                   + //  01000 - 822
+            "en-gb"                   + //  00809 - 827
+            "en-gd"                   + //  01000 - 832
+            "en-gg"                   + //  01000 - 837
+            "en-gh"                   + //  01000 - 842
+            "en-gi"                   + //  01000 - 847
+            "en-gm"                   + //  01000 - 852
+            "en-gu"                   + //  01000 - 857
+            "en-gy"                   + //  01000 - 862
+            "en-hk"                   + //  03c09 - 867
+            "en-id"                   + //  03809 - 872
+            "en-ie"                   + //  01809 - 877
+            "en-il"                   + //  01000 - 882
+            "en-im"                   + //  01000 - 887
+            "en-in"                   + //  04009 - 892
+            "en-io"                   + //  01000 - 897
+            "en-je"                   + //  01000 - 902
+            "en-jm"                   + //  02009 - 907
+            "en-ke"                   + //  01000 - 912
+            "en-ki"                   + //  01000 - 917
+            "en-kn"                   + //  01000 - 922
+            "en-ky"                   + //  01000 - 927
+            "en-lc"                   + //  01000 - 932
+            "en-lr"                   + //  01000 - 937
+            "en-ls"                   + //  01000 - 942
+            "en-mg"                   + //  01000 - 947
+            "en-mh"                   + //  01000 - 952
+            "en-mo"                   + //  01000 - 957
+            "en-mp"                   + //  01000 - 962
+            "en-ms"                   + //  01000 - 967
+            "en-mt"                   + //  01000 - 972
+            "en-mu"                   + //  01000 - 977
+            "en-mw"                   + //  01000 - 982
+            "en-my"                   + //  04409 - 987
+            "en-na"                   + //  01000 - 992
+            "en-nf"                   + //  01000 - 997
+            "en-ng"                   + //  01000 - 1002
+            "en-nl"                   + //  01000 - 1007
+            "en-nr"                   + //  01000 - 1012
+            "en-nu"                   + //  01000 - 1017
+            "en-nz"                   + //  01409 - 1022
+            "en-pg"                   + //  01000 - 1027
+            "en-ph"                   + //  03409 - 1032
+            "en-pk"                   + //  01000 - 1037
+            "en-pn"                   + //  01000 - 1042
+            "en-pr"                   + //  01000 - 1047
+            "en-pw"                   + //  01000 - 1052
+            "en-rw"                   + //  01000 - 1057
+            "en-sb"                   + //  01000 - 1062
+            "en-sc"                   + //  01000 - 1067
+            "en-sd"                   + //  01000 - 1072
+            "en-se"                   + //  01000 - 1077
+            "en-sg"                   + //  04809 - 1082
+            "en-sh"                   + //  01000 - 1087
+            "en-si"                   + //  01000 - 1092
+            "en-sl"                   + //  01000 - 1097
+            "en-ss"                   + //  01000 - 1102
+            "en-sx"                   + //  01000 - 1107
+            "en-sz"                   + //  01000 - 1112
+            "en-tc"                   + //  01000 - 1117
+            "en-tk"                   + //  01000 - 1122
+            "en-to"                   + //  01000 - 1127
+            "en-tt"                   + //  02c09 - 1132
+            "en-tv"                   + //  01000 - 1137
+            "en-tz"                   + //  01000 - 1142
+            "en-ug"                   + //  01000 - 1147
+            "en-um"                   + //  01000 - 1152
+            "en-us"                   + //  00409 - 1157
+            "en-vc"                   + //  01000 - 1162
+            "en-vg"                   + //  01000 - 1167
+            "en-vi"                   + //  01000 - 1172
+            "en-vu"                   + //  01000 - 1177
+            "en-ws"                   + //  01000 - 1182
+            "en-za"                   + //  01c09 - 1187
+            "en-zm"                   + //  01000 - 1192
+            "en-zw"                   + //  03009 - 1197
+            "eo"                      + //  01000 - 1202
+            "eo-001"                  + //  01000 - 1204
+            "es"                      + //  0000a - 1210
+            "es-419"                  + //  0580a - 1212
+            "es-ar"                   + //  02c0a - 1218
+            "es-bo"                   + //  0400a - 1223
+            "es-br"                   + //  01000 - 1228
+            "es-cl"                   + //  0340a - 1233
+            "es-co"                   + //  0240a - 1238
+            "es-cr"                   + //  0140a - 1243
+            "es-cu"                   + //  05c0a - 1248
+            "es-do"                   + //  01c0a - 1253
+            "es-ec"                   + //  0300a - 1258
+            "es-es"                   + //  00c0a - 1263
+            "es-es_tradnl"            + //  0040a - 1268
+            "es-gq"                   + //  01000 - 1280
+            "es-gt"                   + //  0100a - 1285
+            "es-hn"                   + //  0480a - 1290
+            "es-mx"                   + //  0080a - 1295
+            "es-ni"                   + //  04c0a - 1300
+            "es-pa"                   + //  0180a - 1305
+            "es-pe"                   + //  0280a - 1310
+            "es-ph"                   + //  01000 - 1315
+            "es-pr"                   + //  0500a - 1320
+            "es-py"                   + //  03c0a - 1325
+            "es-sv"                   + //  0440a - 1330
+            "es-us"                   + //  0540a - 1335
+            "es-uy"                   + //  0380a - 1340
+            "es-ve"                   + //  0200a - 1345
+            "et"                      + //  00025 - 1350
+            "et-ee"                   + //  00425 - 1352
+            "eu"                      + //  0002d - 1357
+            "eu-es"                   + //  0042d - 1359
+            "ewo"                     + //  01000 - 1364
+            "ewo-cm"                  + //  01000 - 1367
+            "fa"                      + //  00029 - 1373
+            "fa-ir"                   + //  00429 - 1375
+            "ff"                      + //  00067 - 1380
+            "ff-cm"                   + //  01000 - 1382
+            "ff-gn"                   + //  01000 - 1387
+            "ff-latn"                 + //  07c67 - 1392
+            "ff-latn-sn"              + //  00867 - 1399
+            "ff-mr"                   + //  01000 - 1409
+            "ff-ng"                   + //  00467 - 1414
+            "fi"                      + //  0000b - 1419
+            "fi-fi"                   + //  0040b - 1421
+            "fil"                     + //  00064 - 1426
+            "fil-ph"                  + //  00464 - 1429
+            "fo"                      + //  00038 - 1435
+            "fo-dk"                   + //  01000 - 1437
+            "fo-fo"                   + //  00438 - 1442
+            "fr"                      + //  0000c - 1447
+            "fr-029"                  + //  01c0c - 1449
+            "fr-be"                   + //  0080c - 1455
+            "fr-bf"                   + //  01000 - 1460
+            "fr-bi"                   + //  01000 - 1465
+            "fr-bj"                   + //  01000 - 1470
+            "fr-bl"                   + //  01000 - 1475
+            "fr-ca"                   + //  00c0c - 1480
+            "fr-cd"                   + //  0240c - 1485
+            "fr-cf"                   + //  01000 - 1490
+            "fr-cg"                   + //  01000 - 1495
+            "fr-ch"                   + //  0100c - 1500
+            "fr-ci"                   + //  0300c - 1505
+            "fr-cm"                   + //  02c0c - 1510
+            "fr-dj"                   + //  01000 - 1515
+            "fr-dz"                   + //  01000 - 1520
+            "fr-fr"                   + //  0040c - 1525
+            "fr-ga"                   + //  01000 - 1530
+            "fr-gf"                   + //  01000 - 1535
+            "fr-gn"                   + //  01000 - 1540
+            "fr-gp"                   + //  01000 - 1545
+            "fr-gq"                   + //  01000 - 1550
+            "fr-ht"                   + //  03c0c - 1555
+            "fr-km"                   + //  01000 - 1560
+            "fr-lu"                   + //  0140c - 1565
+            "fr-ma"                   + //  0380c - 1570
+            "fr-mc"                   + //  0180c - 1575
+            "fr-mf"                   + //  01000 - 1580
+            "fr-mg"                   + //  01000 - 1585
+            "fr-ml"                   + //  0340c - 1590
+            "fr-mq"                   + //  01000 - 1595
+            "fr-mr"                   + //  01000 - 1600
+            "fr-mu"                   + //  01000 - 1605
+            "fr-nc"                   + //  01000 - 1610
+            "fr-ne"                   + //  01000 - 1615
+            "fr-pf"                   + //  01000 - 1620
+            "fr-pm"                   + //  01000 - 1625
+            "fr-re"                   + //  0200c - 1630
+            "fr-rw"                   + //  01000 - 1635
+            "fr-sc"                   + //  01000 - 1640
+            "fr-sn"                   + //  0280c - 1645
+            "fr-sy"                   + //  01000 - 1650
+            "fr-td"                   + //  01000 - 1655
+            "fr-tg"                   + //  01000 - 1660
+            "fr-tn"                   + //  01000 - 1665
+            "fr-vu"                   + //  01000 - 1670
+            "fr-wf"                   + //  01000 - 1675
+            "fr-yt"                   + //  01000 - 1680
+            "fur"                     + //  01000 - 1685
+            "fur-it"                  + //  01000 - 1688
+            "fy"                      + //  00062 - 1694
+            "fy-nl"                   + //  00462 - 1696
+            "ga"                      + //  0003c - 1701
+            "ga-ie"                   + //  0083c - 1703
+            "gd"                      + //  00091 - 1708
+            "gd-gb"                   + //  00491 - 1710
+            "gl"                      + //  00056 - 1715
+            "gl-es"                   + //  00456 - 1717
+            "gn"                      + //  00074 - 1722
+            "gn-py"                   + //  00474 - 1724
+            "gsw"                     + //  00084 - 1729
+            "gsw-ch"                  + //  01000 - 1732
+            "gsw-fr"                  + //  00484 - 1738
+            "gsw-li"                  + //  01000 - 1744
+            "gu"                      + //  00047 - 1750
+            "gu-in"                   + //  00447 - 1752
+            "guz"                     + //  01000 - 1757
+            "guz-ke"                  + //  01000 - 1760
+            "gv"                      + //  01000 - 1766
+            "gv-im"                   + //  01000 - 1768
+            "ha"                      + //  00068 - 1773
+            "ha-latn"                 + //  07c68 - 1775
+            "ha-latn-gh"              + //  01000 - 1782
+            "ha-latn-ne"              + //  01000 - 1792
+            "ha-latn-ng"              + //  00468 - 1802
+            "haw"                     + //  00075 - 1812
+            "haw-us"                  + //  00475 - 1815
+            "he"                      + //  0000d - 1821
+            "he-il"                   + //  0040d - 1823
+            "hi"                      + //  00039 - 1828
+            "hi-in"                   + //  00439 - 1830
+            "hr"                      + //  0001a - 1835
+            "hr-ba"                   + //  0101a - 1837
+            "hr-hr"                   + //  0041a - 1842
+            "hsb"                     + //  0002e - 1847
+            "hsb-de"                  + //  0042e - 1850
+            "hu"                      + //  0000e - 1856
+            "hu-hu"                   + //  0040e - 1858
+            "hu-hu_technl"            + //  1040e - 1863
+            "hy"                      + //  0002b - 1875
+            "hy-am"                   + //  0042b - 1877
+            "ia"                      + //  01000 - 1882
+            "ia-001"                  + //  01000 - 1884
+            "ia-fr"                   + //  01000 - 1890
+            "ibb"                     + //  00069 - 1895
+            "ibb-ng"                  + //  00469 - 1898
+            "id"                      + //  00021 - 1904
+            "id-id"                   + //  00421 - 1906
+            "ig"                      + //  00070 - 1911
+            "ig-ng"                   + //  00470 - 1913
+            "ii"                      + //  00078 - 1918
+            "ii-cn"                   + //  00478 - 1920
+            "is"                      + //  0000f - 1925
+            "is-is"                   + //  0040f - 1927
+            "it"                      + //  00010 - 1932
+            "it-ch"                   + //  00810 - 1934
+            "it-it"                   + //  00410 - 1939
+            "it-sm"                   + //  01000 - 1944
+            "iu"                      + //  0005d - 1949
+            "iu-cans"                 + //  0785d - 1951
+            "iu-cans-ca"              + //  0045d - 1958
+            "iu-latn"                 + //  07c5d - 1968
+            "iu-latn-ca"              + //  0085d - 1975
+            "ja"                      + //  00011 - 1985
+            "ja-jp"                   + //  00411 - 1987
+            "ja-jp_radstr"            + //  40411 - 1992
+            "jgo"                     + //  01000 - 2004
+            "jgo-cm"                  + //  01000 - 2007
+            "jmc"                     + //  01000 - 2013
+            "jmc-tz"                  + //  01000 - 2016
+            "jv"                      + //  01000 - 2022
+            "jv-java"                 + //  01000 - 2024
+            "jv-java-id"              + //  01000 - 2031
+            "jv-latn"                 + //  01000 - 2041
+            "jv-latn-id"              + //  01000 - 2048
+            "ka"                      + //  00037 - 2058
+            "ka-ge"                   + //  00437 - 2060
+            "ka-ge_modern"            + //  10437 - 2065
+            "kab"                     + //  01000 - 2077
+            "kab-dz"                  + //  01000 - 2080
+            "kam"                     + //  01000 - 2086
+            "kam-ke"                  + //  01000 - 2089
+            "kde"                     + //  01000 - 2095
+            "kde-tz"                  + //  01000 - 2098
+            "kea"                     + //  01000 - 2104
+            "kea-cv"                  + //  01000 - 2107
+            "khq"                     + //  01000 - 2113
+            "khq-ml"                  + //  01000 - 2116
+            "ki"                      + //  01000 - 2122
+            "ki-ke"                   + //  01000 - 2124
+            "kk"                      + //  0003f - 2129
+            "kk-kz"                   + //  0043f - 2131
+            "kkj"                     + //  01000 - 2136
+            "kkj-cm"                  + //  01000 - 2139
+            "kl"                      + //  0006f - 2145
+            "kl-gl"                   + //  0046f - 2147
+            "kln"                     + //  01000 - 2152
+            "kln-ke"                  + //  01000 - 2155
+            "km"                      + //  00053 - 2161
+            "km-kh"                   + //  00453 - 2163
+            "kn"                      + //  0004b - 2168
+            "kn-in"                   + //  0044b - 2170
+            "ko"                      + //  00012 - 2175
+            "ko-kp"                   + //  01000 - 2177
+            "ko-kr"                   + //  00412 - 2182
+            "kok"                     + //  00057 - 2187
+            "kok-in"                  + //  00457 - 2190
+            "kr"                      + //  00071 - 2196
+            "kr-ng"                   + //  00471 - 2198
+            "ks"                      + //  00060 - 2203
+            "ks-arab"                 + //  00460 - 2205
+            "ks-arab-in"              + //  01000 - 2212
+            "ks-deva"                 + //  01000 - 2222
+            "ks-deva-in"              + //  00860 - 2229
+            "ksb"                     + //  01000 - 2239
+            "ksb-tz"                  + //  01000 - 2242
+            "ksf"                     + //  01000 - 2248
+            "ksf-cm"                  + //  01000 - 2251
+            "ksh"                     + //  01000 - 2257
+            "ksh-de"                  + //  01000 - 2260
+            "ku"                      + //  00092 - 2266
+            "ku-arab"                 + //  07c92 - 2268
+            "ku-arab-iq"              + //  00492 - 2275
+            "ku-arab-ir"              + //  01000 - 2285
+            "kw"                      + //  01000 - 2295
+            "kw-gb"                   + //  01000 - 2297
+            "ky"                      + //  00040 - 2302
+            "ky-kg"                   + //  00440 - 2304
+            "la"                      + //  00076 - 2309
+            "la-001"                  + //  00476 - 2311
+            "lag"                     + //  01000 - 2317
+            "lag-tz"                  + //  01000 - 2320
+            "lb"                      + //  0006e - 2326
+            "lb-lu"                   + //  0046e - 2328
+            "lg"                      + //  01000 - 2333
+            "lg-ug"                   + //  01000 - 2335
+            "lkt"                     + //  01000 - 2340
+            "lkt-us"                  + //  01000 - 2343
+            "ln"                      + //  01000 - 2349
+            "ln-ao"                   + //  01000 - 2351
+            "ln-cd"                   + //  01000 - 2356
+            "ln-cf"                   + //  01000 - 2361
+            "ln-cg"                   + //  01000 - 2366
+            "lo"                      + //  00054 - 2371
+            "lo-la"                   + //  00454 - 2373
+            "lrc-iq"                  + //  01000 - 2378
+            "lrc-ir"                  + //  01000 - 2384
+            "lt"                      + //  00027 - 2390
+            "lt-lt"                   + //  00427 - 2392
+            "lu"                      + //  01000 - 2397
+            "lu-cd"                   + //  01000 - 2399
+            "luo"                     + //  01000 - 2404
+            "luo-ke"                  + //  01000 - 2407
+            "luy"                     + //  01000 - 2413
+            "luy-ke"                  + //  01000 - 2416
+            "lv"                      + //  00026 - 2422
+            "lv-lv"                   + //  00426 - 2424
+            "mas"                     + //  01000 - 2429
+            "mas-ke"                  + //  01000 - 2432
+            "mas-tz"                  + //  01000 - 2438
+            "mer"                     + //  01000 - 2444
+            "mer-ke"                  + //  01000 - 2447
+            "mfe"                     + //  01000 - 2453
+            "mfe-mu"                  + //  01000 - 2456
+            "mg"                      + //  01000 - 2462
+            "mg-mg"                   + //  01000 - 2464
+            "mgh"                     + //  01000 - 2469
+            "mgh-mz"                  + //  01000 - 2472
+            "mgo"                     + //  01000 - 2478
+            "mgo-cm"                  + //  01000 - 2481
+            "mi"                      + //  00081 - 2487
+            "mi-nz"                   + //  00481 - 2489
+            "mk"                      + //  0002f - 2494
+            "mk-mk"                   + //  0042f - 2496
+            "ml"                      + //  0004c - 2501
+            "ml-in"                   + //  0044c - 2503
+            "mn"                      + //  00050 - 2508
+            "mn-cyrl"                 + //  07850 - 2510
+            "mn-mn"                   + //  00450 - 2517
+            "mn-mong"                 + //  07c50 - 2522
+            "mn-mong-cn"              + //  00850 - 2529
+            "mn-mong-mn"              + //  00c50 - 2539
+            "mni"                     + //  00058 - 2549
+            "mni-in"                  + //  00458 - 2552
+            "moh"                     + //  0007c - 2558
+            "moh-ca"                  + //  0047c - 2561
+            "mr"                      + //  0004e - 2567
+            "mr-in"                   + //  0044e - 2569
+            "ms"                      + //  0003e - 2574
+            "ms-bn"                   + //  0083e - 2576
+            "ms-my"                   + //  0043e - 2581
+            "ms-sg"                   + //  01000 - 2586
+            "mt"                      + //  0003a - 2591
+            "mt-mt"                   + //  0043a - 2593
+            "mua"                     + //  01000 - 2598
+            "mua-cm"                  + //  01000 - 2601
+            "my"                      + //  00055 - 2607
+            "my-mm"                   + //  00455 - 2609
+            "mzn-ir"                  + //  01000 - 2614
+            "naq"                     + //  01000 - 2620
+            "naq-na"                  + //  01000 - 2623
+            "nb"                      + //  07c14 - 2629
+            "nb-no"                   + //  00414 - 2631
+            "nb-sj"                   + //  01000 - 2636
+            "nd"                      + //  01000 - 2641
+            "nd-zw"                   + //  01000 - 2643
+            "nds-de"                  + //  01000 - 2648
+            "nds-nl"                  + //  01000 - 2654
+            "ne"                      + //  00061 - 2660
+            "ne-in"                   + //  00861 - 2662
+            "ne-np"                   + //  00461 - 2667
+            "nl"                      + //  00013 - 2672
+            "nl-aw"                   + //  01000 - 2674
+            "nl-be"                   + //  00813 - 2679
+            "nl-bq"                   + //  01000 - 2684
+            "nl-cw"                   + //  01000 - 2689
+            "nl-nl"                   + //  00413 - 2694
+            "nl-sr"                   + //  01000 - 2699
+            "nl-sx"                   + //  01000 - 2704
+            "nmg"                     + //  01000 - 2709
+            "nmg-cm"                  + //  01000 - 2712
+            "nn"                      + //  07814 - 2718
+            "nn-no"                   + //  00814 - 2720
+            "nnh"                     + //  01000 - 2725
+            "nnh-cm"                  + //  01000 - 2728
+            "no"                      + //  00014 - 2734
+            "nqo"                     + //  01000 - 2736
+            "nqo-gn"                  + //  01000 - 2739
+            "nr"                      + //  01000 - 2745
+            "nr-za"                   + //  01000 - 2747
+            "nso"                     + //  0006c - 2752
+            "nso-za"                  + //  0046c - 2755
+            "nus"                     + //  01000 - 2761
+            "nus-ss"                  + //  01000 - 2764
+            "nyn"                     + //  01000 - 2770
+            "nyn-ug"                  + //  01000 - 2773
+            "oc"                      + //  00082 - 2779
+            "oc-fr"                   + //  00482 - 2781
+            "om"                      + //  00072 - 2786
+            "om-et"                   + //  00472 - 2788
+            "om-ke"                   + //  01000 - 2793
+            "or"                      + //  00048 - 2798
+            "or-in"                   + //  00448 - 2800
+            "os"                      + //  01000 - 2805
+            "os-ge"                   + //  01000 - 2807
+            "os-ru"                   + //  01000 - 2812
+            "pa"                      + //  00046 - 2817
+            "pa-arab"                 + //  07c46 - 2819
+            "pa-arab-pk"              + //  00846 - 2826
+            "pa-in"                   + //  00446 - 2836
+            "pap"                     + //  00079 - 2841
+            "pap-029"                 + //  00479 - 2844
+            "pl"                      + //  00015 - 2851
+            "pl-pl"                   + //  00415 - 2853
+            "prg-001"                 + //  01000 - 2858
+            "prs"                     + //  0008c - 2865
+            "prs-af"                  + //  0048c - 2868
+            "ps"                      + //  00063 - 2874
+            "ps-af"                   + //  00463 - 2876
+            "pt"                      + //  00016 - 2881
+            "pt-ao"                   + //  01000 - 2883
+            "pt-br"                   + //  00416 - 2888
+            "pt-ch"                   + //  01000 - 2893
+            "pt-cv"                   + //  01000 - 2898
+            "pt-gq"                   + //  01000 - 2903
+            "pt-gw"                   + //  01000 - 2908
+            "pt-lu"                   + //  01000 - 2913
+            "pt-mo"                   + //  01000 - 2918
+            "pt-mz"                   + //  01000 - 2923
+            "pt-pt"                   + //  00816 - 2928
+            "pt-st"                   + //  01000 - 2933
+            "pt-tl"                   + //  01000 - 2938
+            "qps-latn-x-sh"           + //  00901 - 2943
+            "qps-ploc"                + //  00501 - 2956
+            "qps-ploca"               + //  005fe - 2964
+            "qps-plocm"               + //  009ff - 2973
+            "quc"                     + //  00086 - 2982
+            "quc-latn"                + //  07c86 - 2985
+            "quc-latn-gt"             + //  00486 - 2993
+            "quz"                     + //  0006b - 3004
+            "quz-bo"                  + //  0046b - 3007
+            "quz-ec"                  + //  0086b - 3013
+            "quz-pe"                  + //  00c6b - 3019
+            "rm"                      + //  00017 - 3025
+            "rm-ch"                   + //  00417 - 3027
+            "rn"                      + //  01000 - 3032
+            "rn-bi"                   + //  01000 - 3034
+            "ro"                      + //  00018 - 3039
+            "ro-md"                   + //  00818 - 3041
+            "ro-ro"                   + //  00418 - 3046
+            "rof"                     + //  01000 - 3051
+            "rof-tz"                  + //  01000 - 3054
+            "ru"                      + //  00019 - 3060
+            "ru-by"                   + //  01000 - 3062
+            "ru-kg"                   + //  01000 - 3067
+            "ru-kz"                   + //  01000 - 3072
+            "ru-md"                   + //  00819 - 3077
+            "ru-ru"                   + //  00419 - 3082
+            "ru-ua"                   + //  01000 - 3087
+            "rw"                      + //  00087 - 3092
+            "rw-rw"                   + //  00487 - 3094
+            "rwk"                     + //  01000 - 3099
+            "rwk-tz"                  + //  01000 - 3102
+            "sa"                      + //  0004f - 3108
+            "sa-in"                   + //  0044f - 3110
+            "sah"                     + //  00085 - 3115
+            "sah-ru"                  + //  00485 - 3118
+            "saq"                     + //  01000 - 3124
+            "saq-ke"                  + //  01000 - 3127
+            "sbp"                     + //  01000 - 3133
+            "sbp-tz"                  + //  01000 - 3136
+            "sd"                      + //  00059 - 3142
+            "sd-arab"                 + //  07c59 - 3144
+            "sd-arab-pk"              + //  00859 - 3151
+            "sd-deva"                 + //  01000 - 3161
+            "sd-deva-in"              + //  00459 - 3168
+            "se"                      + //  0003b - 3178
+            "se-fi"                   + //  00c3b - 3180
+            "se-no"                   + //  0043b - 3185
+            "se-se"                   + //  0083b - 3190
+            "seh"                     + //  01000 - 3195
+            "seh-mz"                  + //  01000 - 3198
+            "ses"                     + //  01000 - 3204
+            "ses-ml"                  + //  01000 - 3207
+            "sg"                      + //  01000 - 3213
+            "sg-cf"                   + //  01000 - 3215
+            "shi"                     + //  01000 - 3220
+            "shi-latn"                + //  01000 - 3223
+            "shi-latn-ma"             + //  01000 - 3231
+            "shi-tfng"                + //  01000 - 3242
+            "shi-tfng-ma"             + //  01000 - 3250
+            "si"                      + //  0005b - 3261
+            "si-lk"                   + //  0045b - 3263
+            "sk"                      + //  0001b - 3268
+            "sk-sk"                   + //  0041b - 3270
+            "sl"                      + //  00024 - 3275
+            "sl-si"                   + //  00424 - 3277
+            "sma"                     + //  0783b - 3282
+            "sma-no"                  + //  0183b - 3285
+            "sma-se"                  + //  01c3b - 3291
+            "smj"                     + //  07c3b - 3297
+            "smj-no"                  + //  0103b - 3300
+            "smj-se"                  + //  0143b - 3306
+            "smn"                     + //  0703b - 3312
+            "smn-fi"                  + //  0243b - 3315
+            "sms"                     + //  0743b - 3321
+            "sms-fi"                  + //  0203b - 3324
+            "sn"                      + //  01000 - 3330
+            "sn-latn"                 + //  01000 - 3332
+            "sn-latn-zw"              + //  01000 - 3339
+            "so"                      + //  00077 - 3349
+            "so-dj"                   + //  01000 - 3351
+            "so-et"                   + //  01000 - 3356
+            "so-ke"                   + //  01000 - 3361
+            "so-so"                   + //  00477 - 3366
+            "sq"                      + //  0001c - 3371
+            "sq-al"                   + //  0041c - 3373
+            "sq-mk"                   + //  01000 - 3378
+            "sq-xk"                   + //  01000 - 3383
+            "sr"                      + //  07c1a - 3388
+            "sr-cyrl"                 + //  06c1a - 3390
+            "sr-cyrl-ba"              + //  01c1a - 3397
+            "sr-cyrl-cs"              + //  00c1a - 3407
+            "sr-cyrl-me"              + //  0301a - 3417
+            "sr-cyrl-rs"              + //  0281a - 3427
+            "sr-cyrl-xk"              + //  01000 - 3437
+            "sr-latn"                 + //  0701a - 3447
+            "sr-latn-ba"              + //  0181a - 3454
+            "sr-latn-cs"              + //  0081a - 3464
+            "sr-latn-me"              + //  02c1a - 3474
+            "sr-latn-rs"              + //  0241a - 3484
+            "sr-latn-xk"              + //  01000 - 3494
+            "ss"                      + //  01000 - 3504
+            "ss-sz"                   + //  01000 - 3506
+            "ss-za"                   + //  01000 - 3511
+            "ssy"                     + //  01000 - 3516
+            "ssy-er"                  + //  01000 - 3519
+            "st"                      + //  00030 - 3525
+            "st-ls"                   + //  01000 - 3527
+            "st-za"                   + //  00430 - 3532
+            "sv"                      + //  0001d - 3537
+            "sv-ax"                   + //  01000 - 3539
+            "sv-fi"                   + //  0081d - 3544
+            "sv-se"                   + //  0041d - 3549
+            "sw"                      + //  00041 - 3554
+            "sw-cd"                   + //  01000 - 3556
+            "sw-ke"                   + //  00441 - 3561
+            "sw-tz"                   + //  01000 - 3566
+            "sw-ug"                   + //  01000 - 3571
+            "swc"                     + //  01000 - 3576
+            "swc-cd"                  + //  01000 - 3579
+            "syr"                     + //  0005a - 3585
+            "syr-sy"                  + //  0045a - 3588
+            "ta"                      + //  00049 - 3594
+            "ta-in"                   + //  00449 - 3596
+            "ta-lk"                   + //  00849 - 3601
+            "ta-my"                   + //  01000 - 3606
+            "ta-sg"                   + //  01000 - 3611
+            "te"                      + //  0004a - 3616
+            "te-in"                   + //  0044a - 3618
+            "teo"                     + //  01000 - 3623
+            "teo-ke"                  + //  01000 - 3626
+            "teo-ug"                  + //  01000 - 3632
+            "tg"                      + //  00028 - 3638
+            "tg-cyrl"                 + //  07c28 - 3640
+            "tg-cyrl-tj"              + //  00428 - 3647
+            "th"                      + //  0001e - 3657
+            "th-th"                   + //  0041e - 3659
+            "ti"                      + //  00073 - 3664
+            "ti-er"                   + //  00873 - 3666
+            "ti-et"                   + //  00473 - 3671
+            "tig"                     + //  01000 - 3676
+            "tig-er"                  + //  01000 - 3679
+            "tk"                      + //  00042 - 3685
+            "tk-tm"                   + //  00442 - 3687
+            "tn"                      + //  00032 - 3692
+            "tn-bw"                   + //  00832 - 3694
+            "tn-za"                   + //  00432 - 3699
+            "to"                      + //  01000 - 3704
+            "to-to"                   + //  01000 - 3706
+            "tr"                      + //  0001f - 3711
+            "tr-cy"                   + //  01000 - 3713
+            "tr-tr"                   + //  0041f - 3718
+            "ts"                      + //  00031 - 3723
+            "ts-za"                   + //  00431 - 3725
+            "tt"                      + //  00044 - 3730
+            "tt-ru"                   + //  00444 - 3732
+            "twq"                     + //  01000 - 3737
+            "twq-ne"                  + //  01000 - 3740
+            "tzm"                     + //  0005f - 3746
+            "tzm-arab"                + //  01000 - 3749
+            "tzm-arab-ma"             + //  0045f - 3757
+            "tzm-latn"                + //  07c5f - 3768
+            "tzm-latn-dz"             + //  0085f - 3776
+            "tzm-latn-ma"             + //  01000 - 3787
+            "tzm-tfng"                + //  0785f - 3798
+            "tzm-tfng-ma"             + //  0105f - 3806
+            "ug"                      + //  00080 - 3817
+            "ug-cn"                   + //  00480 - 3819
+            "uk"                      + //  00022 - 3824
+            "uk-ua"                   + //  00422 - 3826
+            "ur"                      + //  00020 - 3831
+            "ur-in"                   + //  00820 - 3833
+            "ur-pk"                   + //  00420 - 3838
+            "uz"                      + //  00043 - 3843
+            "uz-arab"                 + //  01000 - 3845
+            "uz-arab-af"              + //  01000 - 3852
+            "uz-cyrl"                 + //  07843 - 3862
+            "uz-cyrl-uz"              + //  00843 - 3869
+            "uz-latn"                 + //  07c43 - 3879
+            "uz-latn-uz"              + //  00443 - 3886
+            "vai"                     + //  01000 - 3896
+            "vai-latn"                + //  01000 - 3899
+            "vai-latn-lr"             + //  01000 - 3907
+            "vai-vaii"                + //  01000 - 3918
+            "vai-vaii-lr"             + //  01000 - 3926
+            "ve"                      + //  00033 - 3937
+            "ve-za"                   + //  00433 - 3939
+            "vi"                      + //  0002a - 3944
+            "vi-vn"                   + //  0042a - 3946
+            "vo"                      + //  01000 - 3951
+            "vo-001"                  + //  01000 - 3953
+            "vun"                     + //  01000 - 3959
+            "vun-tz"                  + //  01000 - 3962
+            "wae"                     + //  01000 - 3968
+            "wae-ch"                  + //  01000 - 3971
+            "wal"                     + //  01000 - 3977
+            "wal-et"                  + //  01000 - 3980
+            "wo"                      + //  00088 - 3986
+            "wo-sn"                   + //  00488 - 3988
+            "x-iv_mathan"             + //  1007f - 3993
+            "xh"                      + //  00034 - 4004
+            "xh-za"                   + //  00434 - 4006
+            "xog"                     + //  01000 - 4011
+            "xog-ug"                  + //  01000 - 4014
+            "yav"                     + //  01000 - 4020
+            "yav-cm"                  + //  01000 - 4023
+            "yi"                      + //  0003d - 4029
+            "yi-001"                  + //  0043d - 4031
+            "yo"                      + //  0006a - 4037
+            "yo-bj"                   + //  01000 - 4039
+            "yo-ng"                   + //  0046a - 4044
+            "yue-hk"                  + //  01000 - 4049
+            "zgh"                     + //  01000 - 4055
+            "zgh-tfng"                + //  01000 - 4058
+            "zgh-tfng-ma"             + //  01000 - 4066
+            "zh"                      + //  07804 - 4077
+            "zh-chs"                  + //  00004 - 4079
+            "zh-cht"                  + //  07c04 - 4085
+            "zh-cn"                   + //  00804 - 4091
+            "zh-cn_phoneb"            + //  50804 - 4096
+            "zh-cn_stroke"            + //  20804 - 4108
+            "zh-hans"                 + //  00004 - 4120
+            "zh-hans-hk"              + //  01000 - 4127
+            "zh-hans-mo"              + //  01000 - 4137
+            "zh-hant"                 + //  07c04 - 4147
+            "zh-hk"                   + //  00c04 - 4154
+            "zh-hk_radstr"            + //  40c04 - 4159
+            "zh-mo"                   + //  01404 - 4171
+            "zh-mo_radstr"            + //  41404 - 4176
+            "zh-mo_stroke"            + //  21404 - 4188
+            "zh-sg"                   + //  01004 - 4200
+            "zh-sg_phoneb"            + //  51004 - 4205
+            "zh-sg_stroke"            + //  21004 - 4217
+            "zh-tw"                   + //  00404 - 4229
+            "zh-tw_pronun"            + //  30404 - 4234
+            "zh-tw_radstr"            + //  40404 - 4246
+            "zu"                      + //  00035 - 4258
+            "zu-za";                    //  00435 - 4260
+        
+        // s_localeNamesIndices contains the start index of every culture name in the string
+        // s_localeNames. We infer the length of each string by looking at the start index
+        // of the next string.
+        private static readonly int[] s_localeNamesIndices = new int[]
+        {
+            // c_localeNames index, // index to this array - culture name
+            0   , // 0    - aa
+            2   , // 1    - aa-dj
+            7   , // 2    - aa-er
+            12  , // 3    - aa-et
+            17  , // 4    - af
+            19  , // 5    - af-na
+            24  , // 6    - af-za
+            29  , // 7    - agq
+            32  , // 8    - agq-cm
+            38  , // 9    - ak
+            40  , // 10   - ak-gh
+            45  , // 11   - am
+            47  , // 12   - am-et
+            52  , // 13   - ar
+            54  , // 14   - ar-001
+            60  , // 15   - ar-ae
+            65  , // 16   - ar-bh
+            70  , // 17   - ar-dj
+            75  , // 18   - ar-dz
+            80  , // 19   - ar-eg
+            85  , // 20   - ar-er
+            90  , // 21   - ar-il
+            95  , // 22   - ar-iq
+            100 , // 23   - ar-jo
+            105 , // 24   - ar-km
+            110 , // 25   - ar-kw
+            115 , // 26   - ar-lb
+            120 , // 27   - ar-ly
+            125 , // 28   - ar-ma
+            130 , // 29   - ar-mr
+            135 , // 30   - ar-om
+            140 , // 31   - ar-ps
+            145 , // 32   - ar-qa
+            150 , // 33   - ar-sa
+            155 , // 34   - ar-sd
+            160 , // 35   - ar-so
+            165 , // 36   - ar-ss
+            170 , // 37   - ar-sy
+            175 , // 38   - ar-td
+            180 , // 39   - ar-tn
+            185 , // 40   - ar-ye
+            190 , // 41   - arn
+            193 , // 42   - arn-cl
+            199 , // 43   - as
+            201 , // 44   - as-in
+            206 , // 45   - asa
+            209 , // 46   - asa-tz
+            215 , // 47   - ast
+            218 , // 48   - ast-es
+            224 , // 49   - az
+            226 , // 50   - az-cyrl
+            233 , // 51   - az-cyrl-az
+            243 , // 52   - az-latn
+            250 , // 53   - az-latn-az
+            260 , // 54   - ba
+            262 , // 55   - ba-ru
+            267 , // 56   - bas
+            270 , // 57   - bas-cm
+            276 , // 58   - be
+            278 , // 59   - be-by
+            283 , // 60   - bem
+            286 , // 61   - bem-zm
+            292 , // 62   - bez
+            295 , // 63   - bez-tz
+            301 , // 64   - bg
+            303 , // 65   - bg-bg
+            308 , // 66   - bin
+            311 , // 67   - bin-ng
+            317 , // 68   - bm
+            319 , // 69   - bm-latn
+            326 , // 70   - bm-latn-ml
+            336 , // 71   - bn
+            338 , // 72   - bn-bd
+            343 , // 73   - bn-in
+            348 , // 74   - bo
+            350 , // 75   - bo-cn
+            355 , // 76   - bo-in
+            360 , // 77   - br
+            362 , // 78   - br-fr
+            367 , // 79   - brx
+            370 , // 80   - brx-in
+            376 , // 81   - bs
+            378 , // 82   - bs-cyrl
+            385 , // 83   - bs-cyrl-ba
+            395 , // 84   - bs-latn
+            402 , // 85   - bs-latn-ba
+            412 , // 86   - byn
+            415 , // 87   - byn-er
+            421 , // 88   - ca
+            423 , // 89   - ca-ad
+            428 , // 90   - ca-es
+            433 , // 91   - ca-es-valencia
+            447 , // 92   - ca-fr
+            452 , // 93   - ca-it
+            457 , // 94   - ce-ru
+            462 , // 95   - cgg
+            465 , // 96   - cgg-ug
+            471 , // 97   - chr
+            474 , // 98   - chr-cher
+            482 , // 99   - chr-cher-us
+            493 , // 100  - co
+            495 , // 101  - co-fr
+            500 , // 102  - cs
+            502 , // 103  - cs-cz
+            507 , // 104  - cu-ru
+            512 , // 105  - cy
+            514 , // 106  - cy-gb
+            519 , // 107  - da
+            521 , // 108  - da-dk
+            526 , // 109  - da-gl
+            531 , // 110  - dav
+            534 , // 111  - dav-ke
+            540 , // 112  - de
+            542 , // 113  - de-at
+            547 , // 114  - de-be
+            552 , // 115  - de-ch
+            557 , // 116  - de-de
+            562 , // 117  - de-de_phoneb
+            574 , // 118  - de-it
+            579 , // 119  - de-li
+            584 , // 120  - de-lu
+            589 , // 121  - dje
+            592 , // 122  - dje-ne
+            598 , // 123  - dsb
+            601 , // 124  - dsb-de
+            607 , // 125  - dua
+            610 , // 126  - dua-cm
+            616 , // 127  - dv
+            618 , // 128  - dv-mv
+            623 , // 129  - dyo
+            626 , // 130  - dyo-sn
+            632 , // 131  - dz
+            634 , // 132  - dz-bt
+            639 , // 133  - ebu
+            642 , // 134  - ebu-ke
+            648 , // 135  - ee
+            650 , // 136  - ee-gh
+            655 , // 137  - ee-tg
+            660 , // 138  - el
+            662 , // 139  - el-cy
+            667 , // 140  - el-gr
+            672 , // 141  - en
+            674 , // 142  - en-001
+            680 , // 143  - en-029
+            686 , // 144  - en-150
+            692 , // 145  - en-ag
+            697 , // 146  - en-ai
+            702 , // 147  - en-as
+            707 , // 148  - en-at
+            712 , // 149  - en-au
+            717 , // 150  - en-bb
+            722 , // 151  - en-be
+            727 , // 152  - en-bi
+            732 , // 153  - en-bm
+            737 , // 154  - en-bs
+            742 , // 155  - en-bw
+            747 , // 156  - en-bz
+            752 , // 157  - en-ca
+            757 , // 158  - en-cc
+            762 , // 159  - en-ch
+            767 , // 160  - en-ck
+            772 , // 161  - en-cm
+            777 , // 162  - en-cx
+            782 , // 163  - en-cy
+            787 , // 164  - en-de
+            792 , // 165  - en-dk
+            797 , // 166  - en-dm
+            802 , // 167  - en-er
+            807 , // 168  - en-fi
+            812 , // 169  - en-fj
+            817 , // 170  - en-fk
+            822 , // 171  - en-fm
+            827 , // 172  - en-gb
+            832 , // 173  - en-gd
+            837 , // 174  - en-gg
+            842 , // 175  - en-gh
+            847 , // 176  - en-gi
+            852 , // 177  - en-gm
+            857 , // 178  - en-gu
+            862 , // 179  - en-gy
+            867 , // 180  - en-hk
+            872 , // 181  - en-id
+            877 , // 182  - en-ie
+            882 , // 183  - en-il
+            887 , // 184  - en-im
+            892 , // 185  - en-in
+            897 , // 186  - en-io
+            902 , // 187  - en-je
+            907 , // 188  - en-jm
+            912 , // 189  - en-ke
+            917 , // 190  - en-ki
+            922 , // 191  - en-kn
+            927 , // 192  - en-ky
+            932 , // 193  - en-lc
+            937 , // 194  - en-lr
+            942 , // 195  - en-ls
+            947 , // 196  - en-mg
+            952 , // 197  - en-mh
+            957 , // 198  - en-mo
+            962 , // 199  - en-mp
+            967 , // 200  - en-ms
+            972 , // 201  - en-mt
+            977 , // 202  - en-mu
+            982 , // 203  - en-mw
+            987 , // 204  - en-my
+            992 , // 205  - en-na
+            997 , // 206  - en-nf
+            1002, // 207  - en-ng
+            1007, // 208  - en-nl
+            1012, // 209  - en-nr
+            1017, // 210  - en-nu
+            1022, // 211  - en-nz
+            1027, // 212  - en-pg
+            1032, // 213  - en-ph
+            1037, // 214  - en-pk
+            1042, // 215  - en-pn
+            1047, // 216  - en-pr
+            1052, // 217  - en-pw
+            1057, // 218  - en-rw
+            1062, // 219  - en-sb
+            1067, // 220  - en-sc
+            1072, // 221  - en-sd
+            1077, // 222  - en-se
+            1082, // 223  - en-sg
+            1087, // 224  - en-sh
+            1092, // 225  - en-si
+            1097, // 226  - en-sl
+            1102, // 227  - en-ss
+            1107, // 228  - en-sx
+            1112, // 229  - en-sz
+            1117, // 230  - en-tc
+            1122, // 231  - en-tk
+            1127, // 232  - en-to
+            1132, // 233  - en-tt
+            1137, // 234  - en-tv
+            1142, // 235  - en-tz
+            1147, // 236  - en-ug
+            1152, // 237  - en-um
+            1157, // 238  - en-us
+            1162, // 239  - en-vc
+            1167, // 240  - en-vg
+            1172, // 241  - en-vi
+            1177, // 242  - en-vu
+            1182, // 243  - en-ws
+            1187, // 244  - en-za
+            1192, // 245  - en-zm
+            1197, // 246  - en-zw
+            1202, // 247  - eo
+            1204, // 248  - eo-001
+            1210, // 249  - es
+            1212, // 250  - es-419
+            1218, // 251  - es-ar
+            1223, // 252  - es-bo
+            1228, // 253  - es-br
+            1233, // 254  - es-cl
+            1238, // 255  - es-co
+            1243, // 256  - es-cr
+            1248, // 257  - es-cu
+            1253, // 258  - es-do
+            1258, // 259  - es-ec
+            1263, // 260  - es-es
+            1268, // 261  - es-es_tradnl
+            1280, // 262  - es-gq
+            1285, // 263  - es-gt
+            1290, // 264  - es-hn
+            1295, // 265  - es-mx
+            1300, // 266  - es-ni
+            1305, // 267  - es-pa
+            1310, // 268  - es-pe
+            1315, // 269  - es-ph
+            1320, // 270  - es-pr
+            1325, // 271  - es-py
+            1330, // 272  - es-sv
+            1335, // 273  - es-us
+            1340, // 274  - es-uy
+            1345, // 275  - es-ve
+            1350, // 276  - et
+            1352, // 277  - et-ee
+            1357, // 278  - eu
+            1359, // 279  - eu-es
+            1364, // 280  - ewo
+            1367, // 281  - ewo-cm
+            1373, // 282  - fa
+            1375, // 283  - fa-ir
+            1380, // 284  - ff
+            1382, // 285  - ff-cm
+            1387, // 286  - ff-gn
+            1392, // 287  - ff-latn
+            1399, // 288  - ff-latn-sn
+            1409, // 289  - ff-mr
+            1414, // 290  - ff-ng
+            1419, // 291  - fi
+            1421, // 292  - fi-fi
+            1426, // 293  - fil
+            1429, // 294  - fil-ph
+            1435, // 295  - fo
+            1437, // 296  - fo-dk
+            1442, // 297  - fo-fo
+            1447, // 298  - fr
+            1449, // 299  - fr-029
+            1455, // 300  - fr-be
+            1460, // 301  - fr-bf
+            1465, // 302  - fr-bi
+            1470, // 303  - fr-bj
+            1475, // 304  - fr-bl
+            1480, // 305  - fr-ca
+            1485, // 306  - fr-cd
+            1490, // 307  - fr-cf
+            1495, // 308  - fr-cg
+            1500, // 309  - fr-ch
+            1505, // 310  - fr-ci
+            1510, // 311  - fr-cm
+            1515, // 312  - fr-dj
+            1520, // 313  - fr-dz
+            1525, // 314  - fr-fr
+            1530, // 315  - fr-ga
+            1535, // 316  - fr-gf
+            1540, // 317  - fr-gn
+            1545, // 318  - fr-gp
+            1550, // 319  - fr-gq
+            1555, // 320  - fr-ht
+            1560, // 321  - fr-km
+            1565, // 322  - fr-lu
+            1570, // 323  - fr-ma
+            1575, // 324  - fr-mc
+            1580, // 325  - fr-mf
+            1585, // 326  - fr-mg
+            1590, // 327  - fr-ml
+            1595, // 328  - fr-mq
+            1600, // 329  - fr-mr
+            1605, // 330  - fr-mu
+            1610, // 331  - fr-nc
+            1615, // 332  - fr-ne
+            1620, // 333  - fr-pf
+            1625, // 334  - fr-pm
+            1630, // 335  - fr-re
+            1635, // 336  - fr-rw
+            1640, // 337  - fr-sc
+            1645, // 338  - fr-sn
+            1650, // 339  - fr-sy
+            1655, // 340  - fr-td
+            1660, // 341  - fr-tg
+            1665, // 342  - fr-tn
+            1670, // 343  - fr-vu
+            1675, // 344  - fr-wf
+            1680, // 345  - fr-yt
+            1685, // 346  - fur
+            1688, // 347  - fur-it
+            1694, // 348  - fy
+            1696, // 349  - fy-nl
+            1701, // 350  - ga
+            1703, // 351  - ga-ie
+            1708, // 352  - gd
+            1710, // 353  - gd-gb
+            1715, // 354  - gl
+            1717, // 355  - gl-es
+            1722, // 356  - gn
+            1724, // 357  - gn-py
+            1729, // 358  - gsw
+            1732, // 359  - gsw-ch
+            1738, // 360  - gsw-fr
+            1744, // 361  - gsw-li
+            1750, // 362  - gu
+            1752, // 363  - gu-in
+            1757, // 364  - guz
+            1760, // 365  - guz-ke
+            1766, // 366  - gv
+            1768, // 367  - gv-im
+            1773, // 368  - ha
+            1775, // 369  - ha-latn
+            1782, // 370  - ha-latn-gh
+            1792, // 371  - ha-latn-ne
+            1802, // 372  - ha-latn-ng
+            1812, // 373  - haw
+            1815, // 374  - haw-us
+            1821, // 375  - he
+            1823, // 376  - he-il
+            1828, // 377  - hi
+            1830, // 378  - hi-in
+            1835, // 379  - hr
+            1837, // 380  - hr-ba
+            1842, // 381  - hr-hr
+            1847, // 382  - hsb
+            1850, // 383  - hsb-de
+            1856, // 384  - hu
+            1858, // 385  - hu-hu
+            1863, // 386  - hu-hu_technl
+            1875, // 387  - hy
+            1877, // 388  - hy-am
+            1882, // 389  - ia
+            1884, // 390  - ia-001
+            1890, // 391  - ia-fr
+            1895, // 392  - ibb
+            1898, // 393  - ibb-ng
+            1904, // 394  - id
+            1906, // 395  - id-id
+            1911, // 396  - ig
+            1913, // 397  - ig-ng
+            1918, // 398  - ii
+            1920, // 399  - ii-cn
+            1925, // 400  - is
+            1927, // 401  - is-is
+            1932, // 402  - it
+            1934, // 403  - it-ch
+            1939, // 404  - it-it
+            1944, // 405  - it-sm
+            1949, // 406  - iu
+            1951, // 407  - iu-cans
+            1958, // 408  - iu-cans-ca
+            1968, // 409  - iu-latn
+            1975, // 410  - iu-latn-ca
+            1985, // 411  - ja
+            1987, // 412  - ja-jp
+            1992, // 413  - ja-jp_radstr
+            2004, // 414  - jgo
+            2007, // 415  - jgo-cm
+            2013, // 416  - jmc
+            2016, // 417  - jmc-tz
+            2022, // 418  - jv
+            2024, // 419  - jv-java
+            2031, // 420  - jv-java-id
+            2041, // 421  - jv-latn
+            2048, // 422  - jv-latn-id
+            2058, // 423  - ka
+            2060, // 424  - ka-ge
+            2065, // 425  - ka-ge_modern
+            2077, // 426  - kab
+            2080, // 427  - kab-dz
+            2086, // 428  - kam
+            2089, // 429  - kam-ke
+            2095, // 430  - kde
+            2098, // 431  - kde-tz
+            2104, // 432  - kea
+            2107, // 433  - kea-cv
+            2113, // 434  - khq
+            2116, // 435  - khq-ml
+            2122, // 436  - ki
+            2124, // 437  - ki-ke
+            2129, // 438  - kk
+            2131, // 439  - kk-kz
+            2136, // 440  - kkj
+            2139, // 441  - kkj-cm
+            2145, // 442  - kl
+            2147, // 443  - kl-gl
+            2152, // 444  - kln
+            2155, // 445  - kln-ke
+            2161, // 446  - km
+            2163, // 447  - km-kh
+            2168, // 448  - kn
+            2170, // 449  - kn-in
+            2175, // 450  - ko
+            2177, // 451  - ko-kp
+            2182, // 452  - ko-kr
+            2187, // 453  - kok
+            2190, // 454  - kok-in
+            2196, // 455  - kr
+            2198, // 456  - kr-ng
+            2203, // 457  - ks
+            2205, // 458  - ks-arab
+            2212, // 459  - ks-arab-in
+            2222, // 460  - ks-deva
+            2229, // 461  - ks-deva-in
+            2239, // 462  - ksb
+            2242, // 463  - ksb-tz
+            2248, // 464  - ksf
+            2251, // 465  - ksf-cm
+            2257, // 466  - ksh
+            2260, // 467  - ksh-de
+            2266, // 468  - ku
+            2268, // 469  - ku-arab
+            2275, // 470  - ku-arab-iq
+            2285, // 471  - ku-arab-ir
+            2295, // 472  - kw
+            2297, // 473  - kw-gb
+            2302, // 474  - ky
+            2304, // 475  - ky-kg
+            2309, // 476  - la
+            2311, // 477  - la-001
+            2317, // 478  - lag
+            2320, // 479  - lag-tz
+            2326, // 480  - lb
+            2328, // 481  - lb-lu
+            2333, // 482  - lg
+            2335, // 483  - lg-ug
+            2340, // 484  - lkt
+            2343, // 485  - lkt-us
+            2349, // 486  - ln
+            2351, // 487  - ln-ao
+            2356, // 488  - ln-cd
+            2361, // 489  - ln-cf
+            2366, // 490  - ln-cg
+            2371, // 491  - lo
+            2373, // 492  - lo-la
+            2378, // 493  - lrc-iq
+            2384, // 494  - lrc-ir
+            2390, // 495  - lt
+            2392, // 496  - lt-lt
+            2397, // 497  - lu
+            2399, // 498  - lu-cd
+            2404, // 499  - luo
+            2407, // 500  - luo-ke
+            2413, // 501  - luy
+            2416, // 502  - luy-ke
+            2422, // 503  - lv
+            2424, // 504  - lv-lv
+            2429, // 505  - mas
+            2432, // 506  - mas-ke
+            2438, // 507  - mas-tz
+            2444, // 508  - mer
+            2447, // 509  - mer-ke
+            2453, // 510  - mfe
+            2456, // 511  - mfe-mu
+            2462, // 512  - mg
+            2464, // 513  - mg-mg
+            2469, // 514  - mgh
+            2472, // 515  - mgh-mz
+            2478, // 516  - mgo
+            2481, // 517  - mgo-cm
+            2487, // 518  - mi
+            2489, // 519  - mi-nz
+            2494, // 520  - mk
+            2496, // 521  - mk-mk
+            2501, // 522  - ml
+            2503, // 523  - ml-in
+            2508, // 524  - mn
+            2510, // 525  - mn-cyrl
+            2517, // 526  - mn-mn
+            2522, // 527  - mn-mong
+            2529, // 528  - mn-mong-cn
+            2539, // 529  - mn-mong-mn
+            2549, // 530  - mni
+            2552, // 531  - mni-in
+            2558, // 532  - moh
+            2561, // 533  - moh-ca
+            2567, // 534  - mr
+            2569, // 535  - mr-in
+            2574, // 536  - ms
+            2576, // 537  - ms-bn
+            2581, // 538  - ms-my
+            2586, // 539  - ms-sg
+            2591, // 540  - mt
+            2593, // 541  - mt-mt
+            2598, // 542  - mua
+            2601, // 543  - mua-cm
+            2607, // 544  - my
+            2609, // 545  - my-mm
+            2614, // 546  - mzn-ir
+            2620, // 547  - naq
+            2623, // 548  - naq-na
+            2629, // 549  - nb
+            2631, // 550  - nb-no
+            2636, // 551  - nb-sj
+            2641, // 552  - nd
+            2643, // 553  - nd-zw
+            2648, // 554  - nds-de
+            2654, // 555  - nds-nl
+            2660, // 556  - ne
+            2662, // 557  - ne-in
+            2667, // 558  - ne-np
+            2672, // 559  - nl
+            2674, // 560  - nl-aw
+            2679, // 561  - nl-be
+            2684, // 562  - nl-bq
+            2689, // 563  - nl-cw
+            2694, // 564  - nl-nl
+            2699, // 565  - nl-sr
+            2704, // 566  - nl-sx
+            2709, // 567  - nmg
+            2712, // 568  - nmg-cm
+            2718, // 569  - nn
+            2720, // 570  - nn-no
+            2725, // 571  - nnh
+            2728, // 572  - nnh-cm
+            2734, // 573  - no
+            2736, // 574  - nqo
+            2739, // 575  - nqo-gn
+            2745, // 576  - nr
+            2747, // 577  - nr-za
+            2752, // 578  - nso
+            2755, // 579  - nso-za
+            2761, // 580  - nus
+            2764, // 581  - nus-ss
+            2770, // 582  - nyn
+            2773, // 583  - nyn-ug
+            2779, // 584  - oc
+            2781, // 585  - oc-fr
+            2786, // 586  - om
+            2788, // 587  - om-et
+            2793, // 588  - om-ke
+            2798, // 589  - or
+            2800, // 590  - or-in
+            2805, // 591  - os
+            2807, // 592  - os-ge
+            2812, // 593  - os-ru
+            2817, // 594  - pa
+            2819, // 595  - pa-arab
+            2826, // 596  - pa-arab-pk
+            2836, // 597  - pa-in
+            2841, // 598  - pap
+            2844, // 599  - pap-029
+            2851, // 600  - pl
+            2853, // 601  - pl-pl
+            2858, // 602  - prg-001
+            2865, // 603  - prs
+            2868, // 604  - prs-af
+            2874, // 605  - ps
+            2876, // 606  - ps-af
+            2881, // 607  - pt
+            2883, // 608  - pt-ao
+            2888, // 609  - pt-br
+            2893, // 610  - pt-ch
+            2898, // 611  - pt-cv
+            2903, // 612  - pt-gq
+            2908, // 613  - pt-gw
+            2913, // 614  - pt-lu
+            2918, // 615  - pt-mo
+            2923, // 616  - pt-mz
+            2928, // 617  - pt-pt
+            2933, // 618  - pt-st
+            2938, // 619  - pt-tl
+            2943, // 620  - qps-latn-x-sh
+            2956, // 621  - qps-ploc
+            2964, // 622  - qps-ploca
+            2973, // 623  - qps-plocm
+            2982, // 624  - quc
+            2985, // 625  - quc-latn
+            2993, // 626  - quc-latn-gt
+            3004, // 627  - quz
+            3007, // 628  - quz-bo
+            3013, // 629  - quz-ec
+            3019, // 630  - quz-pe
+            3025, // 631  - rm
+            3027, // 632  - rm-ch
+            3032, // 633  - rn
+            3034, // 634  - rn-bi
+            3039, // 635  - ro
+            3041, // 636  - ro-md
+            3046, // 637  - ro-ro
+            3051, // 638  - rof
+            3054, // 639  - rof-tz
+            3060, // 640  - ru
+            3062, // 641  - ru-by
+            3067, // 642  - ru-kg
+            3072, // 643  - ru-kz
+            3077, // 644  - ru-md
+            3082, // 645  - ru-ru
+            3087, // 646  - ru-ua
+            3092, // 647  - rw
+            3094, // 648  - rw-rw
+            3099, // 649  - rwk
+            3102, // 650  - rwk-tz
+            3108, // 651  - sa
+            3110, // 652  - sa-in
+            3115, // 653  - sah
+            3118, // 654  - sah-ru
+            3124, // 655  - saq
+            3127, // 656  - saq-ke
+            3133, // 657  - sbp
+            3136, // 658  - sbp-tz
+            3142, // 659  - sd
+            3144, // 660  - sd-arab
+            3151, // 661  - sd-arab-pk
+            3161, // 662  - sd-deva
+            3168, // 663  - sd-deva-in
+            3178, // 664  - se
+            3180, // 665  - se-fi
+            3185, // 666  - se-no
+            3190, // 667  - se-se
+            3195, // 668  - seh
+            3198, // 669  - seh-mz
+            3204, // 670  - ses
+            3207, // 671  - ses-ml
+            3213, // 672  - sg
+            3215, // 673  - sg-cf
+            3220, // 674  - shi
+            3223, // 675  - shi-latn
+            3231, // 676  - shi-latn-ma
+            3242, // 677  - shi-tfng
+            3250, // 678  - shi-tfng-ma
+            3261, // 679  - si
+            3263, // 680  - si-lk
+            3268, // 681  - sk
+            3270, // 682  - sk-sk
+            3275, // 683  - sl
+            3277, // 684  - sl-si
+            3282, // 685  - sma
+            3285, // 686  - sma-no
+            3291, // 687  - sma-se
+            3297, // 688  - smj
+            3300, // 689  - smj-no
+            3306, // 690  - smj-se
+            3312, // 691  - smn
+            3315, // 692  - smn-fi
+            3321, // 693  - sms
+            3324, // 694  - sms-fi
+            3330, // 695  - sn
+            3332, // 696  - sn-latn
+            3339, // 697  - sn-latn-zw
+            3349, // 698  - so
+            3351, // 699  - so-dj
+            3356, // 700  - so-et
+            3361, // 701  - so-ke
+            3366, // 702  - so-so
+            3371, // 703  - sq
+            3373, // 704  - sq-al
+            3378, // 705  - sq-mk
+            3383, // 706  - sq-xk
+            3388, // 707  - sr
+            3390, // 708  - sr-cyrl
+            3397, // 709  - sr-cyrl-ba
+            3407, // 710  - sr-cyrl-cs
+            3417, // 711  - sr-cyrl-me
+            3427, // 712  - sr-cyrl-rs
+            3437, // 713  - sr-cyrl-xk
+            3447, // 714  - sr-latn
+            3454, // 715  - sr-latn-ba
+            3464, // 716  - sr-latn-cs
+            3474, // 717  - sr-latn-me
+            3484, // 718  - sr-latn-rs
+            3494, // 719  - sr-latn-xk
+            3504, // 720  - ss
+            3506, // 721  - ss-sz
+            3511, // 722  - ss-za
+            3516, // 723  - ssy
+            3519, // 724  - ssy-er
+            3525, // 725  - st
+            3527, // 726  - st-ls
+            3532, // 727  - st-za
+            3537, // 728  - sv
+            3539, // 729  - sv-ax
+            3544, // 730  - sv-fi
+            3549, // 731  - sv-se
+            3554, // 732  - sw
+            3556, // 733  - sw-cd
+            3561, // 734  - sw-ke
+            3566, // 735  - sw-tz
+            3571, // 736  - sw-ug
+            3576, // 737  - swc
+            3579, // 738  - swc-cd
+            3585, // 739  - syr
+            3588, // 740  - syr-sy
+            3594, // 741  - ta
+            3596, // 742  - ta-in
+            3601, // 743  - ta-lk
+            3606, // 744  - ta-my
+            3611, // 745  - ta-sg
+            3616, // 746  - te
+            3618, // 747  - te-in
+            3623, // 748  - teo
+            3626, // 749  - teo-ke
+            3632, // 750  - teo-ug
+            3638, // 751  - tg
+            3640, // 752  - tg-cyrl
+            3647, // 753  - tg-cyrl-tj
+            3657, // 754  - th
+            3659, // 755  - th-th
+            3664, // 756  - ti
+            3666, // 757  - ti-er
+            3671, // 758  - ti-et
+            3676, // 759  - tig
+            3679, // 760  - tig-er
+            3685, // 761  - tk
+            3687, // 762  - tk-tm
+            3692, // 763  - tn
+            3694, // 764  - tn-bw
+            3699, // 765  - tn-za
+            3704, // 766  - to
+            3706, // 767  - to-to
+            3711, // 768  - tr
+            3713, // 769  - tr-cy
+            3718, // 770  - tr-tr
+            3723, // 771  - ts
+            3725, // 772  - ts-za
+            3730, // 773  - tt
+            3732, // 774  - tt-ru
+            3737, // 775  - twq
+            3740, // 776  - twq-ne
+            3746, // 777  - tzm
+            3749, // 778  - tzm-arab
+            3757, // 779  - tzm-arab-ma
+            3768, // 780  - tzm-latn
+            3776, // 781  - tzm-latn-dz
+            3787, // 782  - tzm-latn-ma
+            3798, // 783  - tzm-tfng
+            3806, // 784  - tzm-tfng-ma
+            3817, // 785  - ug
+            3819, // 786  - ug-cn
+            3824, // 787  - uk
+            3826, // 788  - uk-ua
+            3831, // 789  - ur
+            3833, // 790  - ur-in
+            3838, // 791  - ur-pk
+            3843, // 792  - uz
+            3845, // 793  - uz-arab
+            3852, // 794  - uz-arab-af
+            3862, // 795  - uz-cyrl
+            3869, // 796  - uz-cyrl-uz
+            3879, // 797  - uz-latn
+            3886, // 798  - uz-latn-uz
+            3896, // 799  - vai
+            3899, // 800  - vai-latn
+            3907, // 801  - vai-latn-lr
+            3918, // 802  - vai-vaii
+            3926, // 803  - vai-vaii-lr
+            3937, // 804  - ve
+            3939, // 805  - ve-za
+            3944, // 806  - vi
+            3946, // 807  - vi-vn
+            3951, // 808  - vo
+            3953, // 809  - vo-001
+            3959, // 810  - vun
+            3962, // 811  - vun-tz
+            3968, // 812  - wae
+            3971, // 813  - wae-ch
+            3977, // 814  - wal
+            3980, // 815  - wal-et
+            3986, // 816  - wo
+            3988, // 817  - wo-sn
+            3993, // 818  - x-iv_mathan
+            4004, // 819  - xh
+            4006, // 820  - xh-za
+            4011, // 821  - xog
+            4014, // 822  - xog-ug
+            4020, // 823  - yav
+            4023, // 824  - yav-cm
+            4029, // 825  - yi
+            4031, // 826  - yi-001
+            4037, // 827  - yo
+            4039, // 828  - yo-bj
+            4044, // 829  - yo-ng
+            4049, // 830  - yue-hk
+            4055, // 831  - zgh
+            4058, // 832  - zgh-tfng
+            4066, // 833  - zgh-tfng-ma
+            4077, // 834  - zh
+            4079, // 835  - zh-chs
+            4085, // 836  - zh-cht
+            4091, // 837  - zh-cn
+            4096, // 838  - zh-cn_phoneb
+            4108, // 839  - zh-cn_stroke
+            4120, // 840  - zh-hans
+            4127, // 841  - zh-hans-hk
+            4137, // 842  - zh-hans-mo
+            4147, // 843  - zh-hant
+            4154, // 844  - zh-hk
+            4159, // 845  - zh-hk_radstr
+            4171, // 846  - zh-mo
+            4176, // 847  - zh-mo_radstr
+            4188, // 848  - zh-mo_stroke
+            4200, // 849  - zh-sg
+            4205, // 850  - zh-sg_phoneb
+            4217, // 851  - zh-sg_stroke
+            4229, // 852  - zh-tw
+            4234, // 853  - zh-tw_pronun
+            4246, // 854  - zh-tw_radstr
+            4258, // 855  - zu
+            4260, // 856  - zu-za
+            4265, // 857  -
+        };
+        
+        // s_nameIndexTolcids is mapping from index in s_localeNamesIndices to lcid
+        private static readonly int[] s_nameIndexTolcids = new int[]
+        {
+            // Lcid, index   - locale name 
+            0x1000 , // 0    - aa
+            0x1000 , // 1    - aa-dj
+            0x1000 , // 2    - aa-er
+            0x1000 , // 3    - aa-et
+            0x36   , // 4    - af
+            0x1000 , // 5    - af-na
+            0x436  , // 6    - af-za
+            0x1000 , // 7    - agq
+            0x1000 , // 8    - agq-cm
+            0x1000 , // 9    - ak
+            0x1000 , // 10   - ak-gh
+            0x5e   , // 11   - am
+            0x45e  , // 12   - am-et
+            0x1    , // 13   - ar
+            0x1000 , // 14   - ar-001
+            0x3801 , // 15   - ar-ae
+            0x3c01 , // 16   - ar-bh
+            0x1000 , // 17   - ar-dj
+            0x1401 , // 18   - ar-dz
+            0xc01  , // 19   - ar-eg
+            0x1000 , // 20   - ar-er
+            0x1000 , // 21   - ar-il
+            0x801  , // 22   - ar-iq
+            0x2c01 , // 23   - ar-jo
+            0x1000 , // 24   - ar-km
+            0x3401 , // 25   - ar-kw
+            0x3001 , // 26   - ar-lb
+            0x1001 , // 27   - ar-ly
+            0x1801 , // 28   - ar-ma
+            0x1000 , // 29   - ar-mr
+            0x2001 , // 30   - ar-om
+            0x1000 , // 31   - ar-ps
+            0x4001 , // 32   - ar-qa
+            0x401  , // 33   - ar-sa
+            0x1000 , // 34   - ar-sd
+            0x1000 , // 35   - ar-so
+            0x1000 , // 36   - ar-ss
+            0x2801 , // 37   - ar-sy
+            0x1000 , // 38   - ar-td
+            0x1c01 , // 39   - ar-tn
+            0x2401 , // 40   - ar-ye
+            0x7a   , // 41   - arn
+            0x47a  , // 42   - arn-cl
+            0x4d   , // 43   - as
+            0x44d  , // 44   - as-in
+            0x1000 , // 45   - asa
+            0x1000 , // 46   - asa-tz
+            0x1000 , // 47   - ast
+            0x1000 , // 48   - ast-es
+            0x2c   , // 49   - az
+            0x742c , // 50   - az-cyrl
+            0x82c  , // 51   - az-cyrl-az
+            0x782c , // 52   - az-latn
+            0x42c  , // 53   - az-latn-az
+            0x6d   , // 54   - ba
+            0x46d  , // 55   - ba-ru
+            0x1000 , // 56   - bas
+            0x1000 , // 57   - bas-cm
+            0x23   , // 58   - be
+            0x423  , // 59   - be-by
+            0x1000 , // 60   - bem
+            0x1000 , // 61   - bem-zm
+            0x1000 , // 62   - bez
+            0x1000 , // 63   - bez-tz
+            0x2    , // 64   - bg
+            0x402  , // 65   - bg-bg
+            0x66   , // 66   - bin
+            0x466  , // 67   - bin-ng
+            0x1000 , // 68   - bm
+            0x1000 , // 69   - bm-latn
+            0x1000 , // 70   - bm-latn-ml
+            0x45   , // 71   - bn
+            0x845  , // 72   - bn-bd
+            0x445  , // 73   - bn-in
+            0x51   , // 74   - bo
+            0x451  , // 75   - bo-cn
+            0x1000 , // 76   - bo-in
+            0x7e   , // 77   - br
+            0x47e  , // 78   - br-fr
+            0x1000 , // 79   - brx
+            0x1000 , // 80   - brx-in
+            0x781a , // 81   - bs
+            0x641a , // 82   - bs-cyrl
+            0x201a , // 83   - bs-cyrl-ba
+            0x681a , // 84   - bs-latn
+            0x141a , // 85   - bs-latn-ba
+            0x1000 , // 86   - byn
+            0x1000 , // 87   - byn-er
+            0x3    , // 88   - ca
+            0x1000 , // 89   - ca-ad
+            0x403  , // 90   - ca-es
+            0x803  , // 91   - ca-es-valencia
+            0x1000 , // 92   - ca-fr
+            0x1000 , // 93   - ca-it
+            0x1000 , // 94   - ce-ru
+            0x1000 , // 95   - cgg
+            0x1000 , // 96   - cgg-ug
+            0x5c   , // 97   - chr
+            0x7c5c , // 98   - chr-cher
+            0x45c  , // 99   - chr-cher-us
+            0x83   , // 100  - co
+            0x483  , // 101  - co-fr
+            0x5    , // 102  - cs
+            0x405  , // 103  - cs-cz
+            0x1000 , // 104  - cu-ru
+            0x52   , // 105  - cy
+            0x452  , // 106  - cy-gb
+            0x6    , // 107  - da
+            0x406  , // 108  - da-dk
+            0x1000 , // 109  - da-gl
+            0x1000 , // 110  - dav
+            0x1000 , // 111  - dav-ke
+            0x7    , // 112  - de
+            0xc07  , // 113  - de-at
+            0x1000 , // 114  - de-be
+            0x807  , // 115  - de-ch
+            0x407  , // 116  - de-de
+            0x10407, // 117  - de-de_phoneb
+            0x1000 , // 118  - de-it
+            0x1407 , // 119  - de-li
+            0x1007 , // 120  - de-lu
+            0x1000 , // 121  - dje
+            0x1000 , // 122  - dje-ne
+            0x7c2e , // 123  - dsb
+            0x82e  , // 124  - dsb-de
+            0x1000 , // 125  - dua
+            0x1000 , // 126  - dua-cm
+            0x65   , // 127  - dv
+            0x465  , // 128  - dv-mv
+            0x1000 , // 129  - dyo
+            0x1000 , // 130  - dyo-sn
+            0x1000 , // 131  - dz
+            0xc51  , // 132  - dz-bt
+            0x1000 , // 133  - ebu
+            0x1000 , // 134  - ebu-ke
+            0x1000 , // 135  - ee
+            0x1000 , // 136  - ee-gh
+            0x1000 , // 137  - ee-tg
+            0x8    , // 138  - el
+            0x1000 , // 139  - el-cy
+            0x408  , // 140  - el-gr
+            0x9    , // 141  - en
+            0x1000 , // 142  - en-001
+            0x2409 , // 143  - en-029
+            0x1000 , // 144  - en-150
+            0x1000 , // 145  - en-ag
+            0x1000 , // 146  - en-ai
+            0x1000 , // 147  - en-as
+            0x1000 , // 148  - en-at
+            0xc09  , // 149  - en-au
+            0x1000 , // 150  - en-bb
+            0x1000 , // 151  - en-be
+            0x1000 , // 152  - en-bi
+            0x1000 , // 153  - en-bm
+            0x1000 , // 154  - en-bs
+            0x1000 , // 155  - en-bw
+            0x2809 , // 156  - en-bz
+            0x1009 , // 157  - en-ca
+            0x1000 , // 158  - en-cc
+            0x1000 , // 159  - en-ch
+            0x1000 , // 160  - en-ck
+            0x1000 , // 161  - en-cm
+            0x1000 , // 162  - en-cx
+            0x1000 , // 163  - en-cy
+            0x1000 , // 164  - en-de
+            0x1000 , // 165  - en-dk
+            0x1000 , // 166  - en-dm
+            0x1000 , // 167  - en-er
+            0x1000 , // 168  - en-fi
+            0x1000 , // 169  - en-fj
+            0x1000 , // 170  - en-fk
+            0x1000 , // 171  - en-fm
+            0x809  , // 172  - en-gb
+            0x1000 , // 173  - en-gd
+            0x1000 , // 174  - en-gg
+            0x1000 , // 175  - en-gh
+            0x1000 , // 176  - en-gi
+            0x1000 , // 177  - en-gm
+            0x1000 , // 178  - en-gu
+            0x1000 , // 179  - en-gy
+            0x3c09 , // 180  - en-hk
+            0x3809 , // 181  - en-id
+            0x1809 , // 182  - en-ie
+            0x1000 , // 183  - en-il
+            0x1000 , // 184  - en-im
+            0x4009 , // 185  - en-in
+            0x1000 , // 186  - en-io
+            0x1000 , // 187  - en-je
+            0x2009 , // 188  - en-jm
+            0x1000 , // 189  - en-ke
+            0x1000 , // 190  - en-ki
+            0x1000 , // 191  - en-kn
+            0x1000 , // 192  - en-ky
+            0x1000 , // 193  - en-lc
+            0x1000 , // 194  - en-lr
+            0x1000 , // 195  - en-ls
+            0x1000 , // 196  - en-mg
+            0x1000 , // 197  - en-mh
+            0x1000 , // 198  - en-mo
+            0x1000 , // 199  - en-mp
+            0x1000 , // 200  - en-ms
+            0x1000 , // 201  - en-mt
+            0x1000 , // 202  - en-mu
+            0x1000 , // 203  - en-mw
+            0x4409 , // 204  - en-my
+            0x1000 , // 205  - en-na
+            0x1000 , // 206  - en-nf
+            0x1000 , // 207  - en-ng
+            0x1000 , // 208  - en-nl
+            0x1000 , // 209  - en-nr
+            0x1000 , // 210  - en-nu
+            0x1409 , // 211  - en-nz
+            0x1000 , // 212  - en-pg
+            0x3409 , // 213  - en-ph
+            0x1000 , // 214  - en-pk
+            0x1000 , // 215  - en-pn
+            0x1000 , // 216  - en-pr
+            0x1000 , // 217  - en-pw
+            0x1000 , // 218  - en-rw
+            0x1000 , // 219  - en-sb
+            0x1000 , // 220  - en-sc
+            0x1000 , // 221  - en-sd
+            0x1000 , // 222  - en-se
+            0x4809 , // 223  - en-sg
+            0x1000 , // 224  - en-sh
+            0x1000 , // 225  - en-si
+            0x1000 , // 226  - en-sl
+            0x1000 , // 227  - en-ss
+            0x1000 , // 228  - en-sx
+            0x1000 , // 229  - en-sz
+            0x1000 , // 230  - en-tc
+            0x1000 , // 231  - en-tk
+            0x1000 , // 232  - en-to
+            0x2c09 , // 233  - en-tt
+            0x1000 , // 234  - en-tv
+            0x1000 , // 235  - en-tz
+            0x1000 , // 236  - en-ug
+            0x1000 , // 237  - en-um
+            0x409  , // 238  - en-us
+            0x1000 , // 239  - en-vc
+            0x1000 , // 240  - en-vg
+            0x1000 , // 241  - en-vi
+            0x1000 , // 242  - en-vu
+            0x1000 , // 243  - en-ws
+            0x1c09 , // 244  - en-za
+            0x1000 , // 245  - en-zm
+            0x3009 , // 246  - en-zw
+            0x1000 , // 247  - eo
+            0x1000 , // 248  - eo-001
+            0xa    , // 249  - es
+            0x580a , // 250  - es-419
+            0x2c0a , // 251  - es-ar
+            0x400a , // 252  - es-bo
+            0x1000 , // 253  - es-br
+            0x340a , // 254  - es-cl
+            0x240a , // 255  - es-co
+            0x140a , // 256  - es-cr
+            0x5c0a , // 257  - es-cu
+            0x1c0a , // 258  - es-do
+            0x300a , // 259  - es-ec
+            0xc0a  , // 260  - es-es
+            0x40a  , // 261  - es-es_tradnl
+            0x1000 , // 262  - es-gq
+            0x100a , // 263  - es-gt
+            0x480a , // 264  - es-hn
+            0x80a  , // 265  - es-mx
+            0x4c0a , // 266  - es-ni
+            0x180a , // 267  - es-pa
+            0x280a , // 268  - es-pe
+            0x1000 , // 269  - es-ph
+            0x500a , // 270  - es-pr
+            0x3c0a , // 271  - es-py
+            0x440a , // 272  - es-sv
+            0x540a , // 273  - es-us
+            0x380a , // 274  - es-uy
+            0x200a , // 275  - es-ve
+            0x25   , // 276  - et
+            0x425  , // 277  - et-ee
+            0x2d   , // 278  - eu
+            0x42d  , // 279  - eu-es
+            0x1000 , // 280  - ewo
+            0x1000 , // 281  - ewo-cm
+            0x29   , // 282  - fa
+            0x429  , // 283  - fa-ir
+            0x67   , // 284  - ff
+            0x1000 , // 285  - ff-cm
+            0x1000 , // 286  - ff-gn
+            0x7c67 , // 287  - ff-latn
+            0x867  , // 288  - ff-latn-sn
+            0x1000 , // 289  - ff-mr
+            0x467  , // 290  - ff-ng
+            0xb    , // 291  - fi
+            0x40b  , // 292  - fi-fi
+            0x64   , // 293  - fil
+            0x464  , // 294  - fil-ph
+            0x38   , // 295  - fo
+            0x1000 , // 296  - fo-dk
+            0x438  , // 297  - fo-fo
+            0xc    , // 298  - fr
+            0x1c0c , // 299  - fr-029
+            0x80c  , // 300  - fr-be
+            0x1000 , // 301  - fr-bf
+            0x1000 , // 302  - fr-bi
+            0x1000 , // 303  - fr-bj
+            0x1000 , // 304  - fr-bl
+            0xc0c  , // 305  - fr-ca
+            0x240c , // 306  - fr-cd
+            0x1000 , // 307  - fr-cf
+            0x1000 , // 308  - fr-cg
+            0x100c , // 309  - fr-ch
+            0x300c , // 310  - fr-ci
+            0x2c0c , // 311  - fr-cm
+            0x1000 , // 312  - fr-dj
+            0x1000 , // 313  - fr-dz
+            0x40c  , // 314  - fr-fr
+            0x1000 , // 315  - fr-ga
+            0x1000 , // 316  - fr-gf
+            0x1000 , // 317  - fr-gn
+            0x1000 , // 318  - fr-gp
+            0x1000 , // 319  - fr-gq
+            0x3c0c , // 320  - fr-ht
+            0x1000 , // 321  - fr-km
+            0x140c , // 322  - fr-lu
+            0x380c , // 323  - fr-ma
+            0x180c , // 324  - fr-mc
+            0x1000 , // 325  - fr-mf
+            0x1000 , // 326  - fr-mg
+            0x340c , // 327  - fr-ml
+            0x1000 , // 328  - fr-mq
+            0x1000 , // 329  - fr-mr
+            0x1000 , // 330  - fr-mu
+            0x1000 , // 331  - fr-nc
+            0x1000 , // 332  - fr-ne
+            0x1000 , // 333  - fr-pf
+            0x1000 , // 334  - fr-pm
+            0x200c , // 335  - fr-re
+            0x1000 , // 336  - fr-rw
+            0x1000 , // 337  - fr-sc
+            0x280c , // 338  - fr-sn
+            0x1000 , // 339  - fr-sy
+            0x1000 , // 340  - fr-td
+            0x1000 , // 341  - fr-tg
+            0x1000 , // 342  - fr-tn
+            0x1000 , // 343  - fr-vu
+            0x1000 , // 344  - fr-wf
+            0x1000 , // 345  - fr-yt
+            0x1000 , // 346  - fur
+            0x1000 , // 347  - fur-it
+            0x62   , // 348  - fy
+            0x462  , // 349  - fy-nl
+            0x3c   , // 350  - ga
+            0x83c  , // 351  - ga-ie
+            0x91   , // 352  - gd
+            0x491  , // 353  - gd-gb
+            0x56   , // 354  - gl
+            0x456  , // 355  - gl-es
+            0x74   , // 356  - gn
+            0x474  , // 357  - gn-py
+            0x84   , // 358  - gsw
+            0x1000 , // 359  - gsw-ch
+            0x484  , // 360  - gsw-fr
+            0x1000 , // 361  - gsw-li
+            0x47   , // 362  - gu
+            0x447  , // 363  - gu-in
+            0x1000 , // 364  - guz
+            0x1000 , // 365  - guz-ke
+            0x1000 , // 366  - gv
+            0x1000 , // 367  - gv-im
+            0x68   , // 368  - ha
+            0x7c68 , // 369  - ha-latn
+            0x1000 , // 370  - ha-latn-gh
+            0x1000 , // 371  - ha-latn-ne
+            0x468  , // 372  - ha-latn-ng
+            0x75   , // 373  - haw
+            0x475  , // 374  - haw-us
+            0xd    , // 375  - he
+            0x40d  , // 376  - he-il
+            0x39   , // 377  - hi
+            0x439  , // 378  - hi-in
+            0x1a   , // 379  - hr
+            0x101a , // 380  - hr-ba
+            0x41a  , // 381  - hr-hr
+            0x2e   , // 382  - hsb
+            0x42e  , // 383  - hsb-de
+            0xe    , // 384  - hu
+            0x40e  , // 385  - hu-hu
+            0x1040e, // 386  - hu-hu_technl
+            0x2b   , // 387  - hy
+            0x42b  , // 388  - hy-am
+            0x1000 , // 389  - ia
+            0x1000 , // 390  - ia-001
+            0x1000 , // 391  - ia-fr
+            0x69   , // 392  - ibb
+            0x469  , // 393  - ibb-ng
+            0x21   , // 394  - id
+            0x421  , // 395  - id-id
+            0x70   , // 396  - ig
+            0x470  , // 397  - ig-ng
+            0x78   , // 398  - ii
+            0x478  , // 399  - ii-cn
+            0xf    , // 400  - is
+            0x40f  , // 401  - is-is
+            0x10   , // 402  - it
+            0x810  , // 403  - it-ch
+            0x410  , // 404  - it-it
+            0x1000 , // 405  - it-sm
+            0x5d   , // 406  - iu
+            0x785d , // 407  - iu-cans
+            0x45d  , // 408  - iu-cans-ca
+            0x7c5d , // 409  - iu-latn
+            0x85d  , // 410  - iu-latn-ca
+            0x11   , // 411  - ja
+            0x411  , // 412  - ja-jp
+            0x40411, // 413  - ja-jp_radstr
+            0x1000 , // 414  - jgo
+            0x1000 , // 415  - jgo-cm
+            0x1000 , // 416  - jmc
+            0x1000 , // 417  - jmc-tz
+            0x1000 , // 418  - jv
+            0x1000 , // 419  - jv-java
+            0x1000 , // 420  - jv-java-id
+            0x1000 , // 421  - jv-latn
+            0x1000 , // 422  - jv-latn-id
+            0x37   , // 423  - ka
+            0x437  , // 424  - ka-ge
+            0x10437, // 425  - ka-ge_modern
+            0x1000 , // 426  - kab
+            0x1000 , // 427  - kab-dz
+            0x1000 , // 428  - kam
+            0x1000 , // 429  - kam-ke
+            0x1000 , // 430  - kde
+            0x1000 , // 431  - kde-tz
+            0x1000 , // 432  - kea
+            0x1000 , // 433  - kea-cv
+            0x1000 , // 434  - khq
+            0x1000 , // 435  - khq-ml
+            0x1000 , // 436  - ki
+            0x1000 , // 437  - ki-ke
+            0x3f   , // 438  - kk
+            0x43f  , // 439  - kk-kz
+            0x1000 , // 440  - kkj
+            0x1000 , // 441  - kkj-cm
+            0x6f   , // 442  - kl
+            0x46f  , // 443  - kl-gl
+            0x1000 , // 444  - kln
+            0x1000 , // 445  - kln-ke
+            0x53   , // 446  - km
+            0x453  , // 447  - km-kh
+            0x4b   , // 448  - kn
+            0x44b  , // 449  - kn-in
+            0x12   , // 450  - ko
+            0x1000 , // 451  - ko-kp
+            0x412  , // 452  - ko-kr
+            0x57   , // 453  - kok
+            0x457  , // 454  - kok-in
+            0x71   , // 455  - kr
+            0x471  , // 456  - kr-ng
+            0x60   , // 457  - ks
+            0x460  , // 458  - ks-arab
+            0x1000 , // 459  - ks-arab-in
+            0x1000 , // 460  - ks-deva
+            0x860  , // 461  - ks-deva-in
+            0x1000 , // 462  - ksb
+            0x1000 , // 463  - ksb-tz
+            0x1000 , // 464  - ksf
+            0x1000 , // 465  - ksf-cm
+            0x1000 , // 466  - ksh
+            0x1000 , // 467  - ksh-de
+            0x92   , // 468  - ku
+            0x7c92 , // 469  - ku-arab
+            0x492  , // 470  - ku-arab-iq
+            0x1000 , // 471  - ku-arab-ir
+            0x1000 , // 472  - kw
+            0x1000 , // 473  - kw-gb
+            0x40   , // 474  - ky
+            0x440  , // 475  - ky-kg
+            0x76   , // 476  - la
+            0x476  , // 477  - la-001
+            0x1000 , // 478  - lag
+            0x1000 , // 479  - lag-tz
+            0x6e   , // 480  - lb
+            0x46e  , // 481  - lb-lu
+            0x1000 , // 482  - lg
+            0x1000 , // 483  - lg-ug
+            0x1000 , // 484  - lkt
+            0x1000 , // 485  - lkt-us
+            0x1000 , // 486  - ln
+            0x1000 , // 487  - ln-ao
+            0x1000 , // 488  - ln-cd
+            0x1000 , // 489  - ln-cf
+            0x1000 , // 490  - ln-cg
+            0x54   , // 491  - lo
+            0x454  , // 492  - lo-la
+            0x1000 , // 493  - lrc-iq
+            0x1000 , // 494  - lrc-ir
+            0x27   , // 495  - lt
+            0x427  , // 496  - lt-lt
+            0x1000 , // 497  - lu
+            0x1000 , // 498  - lu-cd
+            0x1000 , // 499  - luo
+            0x1000 , // 500  - luo-ke
+            0x1000 , // 501  - luy
+            0x1000 , // 502  - luy-ke
+            0x26   , // 503  - lv
+            0x426  , // 504  - lv-lv
+            0x1000 , // 505  - mas
+            0x1000 , // 506  - mas-ke
+            0x1000 , // 507  - mas-tz
+            0x1000 , // 508  - mer
+            0x1000 , // 509  - mer-ke
+            0x1000 , // 510  - mfe
+            0x1000 , // 511  - mfe-mu
+            0x1000 , // 512  - mg
+            0x1000 , // 513  - mg-mg
+            0x1000 , // 514  - mgh
+            0x1000 , // 515  - mgh-mz
+            0x1000 , // 516  - mgo
+            0x1000 , // 517  - mgo-cm
+            0x81   , // 518  - mi
+            0x481  , // 519  - mi-nz
+            0x2f   , // 520  - mk
+            0x42f  , // 521  - mk-mk
+            0x4c   , // 522  - ml
+            0x44c  , // 523  - ml-in
+            0x50   , // 524  - mn
+            0x7850 , // 525  - mn-cyrl
+            0x450  , // 526  - mn-mn
+            0x7c50 , // 527  - mn-mong
+            0x850  , // 528  - mn-mong-cn
+            0xc50  , // 529  - mn-mong-mn
+            0x58   , // 530  - mni
+            0x458  , // 531  - mni-in
+            0x7c   , // 532  - moh
+            0x47c  , // 533  - moh-ca
+            0x4e   , // 534  - mr
+            0x44e  , // 535  - mr-in
+            0x3e   , // 536  - ms
+            0x83e  , // 537  - ms-bn
+            0x43e  , // 538  - ms-my
+            0x1000 , // 539  - ms-sg
+            0x3a   , // 540  - mt
+            0x43a  , // 541  - mt-mt
+            0x1000 , // 542  - mua
+            0x1000 , // 543  - mua-cm
+            0x55   , // 544  - my
+            0x455  , // 545  - my-mm
+            0x1000 , // 546  - mzn-ir
+            0x1000 , // 547  - naq
+            0x1000 , // 548  - naq-na
+            0x7c14 , // 549  - nb
+            0x414  , // 550  - nb-no
+            0x1000 , // 551  - nb-sj
+            0x1000 , // 552  - nd
+            0x1000 , // 553  - nd-zw
+            0x1000 , // 554  - nds-de
+            0x1000 , // 555  - nds-nl
+            0x61   , // 556  - ne
+            0x861  , // 557  - ne-in
+            0x461  , // 558  - ne-np
+            0x13   , // 559  - nl
+            0x1000 , // 560  - nl-aw
+            0x813  , // 561  - nl-be
+            0x1000 , // 562  - nl-bq
+            0x1000 , // 563  - nl-cw
+            0x413  , // 564  - nl-nl
+            0x1000 , // 565  - nl-sr
+            0x1000 , // 566  - nl-sx
+            0x1000 , // 567  - nmg
+            0x1000 , // 568  - nmg-cm
+            0x7814 , // 569  - nn
+            0x814  , // 570  - nn-no
+            0x1000 , // 571  - nnh
+            0x1000 , // 572  - nnh-cm
+            0x14   , // 573  - no
+            0x1000 , // 574  - nqo
+            0x1000 , // 575  - nqo-gn
+            0x1000 , // 576  - nr
+            0x1000 , // 577  - nr-za
+            0x6c   , // 578  - nso
+            0x46c  , // 579  - nso-za
+            0x1000 , // 580  - nus
+            0x1000 , // 581  - nus-ss
+            0x1000 , // 582  - nyn
+            0x1000 , // 583  - nyn-ug
+            0x82   , // 584  - oc
+            0x482  , // 585  - oc-fr
+            0x72   , // 586  - om
+            0x472  , // 587  - om-et
+            0x1000 , // 588  - om-ke
+            0x48   , // 589  - or
+            0x448  , // 590  - or-in
+            0x1000 , // 591  - os
+            0x1000 , // 592  - os-ge
+            0x1000 , // 593  - os-ru
+            0x46   , // 594  - pa
+            0x7c46 , // 595  - pa-arab
+            0x846  , // 596  - pa-arab-pk
+            0x446  , // 597  - pa-in
+            0x79   , // 598  - pap
+            0x479  , // 599  - pap-029
+            0x15   , // 600  - pl
+            0x415  , // 601  - pl-pl
+            0x1000 , // 602  - prg-001
+            0x8c   , // 603  - prs
+            0x48c  , // 604  - prs-af
+            0x63   , // 605  - ps
+            0x463  , // 606  - ps-af
+            0x16   , // 607  - pt
+            0x1000 , // 608  - pt-ao
+            0x416  , // 609  - pt-br
+            0x1000 , // 610  - pt-ch
+            0x1000 , // 611  - pt-cv
+            0x1000 , // 612  - pt-gq
+            0x1000 , // 613  - pt-gw
+            0x1000 , // 614  - pt-lu
+            0x1000 , // 615  - pt-mo
+            0x1000 , // 616  - pt-mz
+            0x816  , // 617  - pt-pt
+            0x1000 , // 618  - pt-st
+            0x1000 , // 619  - pt-tl
+            0x901  , // 620  - qps-latn-x-sh
+            0x501  , // 621  - qps-ploc
+            0x5fe  , // 622  - qps-ploca
+            0x9ff  , // 623  - qps-plocm
+            0x86   , // 624  - quc
+            0x7c86 , // 625  - quc-latn
+            0x486  , // 626  - quc-latn-gt
+            0x6b   , // 627  - quz
+            0x46b  , // 628  - quz-bo
+            0x86b  , // 629  - quz-ec
+            0xc6b  , // 630  - quz-pe
+            0x17   , // 631  - rm
+            0x417  , // 632  - rm-ch
+            0x1000 , // 633  - rn
+            0x1000 , // 634  - rn-bi
+            0x18   , // 635  - ro
+            0x818  , // 636  - ro-md
+            0x418  , // 637  - ro-ro
+            0x1000 , // 638  - rof
+            0x1000 , // 639  - rof-tz
+            0x19   , // 640  - ru
+            0x1000 , // 641  - ru-by
+            0x1000 , // 642  - ru-kg
+            0x1000 , // 643  - ru-kz
+            0x819  , // 644  - ru-md
+            0x419  , // 645  - ru-ru
+            0x1000 , // 646  - ru-ua
+            0x87   , // 647  - rw
+            0x487  , // 648  - rw-rw
+            0x1000 , // 649  - rwk
+            0x1000 , // 650  - rwk-tz
+            0x4f   , // 651  - sa
+            0x44f  , // 652  - sa-in
+            0x85   , // 653  - sah
+            0x485  , // 654  - sah-ru
+            0x1000 , // 655  - saq
+            0x1000 , // 656  - saq-ke
+            0x1000 , // 657  - sbp
+            0x1000 , // 658  - sbp-tz
+            0x59   , // 659  - sd
+            0x7c59 , // 660  - sd-arab
+            0x859  , // 661  - sd-arab-pk
+            0x1000 , // 662  - sd-deva
+            0x459  , // 663  - sd-deva-in
+            0x3b   , // 664  - se
+            0xc3b  , // 665  - se-fi
+            0x43b  , // 666  - se-no
+            0x83b  , // 667  - se-se
+            0x1000 , // 668  - seh
+            0x1000 , // 669  - seh-mz
+            0x1000 , // 670  - ses
+            0x1000 , // 671  - ses-ml
+            0x1000 , // 672  - sg
+            0x1000 , // 673  - sg-cf
+            0x1000 , // 674  - shi
+            0x1000 , // 675  - shi-latn
+            0x1000 , // 676  - shi-latn-ma
+            0x1000 , // 677  - shi-tfng
+            0x1000 , // 678  - shi-tfng-ma
+            0x5b   , // 679  - si
+            0x45b  , // 680  - si-lk
+            0x1b   , // 681  - sk
+            0x41b  , // 682  - sk-sk
+            0x24   , // 683  - sl
+            0x424  , // 684  - sl-si
+            0x783b , // 685  - sma
+            0x183b , // 686  - sma-no
+            0x1c3b , // 687  - sma-se
+            0x7c3b , // 688  - smj
+            0x103b , // 689  - smj-no
+            0x143b , // 690  - smj-se
+            0x703b , // 691  - smn
+            0x243b , // 692  - smn-fi
+            0x743b , // 693  - sms
+            0x203b , // 694  - sms-fi
+            0x1000 , // 695  - sn
+            0x1000 , // 696  - sn-latn
+            0x1000 , // 697  - sn-latn-zw
+            0x77   , // 698  - so
+            0x1000 , // 699  - so-dj
+            0x1000 , // 700  - so-et
+            0x1000 , // 701  - so-ke
+            0x477  , // 702  - so-so
+            0x1c   , // 703  - sq
+            0x41c  , // 704  - sq-al
+            0x1000 , // 705  - sq-mk
+            0x1000 , // 706  - sq-xk
+            0x7c1a , // 707  - sr
+            0x6c1a , // 708  - sr-cyrl
+            0x1c1a , // 709  - sr-cyrl-ba
+            0xc1a  , // 710  - sr-cyrl-cs
+            0x301a , // 711  - sr-cyrl-me
+            0x281a , // 712  - sr-cyrl-rs
+            0x1000 , // 713  - sr-cyrl-xk
+            0x701a , // 714  - sr-latn
+            0x181a , // 715  - sr-latn-ba
+            0x81a  , // 716  - sr-latn-cs
+            0x2c1a , // 717  - sr-latn-me
+            0x241a , // 718  - sr-latn-rs
+            0x1000 , // 719  - sr-latn-xk
+            0x1000 , // 720  - ss
+            0x1000 , // 721  - ss-sz
+            0x1000 , // 722  - ss-za
+            0x1000 , // 723  - ssy
+            0x1000 , // 724  - ssy-er
+            0x30   , // 725  - st
+            0x1000 , // 726  - st-ls
+            0x430  , // 727  - st-za
+            0x1d   , // 728  - sv
+            0x1000 , // 729  - sv-ax
+            0x81d  , // 730  - sv-fi
+            0x41d  , // 731  - sv-se
+            0x41   , // 732  - sw
+            0x1000 , // 733  - sw-cd
+            0x441  , // 734  - sw-ke
+            0x1000 , // 735  - sw-tz
+            0x1000 , // 736  - sw-ug
+            0x1000 , // 737  - swc
+            0x1000 , // 738  - swc-cd
+            0x5a   , // 739  - syr
+            0x45a  , // 740  - syr-sy
+            0x49   , // 741  - ta
+            0x449  , // 742  - ta-in
+            0x849  , // 743  - ta-lk
+            0x1000 , // 744  - ta-my
+            0x1000 , // 745  - ta-sg
+            0x4a   , // 746  - te
+            0x44a  , // 747  - te-in
+            0x1000 , // 748  - teo
+            0x1000 , // 749  - teo-ke
+            0x1000 , // 750  - teo-ug
+            0x28   , // 751  - tg
+            0x7c28 , // 752  - tg-cyrl
+            0x428  , // 753  - tg-cyrl-tj
+            0x1e   , // 754  - th
+            0x41e  , // 755  - th-th
+            0x73   , // 756  - ti
+            0x873  , // 757  - ti-er
+            0x473  , // 758  - ti-et
+            0x1000 , // 759  - tig
+            0x1000 , // 760  - tig-er
+            0x42   , // 761  - tk
+            0x442  , // 762  - tk-tm
+            0x32   , // 763  - tn
+            0x832  , // 764  - tn-bw
+            0x432  , // 765  - tn-za
+            0x1000 , // 766  - to
+            0x1000 , // 767  - to-to
+            0x1f   , // 768  - tr
+            0x1000 , // 769  - tr-cy
+            0x41f  , // 770  - tr-tr
+            0x31   , // 771  - ts
+            0x431  , // 772  - ts-za
+            0x44   , // 773  - tt
+            0x444  , // 774  - tt-ru
+            0x1000 , // 775  - twq
+            0x1000 , // 776  - twq-ne
+            0x5f   , // 777  - tzm
+            0x1000 , // 778  - tzm-arab
+            0x45f  , // 779  - tzm-arab-ma
+            0x7c5f , // 780  - tzm-latn
+            0x85f  , // 781  - tzm-latn-dz
+            0x1000 , // 782  - tzm-latn-ma
+            0x785f , // 783  - tzm-tfng
+            0x105f , // 784  - tzm-tfng-ma
+            0x80   , // 785  - ug
+            0x480  , // 786  - ug-cn
+            0x22   , // 787  - uk
+            0x422  , // 788  - uk-ua
+            0x20   , // 789  - ur
+            0x820  , // 790  - ur-in
+            0x420  , // 791  - ur-pk
+            0x43   , // 792  - uz
+            0x1000 , // 793  - uz-arab
+            0x1000 , // 794  - uz-arab-af
+            0x7843 , // 795  - uz-cyrl
+            0x843  , // 796  - uz-cyrl-uz
+            0x7c43 , // 797  - uz-latn
+            0x443  , // 798  - uz-latn-uz
+            0x1000 , // 799  - vai
+            0x1000 , // 800  - vai-latn
+            0x1000 , // 801  - vai-latn-lr
+            0x1000 , // 802  - vai-vaii
+            0x1000 , // 803  - vai-vaii-lr
+            0x33   , // 804  - ve
+            0x433  , // 805  - ve-za
+            0x2a   , // 806  - vi
+            0x42a  , // 807  - vi-vn
+            0x1000 , // 808  - vo
+            0x1000 , // 809  - vo-001
+            0x1000 , // 810  - vun
+            0x1000 , // 811  - vun-tz
+            0x1000 , // 812  - wae
+            0x1000 , // 813  - wae-ch
+            0x1000 , // 814  - wal
+            0x1000 , // 815  - wal-et
+            0x88   , // 816  - wo
+            0x488  , // 817  - wo-sn
+            0x1007f, // 818  - x-iv_mathan
+            0x34   , // 819  - xh
+            0x434  , // 820  - xh-za
+            0x1000 , // 821  - xog
+            0x1000 , // 822  - xog-ug
+            0x1000 , // 823  - yav
+            0x1000 , // 824  - yav-cm
+            0x3d   , // 825  - yi
+            0x43d  , // 826  - yi-001
+            0x6a   , // 827  - yo
+            0x1000 , // 828  - yo-bj
+            0x46a  , // 829  - yo-ng
+            0x1000 , // 830  - yue-hk
+            0x1000 , // 831  - zgh
+            0x1000 , // 832  - zgh-tfng
+            0x1000 , // 833  - zgh-tfng-ma
+            0x7804 , // 834  - zh
+            0x4    , // 835  - zh-chs
+            0x7c04 , // 836  - zh-cht
+            0x804  , // 837  - zh-cn
+            0x50804, // 838  - zh-cn_phoneb
+            0x20804, // 839  - zh-cn_stroke
+            0x4    , // 840  - zh-hans
+            0x1000 , // 841  - zh-hans-hk
+            0x1000 , // 842  - zh-hans-mo
+            0x7c04 , // 843  - zh-hant
+            0xc04  , // 844  - zh-hk
+            0x40c04, // 845  - zh-hk_radstr
+            0x1404 , // 846  - zh-mo
+            0x41404, // 847  - zh-mo_radstr
+            0x21404, // 848  - zh-mo_stroke
+            0x1004 , // 849  - zh-sg
+            0x51004, // 850  - zh-sg_phoneb
+            0x21004, // 851  - zh-sg_stroke
+            0x404  , // 852  - zh-tw
+            0x30404, // 853  - zh-tw_pronun
+            0x40404, // 854  - zh-tw_radstr
+            0x35   , // 855  - zu
+            0x435  , // 856  - zu-za
+            0x0    , // 857  -        
+        };
+        
+        
+        // s_lcids list all supported lcids. used to binary search and we use the index of the matched lcid to 
+        // get the index in s_localeNamesIndices using s_lcidToCultureNameIndecis
+        private static readonly int[] s_lcids = new int[]
+        {
+           // Lcid , index   - index in  
+            0x1    , // 0    - 52
+            0x2    , // 1    - 301
+            0x3    , // 2    - 421
+            0x4    , // 3    - 4120
+            0x5    , // 4    - 500
+            0x6    , // 5    - 519
+            0x7    , // 6    - 540
+            0x8    , // 7    - 660
+            0x9    , // 8    - 672
+            0xa    , // 9    - 1210
+            0xb    , // 10   - 1419
+            0xc    , // 11   - 1447
+            0xd    , // 12   - 1821
+            0xe    , // 13   - 1856
+            0xf    , // 14   - 1925
+            0x10   , // 15   - 1932
+            0x11   , // 16   - 1985
+            0x12   , // 17   - 2175
+            0x13   , // 18   - 2672
+            0x14   , // 19   - 2734
+            0x15   , // 20   - 2851
+            0x16   , // 21   - 2881
+            0x17   , // 22   - 3025
+            0x18   , // 23   - 3039
+            0x19   , // 24   - 3060
+            0x1a   , // 25   - 1835
+            0x1b   , // 26   - 3268
+            0x1c   , // 27   - 3371
+            0x1d   , // 28   - 3537
+            0x1e   , // 29   - 3657
+            0x1f   , // 30   - 3711
+            0x20   , // 31   - 3831
+            0x21   , // 32   - 1904
+            0x22   , // 33   - 3824
+            0x23   , // 34   - 276
+            0x24   , // 35   - 3275
+            0x25   , // 36   - 1350
+            0x26   , // 37   - 2422
+            0x27   , // 38   - 2390
+            0x28   , // 39   - 3638
+            0x29   , // 40   - 1373
+            0x2a   , // 41   - 3944
+            0x2b   , // 42   - 1875
+            0x2c   , // 43   - 224
+            0x2d   , // 44   - 1357
+            0x2e   , // 45   - 1847
+            0x2f   , // 46   - 2494
+            0x30   , // 47   - 3525
+            0x31   , // 48   - 3723
+            0x32   , // 49   - 3692
+            0x33   , // 50   - 3937
+            0x34   , // 51   - 4004
+            0x35   , // 52   - 4258
+            0x36   , // 53   - 17
+            0x37   , // 54   - 2058
+            0x38   , // 55   - 1435
+            0x39   , // 56   - 1828
+            0x3a   , // 57   - 2591
+            0x3b   , // 58   - 3178
+            0x3c   , // 59   - 1701
+            0x3d   , // 60   - 4029
+            0x3e   , // 61   - 2574
+            0x3f   , // 62   - 2129
+            0x40   , // 63   - 2302
+            0x41   , // 64   - 3554
+            0x42   , // 65   - 3685
+            0x43   , // 66   - 3843
+            0x44   , // 67   - 3730
+            0x45   , // 68   - 336
+            0x46   , // 69   - 2817
+            0x47   , // 70   - 1750
+            0x48   , // 71   - 2798
+            0x49   , // 72   - 3594
+            0x4a   , // 73   - 3616
+            0x4b   , // 74   - 2168
+            0x4c   , // 75   - 2501
+            0x4d   , // 76   - 199
+            0x4e   , // 77   - 2567
+            0x4f   , // 78   - 3108
+            0x50   , // 79   - 2508
+            0x51   , // 80   - 348
+            0x52   , // 81   - 512
+            0x53   , // 82   - 2161
+            0x54   , // 83   - 2371
+            0x55   , // 84   - 2607
+            0x56   , // 85   - 1715
+            0x57   , // 86   - 2187
+            0x58   , // 87   - 2549
+            0x59   , // 88   - 3142
+            0x5a   , // 89   - 3585
+            0x5b   , // 90   - 3261
+            0x5c   , // 91   - 471
+            0x5d   , // 92   - 1949
+            0x5e   , // 93   - 45
+            0x5f   , // 94   - 3746
+            0x60   , // 95   - 2203
+            0x61   , // 96   - 2660
+            0x62   , // 97   - 1694
+            0x63   , // 98   - 2874
+            0x64   , // 99   - 1426
+            0x65   , // 100  - 616
+            0x66   , // 101  - 308
+            0x67   , // 102  - 1380
+            0x68   , // 103  - 1773
+            0x69   , // 104  - 1895
+            0x6a   , // 105  - 4037
+            0x6b   , // 106  - 3004
+            0x6c   , // 107  - 2752
+            0x6d   , // 108  - 260
+            0x6e   , // 109  - 2326
+            0x6f   , // 110  - 2145
+            0x70   , // 111  - 1911
+            0x71   , // 112  - 2196
+            0x72   , // 113  - 2786
+            0x73   , // 114  - 3664
+            0x74   , // 115  - 1722
+            0x75   , // 116  - 1812
+            0x76   , // 117  - 2309
+            0x77   , // 118  - 3349
+            0x78   , // 119  - 1918
+            0x79   , // 120  - 2841
+            0x7a   , // 121  - 190
+            0x7c   , // 122  - 2558
+            0x7e   , // 123  - 360
+            0x80   , // 124  - 3817
+            0x81   , // 125  - 2487
+            0x82   , // 126  - 2779
+            0x83   , // 127  - 493
+            0x84   , // 128  - 1729
+            0x85   , // 129  - 3115
+            0x86   , // 130  - 2982
+            0x87   , // 131  - 3092
+            0x88   , // 132  - 3986
+            0x8c   , // 133  - 2865
+            0x91   , // 134  - 1708
+            0x92   , // 135  - 2266
+            0x401  , // 136  - 150
+            0x402  , // 137  - 303
+            0x403  , // 138  - 428
+            0x404  , // 139  - 4229
+            0x405  , // 140  - 502
+            0x406  , // 141  - 521
+            0x407  , // 142  - 557
+            0x408  , // 143  - 667
+            0x409  , // 144  - 1157
+            0x40a  , // 145  - 1268
+            0x40b  , // 146  - 1421
+            0x40c  , // 147  - 1525
+            0x40d  , // 148  - 1823
+            0x40e  , // 149  - 1858
+            0x40f  , // 150  - 1927
+            0x410  , // 151  - 1939
+            0x411  , // 152  - 1987
+            0x412  , // 153  - 2182
+            0x413  , // 154  - 2694
+            0x414  , // 155  - 2631
+            0x415  , // 156  - 2853
+            0x416  , // 157  - 2888
+            0x417  , // 158  - 3027
+            0x418  , // 159  - 3046
+            0x419  , // 160  - 3082
+            0x41a  , // 161  - 1842
+            0x41b  , // 162  - 3270
+            0x41c  , // 163  - 3373
+            0x41d  , // 164  - 3549
+            0x41e  , // 165  - 3659
+            0x41f  , // 166  - 3718
+            0x420  , // 167  - 3838
+            0x421  , // 168  - 1906
+            0x422  , // 169  - 3826
+            0x423  , // 170  - 278
+            0x424  , // 171  - 3277
+            0x425  , // 172  - 1352
+            0x426  , // 173  - 2424
+            0x427  , // 174  - 2392
+            0x428  , // 175  - 3647
+            0x429  , // 176  - 1375
+            0x42a  , // 177  - 3946
+            0x42b  , // 178  - 1877
+            0x42c  , // 179  - 250
+            0x42d  , // 180  - 1359
+            0x42e  , // 181  - 1850
+            0x42f  , // 182  - 2496
+            0x430  , // 183  - 3532
+            0x431  , // 184  - 3725
+            0x432  , // 185  - 3699
+            0x433  , // 186  - 3939
+            0x434  , // 187  - 4006
+            0x435  , // 188  - 4260
+            0x436  , // 189  - 24
+            0x437  , // 190  - 2060
+            0x438  , // 191  - 1442
+            0x439  , // 192  - 1830
+            0x43a  , // 193  - 2593
+            0x43b  , // 194  - 3185
+            0x43d  , // 195  - 4031
+            0x43e  , // 196  - 2581
+            0x43f  , // 197  - 2131
+            0x440  , // 198  - 2304
+            0x441  , // 199  - 3561
+            0x442  , // 200  - 3687
+            0x443  , // 201  - 3886
+            0x444  , // 202  - 3732
+            0x445  , // 203  - 343
+            0x446  , // 204  - 2836
+            0x447  , // 205  - 1752
+            0x448  , // 206  - 2800
+            0x449  , // 207  - 3596
+            0x44a  , // 208  - 3618
+            0x44b  , // 209  - 2170
+            0x44c  , // 210  - 2503
+            0x44d  , // 211  - 201
+            0x44e  , // 212  - 2569
+            0x44f  , // 213  - 3110
+            0x450  , // 214  - 2517
+            0x451  , // 215  - 350
+            0x452  , // 216  - 514
+            0x453  , // 217  - 2163
+            0x454  , // 218  - 2373
+            0x455  , // 219  - 2609
+            0x456  , // 220  - 1717
+            0x457  , // 221  - 2190
+            0x458  , // 222  - 2552
+            0x459  , // 223  - 3168
+            0x45a  , // 224  - 3588
+            0x45b  , // 225  - 3263
+            0x45c  , // 226  - 482
+            0x45d  , // 227  - 1958
+            0x45e  , // 228  - 47
+            0x45f  , // 229  - 3757
+            0x460  , // 230  - 2205
+            0x461  , // 231  - 2667
+            0x462  , // 232  - 1696
+            0x463  , // 233  - 2876
+            0x464  , // 234  - 1429
+            0x465  , // 235  - 618
+            0x466  , // 236  - 311
+            0x467  , // 237  - 1414
+            0x468  , // 238  - 1802
+            0x469  , // 239  - 1898
+            0x46a  , // 240  - 4044
+            0x46b  , // 241  - 3007
+            0x46c  , // 242  - 2755
+            0x46d  , // 243  - 262
+            0x46e  , // 244  - 2328
+            0x46f  , // 245  - 2147
+            0x470  , // 246  - 1913
+            0x471  , // 247  - 2198
+            0x472  , // 248  - 2788
+            0x473  , // 249  - 3671
+            0x474  , // 250  - 1724
+            0x475  , // 251  - 1815
+            0x476  , // 252  - 2311
+            0x477  , // 253  - 3366
+            0x478  , // 254  - 1920
+            0x479  , // 255  - 2844
+            0x47a  , // 256  - 193
+            0x47c  , // 257  - 2561
+            0x47e  , // 258  - 362
+            0x480  , // 259  - 3819
+            0x481  , // 260  - 2489
+            0x482  , // 261  - 2781
+            0x483  , // 262  - 495
+            0x484  , // 263  - 1738
+            0x485  , // 264  - 3118
+            0x486  , // 265  - 2993
+            0x487  , // 266  - 3094
+            0x488  , // 267  - 3988
+            0x48c  , // 268  - 2868
+            0x491  , // 269  - 1710
+            0x492  , // 270  - 2275
+            0x501  , // 271  - 2956
+            0x5fe  , // 272  - 2964
+            0x801  , // 273  - 95
+            0x803  , // 274  - 433
+            0x804  , // 275  - 4091
+            0x807  , // 276  - 552
+            0x809  , // 277  - 827
+            0x80a  , // 278  - 1295
+            0x80c  , // 279  - 1455
+            0x810  , // 280  - 1934
+            0x813  , // 281  - 2679
+            0x814  , // 282  - 2720
+            0x816  , // 283  - 2928
+            0x818  , // 284  - 3041
+            0x819  , // 285  - 3077
+            0x81a  , // 286  - 3464
+            0x81d  , // 287  - 3544
+            0x820  , // 288  - 3833
+            0x82c  , // 289  - 233
+            0x82e  , // 290  - 601
+            0x832  , // 291  - 3694
+            0x83b  , // 292  - 3190
+            0x83c  , // 293  - 1703
+            0x83e  , // 294  - 2576
+            0x843  , // 295  - 3869
+            0x845  , // 296  - 338
+            0x846  , // 297  - 2826
+            0x849  , // 298  - 3601
+            0x850  , // 299  - 2529
+            0x859  , // 300  - 3151
+            0x85d  , // 301  - 1975
+            0x85f  , // 302  - 3776
+            0x860  , // 303  - 2229
+            0x861  , // 304  - 2662
+            0x867  , // 305  - 1399
+            0x86b  , // 306  - 3013
+            0x873  , // 307  - 3666
+            0x901  , // 308  - 2943
+            0x9ff  , // 309  - 2973
+            0xc01  , // 310  - 80
+            0xc04  , // 311  - 4154
+            0xc07  , // 312  - 542
+            0xc09  , // 313  - 712
+            0xc0a  , // 314  - 1263
+            0xc0c  , // 315  - 1480
+            0xc1a  , // 316  - 3407
+            0xc3b  , // 317  - 3180
+            0xc50  , // 318  - 2539
+            0xc51  , // 319  - 634
+            0xc6b  , // 320  - 3019
+            0x1001 , // 321  - 120
+            0x1004 , // 322  - 4200
+            0x1007 , // 323  - 584
+            0x1009 , // 324  - 752
+            0x100a , // 325  - 1285
+            0x100c , // 326  - 1500
+            0x101a , // 327  - 1837
+            0x103b , // 328  - 3300
+            0x105f , // 329  - 3806
+            0x1401 , // 330  - 75
+            0x1404 , // 331  - 4171
+            0x1407 , // 332  - 579
+            0x1409 , // 333  - 1022
+            0x140a , // 334  - 1243
+            0x140c , // 335  - 1565
+            0x141a , // 336  - 402
+            0x143b , // 337  - 3306
+            0x1801 , // 338  - 125
+            0x1809 , // 339  - 877
+            0x180a , // 340  - 1305
+            0x180c , // 341  - 1575
+            0x181a , // 342  - 3454
+            0x183b , // 343  - 3285
+            0x1c01 , // 344  - 180
+            0x1c09 , // 345  - 1187
+            0x1c0a , // 346  - 1253
+            0x1c0c , // 347  - 1449
+            0x1c1a , // 348  - 3397
+            0x1c3b , // 349  - 3291
+            0x2001 , // 350  - 135
+            0x2009 , // 351  - 907
+            0x200a , // 352  - 1345
+            0x200c , // 353  - 1630
+            0x201a , // 354  - 385
+            0x203b , // 355  - 3324
+            0x2401 , // 356  - 185
+            0x2409 , // 357  - 680
+            0x240a , // 358  - 1238
+            0x240c , // 359  - 1485
+            0x241a , // 360  - 3484
+            0x243b , // 361  - 3315
+            0x2801 , // 362  - 170
+            0x2809 , // 363  - 747
+            0x280a , // 364  - 1310
+            0x280c , // 365  - 1645
+            0x281a , // 366  - 3427
+            0x2c01 , // 367  - 100
+            0x2c09 , // 368  - 1132
+            0x2c0a , // 369  - 1218
+            0x2c0c , // 370  - 1510
+            0x2c1a , // 371  - 3474
+            0x3001 , // 372  - 115
+            0x3009 , // 373  - 1197
+            0x300a , // 374  - 1258
+            0x300c , // 375  - 1505
+            0x301a , // 376  - 3417
+            0x3401 , // 377  - 110
+            0x3409 , // 378  - 1032
+            0x340a , // 379  - 1233
+            0x340c , // 380  - 1590
+            0x3801 , // 381  - 60
+            0x3809 , // 382  - 872
+            0x380a , // 383  - 1340
+            0x380c , // 384  - 1570
+            0x3c01 , // 385  - 65
+            0x3c09 , // 386  - 867
+            0x3c0a , // 387  - 1325
+            0x3c0c , // 388  - 1555
+            0x4001 , // 389  - 145
+            0x4009 , // 390  - 892
+            0x400a , // 391  - 1223
+            0x4409 , // 392  - 987
+            0x440a , // 393  - 1330
+            0x4809 , // 394  - 1082
+            0x480a , // 395  - 1290
+            0x4c0a , // 396  - 1300
+            0x500a , // 397  - 1320
+            0x540a , // 398  - 1335
+            0x580a , // 399  - 1212
+            0x5c0a , // 400  - 1248
+            0x641a , // 401  - 378
+            0x681a , // 402  - 395
+            0x6c1a , // 403  - 3390
+            0x701a , // 404  - 3447
+            0x703b , // 405  - 3312
+            0x742c , // 406  - 226
+            0x743b , // 407  - 3321
+            0x7804 , // 408  - 4077
+            0x7814 , // 409  - 2718
+            0x781a , // 410  - 376
+            0x782c , // 411  - 243
+            0x783b , // 412  - 3282
+            0x7843 , // 413  - 3862
+            0x7850 , // 414  - 2510
+            0x785d , // 415  - 1951
+            0x785f , // 416  - 3798
+            0x7c04 , // 417  - 4147
+            0x7c14 , // 418  - 2629
+            0x7c1a , // 419  - 3388
+            0x7c28 , // 420  - 3640
+            0x7c2e , // 421  - 598
+            0x7c3b , // 422  - 3297
+            0x7c43 , // 423  - 3879
+            0x7c46 , // 424  - 2819
+            0x7c50 , // 425  - 2522
+            0x7c59 , // 426  - 3144
+            0x7c5c , // 427  - 474
+            0x7c5d , // 428  - 1968
+            0x7c5f , // 429  - 3768
+            0x7c67 , // 430  - 1392
+            0x7c68 , // 431  - 1775
+            0x7c86 , // 432  - 2985
+            0x7c92 , // 433  - 2268
+            0x1007f, // 434  - 3993
+            0x10407, // 435  - 562
+            0x1040e, // 436  - 1863
+            0x10437, // 437  - 2065
+            0x20804, // 438  - 4108
+            0x21004, // 439  - 4217
+            0x21404, // 440  - 4188
+            0x30404, // 441  - 4234
+            0x40404, // 442  - 4246
+            0x40411, // 443  - 1992
+            0x40c04, // 444  - 4159
+            0x41404, // 445  - 4176
+            0x50804, // 446  - 4096
+            0x51004, // 447  - 4205
+        };        
+        
+        // each element in s_lcidToCultureNameIndecis is index to s_localeNamesIndices
+        private static readonly int[] s_lcidToCultureNameIndecis = new int[]
+        {
+        // Index to s_localeNamesIndices, index to this array - lcid  - index to the c_localeNames    
+            13   , // 0    - 1     - 52
+            64   , // 1    - 2     - 301
+            88   , // 2    - 3     - 421
+            840  , // 3    - 4     - 4120
+            102  , // 4    - 5     - 500
+            107  , // 5    - 6     - 519
+            112  , // 6    - 7     - 540
+            138  , // 7    - 8     - 660
+            141  , // 8    - 9     - 672
+            249  , // 9    - a     - 1210
+            291  , // 10   - b     - 1419
+            298  , // 11   - c     - 1447
+            375  , // 12   - d     - 1821
+            384  , // 13   - e     - 1856
+            400  , // 14   - f     - 1925
+            402  , // 15   - 10    - 1932
+            411  , // 16   - 11    - 1985
+            450  , // 17   - 12    - 2175
+            559  , // 18   - 13    - 2672
+            573  , // 19   - 14    - 2734
+            600  , // 20   - 15    - 2851
+            607  , // 21   - 16    - 2881
+            631  , // 22   - 17    - 3025
+            635  , // 23   - 18    - 3039
+            640  , // 24   - 19    - 3060
+            379  , // 25   - 1a    - 1835
+            681  , // 26   - 1b    - 3268
+            703  , // 27   - 1c    - 3371
+            728  , // 28   - 1d    - 3537
+            754  , // 29   - 1e    - 3657
+            768  , // 30   - 1f    - 3711
+            789  , // 31   - 20    - 3831
+            394  , // 32   - 21    - 1904
+            787  , // 33   - 22    - 3824
+            58   , // 34   - 23    - 276
+            683  , // 35   - 24    - 3275
+            276  , // 36   - 25    - 1350
+            503  , // 37   - 26    - 2422
+            495  , // 38   - 27    - 2390
+            751  , // 39   - 28    - 3638
+            282  , // 40   - 29    - 1373
+            806  , // 41   - 2a    - 3944
+            387  , // 42   - 2b    - 1875
+            49   , // 43   - 2c    - 224
+            278  , // 44   - 2d    - 1357
+            382  , // 45   - 2e    - 1847
+            520  , // 46   - 2f    - 2494
+            725  , // 47   - 30    - 3525
+            771  , // 48   - 31    - 3723
+            763  , // 49   - 32    - 3692
+            804  , // 50   - 33    - 3937
+            819  , // 51   - 34    - 4004
+            855  , // 52   - 35    - 4258
+            4    , // 53   - 36    - 17
+            423  , // 54   - 37    - 2058
+            295  , // 55   - 38    - 1435
+            377  , // 56   - 39    - 1828
+            540  , // 57   - 3a    - 2591
+            664  , // 58   - 3b    - 3178
+            350  , // 59   - 3c    - 1701
+            825  , // 60   - 3d    - 4029
+            536  , // 61   - 3e    - 2574
+            438  , // 62   - 3f    - 2129
+            474  , // 63   - 40    - 2302
+            732  , // 64   - 41    - 3554
+            761  , // 65   - 42    - 3685
+            792  , // 66   - 43    - 3843
+            773  , // 67   - 44    - 3730
+            71   , // 68   - 45    - 336
+            594  , // 69   - 46    - 2817
+            362  , // 70   - 47    - 1750
+            589  , // 71   - 48    - 2798
+            741  , // 72   - 49    - 3594
+            746  , // 73   - 4a    - 3616
+            448  , // 74   - 4b    - 2168
+            522  , // 75   - 4c    - 2501
+            43   , // 76   - 4d    - 199
+            534  , // 77   - 4e    - 2567
+            651  , // 78   - 4f    - 3108
+            524  , // 79   - 50    - 2508
+            74   , // 80   - 51    - 348
+            105  , // 81   - 52    - 512
+            446  , // 82   - 53    - 2161
+            491  , // 83   - 54    - 2371
+            544  , // 84   - 55    - 2607
+            354  , // 85   - 56    - 1715
+            453  , // 86   - 57    - 2187
+            530  , // 87   - 58    - 2549
+            659  , // 88   - 59    - 3142
+            739  , // 89   - 5a    - 3585
+            679  , // 90   - 5b    - 3261
+            97   , // 91   - 5c    - 471
+            406  , // 92   - 5d    - 1949
+            11   , // 93   - 5e    - 45
+            777  , // 94   - 5f    - 3746
+            457  , // 95   - 60    - 2203
+            556  , // 96   - 61    - 2660
+            348  , // 97   - 62    - 1694
+            605  , // 98   - 63    - 2874
+            293  , // 99   - 64    - 1426
+            127  , // 100  - 65    - 616
+            66   , // 101  - 66    - 308
+            284  , // 102  - 67    - 1380
+            368  , // 103  - 68    - 1773
+            392  , // 104  - 69    - 1895
+            827  , // 105  - 6a    - 4037
+            627  , // 106  - 6b    - 3004
+            578  , // 107  - 6c    - 2752
+            54   , // 108  - 6d    - 260
+            480  , // 109  - 6e    - 2326
+            442  , // 110  - 6f    - 2145
+            396  , // 111  - 70    - 1911
+            455  , // 112  - 71    - 2196
+            586  , // 113  - 72    - 2786
+            756  , // 114  - 73    - 3664
+            356  , // 115  - 74    - 1722
+            373  , // 116  - 75    - 1812
+            476  , // 117  - 76    - 2309
+            698  , // 118  - 77    - 3349
+            398  , // 119  - 78    - 1918
+            598  , // 120  - 79    - 2841
+            41   , // 121  - 7a    - 190
+            532  , // 122  - 7c    - 2558
+            77   , // 123  - 7e    - 360
+            785  , // 124  - 80    - 3817
+            518  , // 125  - 81    - 2487
+            584  , // 126  - 82    - 2779
+            100  , // 127  - 83    - 493
+            358  , // 128  - 84    - 1729
+            653  , // 129  - 85    - 3115
+            624  , // 130  - 86    - 2982
+            647  , // 131  - 87    - 3092
+            816  , // 132  - 88    - 3986
+            603  , // 133  - 8c    - 2865
+            352  , // 134  - 91    - 1708
+            468  , // 135  - 92    - 2266
+            33   , // 136  - 401   - 150
+            65   , // 137  - 402   - 303
+            90   , // 138  - 403   - 428
+            852  , // 139  - 404   - 4229
+            103  , // 140  - 405   - 502
+            108  , // 141  - 406   - 521
+            116  , // 142  - 407   - 557
+            140  , // 143  - 408   - 667
+            238  , // 144  - 409   - 1157
+            261  , // 145  - 40a   - 1268
+            292  , // 146  - 40b   - 1421
+            314  , // 147  - 40c   - 1525
+            376  , // 148  - 40d   - 1823
+            385  , // 149  - 40e   - 1858
+            401  , // 150  - 40f   - 1927
+            404  , // 151  - 410   - 1939
+            412  , // 152  - 411   - 1987
+            452  , // 153  - 412   - 2182
+            564  , // 154  - 413   - 2694
+            550  , // 155  - 414   - 2631
+            601  , // 156  - 415   - 2853
+            609  , // 157  - 416   - 2888
+            632  , // 158  - 417   - 3027
+            637  , // 159  - 418   - 3046
+            645  , // 160  - 419   - 3082
+            381  , // 161  - 41a   - 1842
+            682  , // 162  - 41b   - 3270
+            704  , // 163  - 41c   - 3373
+            731  , // 164  - 41d   - 3549
+            755  , // 165  - 41e   - 3659
+            770  , // 166  - 41f   - 3718
+            791  , // 167  - 420   - 3838
+            395  , // 168  - 421   - 1906
+            788  , // 169  - 422   - 3826
+            59   , // 170  - 423   - 278
+            684  , // 171  - 424   - 3277
+            277  , // 172  - 425   - 1352
+            504  , // 173  - 426   - 2424
+            496  , // 174  - 427   - 2392
+            753  , // 175  - 428   - 3647
+            283  , // 176  - 429   - 1375
+            807  , // 177  - 42a   - 3946
+            388  , // 178  - 42b   - 1877
+            53   , // 179  - 42c   - 250
+            279  , // 180  - 42d   - 1359
+            383  , // 181  - 42e   - 1850
+            521  , // 182  - 42f   - 2496
+            727  , // 183  - 430   - 3532
+            772  , // 184  - 431   - 3725
+            765  , // 185  - 432   - 3699
+            805  , // 186  - 433   - 3939
+            820  , // 187  - 434   - 4006
+            856  , // 188  - 435   - 4260
+            6    , // 189  - 436   - 24
+            424  , // 190  - 437   - 2060
+            297  , // 191  - 438   - 1442
+            378  , // 192  - 439   - 1830
+            541  , // 193  - 43a   - 2593
+            666  , // 194  - 43b   - 3185
+            826  , // 195  - 43d   - 4031
+            538  , // 196  - 43e   - 2581
+            439  , // 197  - 43f   - 2131
+            475  , // 198  - 440   - 2304
+            734  , // 199  - 441   - 3561
+            762  , // 200  - 442   - 3687
+            798  , // 201  - 443   - 3886
+            774  , // 202  - 444   - 3732
+            73   , // 203  - 445   - 343
+            597  , // 204  - 446   - 2836
+            363  , // 205  - 447   - 1752
+            590  , // 206  - 448   - 2800
+            742  , // 207  - 449   - 3596
+            747  , // 208  - 44a   - 3618
+            449  , // 209  - 44b   - 2170
+            523  , // 210  - 44c   - 2503
+            44   , // 211  - 44d   - 201
+            535  , // 212  - 44e   - 2569
+            652  , // 213  - 44f   - 3110
+            526  , // 214  - 450   - 2517
+            75   , // 215  - 451   - 350
+            106  , // 216  - 452   - 514
+            447  , // 217  - 453   - 2163
+            492  , // 218  - 454   - 2373
+            545  , // 219  - 455   - 2609
+            355  , // 220  - 456   - 1717
+            454  , // 221  - 457   - 2190
+            531  , // 222  - 458   - 2552
+            663  , // 223  - 459   - 3168
+            740  , // 224  - 45a   - 3588
+            680  , // 225  - 45b   - 3263
+            99   , // 226  - 45c   - 482
+            408  , // 227  - 45d   - 1958
+            12   , // 228  - 45e   - 47
+            779  , // 229  - 45f   - 3757
+            458  , // 230  - 460   - 2205
+            558  , // 231  - 461   - 2667
+            349  , // 232  - 462   - 1696
+            606  , // 233  - 463   - 2876
+            294  , // 234  - 464   - 1429
+            128  , // 235  - 465   - 618
+            67   , // 236  - 466   - 311
+            290  , // 237  - 467   - 1414
+            372  , // 238  - 468   - 1802
+            393  , // 239  - 469   - 1898
+            829  , // 240  - 46a   - 4044
+            628  , // 241  - 46b   - 3007
+            579  , // 242  - 46c   - 2755
+            55   , // 243  - 46d   - 262
+            481  , // 244  - 46e   - 2328
+            443  , // 245  - 46f   - 2147
+            397  , // 246  - 470   - 1913
+            456  , // 247  - 471   - 2198
+            587  , // 248  - 472   - 2788
+            758  , // 249  - 473   - 3671
+            357  , // 250  - 474   - 1724
+            374  , // 251  - 475   - 1815
+            477  , // 252  - 476   - 2311
+            702  , // 253  - 477   - 3366
+            399  , // 254  - 478   - 1920
+            599  , // 255  - 479   - 2844
+            42   , // 256  - 47a   - 193
+            533  , // 257  - 47c   - 2561
+            78   , // 258  - 47e   - 362
+            786  , // 259  - 480   - 3819
+            519  , // 260  - 481   - 2489
+            585  , // 261  - 482   - 2781
+            101  , // 262  - 483   - 495
+            360  , // 263  - 484   - 1738
+            654  , // 264  - 485   - 3118
+            626  , // 265  - 486   - 2993
+            648  , // 266  - 487   - 3094
+            817  , // 267  - 488   - 3988
+            604  , // 268  - 48c   - 2868
+            353  , // 269  - 491   - 1710
+            470  , // 270  - 492   - 2275
+            621  , // 271  - 501   - 2956
+            622  , // 272  - 5fe   - 2964
+            22   , // 273  - 801   - 95
+            91   , // 274  - 803   - 433
+            837  , // 275  - 804   - 4091
+            115  , // 276  - 807   - 552
+            172  , // 277  - 809   - 827
+            265  , // 278  - 80a   - 1295
+            300  , // 279  - 80c   - 1455
+            403  , // 280  - 810   - 1934
+            561  , // 281  - 813   - 2679
+            570  , // 282  - 814   - 2720
+            617  , // 283  - 816   - 2928
+            636  , // 284  - 818   - 3041
+            644  , // 285  - 819   - 3077
+            716  , // 286  - 81a   - 3464
+            730  , // 287  - 81d   - 3544
+            790  , // 288  - 820   - 3833
+            51   , // 289  - 82c   - 233
+            124  , // 290  - 82e   - 601
+            764  , // 291  - 832   - 3694
+            667  , // 292  - 83b   - 3190
+            351  , // 293  - 83c   - 1703
+            537  , // 294  - 83e   - 2576
+            796  , // 295  - 843   - 3869
+            72   , // 296  - 845   - 338
+            596  , // 297  - 846   - 2826
+            743  , // 298  - 849   - 3601
+            528  , // 299  - 850   - 2529
+            661  , // 300  - 859   - 3151
+            410  , // 301  - 85d   - 1975
+            781  , // 302  - 85f   - 3776
+            461  , // 303  - 860   - 2229
+            557  , // 304  - 861   - 2662
+            288  , // 305  - 867   - 1399
+            629  , // 306  - 86b   - 3013
+            757  , // 307  - 873   - 3666
+            620  , // 308  - 901   - 2943
+            623  , // 309  - 9ff   - 2973
+            19   , // 310  - c01   - 80
+            844  , // 311  - c04   - 4154
+            113  , // 312  - c07   - 542
+            149  , // 313  - c09   - 712
+            260  , // 314  - c0a   - 1263
+            305  , // 315  - c0c   - 1480
+            710  , // 316  - c1a   - 3407
+            665  , // 317  - c3b   - 3180
+            529  , // 318  - c50   - 2539
+            132  , // 319  - c51   - 634
+            630  , // 320  - c6b   - 3019
+            27   , // 321  - 1001  - 120
+            849  , // 322  - 1004  - 4200
+            120  , // 323  - 1007  - 584
+            157  , // 324  - 1009  - 752
+            263  , // 325  - 100a  - 1285
+            309  , // 326  - 100c  - 1500
+            380  , // 327  - 101a  - 1837
+            689  , // 328  - 103b  - 3300
+            784  , // 329  - 105f  - 3806
+            18   , // 330  - 1401  - 75
+            846  , // 331  - 1404  - 4171
+            119  , // 332  - 1407  - 579
+            211  , // 333  - 1409  - 1022
+            256  , // 334  - 140a  - 1243
+            322  , // 335  - 140c  - 1565
+            85   , // 336  - 141a  - 402
+            690  , // 337  - 143b  - 3306
+            28   , // 338  - 1801  - 125
+            182  , // 339  - 1809  - 877
+            267  , // 340  - 180a  - 1305
+            324  , // 341  - 180c  - 1575
+            715  , // 342  - 181a  - 3454
+            686  , // 343  - 183b  - 3285
+            39   , // 344  - 1c01  - 180
+            244  , // 345  - 1c09  - 1187
+            258  , // 346  - 1c0a  - 1253
+            299  , // 347  - 1c0c  - 1449
+            709  , // 348  - 1c1a  - 3397
+            687  , // 349  - 1c3b  - 3291
+            30   , // 350  - 2001  - 135
+            188  , // 351  - 2009  - 907
+            275  , // 352  - 200a  - 1345
+            335  , // 353  - 200c  - 1630
+            83   , // 354  - 201a  - 385
+            694  , // 355  - 203b  - 3324
+            40   , // 356  - 2401  - 185
+            143  , // 357  - 2409  - 680
+            255  , // 358  - 240a  - 1238
+            306  , // 359  - 240c  - 1485
+            718  , // 360  - 241a  - 3484
+            692  , // 361  - 243b  - 3315
+            37   , // 362  - 2801  - 170
+            156  , // 363  - 2809  - 747
+            268  , // 364  - 280a  - 1310
+            338  , // 365  - 280c  - 1645
+            712  , // 366  - 281a  - 3427
+            23   , // 367  - 2c01  - 100
+            233  , // 368  - 2c09  - 1132
+            251  , // 369  - 2c0a  - 1218
+            311  , // 370  - 2c0c  - 1510
+            717  , // 371  - 2c1a  - 3474
+            26   , // 372  - 3001  - 115
+            246  , // 373  - 3009  - 1197
+            259  , // 374  - 300a  - 1258
+            310  , // 375  - 300c  - 1505
+            711  , // 376  - 301a  - 3417
+            25   , // 377  - 3401  - 110
+            213  , // 378  - 3409  - 1032
+            254  , // 379  - 340a  - 1233
+            327  , // 380  - 340c  - 1590
+            15   , // 381  - 3801  - 60
+            181  , // 382  - 3809  - 872
+            274  , // 383  - 380a  - 1340
+            323  , // 384  - 380c  - 1570
+            16   , // 385  - 3c01  - 65
+            180  , // 386  - 3c09  - 867
+            271  , // 387  - 3c0a  - 1325
+            320  , // 388  - 3c0c  - 1555
+            32   , // 389  - 4001  - 145
+            185  , // 390  - 4009  - 892
+            252  , // 391  - 400a  - 1223
+            204  , // 392  - 4409  - 987
+            272  , // 393  - 440a  - 1330
+            223  , // 394  - 4809  - 1082
+            264  , // 395  - 480a  - 1290
+            266  , // 396  - 4c0a  - 1300
+            270  , // 397  - 500a  - 1320
+            273  , // 398  - 540a  - 1335
+            250  , // 399  - 580a  - 1212
+            257  , // 400  - 5c0a  - 1248
+            82   , // 401  - 641a  - 378
+            84   , // 402  - 681a  - 395
+            708  , // 403  - 6c1a  - 3390
+            714  , // 404  - 701a  - 3447
+            691  , // 405  - 703b  - 3312
+            50   , // 406  - 742c  - 226
+            693  , // 407  - 743b  - 3321
+            834  , // 408  - 7804  - 4077
+            569  , // 409  - 7814  - 2718
+            81   , // 410  - 781a  - 376
+            52   , // 411  - 782c  - 243
+            685  , // 412  - 783b  - 3282
+            795  , // 413  - 7843  - 3862
+            525  , // 414  - 7850  - 2510
+            407  , // 415  - 785d  - 1951
+            783  , // 416  - 785f  - 3798
+            843  , // 417  - 7c04  - 4147
+            549  , // 418  - 7c14  - 2629
+            707  , // 419  - 7c1a  - 3388
+            752  , // 420  - 7c28  - 3640
+            123  , // 421  - 7c2e  - 598
+            688  , // 422  - 7c3b  - 3297
+            797  , // 423  - 7c43  - 3879
+            595  , // 424  - 7c46  - 2819
+            527  , // 425  - 7c50  - 2522
+            660  , // 426  - 7c59  - 3144
+            98   , // 427  - 7c5c  - 474
+            409  , // 428  - 7c5d  - 1968
+            780  , // 429  - 7c5f  - 3768
+            287  , // 430  - 7c67  - 1392
+            369  , // 431  - 7c68  - 1775
+            625  , // 432  - 7c86  - 2985
+            469  , // 433  - 7c92  - 2268
+            818  , // 434  - 1007f - 3993
+            117  , // 435  - 10407 - 562
+            386  , // 436  - 1040e - 1863
+            425  , // 437  - 10437 - 2065
+            839  , // 438  - 20804 - 4108
+            851  , // 439  - 21004 - 4217
+            848  , // 440  - 21404 - 4188
+            853  , // 441  - 30404 - 4234
+            854  , // 442  - 40404 - 4246
+            413  , // 443  - 40411 - 1992
+            845  , // 444  - 40c04 - 4159
+            847  , // 445  - 41404 - 4176
+            838  , // 446  - 50804 - 4096
+            850  , // 447  - 51004 - 4205            
+        };
+        
         /// <summary>
         /// This method uses the sRealName field (which is initialized by the constructor before this is called) to
         /// initialize the rest of the state of CultureData based on the underlying OS globalization library.
@@ -26,7 +3532,7 @@ namespace System.Globalization
         private unsafe bool InitCultureData()
         {
             Contract.Assert(_sRealName != null);
-
+            
             string alternateSortName = string.Empty;
             string realNameBuffer = _sRealName;
 
@@ -71,18 +3577,15 @@ namespace System.Globalization
             _iLanguage = this.ILANGUAGE;
             if (_iLanguage == 0)
             {
-                _iLanguage = LOCALE_CUSTOM_UNSPECIFIED;
+                _iLanguage = CultureInfo.LOCALE_CUSTOM_UNSPECIFIED;
             }
 
             _bNeutral = (this.SISO3166CTRYNAME.Length == 0);
 
             // Remove the sort from sName unless custom culture
-            if (!_bNeutral)
+            if (index>0 && !_bNeutral && !IsCustomCultureId(_iLanguage))
             {
-                if (!IsCustomCultureId(_iLanguage))
-                {
-                    _sName = _sWindowsName.Substring(0, index);
-                }
+                _sName = _sWindowsName.Substring(0, index);
             }
             return true;
         }
@@ -120,7 +3623,7 @@ namespace System.Globalization
             windowsName = StringBuilderCache.GetStringAndRelease(sb); // the name passed to subsequent ICU calls
             return true;
         }
-
+        
         private string GetLocaleInfo(LocaleStringData type)
         {
             Contract.Assert(_sWindowsName != null, "[CultureData.GetLocaleInfo] Expected _sWindowsName to be populated already");
@@ -300,5 +3803,119 @@ namespace System.Globalization
 
             return StringBuilderCache.GetStringAndRelease(sb);
         }
+        
+        private static string LCIDToLocaleName(int culture)
+        {
+            int left = 0;
+            int right = s_lcids.Length - 1;
+            int index;
+
+            Contract.Assert(s_lcids.Length == s_lcidToCultureNameIndecis.Length);
+
+            while (left <= right)
+            {
+                index = (right + left) / 2;
+
+                if (culture == s_lcids[index])
+                {
+                    int indexToLocaleNamesIndices = s_lcidToCultureNameIndecis[index];
+                    Contract.Assert(indexToLocaleNamesIndices < s_localeNamesIndices.Length - 1);
+                    
+                    return c_localeNames.Substring(s_localeNamesIndices[indexToLocaleNamesIndices], 
+                                                                         s_localeNamesIndices[indexToLocaleNamesIndices + 1] - 
+                                                                         s_localeNamesIndices[indexToLocaleNamesIndices]);
+                }
+                else if (culture < s_lcids[index])
+                {
+                    right = index - 1;
+                }
+                else
+                {
+                    left = index + 1;
+                }
+            }
+
+            return null;
+        }
+
+        private static int LocaleNameToLCID(string cultureName)
+        {
+            int index = SearchCultureName(cultureName);
+            if (index < 0)
+            {
+                return CultureInfo.LOCALE_CUSTOM_UNSPECIFIED; 
+            }
+            
+            Contract.Assert(s_localeNamesIndices.Length == s_nameIndexTolcids.Length && index < s_localeNamesIndices.Length);
+            
+            return s_nameIndexTolcids[index];
+        }
+        
+        
+        // SearchCultureName will binary search c_localeNames using s_localeNamesIndices.
+        // return index in s_localeNamesIndices, or -1 if it fail finding any match   
+        private static int SearchCultureName(string name)
+        {
+            int left = 0;
+            int right = s_localeNamesIndices.Length - 2;
+            int index;
+            int result;
+
+            Contract.Assert(s_localeNamesIndices[s_localeNamesIndices.Length - 1] == c_localeNames.Length);
+
+            name = AnsiToLower(name);
+
+            // Binary search the array until we have only a couple of elements left and then
+            // just walk those elements.
+            while ((right - left) > 3)
+            {
+                index = ((right - left) / 2) + left;
+
+                Contract.Assert(index < s_localeNamesIndices.Length - 1);
+                result = CompareOrdinal(name, c_localeNames, s_localeNamesIndices[index], s_localeNamesIndices[index + 1] - s_localeNamesIndices[index]);
+                if (result == 0)
+                {
+                    return index;
+                }
+                else if (result < 0)
+                {
+                    right = index;
+                }
+                else
+                {
+                    left = index;
+                }
+            }
+
+            // Walk the remaining elements (it'll be 3 or fewer).
+            for (; left <= right; left++)
+            {
+                Contract.Assert(left < s_localeNamesIndices.Length - 1);
+                if (CompareOrdinal(name, c_localeNames, s_localeNamesIndices[left], s_localeNamesIndices[left + 1] - s_localeNamesIndices[left]) == 0)
+                {
+                    return (left);
+                }
+            }
+
+            // The encoding name is not valid.
+            return -1;
+        }
+        
+        // optimized to avoid parameters checking
+        private static int CompareOrdinal(string s1, string s2, int index, int length)
+        {
+            int count = s1.Length;
+            if (count > length)
+                count = length;
+
+            int i = 0;
+            while (i < count && s1[i] == s2[index + i])
+                i++;
+
+            if (i < count)
+                return (int)(s1[i] - s2[index + i]);
+
+            return s1.Length - length;
+        }
     }
 }
index 9969ecb..2f7fbca 100644 (file)
@@ -557,5 +557,15 @@ namespace System.Globalization
 
             return null;
         }
+        
+        private static int LocaleNameToLCID(string cultureName)
+        {
+            throw new NotImplementedException();
+        }
+        
+        private static string LCIDToLocaleName(int culture)
+        {
+            throw new NotImplementedException();
+        }
     }
 }
index b2043d1..2d2708b 100644 (file)
@@ -16,11 +16,13 @@ namespace System.Globalization
 
 #if INSIDE_CLR
     using StringStringDictionary = Dictionary<string, string>;
-    using StringCultureDataDictionary = Dictionary<String, CultureData>;
+    using StringCultureDataDictionary = Dictionary<string, CultureData>;
+    using LcidToCultureNameDictionary = Dictionary<int, string>;
     using Lock = Object;
 #else
     using StringStringDictionary = LowLevelDictionary<string, string>;
     using StringCultureDataDictionary = LowLevelDictionary<string, CultureData>;
+    using LcidToCultureNameDictionary = LowLevelDictionary<int, string>;
 #endif
 
     //
@@ -57,8 +59,6 @@ namespace System.Globalization
     internal partial class CultureData
     {
         private const int undef = -1;
-        private const int LOCALE_CUSTOM_UNSPECIFIED = 0x1000;
-        private const int LOCALE_CUSTOM_DEFAULT = 0x0c00;
 
         // Override flag
         private String _sRealName; // Name you passed in (ie: en-US, en, or de-DE_phoneb)
@@ -605,6 +605,33 @@ namespace System.Globalization
             return true;
         }
 
+        // We'd rather people use the named version since this doesn't allow custom locales
+        internal static CultureData GetCultureData(int culture, bool bUseUserOverride)
+        {
+            string localeName = null;
+            CultureData retVal = null;
+
+            if (culture == 0x007f)
+                return Invariant;
+
+            // Convert the lcid to a name, then use that
+            // Note that this'll return neutral names (unlike Vista native API)
+            localeName = LCIDToLocaleName(culture);
+
+            if (!String.IsNullOrEmpty(localeName))
+            {
+                // Valid name, use it
+                retVal = GetCultureData(localeName, bUseUserOverride);
+            }
+
+            // If not successful, throw
+            if (retVal == null)
+                throw new CultureNotFoundException("culture", culture, SR.Argument_CultureNotSupported);
+
+            // Return the one we found
+            return retVal;
+        }
+
         ////////////////////////////////////////////////////////////////////////
         //
         //  All the accessors
@@ -1694,6 +1721,11 @@ namespace System.Globalization
         {
             get
             {
+                if (_iLanguage == 0)
+                {
+                    Contract.Assert(_sRealName != null, "[CultureData.ILANGUAGE] Expected this.sRealName to be populated by COMNlsInfo::nativeInitCultureData already");
+                    _iLanguage = LocaleNameToLCID(_sRealName);
+                }
                 return _iLanguage;
             }
         }
@@ -1944,9 +1976,9 @@ namespace System.Globalization
             return -1;
         }
 
-        private static bool IsCustomCultureId(int cultureId)
+        internal static bool IsCustomCultureId(int cultureId)
         {
-            return (cultureId == LOCALE_CUSTOM_DEFAULT || cultureId == LOCALE_CUSTOM_UNSPECIFIED);
+            return (cultureId == CultureInfo.LOCALE_CUSTOM_DEFAULT || cultureId == CultureInfo.LOCALE_CUSTOM_UNSPECIFIED);
         }
 
         internal void GetNFIValues(NumberFormatInfo nfi)
@@ -2043,9 +2075,26 @@ namespace System.Globalization
         // This is ONLY used for caching names and shouldn't be used for anything else
         internal static string AnsiToLower(string testString)
         {
+            int index = 0; 
+            
+            while (index<testString.Length && (testString[index]<'A' || testString[index]>'Z' ))
+            {
+                index++;
+            }
+            if (index >= testString.Length)
+            {
+                return testString; // we didn't really change the string
+            }
+            
             StringBuilder sb = new StringBuilder(testString.Length);
+            for (int i=0; i<index; i++)
+            {
+                sb.Append(testString[i]);
+            }
+
+            sb.Append((char) (testString[index] -'A' + 'a'));
 
-            for (int ich = 0; ich < testString.Length; ich++)
+            for (int ich = index+1; ich < testString.Length; ich++)
             {
                 char ch = testString[ich];
                 sb.Append(ch <= 'Z' && ch >= 'A' ? (char)(ch - 'A' + 'a') : ch);
index 2275dd2..6b64386 100644 (file)
@@ -42,9 +42,12 @@ namespace System.Globalization
 
 #if INSIDE_CLR
     using StringCultureInfoDictionary = Dictionary<string, CultureInfo>;
+    using StringLcidDictionary = Dictionary<int, CultureInfo>;
+    
     using Lock = Object;
 #else
     using StringCultureInfoDictionary = LowLevelDictionary<string, CultureInfo>;
+    using StringLcidDictionary = LowLevelDictionary<int, CultureInfo>;
 #endif
 
     [Serializable]
@@ -139,11 +142,20 @@ namespace System.Globalization
 
         private static readonly Lock m_lock = new Lock();
         private static volatile StringCultureInfoDictionary s_NameCachedCultures;
+        private static volatile StringLcidDictionary s_LcidCachedCultures;       
 
         //The parent culture.
         [NonSerialized]
         private CultureInfo m_parent;
 
+        // LOCALE constants of interest to us internally and privately for LCID functions
+        // (ie: avoid using these and use names if possible)
+        private  const int LOCALE_NEUTRAL        = 0x0000;
+        private  const int LOCALE_USER_DEFAULT   = 0x0400;
+        private  const int LOCALE_SYSTEM_DEFAULT = 0x0800;
+        internal const int LOCALE_CUSTOM_UNSPECIFIED = 0x1000;
+        internal const int LOCALE_CUSTOM_DEFAULT = 0x0c00;
+
         static AsyncLocal<CultureInfo> s_asyncLocalCurrentCulture; 
         static AsyncLocal<CultureInfo> s_asyncLocalCurrentUICulture;
 
@@ -200,6 +212,44 @@ namespace System.Globalization
             InitializeFromName(name, useUserOverride);
         }
 
+        public CultureInfo(int culture) : this(culture, true) 
+        {
+        }
+
+        public CultureInfo(int culture, bool useUserOverride)
+        {
+            // We don't check for other invalid LCIDS here...
+            if (culture < 0)
+            {
+                throw new ArgumentOutOfRangeException("culture", SR.ArgumentOutOfRange_NeedPosNum);
+            }
+            Contract.EndContractBlock();
+
+            InitializeFromCultureId(culture, useUserOverride);
+        }
+
+        private void InitializeFromCultureId(int culture, bool useUserOverride)
+        {
+            switch (culture)
+            {
+                case LOCALE_CUSTOM_DEFAULT:
+                case LOCALE_SYSTEM_DEFAULT:
+                case LOCALE_NEUTRAL:
+                case LOCALE_USER_DEFAULT:
+                case LOCALE_CUSTOM_UNSPECIFIED:
+                    // Can't support unknown custom cultures and we do not support neutral or
+                    // non-custom user locales.
+                    throw new CultureNotFoundException("culture", culture, SR.Argument_CultureNotSupported);
+
+                default:
+                    // Now see if this LCID is supported in the system default CultureData table.
+                    m_cultureData = CultureData.GetCultureData(culture, useUserOverride);
+                    break;
+            }
+            m_isInherited = (this.GetType() != typeof(System.Globalization.CultureInfo));
+            m_name = m_cultureData.CultureName;
+        }
+
         private void InitializeFromName(string name, bool useUserOverride)
         {
             // Get our data providing record
@@ -214,6 +264,31 @@ namespace System.Globalization
             this.m_isInherited = (this.GetType() != typeof(System.Globalization.CultureInfo));
         }
 
+        // Constructor called by SQL Server's special munged culture - creates a culture with
+        // a TextInfo and CompareInfo that come from a supplied alternate source. This object
+        // is ALWAYS read-only.
+        // Note that we really cannot use an LCID version of this override as the cached
+        // name we create for it has to include both names, and the logic for this is in
+        // the GetCultureInfo override *only*.
+        internal CultureInfo(String cultureName, String textAndCompareCultureName)
+        {
+            if (cultureName == null)
+            {
+                throw new ArgumentNullException("cultureName",SR.ArgumentNull_String);
+            }
+            Contract.EndContractBlock();
+
+            m_cultureData = CultureData.GetCultureData(cultureName, false);
+            if (m_cultureData == null)
+                throw new CultureNotFoundException("cultureName", cultureName, SR.Argument_CultureNotSupported);
+            
+            m_name = m_cultureData.CultureName;
+
+            CultureInfo altCulture = GetCultureInfo(textAndCompareCultureName);
+            compareInfo = altCulture.CompareInfo;
+            textInfo = altCulture.TextInfo;
+        }
+
         // We do this to try to return the system UI language and the default user languages
         // This method will fallback if this fails (like Invariant)
         //
@@ -513,6 +588,14 @@ namespace System.Globalization
             }
         }
 
+        public virtual int LCID
+        {
+            get
+            {
+                return (this.m_cultureData.ILANGUAGE);
+            }
+        }
+
         ////////////////////////////////////////////////////////////////////////
         //
         //  Name
@@ -1054,26 +1137,25 @@ namespace System.Globalization
             get { return Name == CultureInfo.InvariantCulture.Name; }
         }
 
-        // Helper function both both overloads of GetCachedReadOnlyCulture.
-        internal static CultureInfo GetCultureInfoHelper(string name)
+        // Helper function both both overloads of GetCachedReadOnlyCulture.  If lcid is 0, we use the name.
+        // If lcid is -1, use the altName and create one of those special SQL cultures.
+        internal static CultureInfo GetCultureInfoHelper(int lcid, string name, string altName)
         {
-            // There is a race condition in this code with the side effect that the second thread's value
-            // clobbers the first in the dictionary. This is an acceptable race since the CultureInfo objects
-            // are content equal (but not reference equal). Since we make no guarantees there, this race is
-            // acceptable.
-
             // retval is our return value.
             CultureInfo retval;
 
-            if (name == null)
-            {
-                return null;
-            }
-
             // Temporary hashtable for the names.
             StringCultureInfoDictionary tempNameHT = s_NameCachedCultures;
 
-            name = CultureData.AnsiToLower(name);
+            if (name != null)
+            {
+                name = CultureData.AnsiToLower(name);
+            }
+            
+            if (altName != null)
+            {
+                altName = CultureData.AnsiToLower(altName);
+            }
 
             // We expect the same result for both hashtables, but will test individually for added safety.
             if (tempNameHT == null)
@@ -1082,20 +1164,66 @@ namespace System.Globalization
             }
             else
             {
-                bool ret;
-                lock (m_lock)
+                // If we are called by name, check if the object exists in the hashtable.  If so, return it.
+                if (lcid == -1 || lcid == 0)
                 {
-                    ret = tempNameHT.TryGetValue(name, out retval);
+                    bool ret;
+                    lock (m_lock)
+                    {
+                        ret = tempNameHT.TryGetValue(lcid == 0 ? name : name + '\xfffd' + altName, out retval);
+                    }
+
+                    if (ret && retval != null)
+                    {
+                        return retval;
+                    }
                 }
+            }
+
+            // Next, the Lcid table.
+            StringLcidDictionary tempLcidHT = s_LcidCachedCultures;
 
-                if (ret && retval != null)
+            if (tempLcidHT == null)
+            {
+                // Case insensitive is not an issue here, save the constructor call.
+                tempLcidHT = new StringLcidDictionary();
+            }
+            else
+            {
+                // If we were called by Lcid, check if the object exists in the table.  If so, return it.
+                if (lcid > 0)
                 {
-                    return retval;
+                    bool ret;
+                    lock (m_lock)
+                    {
+                        ret = tempLcidHT.TryGetValue(lcid, out retval);
+                    }
+                    if (ret && retval != null)
+                    {
+                        return retval;
+                    }
                 }
             }
+
+            // We now have two temporary hashtables and the desired object was not found.
+            // We'll construct it.  We catch any exceptions from the constructor call and return null.
             try
             {
-                retval = new CultureInfo(name, false);
+                switch (lcid)
+                {
+                    case -1:
+                        // call the private constructor
+                        retval = new CultureInfo(name, altName);
+                        break;
+
+                    case 0:
+                        retval = new CultureInfo(name, false);
+                        break;
+
+                    default:
+                        retval = new CultureInfo(lcid, false);
+                        break;
+                }
             }
             catch (ArgumentException)
             {
@@ -1105,14 +1233,42 @@ namespace System.Globalization
             // Set it to read-only
             retval.m_isReadOnly = true;
 
-            // Remember our name (as constructed).  Do NOT use alternate sort name versions because
-            // we have internal state representing the sort.  (So someone would get the wrong cached version)
-            string newName = CultureData.AnsiToLower(retval.m_name);
+            if (lcid == -1)
+            {
+                lock (m_lock)
+                {
+                    // This new culture will be added only to the name hash table.
+                    tempNameHT[name + '\xfffd' + altName] = retval;
+                }
+                // when lcid == -1 then TextInfo object is already get created and we need to set it as read only.
+                retval.TextInfo.SetReadOnlyState(true);
+            }
+            else if (lcid == 0)
+            {
+                // Remember our name (as constructed).  Do NOT use alternate sort name versions because
+                // we have internal state representing the sort.  (So someone would get the wrong cached version)
+                string newName = CultureData.AnsiToLower(retval.m_name);
+                
+                // We add this new culture info object to both tables.
+                lock (m_lock)
+                {
+                    tempNameHT[newName] = retval;
+                }
+            } 
+            else
+            {
+                lock (m_lock)
+                {
+                    tempLcidHT[lcid] = retval;
+                }
+            }
 
-            // We add this new culture info object to both tables.
-            lock (m_lock)
+            // Copy the two hashtables to the corresponding member variables.  This will potentially overwrite
+            // new tables simultaneously created by a new thread, but maximizes thread safety.
+            if (-1 != lcid)
             {
-                tempNameHT[newName] = retval;
+                // Only when we modify the lcid hash table, is there a need to overwrite.
+                s_LcidCachedCultures = tempLcidHT;
             }
 
             s_NameCachedCultures = tempNameHT;
@@ -1122,6 +1278,27 @@ namespace System.Globalization
         }
 
         // Gets a cached copy of the specified culture from an internal hashtable (or creates it
+        // if not found).  (LCID version)... use named version
+        public static CultureInfo GetCultureInfo(int culture)
+        {
+            // Must check for -1 now since the helper function uses the value to signal
+            // the altCulture code path for SQL Server.
+            // Also check for zero as this would fail trying to add as a key to the hash.
+            if (culture <= 0) 
+            {
+                throw new ArgumentOutOfRangeException("culture", SR.ArgumentOutOfRange_NeedPosNum);
+            }
+            Contract.Ensures(Contract.Result<CultureInfo>() != null);
+            Contract.EndContractBlock();
+            CultureInfo retval = GetCultureInfoHelper(culture, null, null);
+            if (null == retval)
+            {
+                throw new CultureNotFoundException("culture", culture, SR.Argument_CultureNotSupported);
+            }
+            return retval;
+        }
+
+        // Gets a cached copy of the specified culture from an internal hashtable (or creates it
         // if not found).  (Named version)
         public static CultureInfo GetCultureInfo(string name)
         {
@@ -1131,7 +1308,7 @@ namespace System.Globalization
                 throw new ArgumentNullException("name");
             }
 
-            CultureInfo retval = GetCultureInfoHelper(name);
+            CultureInfo retval = GetCultureInfoHelper(0, name, null);
             if (retval == null)
             {
                 throw new CultureNotFoundException(
index b3e61ea..73e319e 100644 (file)
@@ -1,35 +1,12 @@
 namespace System.Globalization
 {
-    public partial class CompareInfo : System.Runtime.Serialization.IDeserializationCallback
-    {
-        public int LCID { get { throw new NotImplementedException(); } }
-        public static System.Globalization.CompareInfo GetCompareInfo(int culture) { throw new NotImplementedException(); }
-        public static System.Globalization.CompareInfo GetCompareInfo(int culture, System.Reflection.Assembly assembly) { throw new NotImplementedException(); }
-        public static System.Globalization.CompareInfo GetCompareInfo(string name, System.Reflection.Assembly assembly) { throw new NotImplementedException(); }
-        public virtual System.Globalization.SortKey GetSortKey(string source) { throw new NotImplementedException(); }
-        public virtual System.Globalization.SortKey GetSortKey(string source, System.Globalization.CompareOptions options) { throw new NotImplementedException(); }
-        public virtual int IndexOf(string source, char value, int startIndex) { throw new NotImplementedException(); }
-        public virtual int IndexOf(string source, string value, int startIndex) { throw new NotImplementedException(); }
-        [System.Runtime.InteropServices.ComVisibleAttribute(false)]
-        public static bool IsSortable(char ch) { throw new NotImplementedException(); }
-        [System.Runtime.InteropServices.ComVisibleAttribute(false)]
-        [System.Security.SecuritySafeCriticalAttribute]
-        public static bool IsSortable(string text) { throw new NotImplementedException(); }
-        public virtual int LastIndexOf(string source, char value, int startIndex) { throw new NotImplementedException(); }
-        public virtual int LastIndexOf(string source, string value, int startIndex) { throw new NotImplementedException(); }
-    }
-
     public partial class CultureInfo : System.ICloneable, System.IFormatProvider
     {
-        public CultureInfo(int culture) { throw new NotImplementedException(); }
-        public CultureInfo(int culture, bool useUserOverride) { throw new NotImplementedException(); }
         public static System.Globalization.CultureInfo InstalledUICulture { get { throw new NotImplementedException(); } }
-        public virtual int LCID { get { throw new NotImplementedException(); } }
         public virtual string ThreeLetterISOLanguageName { get { throw new NotImplementedException(); } }
         public virtual string ThreeLetterWindowsLanguageName { get { throw new NotImplementedException(); } }
         public void ClearCachedData() { throw new NotImplementedException(); }
         public static System.Globalization.CultureInfo CreateSpecificCulture(string name) { throw new NotImplementedException(); }
-        public static System.Globalization.CultureInfo GetCultureInfo(int culture) { throw new NotImplementedException(); }
         public static System.Globalization.CultureInfo GetCultureInfo(string name, string altName) { throw new NotImplementedException(); }
         public static System.Globalization.CultureInfo GetCultureInfoByIetfLanguageTag(string name) { throw new NotImplementedException(); }
         public static System.Globalization.CultureInfo[] GetCultures(System.Globalization.CultureTypes types) { throw new NotImplementedException(); }
@@ -111,29 +88,6 @@ namespace System.Globalization
         public virtual string ThreeLetterWindowsRegionName { get { throw new NotImplementedException(); } }
     }
 
-    public partial class SortKey
-    {
-        internal SortKey() { throw new NotImplementedException(); }
-        public virtual byte[] KeyData { get { throw new NotImplementedException(); } }
-        public virtual string OriginalString { get { throw new NotImplementedException(); } }
-        public static int Compare(System.Globalization.SortKey sortkey1, System.Globalization.SortKey sortkey2) { throw new NotImplementedException(); }
-        public override bool Equals(object value) { throw new NotImplementedException(); }
-        public override int GetHashCode() { throw new NotImplementedException(); }
-        public override string ToString() { throw new NotImplementedException(); }
-    }
-
-    public sealed partial class SortVersion : System.IEquatable<System.Globalization.SortVersion>
-    {
-        public SortVersion(int fullVersion, System.Guid sortId) { throw new NotImplementedException(); }
-        public int FullVersion { get { throw new NotImplementedException(); } }
-        public System.Guid SortId { get { throw new NotImplementedException(); } }
-        public bool Equals(System.Globalization.SortVersion other) { throw new NotImplementedException(); }
-        public override bool Equals(object obj) { throw new NotImplementedException(); }
-        public override int GetHashCode() { throw new NotImplementedException(); }
-        public static bool operator ==(System.Globalization.SortVersion left, System.Globalization.SortVersion right) { throw new NotImplementedException(); }
-        public static bool operator !=(System.Globalization.SortVersion left, System.Globalization.SortVersion right) { throw new NotImplementedException(); }
-    }
-
     public partial class TextInfo : System.ICloneable, System.Runtime.Serialization.IDeserializationCallback 
     {
         public virtual int ANSICodePage { get { throw new NotImplementedException(); } }
diff --git a/src/mscorlib/corefx/System/Globalization/SortKey.cs b/src/mscorlib/corefx/System/Globalization/SortKey.cs
new file mode 100644 (file)
index 0000000..a57380c
--- /dev/null
@@ -0,0 +1,208 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+////////////////////////////////////////////////////////////////////////////
+//
+//
+//  Purpose:  This class implements a set of methods for retrieving
+//            sort key information.
+//
+//
+////////////////////////////////////////////////////////////////////////////
+
+namespace System.Globalization {
+    
+    using System;
+    using System.Runtime.CompilerServices;
+    using System.Runtime.Serialization;
+    using System.Diagnostics.Contracts;
+
+    [System.Runtime.InteropServices.ComVisible(true)]
+    [Serializable]
+    public partial class SortKey
+    {
+        //--------------------------------------------------------------------//
+        //                        Internal Information                        //
+        //--------------------------------------------------------------------//
+    
+        //
+        //  Variables.
+        //
+
+        [OptionalField(VersionAdded = 3)]
+        internal string _localeName;       // locale identifier
+
+        [OptionalField(VersionAdded = 1)] // LCID field so serialization is Whidbey compatible though we don't officially support it
+        internal int _win32LCID;            
+                                          // Whidbey serialization 
+
+        internal CompareOptions _options;  // options
+        internal string _string;         // original string
+        internal byte[] _keyData;        // sortkey data
+
+        //
+        // The following constructor is designed to be called from CompareInfo to get the 
+        // the sort key of specific string for synthetic culture
+        //
+        internal SortKey(String localeName, String str, CompareOptions options, byte[] keyData)
+        {
+            _keyData = keyData;
+            _localeName = localeName;
+            _options    = options;
+            _string   = str;
+        }
+
+        [OnSerializing]
+        private void OnSerializing(StreamingContext context)
+        {
+            //set LCID to proper value for Whidbey serialization (no other use)
+            if (_win32LCID == 0)
+            {
+                _win32LCID = CultureInfo.GetCultureInfo(_localeName).LCID;
+            }
+        }
+
+        [OnDeserialized]
+        private void OnDeserialized(StreamingContext context)
+        {
+            //set locale name to proper value after Whidbey deserialization
+            if (String.IsNullOrEmpty(_localeName) && _win32LCID != 0)
+            {
+                _localeName = CultureInfo.GetCultureInfo(_win32LCID).Name;
+            }
+        }
+    
+        ////////////////////////////////////////////////////////////////////////
+        //
+        //  GetOriginalString
+        //
+        //  Returns the original string used to create the current instance
+        //  of SortKey.
+        //
+        ////////////////////////////////////////////////////////////////////////
+        public virtual String OriginalString
+        {
+            get
+            {
+                return (_string);
+            }
+        }
+    
+        ////////////////////////////////////////////////////////////////////////
+        //
+        //  GetKeyData
+        //
+        //  Returns a byte array representing the current instance of the
+        //  sort key.
+        //
+        ////////////////////////////////////////////////////////////////////////
+        public virtual byte[] KeyData
+        {
+            get
+            {
+                return (byte[])(_keyData.Clone());
+            }
+        }
+    
+        ////////////////////////////////////////////////////////////////////////
+        //
+        //  Compare
+        //
+        //  Compares the two sort keys.  Returns 0 if the two sort keys are
+        //  equal, a number less than 0 if sortkey1 is less than sortkey2,
+        //  and a number greater than 0 if sortkey1 is greater than sortkey2.
+        //
+        ////////////////////////////////////////////////////////////////////////
+        public static int Compare(SortKey sortkey1, SortKey sortkey2)
+        {
+            if (sortkey1==null || sortkey2==null)
+            {
+                throw new ArgumentNullException((sortkey1 == null ? "sortkey1" : "sortkey2"));
+            }
+            Contract.EndContractBlock();
+    
+            byte[] key1Data = sortkey1._keyData;
+            byte[] key2Data = sortkey2._keyData;
+    
+            Contract.Assert(key1Data != null, "key1Data != null");
+            Contract.Assert(key2Data != null, "key2Data != null");
+
+            if (key1Data.Length == 0)
+            {
+                if (key2Data.Length == 0)
+                {
+                    return (0);
+                }
+                return (-1);
+            }
+            if (key2Data.Length == 0)
+            {
+                return (1);
+            }
+    
+            int compLen = (key1Data.Length<key2Data.Length)?key1Data.Length:key2Data.Length;
+
+            for (int i=0; i<compLen; i++)
+            {
+                if (key1Data[i]>key2Data[i])
+                {
+                    return (1);
+                }
+                if (key1Data[i]<key2Data[i])
+                {
+                    return (-1);
+                }
+            }
+    
+            return 0;
+        }
+    
+        ////////////////////////////////////////////////////////////////////////
+        //
+        //  Equals
+        //
+        //  Implements Object.Equals().  Returns a boolean indicating whether
+        //  or not object refers to the same SortKey as the current instance.
+        //
+        ////////////////////////////////////////////////////////////////////////
+        public override bool Equals(Object value)
+        {
+            SortKey that = value as SortKey;
+            
+            if (that != null)
+            {
+                return Compare(this, that) == 0;
+            }
+
+            return (false);
+        }
+    
+        ////////////////////////////////////////////////////////////////////////
+        //
+        //  GetHashCode
+        //
+        //  Implements Object.GetHashCode().  Returns the hash code for the
+        //  SortKey.  The hash code is guaranteed to be the same for
+        //  SortKey A and B where A.Equals(B) is true.
+        //
+        ////////////////////////////////////////////////////////////////////////
+        public override int GetHashCode()
+        {
+            return (CompareInfo.GetCompareInfo(_localeName).GetHashCodeOfString(_string, _options));
+        }
+    
+        ////////////////////////////////////////////////////////////////////////
+        //
+        //  ToString
+        //
+        //  Implements Object.ToString().  Returns a string describing the
+        //  SortKey.
+        //
+        ////////////////////////////////////////////////////////////////////////
+        public override String ToString()
+        {
+            return ("SortKey - " + _localeName + ", " + _options + ", " + _string);
+        }
+    }
+}
diff --git a/src/mscorlib/corefx/System/Globalization/SortVersion.cs b/src/mscorlib/corefx/System/Globalization/SortVersion.cs
new file mode 100644 (file)
index 0000000..72aa6d6
--- /dev/null
@@ -0,0 +1,101 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Diagnostics.Contracts;
+
+namespace System.Globalization 
+{
+    [Serializable]
+    public sealed class SortVersion : IEquatable<SortVersion>
+    {
+        private int _nlsVersion;
+        private Guid _sortId;
+
+        public int FullVersion 
+        {
+            get 
+            {
+                return _nlsVersion;
+            }
+        }
+
+        public Guid SortId 
+        {
+            get 
+            {
+                return _sortId;
+            }
+        }
+
+        public SortVersion(int fullVersion, Guid sortId) 
+        {           
+            _sortId = sortId;
+            _nlsVersion = fullVersion;
+        }
+
+        internal SortVersion(int nlsVersion, int effectiveId, Guid customVersion) 
+        {
+            _nlsVersion = nlsVersion;
+
+            if (customVersion == Guid.Empty) 
+            {
+                byte b1 = (byte) (effectiveId >> 24);
+                byte b2 = (byte) ((effectiveId  & 0x00FF0000) >> 16);
+                byte b3 = (byte) ((effectiveId  & 0x0000FF00) >> 8);
+                byte b4 = (byte) (effectiveId  & 0xFF);
+                customVersion = new Guid(0,0,0,0,0,0,0,b1,b2,b3,b4);
+            }
+
+            _sortId = customVersion;
+        }
+
+        public override bool Equals(object obj) 
+        {
+            SortVersion n = obj as SortVersion;
+            if (n != null) 
+            {
+                return this.Equals(n);
+            }
+
+            return false;
+        }
+
+        public bool Equals(SortVersion other) 
+        {
+            if (other == null) 
+            {
+                return false;
+            }
+
+            return _nlsVersion == other._nlsVersion && _sortId == other._sortId;
+        }
+
+        public override int GetHashCode() 
+        { 
+            return _nlsVersion * 7 | _sortId.GetHashCode(); 
+        }
+
+        public static bool operator ==(SortVersion left, SortVersion right) 
+        {
+            if (((object) left) != null) 
+            {
+                return left.Equals(right);
+            }
+
+            if (((object) right) != null) 
+            {
+                return right.Equals(left);
+            }
+
+            // Both null.
+            return true;
+        }
+
+        public static bool operator !=(SortVersion left, SortVersion right) 
+        {
+            return !(left == right);
+        }
+    }
+}
\ No newline at end of file
index 2ab5e63..90de16e 100644 (file)
     <GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\NumberFormatInfo.cs" />
     <GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\PersianCalendar.cs" />
     <GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\RegionInfo.cs" />
+    <GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\SortKey.cs" />
+    <GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\SortVersion.cs" />
     <GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\StringInfo.cs" />
     <GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\TaiwanCalendar.cs" />
     <GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\TaiwanLunisolarCalendar.cs" />