Home | History | Annotate | Download | only in configuration
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Eclipse Public License, Version 1.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.eclipse.org/org/documents/epl-v10.php
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.android.ide.eclipse.adt.internal.editors.layout.configuration;
     17 
     18 import com.android.annotations.NonNull;
     19 import com.android.annotations.Nullable;
     20 import com.android.annotations.VisibleForTesting;
     21 import com.android.ide.common.resources.configuration.LanguageQualifier;
     22 import com.android.ide.common.resources.configuration.RegionQualifier;
     23 import com.android.ide.eclipse.adt.internal.editors.IconFactory;
     24 import com.google.common.base.Splitter;
     25 import com.google.common.collect.Maps;
     26 
     27 import org.eclipse.swt.graphics.Image;
     28 import org.eclipse.wb.internal.core.DesignerPlugin;
     29 
     30 import java.util.Collections;
     31 import java.util.Locale;
     32 import java.util.Map;
     33 import java.util.Set;
     34 
     35 /**
     36  * The {@linkplain LocaleManager} provides access to locale information such as
     37  * language names and flag icons for the various locales.
     38  * <p>
     39  * All the flag images came from the WindowBuilder subversion repository
     40  * http://dev.eclipse.org/svnroot/tools/org.eclipse.windowbuilder/trunk (and in
     41  * particular, a snapshot of revision 424). However, it appears that the icons
     42  * are from http://www.famfamfam.com/lab/icons/flags/ which states that "these
     43  * flag icons are available for free use for any purpose with no requirement for
     44  * attribution." Adding the URL here such that we can check back occasionally
     45  * and see if there are corrections or updates. Also note that the flag names
     46  * are in ISO 3166-1 alpha-2 country codes.
     47  */
     48 public class LocaleManager {
     49     private static final LocaleManager sInstance = new LocaleManager();
     50 
     51     /**
     52      * Returns the {@linkplain LocaleManager} singleton
     53      *
     54      * @return the {@linkplain LocaleManager} singleton, never null
     55      */
     56     @NonNull
     57     public static LocaleManager get() {
     58         return sInstance;
     59     }
     60 
     61     /** Use the {@link #get()} factory method */
     62     private LocaleManager() {
     63     }
     64 
     65     /** Map from region to flag icon */
     66     private Map<String, Image> mImageMap = Maps.newHashMap();
     67 
     68     /**
     69      * Map of default bindings from language to country (if a region is not
     70      * specified). Note that if a given language is the language of the default
     71      * locale on the user's machine, then the country corresponding to that
     72      * locale is used. Thus, even if for example the default binding of the "en"
     73      * language is "US", if the current locale has language="en" and the country
     74      * for that locale is "GB", then "GB" will be used.
     75      */
     76     private static Map<String, String> sLanguageToCountry = Maps.newHashMapWithExpectedSize(177);
     77     /** Names of the various languages according to ISO 639-1 */
     78     private static Map<String, String> sLanguageNames = Maps.newHashMapWithExpectedSize(187);
     79     /** Names of the various regions according to ISO 3166-1 */
     80     private static Map<String, String> sRegionNames = Maps.newHashMapWithExpectedSize(249);
     81 
     82     /**
     83      * Returns the empty flag icon used to indicate an unknown country
     84      *
     85      * @return the globe icon used to indicate an unknown country
     86      */
     87     public static Image getEmptyIcon() {
     88       return DesignerPlugin.getImage("nls/flags/flag_empty.png"); //$NON-NLS-1$
     89     }
     90 
     91     /**
     92      * Returns the globe icon used to indicate "any" language
     93      *
     94      * @return the globe icon used to indicate "any" language
     95      */
     96     public static Image getGlobeIcon() {
     97         return IconFactory.getInstance().getIcon("globe"); //$NON-NLS-1$
     98     }
     99 
    100     /**
    101      * Returns the flag for the given language and region.
    102      *
    103      * @param language the language, or null (if null, region must not be null),
    104      *            the 2 letter language code (ISO 639-1), in lower case
    105      * @param region the region, or null (if null, language must not be null),
    106      *            the 2 letter region code (ISO 3166-1 alpha-2), in upper case
    107      * @return a suitable flag icon, or null
    108      */
    109     @Nullable
    110     public Image getFlag(@Nullable String language, @Nullable String region) {
    111         assert region != null || language != null;
    112         if (region == null || region.isEmpty()) {
    113             // Look up the region for a given language
    114             assert language != null;
    115 
    116             // Prefer the local registration of the current locale; even if
    117             // for example the default locale for English is the US, if the current
    118             // default locale is English, then use its associated country, which could
    119             // for example be Australia.
    120             Locale locale = Locale.getDefault();
    121             if (language.equals(locale.getLanguage())) {
    122                 Image flag = getFlag(locale.getCountry());
    123                 if (flag != null) {
    124                     return flag;
    125                 }
    126             }
    127 
    128             // Special cases where we have a dedicated flag available:
    129             if (language.equals("ca")) {        //$NON-NLS-1$
    130                 region = "catalonia";           //$NON-NLS-1$
    131             } else if (language.equals("gd")) { //$NON-NLS-1$
    132                 region = "scotland";            //$NON-NLS-1$
    133             } else if (language.equals("cy")) { //$NON-NLS-1$
    134                 region = "wales";               //$NON-NLS-1$
    135             } else {
    136                 // Attempt to look up the country from the language
    137                 region = sLanguageToCountry.get(language);
    138             }
    139         }
    140 
    141         if (region == null || region.isEmpty()) {
    142             // No country specified, and the language is for a country we
    143             // don't have a flag for
    144             return null;
    145         }
    146 
    147         return getIcon(region);
    148     }
    149 
    150     /**
    151      * Returns the flag for the given language and region.
    152      *
    153      * @param language the language qualifier, or null (if null, region must not be null),
    154      * @param region the region, or null (if null, language must not be null),
    155      * @return a suitable flag icon, or null
    156      */
    157     public Image getFlag(LanguageQualifier language, RegionQualifier region) {
    158         String languageCode = language != null ? language.getValue() : null;
    159         String regionCode = region != null ? region.getValue() : null;
    160         if (LanguageQualifier.FAKE_LANG_VALUE.equals(languageCode)) {
    161             languageCode = null;
    162         }
    163         if (RegionQualifier.FAKE_REGION_VALUE.equals(regionCode)) {
    164             regionCode = null;
    165         }
    166         return getFlag(languageCode, regionCode);
    167     }
    168 
    169     /**
    170      * Returns a flag for a given resource folder name (such as
    171      * {@code values-en-rUS}), or null
    172      *
    173      * @param folder the folder name
    174      * @return a corresponding flag icon, or null if none was found
    175      */
    176     @Nullable
    177     public Image getFlagForFolderName(@NonNull String folder) {
    178         RegionQualifier region = null;
    179         LanguageQualifier language = null;
    180         for (String qualifier : Splitter.on('-').split(folder)) {
    181             if (qualifier.length() == 3) {
    182                 region = RegionQualifier.getQualifier(qualifier);
    183                 if (region != null) {
    184                     break;
    185                 }
    186             } else if (qualifier.length() == 2 && language == null) {
    187                 language = LanguageQualifier.getQualifier(qualifier);
    188             }
    189         }
    190         if (region != null || language != null) {
    191             return LocaleManager.get().getFlag(language, region);
    192         }
    193 
    194         return null;
    195     }
    196 
    197     /**
    198      * Returns the flag for the given region.
    199      *
    200      * @param region the 2 letter region code (ISO 3166-1 alpha-2), in upper case
    201      * @return a suitable flag icon, or null
    202      */
    203     @Nullable
    204     public Image getFlag(@NonNull String region) {
    205         assert region.length() == 2
    206                 && Character.isUpperCase(region.charAt(0))
    207                 && Character.isUpperCase(region.charAt(1)) : region;
    208 
    209         return getIcon(region);
    210     }
    211 
    212     private Image getIcon(@NonNull String base) {
    213         Image flagImage = mImageMap.get(base);
    214           if (flagImage == null) {
    215               // TODO: Special case locale currently running on system such
    216               // that the current country matches the current locale
    217               if (mImageMap.containsKey(base)) {
    218                   // Already checked: there's just no image there
    219                   return null;
    220               }
    221               String flagFileName = base.toLowerCase(Locale.US) + ".png"; //$NON-NLS-1$
    222               flagImage = DesignerPlugin.getImage("nls/flags/" + flagFileName); //$NON-NLS-1$
    223               mImageMap.put(base, flagImage);
    224           }
    225 
    226         return flagImage;
    227     }
    228 
    229     /**
    230      * Returns the name of the given region for a 2 letter region code, in English.
    231      *
    232      * @param regionCode the 2 letter region code (ISO 3166-1 alpha-2)
    233      * @return the name of the given region for a region code, in English, or
    234      *         null if not known
    235      */
    236     @Nullable
    237     public static String getRegionName(@NonNull String regionCode) {
    238         assert regionCode.length() == 2
    239                 && Character.isUpperCase(regionCode.charAt(0))
    240                 && Character.isUpperCase(regionCode.charAt(1)) : regionCode;
    241 
    242         return sRegionNames.get(regionCode);
    243     }
    244 
    245     /**
    246      * Returns the name of the given language for a language code, in English.
    247      *
    248      * @param languageCode the 2 letter language code (ISO 639-1)
    249      * @return the name of the given language for a language code, in English, or
    250      *         null if not known
    251      */
    252     @Nullable
    253     public static String getLanguageName(@NonNull String languageCode) {
    254         assert languageCode.length() == 2
    255                 && Character.isLowerCase(languageCode.charAt(0))
    256                 && Character.isLowerCase(languageCode.charAt(1)) : languageCode;
    257 
    258         return sLanguageNames.get(languageCode);
    259     }
    260 
    261     /**
    262      * Returns all the known language codes
    263      *
    264      * @return all the known language codes
    265      */
    266     @NonNull
    267     public static Set<String> getLanguageCodes() {
    268         return Collections.unmodifiableSet(sLanguageNames.keySet());
    269     }
    270 
    271     /**
    272      * Returns all the known region codes
    273      *
    274      * @return all the known region codes
    275      */
    276     @NonNull
    277     public static Set<String> getRegionCodes() {
    278         return Collections.unmodifiableSet(sRegionNames.keySet());
    279     }
    280 
    281     /**
    282      * Populate the various maps.
    283      * <p>
    284      * The language to region mapping was constructed by using the ISO 639-1 table from
    285      * http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
    286      * and for each language, looking up the corresponding Wikipedia entry
    287      * and picking the first mentioned or in some cases largest country where
    288      * the language is spoken, then mapping that back to the corresponding ISO 3166-1
    289      * code.
    290      */
    291     static {
    292         // Afar -> Ethiopia
    293         sLanguageToCountry.put("aa", "ET"); //$NON-NLS-1$ //$NON-NLS-2$
    294         sLanguageNames.put("aa", "Afar"); //$NON-NLS-1$
    295 
    296          // "ab": Abkhaz -> Abkhazia, Georgia
    297          sLanguageToCountry.put("ab", "GE"); //$NON-NLS-1$ //$NON-NLS-2$
    298          sLanguageNames.put("ab", "Abkhaz"); //$NON-NLS-1$
    299 
    300          // "af": Afrikaans  -> South Africa, Namibia
    301          sLanguageToCountry.put("af", "ZA"); //$NON-NLS-1$ //$NON-NLS-2$
    302          sLanguageNames.put("af", "Afrikaans"); //$NON-NLS-1$
    303 
    304          // "ak": Akan -> Ghana, Ivory Coast
    305          sLanguageToCountry.put("ak", "GH"); //$NON-NLS-1$ //$NON-NLS-2$
    306          sLanguageNames.put("ak", "Akan"); //$NON-NLS-1$
    307 
    308          // "am": Amharic -> Ethiopia
    309          sLanguageToCountry.put("am", "ET"); //$NON-NLS-1$ //$NON-NLS-2$
    310          sLanguageNames.put("am", "Amharic"); //$NON-NLS-1$
    311 
    312          // "an": Aragonese  -> Aragon in Spain
    313          sLanguageToCountry.put("an", "ES"); //$NON-NLS-1$ //$NON-NLS-2$
    314          sLanguageNames.put("an", "Aragonese"); //$NON-NLS-1$
    315 
    316          // "ar": Arabic -> United Arab Emirates, Kuwait, Oman, Saudi Arabia, Qatar, and Bahrain
    317          sLanguageToCountry.put("ar", "AE"); //$NON-NLS-1$ //$NON-NLS-2$
    318          sLanguageNames.put("ar", "Arabic"); //$NON-NLS-1$
    319 
    320          // "as": Assamese -> India
    321          sLanguageToCountry.put("as", "IN"); //$NON-NLS-1$ //$NON-NLS-2$
    322          sLanguageNames.put("as", "Assamese"); //$NON-NLS-1$
    323 
    324          // "av": Avaric -> Azerbaijan
    325          sLanguageToCountry.put("av", "AZ"); //$NON-NLS-1$ //$NON-NLS-2$
    326          sLanguageNames.put("av", "Avaric"); //$NON-NLS-1$
    327 
    328          // "ay": Aymara -> Bolivia
    329          sLanguageToCountry.put("ay", "BO"); //$NON-NLS-1$ //$NON-NLS-2$
    330          sLanguageNames.put("ay", "Aymara"); //$NON-NLS-1$
    331 
    332          // "az": Azerbaijani -> Azerbaijan
    333          sLanguageToCountry.put("az", "AZ"); //$NON-NLS-1$ //$NON-NLS-2$
    334          sLanguageNames.put("az", "Azerbaijani"); //$NON-NLS-1$
    335 
    336          // "ba": Bashkir -> Russia
    337          sLanguageToCountry.put("ba", "RU"); //$NON-NLS-1$ //$NON-NLS-2$
    338          sLanguageNames.put("ba", "Bashkir"); //$NON-NLS-1$
    339 
    340          // "be": Belarusian -> Belarus
    341          sLanguageToCountry.put("be", "BY"); //$NON-NLS-1$ //$NON-NLS-2$
    342          sLanguageNames.put("be", "Belarusian"); //$NON-NLS-1$
    343 
    344          // "bg": Bulgarian -> Bulgaria
    345          sLanguageToCountry.put("bg", "BG"); //$NON-NLS-1$ //$NON-NLS-2$
    346          sLanguageNames.put("bg", "Bulgarian"); //$NON-NLS-1$
    347 
    348          // "bh": Bihari languages -> India, Nepal
    349          sLanguageToCountry.put("bh", "IN"); //$NON-NLS-1$ //$NON-NLS-2$
    350          sLanguageNames.put("bh", "Bihari languages"); //$NON-NLS-1$
    351 
    352          // "bi": Bislama -> Vanatu
    353          sLanguageToCountry.put("bi", "VU"); //$NON-NLS-1$ //$NON-NLS-2$
    354          sLanguageNames.put("bi", "Bislama"); //$NON-NLS-1$
    355 
    356          // "bm": Bambara -> Mali
    357          sLanguageToCountry.put("bm", "ML"); //$NON-NLS-1$ //$NON-NLS-2$
    358          sLanguageNames.put("bm", "Bambara"); //$NON-NLS-1$
    359 
    360          // "bn": Bengali -> Bangladesh, India
    361          sLanguageToCountry.put("bn", "BD"); //$NON-NLS-1$ //$NON-NLS-2$
    362          sLanguageNames.put("bn", "Bengali"); //$NON-NLS-1$
    363 
    364          // "bo": Tibetan -> China
    365          sLanguageToCountry.put("bo", "CN"); //$NON-NLS-1$ //$NON-NLS-2$
    366          sLanguageNames.put("bo", "Tibetan"); //$NON-NLS-1$
    367 
    368          // "br": Breton -> France
    369          sLanguageToCountry.put("br", "FR"); //$NON-NLS-1$ //$NON-NLS-2$
    370          sLanguageNames.put("br", "Breton"); //$NON-NLS-1$
    371 
    372          // "bs": Bosnian -> Bosnia and Herzegovina
    373          sLanguageToCountry.put("bs", "BA"); //$NON-NLS-1$ //$NON-NLS-2$
    374          sLanguageNames.put("bs", "Bosnian"); //$NON-NLS-1$
    375 
    376          // "ca": Catalan -> Andorra, Catalonia
    377          sLanguageToCountry.put("ca", "AD"); //$NON-NLS-1$ //$NON-NLS-2$
    378          sLanguageNames.put("ca", "Catalan"); //$NON-NLS-1$
    379 
    380          // "ce": Chechen -> Russia
    381          sLanguageToCountry.put("ce", "RU"); //$NON-NLS-1$ //$NON-NLS-2$
    382          sLanguageNames.put("ce", "Chechen"); //$NON-NLS-1$
    383 
    384          // "ch": Chamorro -> Guam, Northern Mariana Islands
    385          sLanguageToCountry.put("ch", "GU"); //$NON-NLS-1$ //$NON-NLS-2$
    386          sLanguageNames.put("ch", "Chamorro"); //$NON-NLS-1$
    387 
    388          // "co": Corsican -> France
    389          sLanguageToCountry.put("co", "FR"); //$NON-NLS-1$ //$NON-NLS-2$
    390          sLanguageNames.put("co", "Corsican"); //$NON-NLS-1$
    391 
    392          // "cr": Cree -> Canada and United States
    393          sLanguageToCountry.put("cr", "CA"); //$NON-NLS-1$ //$NON-NLS-2$
    394          sLanguageNames.put("cr", "Cree"); //$NON-NLS-1$
    395 
    396          // "cs": Czech -> Czech Republic
    397          sLanguageToCountry.put("cs", "CZ"); //$NON-NLS-1$ //$NON-NLS-2$
    398          sLanguageNames.put("cs", "Czech"); //$NON-NLS-1$
    399 
    400          // "cv": Chuvash -> Russia, Kazakhstan, Ukraine, Uzbekistan...
    401          sLanguageToCountry.put("cv", "RU"); //$NON-NLS-1$ //$NON-NLS-2$
    402          sLanguageNames.put("cv", "Chuvash"); //$NON-NLS-1$
    403 
    404          // "cy": Welsh -> Wales (no 3166 code; using GB)
    405          sLanguageToCountry.put("cy", "GB"); //$NON-NLS-1$ //$NON-NLS-2$
    406          sLanguageNames.put("cy", "Welsh"); //$NON-NLS-1$
    407 
    408          // "da": Danish -> Denmark
    409          sLanguageToCountry.put("da", "DK"); //$NON-NLS-1$ //$NON-NLS-2$
    410          sLanguageNames.put("da", "Danish"); //$NON-NLS-1$
    411 
    412          // "de": German -> Germany
    413          sLanguageToCountry.put("de", "DE"); //$NON-NLS-1$ //$NON-NLS-2$
    414          sLanguageNames.put("de", "German"); //$NON-NLS-1$
    415 
    416          // "dv": Divehi -> Maldives
    417          sLanguageToCountry.put("dv", "MV"); //$NON-NLS-1$ //$NON-NLS-2$
    418          sLanguageNames.put("dv", "Divehi"); //$NON-NLS-1$
    419 
    420          // "dz": Dzongkha -> Bhutan
    421          sLanguageToCountry.put("dz", "BT"); //$NON-NLS-1$ //$NON-NLS-2$
    422          sLanguageNames.put("dz", "Dzongkha"); //$NON-NLS-1$
    423 
    424          // "ee": Ewe -> Ghana, Togo
    425          sLanguageToCountry.put("ee", "GH"); //$NON-NLS-1$ //$NON-NLS-2$
    426          sLanguageNames.put("ee", "Ewe"); //$NON-NLS-1$
    427 
    428          // "el": Greek -> Greece
    429          sLanguageToCountry.put("el", "GR"); //$NON-NLS-1$ //$NON-NLS-2$
    430          sLanguageNames.put("el", "Greek"); //$NON-NLS-1$
    431 
    432          // "en": English -> United States, United Kingdom, Australia, ...
    433          sLanguageToCountry.put("en", "US"); //$NON-NLS-1$ //$NON-NLS-2$
    434          sLanguageNames.put("en", "English"); //$NON-NLS-1$
    435 
    436          // "es": Spanish -> Spain, Mexico, ...
    437          sLanguageToCountry.put("es", "ES"); //$NON-NLS-1$ //$NON-NLS-2$
    438          sLanguageNames.put("es", "Spanish"); //$NON-NLS-1$
    439 
    440          // "et": Estonian ->
    441          sLanguageToCountry.put("et", "EE"); //$NON-NLS-1$ //$NON-NLS-2$
    442          sLanguageNames.put("et", "Estonian"); //$NON-NLS-1$
    443 
    444          // "eu": Basque -> Spain, France
    445          sLanguageToCountry.put("eu", "ES"); //$NON-NLS-1$ //$NON-NLS-2$
    446          sLanguageNames.put("eu", "Basque"); //$NON-NLS-1$
    447 
    448          // "fa": Persian -> Iran, Afghanistan
    449          sLanguageToCountry.put("fa", "IR"); //$NON-NLS-1$ //$NON-NLS-2$
    450          sLanguageNames.put("fa", "Persian"); //$NON-NLS-1$
    451 
    452          // "ff": Fulah -> Mauritania, Senegal, Mali, Guinea, Burkina Faso, ...
    453          sLanguageToCountry.put("ff", "MR"); //$NON-NLS-1$ //$NON-NLS-2$
    454          sLanguageNames.put("ff", "Fulah"); //$NON-NLS-1$
    455 
    456          // "fi": Finnish -> Finland
    457          sLanguageToCountry.put("fi", "FI"); //$NON-NLS-1$ //$NON-NLS-2$
    458          sLanguageNames.put("fi", "Finnish"); //$NON-NLS-1$
    459 
    460          // "fj": Fijian -> Fiji
    461          sLanguageToCountry.put("fj", "FJ"); //$NON-NLS-1$ //$NON-NLS-2$
    462          sLanguageNames.put("fj", "Fijian"); //$NON-NLS-1$
    463 
    464          // "fo": Faroese -> Denmark
    465          sLanguageToCountry.put("fo", "DK"); //$NON-NLS-1$ //$NON-NLS-2$
    466          sLanguageNames.put("fo", "Faroese"); //$NON-NLS-1$
    467 
    468          // "fr": French -> France
    469          sLanguageToCountry.put("fr", "FR"); //$NON-NLS-1$ //$NON-NLS-2$
    470          sLanguageNames.put("fr", "French"); //$NON-NLS-1$
    471 
    472          // "fy": Western Frisian -> Netherlands
    473          sLanguageToCountry.put("fy", "NL"); //$NON-NLS-1$ //$NON-NLS-2$
    474          sLanguageNames.put("fy", "Western Frisian"); //$NON-NLS-1$
    475 
    476          // "ga": Irish -> Ireland
    477          sLanguageToCountry.put("ga", "IE"); //$NON-NLS-1$ //$NON-NLS-2$
    478          sLanguageNames.put("ga", "Irish"); //$NON-NLS-1$
    479 
    480          // "gd": Gaelic -> Scotland
    481          sLanguageToCountry.put("gd", "GB"); //$NON-NLS-1$ //$NON-NLS-2$
    482          sLanguageNames.put("gd", "Gaelic"); //$NON-NLS-1$
    483 
    484          // "gl": Galician -> Galicia/Spain
    485          sLanguageToCountry.put("gl", "ES"); //$NON-NLS-1$ //$NON-NLS-2$
    486          sLanguageNames.put("gl", "Galician"); //$NON-NLS-1$
    487 
    488          // "gn": Guaran -> Paraguay
    489          sLanguageToCountry.put("gn", "PY"); //$NON-NLS-1$ //$NON-NLS-2$
    490          sLanguageNames.put("gn", "Guaran\u00ed" /*Guaran*/); //$NON-NLS-1$
    491 
    492          // "gu": Gujarati -> India
    493          sLanguageToCountry.put("gu", "IN"); //$NON-NLS-1$ //$NON-NLS-2$
    494          sLanguageNames.put("gu", "Gujarati"); //$NON-NLS-1$
    495 
    496          // "gv": Manx -> Isle of Man
    497          // We don't have an icon for IM
    498          //sLanguageToCountry.put("gv", "IM"); //$NON-NLS-1$ //$NON-NLS-2$
    499          sLanguageNames.put("gv", "Manx"); //$NON-NLS-1$
    500 
    501          // "ha": Hausa -> Nigeria, Niger
    502          sLanguageToCountry.put("ha", "NG"); //$NON-NLS-1$ //$NON-NLS-2$
    503          sLanguageNames.put("ha", "Hausa"); //$NON-NLS-1$
    504 
    505          // "he": Hebrew -> Israel
    506          sLanguageToCountry.put("he", "IL"); //$NON-NLS-1$ //$NON-NLS-2$
    507          sLanguageNames.put("he", "Hebrew"); //$NON-NLS-1$
    508 
    509          // "hi": Hindi -> India
    510          sLanguageToCountry.put("hi", "IN"); //$NON-NLS-1$ //$NON-NLS-2$
    511          sLanguageNames.put("hi", "Hindi"); //$NON-NLS-1$
    512 
    513          // "ho": Hiri Motu -> Papua New Guinea
    514          sLanguageToCountry.put("ho", "PG"); //$NON-NLS-1$ //$NON-NLS-2$
    515          sLanguageNames.put("ho", "Hiri Motu"); //$NON-NLS-1$
    516 
    517          // "hr": Croatian ->
    518          sLanguageToCountry.put("hr", "HR"); //$NON-NLS-1$ //$NON-NLS-2$
    519          sLanguageNames.put("hr", "Croatian"); //$NON-NLS-1$
    520 
    521          // "ht": Haitian -> Haiti
    522          sLanguageToCountry.put("ht", "HT"); //$NON-NLS-1$ //$NON-NLS-2$
    523          sLanguageNames.put("ht", "Haitian"); //$NON-NLS-1$
    524 
    525          // "hu": Hungarian -> Hungary
    526          sLanguageToCountry.put("hu", "HU"); //$NON-NLS-1$ //$NON-NLS-2$
    527          sLanguageNames.put("hu", "Hungarian"); //$NON-NLS-1$
    528 
    529          // "hy": Armenian -> Armenia
    530          sLanguageToCountry.put("hy", "AM"); //$NON-NLS-1$ //$NON-NLS-2$
    531          sLanguageNames.put("hy", "Armenian"); //$NON-NLS-1$
    532 
    533          // "hz": Herero -> Namibia, Botswana
    534          sLanguageToCountry.put("hz", "NA"); //$NON-NLS-1$ //$NON-NLS-2$
    535          sLanguageNames.put("hz", "Herero"); //$NON-NLS-1$
    536 
    537          // "id": Indonesian -> Indonesia
    538          sLanguageToCountry.put("id", "ID"); //$NON-NLS-1$ //$NON-NLS-2$
    539          sLanguageNames.put("id", "Indonesian"); //$NON-NLS-1$
    540 
    541          // "ig": Igbo ->
    542          sLanguageToCountry.put("ig", "NG"); //$NON-NLS-1$ //$NON-NLS-2$
    543          sLanguageNames.put("ig", "Igbo"); //$NON-NLS-1$
    544 
    545          // "ii": Nuosu -> China
    546          sLanguageToCountry.put("ii", "CN"); //$NON-NLS-1$ //$NON-NLS-2$
    547          sLanguageNames.put("ii", "Nuosu"); //$NON-NLS-1$
    548 
    549          // "ik": Inupiaq -> USA
    550          sLanguageToCountry.put("ik", "US"); //$NON-NLS-1$ //$NON-NLS-2$
    551          sLanguageNames.put("ik", "Inupiaq"); //$NON-NLS-1$
    552 
    553          // "is": Icelandic -> Iceland
    554          sLanguageToCountry.put("is", "IS"); //$NON-NLS-1$ //$NON-NLS-2$
    555          sLanguageNames.put("is", "Icelandic"); //$NON-NLS-1$
    556 
    557          // "it": Italian -> Italy
    558          sLanguageToCountry.put("it", "IT"); //$NON-NLS-1$ //$NON-NLS-2$
    559          sLanguageNames.put("it", "Italian"); //$NON-NLS-1$
    560 
    561          // "iu": Inuktitut -> Canada
    562          sLanguageToCountry.put("iu", "CA"); //$NON-NLS-1$ //$NON-NLS-2$
    563          sLanguageNames.put("iu", "Inuktitut"); //$NON-NLS-1$
    564 
    565          // "ja": Japanese -> Japan
    566          sLanguageToCountry.put("ja", "JP"); //$NON-NLS-1$ //$NON-NLS-2$
    567          sLanguageNames.put("ja", "Japanese"); //$NON-NLS-1$
    568 
    569          // "jv": Javanese -> Indonesia
    570          sLanguageToCountry.put("jv", "ID"); //$NON-NLS-1$ //$NON-NLS-2$
    571          sLanguageNames.put("jv", "Javanese"); //$NON-NLS-1$
    572 
    573          // "ka": Georgian -> Georgia
    574          sLanguageToCountry.put("ka", "GE"); //$NON-NLS-1$ //$NON-NLS-2$
    575          sLanguageNames.put("ka", "Georgian"); //$NON-NLS-1$
    576 
    577          // "kg": Kongo -> Angola, Congo
    578          sLanguageToCountry.put("kg", "AO"); //$NON-NLS-1$ //$NON-NLS-2$
    579          sLanguageNames.put("kg", "Kongo"); //$NON-NLS-1$
    580 
    581          // "ki": Kikuyu -> Kenya
    582          sLanguageToCountry.put("ki", "KE"); //$NON-NLS-1$ //$NON-NLS-2$
    583          sLanguageNames.put("ki", "Kikuyu"); //$NON-NLS-1$
    584 
    585          // "kj": Kwanyama -> Angola, Namibia
    586          sLanguageToCountry.put("kj", "AO"); //$NON-NLS-1$ //$NON-NLS-2$
    587          sLanguageNames.put("kj", "Kwanyama"); //$NON-NLS-1$
    588 
    589          // "kk": Kazakh -> Kazakhstan
    590          sLanguageToCountry.put("kk", "KZ"); //$NON-NLS-1$ //$NON-NLS-2$
    591          sLanguageNames.put("kk", "Kazakh"); //$NON-NLS-1$
    592 
    593          // "kl": Kalaallisut -> Denmark
    594          sLanguageToCountry.put("kl", "DK"); //$NON-NLS-1$ //$NON-NLS-2$
    595          sLanguageNames.put("kl", "Kalaallisut"); //$NON-NLS-1$
    596 
    597          // "km": Khmer -> Cambodia
    598          sLanguageToCountry.put("km", "KH"); //$NON-NLS-1$ //$NON-NLS-2$
    599          sLanguageNames.put("km", "Khmer"); //$NON-NLS-1$
    600 
    601          // "kn": Kannada -> India
    602          sLanguageToCountry.put("kn", "IN"); //$NON-NLS-1$ //$NON-NLS-2$
    603          sLanguageNames.put("kn", "Kannada"); //$NON-NLS-1$
    604 
    605          // "ko": Korean -> Korea
    606          sLanguageToCountry.put("ko", "KR"); //$NON-NLS-1$ //$NON-NLS-2$
    607          sLanguageNames.put("ko", "Korean"); //$NON-NLS-1$
    608 
    609          // "kr": Kanuri -> Nigeria
    610          sLanguageToCountry.put("kr", "NG"); //$NON-NLS-1$ //$NON-NLS-2$
    611          sLanguageNames.put("kr", "Kanuri"); //$NON-NLS-1$
    612 
    613          // "ks": Kashmiri -> India
    614          sLanguageToCountry.put("ks", "IN"); //$NON-NLS-1$ //$NON-NLS-2$
    615          sLanguageNames.put("ks", "Kashmiri"); //$NON-NLS-1$
    616 
    617          // "ku": Kurdish -> Turkey, Iran, Iraq, Syria, Armenia, Azerbaijan
    618          sLanguageToCountry.put("ku", "TR"); //$NON-NLS-1$ //$NON-NLS-2$
    619          sLanguageNames.put("ku", "Kurdish"); //$NON-NLS-1$
    620 
    621          // "kv": Komi -> Russia
    622          sLanguageToCountry.put("kv", "RU"); //$NON-NLS-1$ //$NON-NLS-2$
    623          sLanguageNames.put("kv", "Komi"); //$NON-NLS-1$
    624 
    625          // "kw": Cornish -> UK
    626          sLanguageToCountry.put("kw", "GB"); //$NON-NLS-1$ //$NON-NLS-2$
    627          sLanguageNames.put("kw", "Cornish"); //$NON-NLS-1$
    628 
    629          // "ky": Kyrgyz -> Kyrgyzstan
    630          sLanguageToCountry.put("ky", "KG"); //$NON-NLS-1$ //$NON-NLS-2$
    631          sLanguageNames.put("ky", "Kyrgyz"); //$NON-NLS-1$
    632 
    633          // "lb": Luxembourgish -> Luxembourg
    634          sLanguageToCountry.put("lb", "LU"); //$NON-NLS-1$ //$NON-NLS-2$
    635          sLanguageNames.put("lb", "Luxembourgish"); //$NON-NLS-1$
    636 
    637          // "lg": Ganda -> Uganda
    638          sLanguageToCountry.put("lg", "UG"); //$NON-NLS-1$ //$NON-NLS-2$
    639          sLanguageNames.put("lg", "Ganda"); //$NON-NLS-1$
    640 
    641          // "li": Limburgish -> Netherlands
    642          sLanguageToCountry.put("li", "NL"); //$NON-NLS-1$ //$NON-NLS-2$
    643          sLanguageNames.put("li", "Limburgish"); //$NON-NLS-1$
    644 
    645          // "ln": Lingala -> Congo
    646          sLanguageToCountry.put("ln", "CD"); //$NON-NLS-1$ //$NON-NLS-2$
    647          sLanguageNames.put("ln", "Lingala"); //$NON-NLS-1$
    648 
    649          // "lo": Lao -> Laos
    650          sLanguageToCountry.put("lo", "LA"); //$NON-NLS-1$ //$NON-NLS-2$
    651          sLanguageNames.put("lo", "Lao"); //$NON-NLS-1$
    652 
    653          // "lt": Lithuanian -> Lithuania
    654          sLanguageToCountry.put("lt", "LT"); //$NON-NLS-1$ //$NON-NLS-2$
    655          sLanguageNames.put("lt", "Lithuanian"); //$NON-NLS-1$
    656 
    657          // "lu": Luba-Katanga -> Congo
    658          sLanguageToCountry.put("lu", "CD"); //$NON-NLS-1$ //$NON-NLS-2$
    659          sLanguageNames.put("lu", "Luba-Katanga"); //$NON-NLS-1$
    660 
    661          // "lv": Latvian -> Latvia
    662          sLanguageToCountry.put("lv", "LV"); //$NON-NLS-1$ //$NON-NLS-2$
    663          sLanguageNames.put("lv", "Latvian"); //$NON-NLS-1$
    664 
    665          // "mg": Malagasy -> Madagascar
    666          sLanguageToCountry.put("mg", "MG"); //$NON-NLS-1$ //$NON-NLS-2$
    667          sLanguageNames.put("mg", "Malagasy"); //$NON-NLS-1$
    668 
    669          // "mh": Marshallese -> Marshall Islands
    670          sLanguageToCountry.put("mh", "MH"); //$NON-NLS-1$ //$NON-NLS-2$
    671          sLanguageNames.put("mh", "Marshallese"); //$NON-NLS-1$
    672 
    673          // "mi": Maori -> New Zealand
    674          sLanguageToCountry.put("mi", "NZ"); //$NON-NLS-1$ //$NON-NLS-2$
    675          sLanguageNames.put("mi", "M\u0101ori"); //$NON-NLS-1$
    676 
    677          // "mk": Macedonian -> Macedonia
    678          sLanguageToCountry.put("mk", "MK"); //$NON-NLS-1$ //$NON-NLS-2$
    679          sLanguageNames.put("mk", "Macedonian"); //$NON-NLS-1$
    680 
    681          // "ml": Malayalam -> India
    682          sLanguageToCountry.put("ml", "IN"); //$NON-NLS-1$ //$NON-NLS-2$
    683          sLanguageNames.put("ml", "Malayalam"); //$NON-NLS-1$
    684 
    685          // "mn": Mongolian -> Mongolia
    686          sLanguageToCountry.put("mn", "MN"); //$NON-NLS-1$ //$NON-NLS-2$
    687          sLanguageNames.put("mn", "Mongolian"); //$NON-NLS-1$
    688 
    689          // "mr": Marathi -> India
    690          sLanguageToCountry.put("mr", "IN"); //$NON-NLS-1$ //$NON-NLS-2$
    691          sLanguageNames.put("mr", "Marathi"); //$NON-NLS-1$
    692 
    693          // "ms": Malay -> Malaysia, Indonesia ...
    694          sLanguageToCountry.put("ms", "MY"); //$NON-NLS-1$ //$NON-NLS-2$
    695          sLanguageNames.put("ms", "Malay"); //$NON-NLS-1$
    696 
    697          // "mt": Maltese -> Malta
    698          sLanguageToCountry.put("mt", "MT"); //$NON-NLS-1$ //$NON-NLS-2$
    699          sLanguageNames.put("mt", "Maltese"); //$NON-NLS-1$
    700 
    701          // "my": Burmese -> Myanmar
    702          sLanguageToCountry.put("my", "MM"); //$NON-NLS-1$ //$NON-NLS-2$
    703          sLanguageNames.put("my", "Burmese"); //$NON-NLS-1$
    704 
    705          // "na": Nauru -> Nauru
    706          sLanguageToCountry.put("na", "NR"); //$NON-NLS-1$ //$NON-NLS-2$
    707          sLanguageNames.put("na", "Nauru"); //$NON-NLS-1$
    708 
    709          // "nb": Norwegian -> Norway
    710          sLanguageToCountry.put("nb", "NO"); //$NON-NLS-1$ //$NON-NLS-2$
    711          sLanguageNames.put("nb", "Norwegian Bokm\u00e5l" /*Norwegian Bokml*/); //$NON-NLS-1$
    712 
    713          // "nd": North Ndebele -> Zimbabwe
    714          sLanguageToCountry.put("nd", "ZW"); //$NON-NLS-1$ //$NON-NLS-2$
    715          sLanguageNames.put("nd", "North Ndebele"); //$NON-NLS-1$
    716 
    717          // "ne": Nepali -> Nepal
    718          sLanguageToCountry.put("ne", "NP"); //$NON-NLS-1$ //$NON-NLS-2$
    719          sLanguageNames.put("ne", "Nepali"); //$NON-NLS-1$
    720 
    721          // "ng":Ndonga  -> Namibia
    722          sLanguageToCountry.put("ng", "NA"); //$NON-NLS-1$ //$NON-NLS-2$
    723          sLanguageNames.put("ng", "Ndonga"); //$NON-NLS-1$
    724 
    725          // "nl": Dutch -> Netherlands
    726          sLanguageToCountry.put("nl", "NL"); //$NON-NLS-1$ //$NON-NLS-2$
    727          sLanguageNames.put("nl", "Dutch"); //$NON-NLS-1$
    728 
    729          // "nn": Norwegian Nynorsk -> Norway
    730          sLanguageToCountry.put("nn", "NO"); //$NON-NLS-1$ //$NON-NLS-2$
    731          sLanguageNames.put("nn", "Norwegian Nynorsk"); //$NON-NLS-1$
    732 
    733          // "no": Norwegian -> Norway
    734          sLanguageToCountry.put("no", "NO"); //$NON-NLS-1$ //$NON-NLS-2$
    735          sLanguageNames.put("no", "Norwegian"); //$NON-NLS-1$
    736 
    737          // "nr": South Ndebele -> South Africa
    738          sLanguageToCountry.put("nr", "ZA"); //$NON-NLS-1$ //$NON-NLS-2$
    739          sLanguageNames.put("nr", "South Ndebele"); //$NON-NLS-1$
    740 
    741          // "nv": Navajo -> USA
    742          sLanguageToCountry.put("nv", "US"); //$NON-NLS-1$ //$NON-NLS-2$
    743          sLanguageNames.put("nv", "Navajo"); //$NON-NLS-1$
    744 
    745          // "ny": Chichewa -> Malawi, Zambia
    746          sLanguageToCountry.put("ny", "MW"); //$NON-NLS-1$ //$NON-NLS-2$
    747          sLanguageNames.put("ny", "Chichewa"); //$NON-NLS-1$
    748 
    749          // "oc": Occitan -> France, Italy, Spain, Monaco
    750          sLanguageToCountry.put("oc", "FR"); //$NON-NLS-1$ //$NON-NLS-2$
    751          sLanguageNames.put("oc", "Occitan"); //$NON-NLS-1$
    752 
    753          // "oj": Ojibwe -> Canada, United States
    754          sLanguageToCountry.put("oj", "CA"); //$NON-NLS-1$ //$NON-NLS-2$
    755          sLanguageNames.put("oj", "Ojibwe"); //$NON-NLS-1$
    756 
    757          // "om": Oromo -> Ethiopia
    758          sLanguageToCountry.put("om", "ET"); //$NON-NLS-1$ //$NON-NLS-2$
    759          sLanguageNames.put("om", "Oromo"); //$NON-NLS-1$
    760 
    761          // "or": Oriya -> India
    762          sLanguageToCountry.put("or", "IN"); //$NON-NLS-1$ //$NON-NLS-2$
    763          sLanguageNames.put("or", "Oriya"); //$NON-NLS-1$
    764 
    765          // "os": Ossetian -> Russia (North Ossetia), Georgia
    766          sLanguageToCountry.put("os", "RU"); //$NON-NLS-1$ //$NON-NLS-2$
    767          sLanguageNames.put("os", "Ossetian"); //$NON-NLS-1$
    768 
    769          // "pa": Panjabi, -> Pakistan, India
    770          sLanguageToCountry.put("pa", "PK"); //$NON-NLS-1$ //$NON-NLS-2$
    771          sLanguageNames.put("pa", "Panjabi"); //$NON-NLS-1$
    772 
    773          // "pl": Polish -> Poland
    774          sLanguageToCountry.put("pl", "PL"); //$NON-NLS-1$ //$NON-NLS-2$
    775          sLanguageNames.put("pl", "Polish"); //$NON-NLS-1$
    776 
    777          // "ps": Pashto -> Afghanistan, Pakistan
    778          sLanguageToCountry.put("ps", "AF"); //$NON-NLS-1$ //$NON-NLS-2$
    779          sLanguageNames.put("ps", "Pashto"); //$NON-NLS-1$
    780 
    781          // "pt": Portuguese -> Brazil, Portugal, ...
    782          sLanguageToCountry.put("pt", "BR"); //$NON-NLS-1$ //$NON-NLS-2$
    783          sLanguageNames.put("pt", "Portuguese"); //$NON-NLS-1$
    784 
    785          // "qu": Quechua -> Peru, Bolivia
    786          sLanguageToCountry.put("qu", "PE"); //$NON-NLS-1$ //$NON-NLS-2$
    787          sLanguageNames.put("qu", "Quechua"); //$NON-NLS-1$
    788 
    789          // "rm": Romansh -> Switzerland
    790          sLanguageToCountry.put("rm", "CH"); //$NON-NLS-1$ //$NON-NLS-2$
    791          sLanguageNames.put("rm", "Romansh"); //$NON-NLS-1$
    792 
    793          // "rn": Kirundi -> Burundi, Uganda
    794          sLanguageToCountry.put("rn", "BI"); //$NON-NLS-1$ //$NON-NLS-2$
    795          sLanguageNames.put("rn", "Kirundi"); //$NON-NLS-1$
    796 
    797          // "ro": Romanian -> Romania, Republic of Moldova
    798          sLanguageToCountry.put("ro", "RO"); //$NON-NLS-1$ //$NON-NLS-2$
    799          sLanguageNames.put("ro", "Romanian"); //$NON-NLS-1$
    800 
    801          // "ru": Russian -> Russia
    802          sLanguageToCountry.put("ru", "RU"); //$NON-NLS-1$ //$NON-NLS-2$
    803          sLanguageNames.put("ru", "Russian"); //$NON-NLS-1$
    804 
    805          // "rw": Kinyarwanda -> Rwanda, Uganda, Democratic Republic of the Congo
    806          sLanguageToCountry.put("rw", "RW"); //$NON-NLS-1$ //$NON-NLS-2$
    807          sLanguageNames.put("rw", "Kinyarwanda"); //$NON-NLS-1$
    808 
    809          // "sa": Sanskrit -> India
    810          sLanguageToCountry.put("sa", "IN"); //$NON-NLS-1$ //$NON-NLS-2$
    811          sLanguageNames.put("sa", "Sanskrit"); //$NON-NLS-1$
    812 
    813          // "sc": Sardinian -> Italy
    814          sLanguageToCountry.put("sc", "IT"); //$NON-NLS-1$ //$NON-NLS-2$
    815          sLanguageNames.put("sc", "Sardinian"); //$NON-NLS-1$
    816 
    817          // "sd": Sindhi -> Pakistan, India
    818          sLanguageToCountry.put("sd", "PK"); //$NON-NLS-1$ //$NON-NLS-2$
    819          sLanguageNames.put("sd", "Sindhi"); //$NON-NLS-1$
    820 
    821          // "se": Northern Sami -> Norway, Sweden, Finland
    822          sLanguageToCountry.put("se", "NO"); //$NON-NLS-1$ //$NON-NLS-2$
    823          sLanguageNames.put("se", "Northern Sami"); //$NON-NLS-1$
    824 
    825          // "sg": Sango -> Central African Republic
    826          sLanguageToCountry.put("sg", "CF"); //$NON-NLS-1$ //$NON-NLS-2$
    827          sLanguageNames.put("sg", "Sango"); //$NON-NLS-1$
    828 
    829          // "si": Sinhala ->  Sri Lanka
    830          sLanguageToCountry.put("si", "LK"); //$NON-NLS-1$ //$NON-NLS-2$
    831          sLanguageNames.put("si", "Sinhala"); //$NON-NLS-1$
    832 
    833          // "sk": Slovak -> Slovakia
    834          sLanguageToCountry.put("sk", "SK"); //$NON-NLS-1$ //$NON-NLS-2$
    835          sLanguageNames.put("sk", "Slovak"); //$NON-NLS-1$
    836 
    837          // "sl": Slovene -> Slovenia
    838          sLanguageToCountry.put("sl", "SI"); //$NON-NLS-1$ //$NON-NLS-2$
    839          sLanguageNames.put("sl", "Slovene"); //$NON-NLS-1$
    840 
    841          // "sm": Samoan -> Samoa
    842          sLanguageToCountry.put("sm", "WS"); //$NON-NLS-1$ //$NON-NLS-2$
    843          sLanguageNames.put("sm", "Samoan"); //$NON-NLS-1$
    844 
    845          // "sn": Shona -> Zimbabwe
    846          sLanguageToCountry.put("sn", "ZW"); //$NON-NLS-1$ //$NON-NLS-2$
    847          sLanguageNames.put("sn", "Shona"); //$NON-NLS-1$
    848 
    849          // "so": Somali -> Somalia
    850          sLanguageToCountry.put("so", "SO"); //$NON-NLS-1$ //$NON-NLS-2$
    851          sLanguageNames.put("so", "Somali"); //$NON-NLS-1$
    852 
    853          // "sq": Albanian -> Albania
    854          sLanguageToCountry.put("sq", "AL"); //$NON-NLS-1$ //$NON-NLS-2$
    855          sLanguageNames.put("sq", "Albanian"); //$NON-NLS-1$
    856 
    857          // "sr": Serbian -> Serbia, Bosnia and Herzegovina
    858          sLanguageToCountry.put("sr", "RS"); //$NON-NLS-1$ //$NON-NLS-2$
    859          sLanguageNames.put("sr", "Serbian"); //$NON-NLS-1$
    860 
    861          // "ss": Swati -> Swaziland
    862          sLanguageToCountry.put("ss", "SZ"); //$NON-NLS-1$ //$NON-NLS-2$
    863          sLanguageNames.put("ss", "Swati"); //$NON-NLS-1$
    864 
    865          // "st": Southern Sotho -> Lesotho, South Africa
    866          sLanguageToCountry.put("st", "LS"); //$NON-NLS-1$ //$NON-NLS-2$
    867          sLanguageNames.put("st", "Southern Sotho"); //$NON-NLS-1$
    868 
    869          // "su": Sundanese -> Indoniesia
    870          sLanguageToCountry.put("su", "ID"); //$NON-NLS-1$ //$NON-NLS-2$
    871          sLanguageNames.put("su", "Sundanese"); //$NON-NLS-1$
    872 
    873          // "sv": Swedish -> Sweden
    874          sLanguageToCountry.put("sv", "SE"); //$NON-NLS-1$ //$NON-NLS-2$
    875          sLanguageNames.put("sv", "Swedish"); //$NON-NLS-1$
    876 
    877          // "sw": Swahili -> Tanzania, Kenya, and Congo (DRC)
    878          sLanguageToCountry.put("sw", "TZ"); //$NON-NLS-1$ //$NON-NLS-2$
    879          sLanguageNames.put("sw", "Swahili"); //$NON-NLS-1$
    880 
    881          // "ta": Tamil -> India, Sri Lanka
    882          sLanguageToCountry.put("ta", "IN"); //$NON-NLS-1$ //$NON-NLS-2$
    883          sLanguageNames.put("ta", "Tamil"); //$NON-NLS-1$
    884 
    885          // "te": Telugu -> India
    886          sLanguageToCountry.put("te", "IN"); //$NON-NLS-1$ //$NON-NLS-2$
    887          sLanguageNames.put("te", "Telugu"); //$NON-NLS-1$
    888 
    889          // "tg": Tajik -> Tajikistan, Uzbekistan, Russia, Afghanistan
    890          sLanguageToCountry.put("tg", "TJ"); //$NON-NLS-1$ //$NON-NLS-2$
    891          sLanguageNames.put("tg", "Tajik"); //$NON-NLS-1$
    892 
    893          // "th": Thai -> Thailand
    894          sLanguageToCountry.put("th", "TH"); //$NON-NLS-1$ //$NON-NLS-2$
    895          sLanguageNames.put("th", "Thai"); //$NON-NLS-1$
    896 
    897          // "ti": Tigrinya -> Eritrea, Ethiopia
    898          sLanguageToCountry.put("ti", "ER"); //$NON-NLS-1$ //$NON-NLS-2$
    899          sLanguageNames.put("ti", "Tigrinya"); //$NON-NLS-1$
    900 
    901          // "tk": Turkmen -> Turkmenistan
    902          sLanguageToCountry.put("tk", "TM"); //$NON-NLS-1$ //$NON-NLS-2$
    903          sLanguageNames.put("tk", "Turkmen"); //$NON-NLS-1$
    904 
    905          // "tl": Tagalog -> Philippines
    906          sLanguageToCountry.put("tl", "PH"); //$NON-NLS-1$ //$NON-NLS-2$
    907          sLanguageNames.put("tl", "Tagalog"); //$NON-NLS-1$
    908 
    909          // "tn": Tswana -> Botswana, South Africa,
    910          sLanguageToCountry.put("tn", "BW"); //$NON-NLS-1$ //$NON-NLS-2$
    911          sLanguageNames.put("tn", "Tswana"); //$NON-NLS-1$
    912 
    913          // "to": Tonga -> Tonga
    914          sLanguageToCountry.put("to", "TO"); //$NON-NLS-1$ //$NON-NLS-2$
    915          sLanguageNames.put("to", "Tonga"); //$NON-NLS-1$
    916 
    917          // "tr": Turkish -> Turkey
    918          sLanguageToCountry.put("tr", "TR"); //$NON-NLS-1$ //$NON-NLS-2$
    919          sLanguageNames.put("tr", "Turkish"); //$NON-NLS-1$
    920 
    921          // "ts": Tsonga -> Mozambique, South Africa
    922          sLanguageToCountry.put("ts", "MZ"); //$NON-NLS-1$ //$NON-NLS-2$
    923          sLanguageNames.put("ts", "Tsonga"); //$NON-NLS-1$
    924 
    925          // "tt": Tatar -> Russia
    926          sLanguageToCountry.put("tt", "RU"); //$NON-NLS-1$ //$NON-NLS-2$
    927          sLanguageNames.put("tt", "Tatar"); //$NON-NLS-1$
    928 
    929          // "tw": Twi -> Ghana, Ivory Coast
    930          sLanguageToCountry.put("tw", "GH"); //$NON-NLS-1$ //$NON-NLS-2$
    931          sLanguageNames.put("tw", "Twi"); //$NON-NLS-1$
    932 
    933          // "ty": Tahitian -> French Polynesia
    934          sLanguageToCountry.put("ty", "PF"); //$NON-NLS-1$ //$NON-NLS-2$
    935          sLanguageNames.put("ty", "Tahitian"); //$NON-NLS-1$
    936 
    937          // "ug": Uighur -> China, Kazakhstan
    938          sLanguageToCountry.put("ug", "CN"); //$NON-NLS-1$ //$NON-NLS-2$
    939          sLanguageNames.put("ug", "Uighur"); //$NON-NLS-1$
    940 
    941          // "uk": Ukrainian -> Ukraine
    942          sLanguageToCountry.put("uk", "UA"); //$NON-NLS-1$ //$NON-NLS-2$
    943          sLanguageNames.put("uk", "Ukrainian"); //$NON-NLS-1$
    944 
    945          // "ur": Urdu -> India, Pakistan
    946          sLanguageToCountry.put("ur", "IN"); //$NON-NLS-1$ //$NON-NLS-2$
    947          sLanguageNames.put("ur", "Urdu"); //$NON-NLS-1$
    948 
    949          // "uz": Uzbek -> Uzbekistan
    950          sLanguageToCountry.put("uz", "UZ"); //$NON-NLS-1$ //$NON-NLS-2$
    951          sLanguageNames.put("uz", "Uzbek"); //$NON-NLS-1$
    952 
    953          // "ve": Venda -> South Africa, Zimbabwe
    954          sLanguageToCountry.put("ve", "ZA"); //$NON-NLS-1$ //$NON-NLS-2$
    955          sLanguageNames.put("ve", "Venda"); //$NON-NLS-1$
    956 
    957          // "vi": Vietnamese -> Vietnam
    958          sLanguageToCountry.put("vi", "VN"); //$NON-NLS-1$ //$NON-NLS-2$
    959          sLanguageNames.put("vi", "Vietnamese"); //$NON-NLS-1$
    960 
    961          // "wa": Walloon -> Belgium, France
    962          sLanguageToCountry.put("wa", "BE"); //$NON-NLS-1$ //$NON-NLS-2$
    963          sLanguageNames.put("wa", "Walloon"); //$NON-NLS-1$
    964 
    965          // "wo": Wolof -> Senegal, Gambia, Mauritania
    966          sLanguageToCountry.put("wo", "SN"); //$NON-NLS-1$ //$NON-NLS-2$
    967          sLanguageNames.put("wo", "Wolof"); //$NON-NLS-1$
    968 
    969          // "xh": Xhosa -> South Africa, Lesotho
    970          sLanguageToCountry.put("xh", "ZA"); //$NON-NLS-1$ //$NON-NLS-2$
    971          sLanguageNames.put("xh", "Xhosa"); //$NON-NLS-1$
    972 
    973          // "yi": Yiddish -> United States, Israel, Argentina, Brazil, ...
    974          sLanguageToCountry.put("yi", "US"); //$NON-NLS-1$ //$NON-NLS-2$
    975          sLanguageNames.put("yi", "Yiddish"); //$NON-NLS-1$
    976 
    977          // "yo": Yorb -> Nigeria, Togo, Benin
    978          sLanguageToCountry.put("yo", "NG"); //$NON-NLS-1$ //$NON-NLS-2$
    979          sLanguageNames.put("yo", "Yor\u00f9b\u00e1" /*Yorb*/); //$NON-NLS-1$
    980 
    981          // "za": Zhuang -> China
    982          sLanguageToCountry.put("za", "CN"); //$NON-NLS-1$ //$NON-NLS-2$
    983          sLanguageNames.put("za", "Zhuang"); //$NON-NLS-1$
    984 
    985          // "zh": Chinese -> China, Taiwan, Singapore
    986          sLanguageToCountry.put("zh", "CN"); //$NON-NLS-1$ //$NON-NLS-2$
    987          sLanguageNames.put("zh", "Chinese"); //$NON-NLS-1$
    988 
    989          // "zu": Zulu -> South Africa
    990          sLanguageToCountry.put("zu", "ZA"); //$NON-NLS-1$ //$NON-NLS-2$
    991          sLanguageNames.put("zu", "Zulu"); //$NON-NLS-1$
    992 
    993          // Region Name Map, ISO_3166-1, alpha-2
    994          sRegionNames.put("AD", "Andorra"); //$NON-NLS-1$
    995          sRegionNames.put("AE", "United Arab Emirates"); //$NON-NLS-1$
    996          sRegionNames.put("AF", "Afghanistan"); //$NON-NLS-1$
    997          sRegionNames.put("AG", "Antigua and Barbuda"); //$NON-NLS-1$
    998          sRegionNames.put("AI", "Anguilla"); //$NON-NLS-1$
    999          sRegionNames.put("AL", "Albania"); //$NON-NLS-1$
   1000          sRegionNames.put("AM", "Armenia"); //$NON-NLS-1$
   1001          sRegionNames.put("AO", "Angola"); //$NON-NLS-1$
   1002          sRegionNames.put("AQ", "Antarctica"); //$NON-NLS-1$
   1003          sRegionNames.put("AR", "Argentina"); //$NON-NLS-1$
   1004          sRegionNames.put("AS", "American Samoa"); //$NON-NLS-1$
   1005          sRegionNames.put("AT", "Austria"); //$NON-NLS-1$
   1006          sRegionNames.put("AU", "Australia"); //$NON-NLS-1$
   1007          sRegionNames.put("AW", "Aruba"); //$NON-NLS-1$
   1008          sRegionNames.put("AX", "\u00c5land Islands" /*land Islands*/); //$NON-NLS-1$
   1009          sRegionNames.put("AZ", "Azerbaijan"); //$NON-NLS-1$
   1010          sRegionNames.put("BA", "Bosnia and Herzegovina"); //$NON-NLS-1$
   1011          sRegionNames.put("BB", "Barbados"); //$NON-NLS-1$
   1012          sRegionNames.put("BD", "Bangladesh"); //$NON-NLS-1$
   1013          sRegionNames.put("BE", "Belgium"); //$NON-NLS-1$
   1014          sRegionNames.put("BF", "Burkina Faso"); //$NON-NLS-1$
   1015          sRegionNames.put("BG", "Bulgaria"); //$NON-NLS-1$
   1016          sRegionNames.put("BH", "Bahrain"); //$NON-NLS-1$
   1017          sRegionNames.put("BI", "Burundi"); //$NON-NLS-1$
   1018          sRegionNames.put("BJ", "Benin"); //$NON-NLS-1$
   1019          sRegionNames.put("BL", "Saint Barth\u00e9lemy" /*Saint Barthlemy*/); //$NON-NLS-1$
   1020          sRegionNames.put("BM", "Bermuda"); //$NON-NLS-1$
   1021          sRegionNames.put("BN", "Brunei Darussalam"); //$NON-NLS-1$
   1022          sRegionNames.put("BO", "Bolivia, Plurinational State of"); //$NON-NLS-1$
   1023          sRegionNames.put("BQ", "Bonaire, Sint Eustatius and Saba"); //$NON-NLS-1$
   1024          sRegionNames.put("BR", "Brazil"); //$NON-NLS-1$
   1025          sRegionNames.put("BS", "Bahamas"); //$NON-NLS-1$
   1026          sRegionNames.put("BT", "Bhutan"); //$NON-NLS-1$
   1027          sRegionNames.put("BV", "Bouvet Island"); //$NON-NLS-1$
   1028          sRegionNames.put("BW", "Botswana"); //$NON-NLS-1$
   1029          sRegionNames.put("BY", "Belarus"); //$NON-NLS-1$
   1030          sRegionNames.put("BZ", "Belize"); //$NON-NLS-1$
   1031          sRegionNames.put("CA", "Canada"); //$NON-NLS-1$
   1032          sRegionNames.put("CC", "Cocos (Keeling) Islands"); //$NON-NLS-1$
   1033          sRegionNames.put("CD", "Congo, the Democratic Republic of the"); //$NON-NLS-1$
   1034          sRegionNames.put("CF", "Central African Republic"); //$NON-NLS-1$
   1035          sRegionNames.put("CG", "Congo"); //$NON-NLS-1$
   1036          sRegionNames.put("CH", "Switzerland"); //$NON-NLS-1$
   1037          sRegionNames.put("CI", "C\u00f4te d'Ivoire" /*Cte d'Ivoire*/); //$NON-NLS-1$
   1038          sRegionNames.put("CK", "Cook Islands"); //$NON-NLS-1$
   1039          sRegionNames.put("CL", "Chile"); //$NON-NLS-1$
   1040          sRegionNames.put("CM", "Cameroon"); //$NON-NLS-1$
   1041          sRegionNames.put("CN", "China"); //$NON-NLS-1$
   1042          sRegionNames.put("CO", "Colombia"); //$NON-NLS-1$
   1043          sRegionNames.put("CR", "Costa Rica"); //$NON-NLS-1$
   1044          sRegionNames.put("CU", "Cuba"); //$NON-NLS-1$
   1045          sRegionNames.put("CV", "Cape Verde"); //$NON-NLS-1$
   1046          sRegionNames.put("CW", "Cura\u00e7ao" /*Curaao*/); //$NON-NLS-1$
   1047          sRegionNames.put("CX", "Christmas Island"); //$NON-NLS-1$
   1048          sRegionNames.put("CY", "Cyprus"); //$NON-NLS-1$
   1049          sRegionNames.put("CZ", "Czech Republic"); //$NON-NLS-1$
   1050          sRegionNames.put("DE", "Germany"); //$NON-NLS-1$
   1051          sRegionNames.put("DJ", "Djibouti"); //$NON-NLS-1$
   1052          sRegionNames.put("DK", "Denmark"); //$NON-NLS-1$
   1053          sRegionNames.put("DM", "Dominica"); //$NON-NLS-1$
   1054          sRegionNames.put("DO", "Dominican Republic"); //$NON-NLS-1$
   1055          sRegionNames.put("DZ", "Algeria"); //$NON-NLS-1$
   1056          sRegionNames.put("EC", "Ecuador"); //$NON-NLS-1$
   1057          sRegionNames.put("EE", "Estonia"); //$NON-NLS-1$
   1058          sRegionNames.put("EG", "Egypt"); //$NON-NLS-1$
   1059          sRegionNames.put("EH", "Western Sahara"); //$NON-NLS-1$
   1060          sRegionNames.put("ER", "Eritrea"); //$NON-NLS-1$
   1061          sRegionNames.put("ES", "Spain"); //$NON-NLS-1$
   1062          sRegionNames.put("ET", "Ethiopia"); //$NON-NLS-1$
   1063          sRegionNames.put("FI", "Finland"); //$NON-NLS-1$
   1064          sRegionNames.put("FJ", "Fiji"); //$NON-NLS-1$
   1065          sRegionNames.put("FK", "Falkland Islands (Malvinas)"); //$NON-NLS-1$
   1066          sRegionNames.put("FM", "Micronesia, Federated States of"); //$NON-NLS-1$
   1067          sRegionNames.put("FO", "Faroe Islands"); //$NON-NLS-1$
   1068          sRegionNames.put("FR", "France"); //$NON-NLS-1$
   1069          sRegionNames.put("GA", "Gabon"); //$NON-NLS-1$
   1070          sRegionNames.put("GB", "United Kingdom"); //$NON-NLS-1$
   1071          sRegionNames.put("GD", "Grenada"); //$NON-NLS-1$
   1072          sRegionNames.put("GE", "Georgia"); //$NON-NLS-1$
   1073          sRegionNames.put("GF", "French Guiana"); //$NON-NLS-1$
   1074          sRegionNames.put("GG", "Guernsey"); //$NON-NLS-1$
   1075          sRegionNames.put("GH", "Ghana"); //$NON-NLS-1$
   1076          sRegionNames.put("GI", "Gibraltar"); //$NON-NLS-1$
   1077          sRegionNames.put("GL", "Greenland"); //$NON-NLS-1$
   1078          sRegionNames.put("GM", "Gambia"); //$NON-NLS-1$
   1079          sRegionNames.put("GN", "Guinea"); //$NON-NLS-1$
   1080          sRegionNames.put("GP", "Guadeloupe"); //$NON-NLS-1$
   1081          sRegionNames.put("GQ", "Equatorial Guinea"); //$NON-NLS-1$
   1082          sRegionNames.put("GR", "Greece"); //$NON-NLS-1$
   1083          sRegionNames.put("GS", "South Georgia and the South Sandwich Islands"); //$NON-NLS-1$
   1084          sRegionNames.put("GT", "Guatemala"); //$NON-NLS-1$
   1085          sRegionNames.put("GU", "Guam"); //$NON-NLS-1$
   1086          sRegionNames.put("GW", "Guinea-Bissau"); //$NON-NLS-1$
   1087          sRegionNames.put("GY", "Guyana"); //$NON-NLS-1$
   1088          sRegionNames.put("HK", "Hong Kong"); //$NON-NLS-1$
   1089          sRegionNames.put("HM", "Heard Island and McDonald Islands"); //$NON-NLS-1$
   1090          sRegionNames.put("HN", "Honduras"); //$NON-NLS-1$
   1091          sRegionNames.put("HR", "Croatia"); //$NON-NLS-1$
   1092          sRegionNames.put("HT", "Haiti"); //$NON-NLS-1$
   1093          sRegionNames.put("HU", "Hungary"); //$NON-NLS-1$
   1094          sRegionNames.put("ID", "Indonesia"); //$NON-NLS-1$
   1095          sRegionNames.put("IE", "Ireland"); //$NON-NLS-1$
   1096          sRegionNames.put("IL", "Israel"); //$NON-NLS-1$
   1097          sRegionNames.put("IM", "Isle of Man"); //$NON-NLS-1$
   1098          sRegionNames.put("IN", "India"); //$NON-NLS-1$
   1099          sRegionNames.put("IO", "British Indian Ocean Territory"); //$NON-NLS-1$
   1100          sRegionNames.put("IQ", "Iraq"); //$NON-NLS-1$
   1101          sRegionNames.put("IR", "Iran, Islamic Republic of"); //$NON-NLS-1$
   1102          sRegionNames.put("IS", "Iceland"); //$NON-NLS-1$
   1103          sRegionNames.put("IT", "Italy"); //$NON-NLS-1$
   1104          sRegionNames.put("JE", "Jersey"); //$NON-NLS-1$
   1105          sRegionNames.put("JM", "Jamaica"); //$NON-NLS-1$
   1106          sRegionNames.put("JO", "Jordan"); //$NON-NLS-1$
   1107          sRegionNames.put("JP", "Japan"); //$NON-NLS-1$
   1108          sRegionNames.put("KE", "Kenya"); //$NON-NLS-1$
   1109          sRegionNames.put("KG", "Kyrgyzstan"); //$NON-NLS-1$
   1110          sRegionNames.put("KH", "Cambodia"); //$NON-NLS-1$
   1111          sRegionNames.put("KI", "Kiribati"); //$NON-NLS-1$
   1112          sRegionNames.put("KM", "Comoros"); //$NON-NLS-1$
   1113          sRegionNames.put("KN", "Saint Kitts and Nevis"); //$NON-NLS-1$
   1114          sRegionNames.put("KP", "Korea, Democratic People's Republic of"); //$NON-NLS-1$
   1115          sRegionNames.put("KR", "Korea, Republic of"); //$NON-NLS-1$
   1116          sRegionNames.put("KW", "Kuwait"); //$NON-NLS-1$
   1117          sRegionNames.put("KY", "Cayman Islands"); //$NON-NLS-1$
   1118          sRegionNames.put("KZ", "Kazakhstan"); //$NON-NLS-1$
   1119          sRegionNames.put("LA", "Lao People's Democratic Republic"); //$NON-NLS-1$
   1120          sRegionNames.put("LB", "Lebanon"); //$NON-NLS-1$
   1121          sRegionNames.put("LC", "Saint Lucia"); //$NON-NLS-1$
   1122          sRegionNames.put("LI", "Liechtenstein"); //$NON-NLS-1$
   1123          sRegionNames.put("LK", "Sri Lanka"); //$NON-NLS-1$
   1124          sRegionNames.put("LR", "Liberia"); //$NON-NLS-1$
   1125          sRegionNames.put("LS", "Lesotho"); //$NON-NLS-1$
   1126          sRegionNames.put("LT", "Lithuania"); //$NON-NLS-1$
   1127          sRegionNames.put("LU", "Luxembourg"); //$NON-NLS-1$
   1128          sRegionNames.put("LV", "Latvia"); //$NON-NLS-1$
   1129          sRegionNames.put("LY", "Libya"); //$NON-NLS-1$
   1130          sRegionNames.put("MA", "Morocco"); //$NON-NLS-1$
   1131          sRegionNames.put("MC", "Monaco"); //$NON-NLS-1$
   1132          sRegionNames.put("MD", "Moldova, Republic of"); //$NON-NLS-1$
   1133          sRegionNames.put("ME", "Montenegro"); //$NON-NLS-1$
   1134          sRegionNames.put("MF", "Saint Martin (French part)"); //$NON-NLS-1$
   1135          sRegionNames.put("MG", "Madagascar"); //$NON-NLS-1$
   1136          sRegionNames.put("MH", "Marshall Islands"); //$NON-NLS-1$
   1137          sRegionNames.put("MK", "Macedonia, the former Yugoslav Republic of"); //$NON-NLS-1$
   1138          sRegionNames.put("ML", "Mali"); //$NON-NLS-1$
   1139          sRegionNames.put("MM", "Myanmar"); //$NON-NLS-1$
   1140          sRegionNames.put("MN", "Mongolia"); //$NON-NLS-1$
   1141          sRegionNames.put("MO", "Macao"); //$NON-NLS-1$
   1142          sRegionNames.put("MP", "Northern Mariana Islands"); //$NON-NLS-1$
   1143          sRegionNames.put("MQ", "Martinique"); //$NON-NLS-1$
   1144          sRegionNames.put("MR", "Mauritania"); //$NON-NLS-1$
   1145          sRegionNames.put("MS", "Montserrat"); //$NON-NLS-1$
   1146          sRegionNames.put("MT", "Malta"); //$NON-NLS-1$
   1147          sRegionNames.put("MU", "Mauritius"); //$NON-NLS-1$
   1148          sRegionNames.put("MV", "Maldives"); //$NON-NLS-1$
   1149          sRegionNames.put("MW", "Malawi"); //$NON-NLS-1$
   1150          sRegionNames.put("MX", "Mexico"); //$NON-NLS-1$
   1151          sRegionNames.put("MY", "Malaysia"); //$NON-NLS-1$
   1152          sRegionNames.put("MZ", "Mozambique"); //$NON-NLS-1$
   1153          sRegionNames.put("NA", "Namibia"); //$NON-NLS-1$
   1154          sRegionNames.put("NC", "New Caledonia"); //$NON-NLS-1$
   1155          sRegionNames.put("NE", "Niger"); //$NON-NLS-1$
   1156          sRegionNames.put("NF", "Norfolk Island"); //$NON-NLS-1$
   1157          sRegionNames.put("NG", "Nigeria"); //$NON-NLS-1$
   1158          sRegionNames.put("NI", "Nicaragua"); //$NON-NLS-1$
   1159          sRegionNames.put("NL", "Netherlands"); //$NON-NLS-1$
   1160          sRegionNames.put("NO", "Norway"); //$NON-NLS-1$
   1161          sRegionNames.put("NP", "Nepal"); //$NON-NLS-1$
   1162          sRegionNames.put("NR", "Nauru"); //$NON-NLS-1$
   1163          sRegionNames.put("NU", "Niue"); //$NON-NLS-1$
   1164          sRegionNames.put("NZ", "New Zealand"); //$NON-NLS-1$
   1165          sRegionNames.put("OM", "Oman"); //$NON-NLS-1$
   1166          sRegionNames.put("PA", "Panama"); //$NON-NLS-1$
   1167          sRegionNames.put("PE", "Peru"); //$NON-NLS-1$
   1168          sRegionNames.put("PF", "French Polynesia"); //$NON-NLS-1$
   1169          sRegionNames.put("PG", "Papua New Guinea"); //$NON-NLS-1$
   1170          sRegionNames.put("PH", "Philippines"); //$NON-NLS-1$
   1171          sRegionNames.put("PK", "Pakistan"); //$NON-NLS-1$
   1172          sRegionNames.put("PL", "Poland"); //$NON-NLS-1$
   1173          sRegionNames.put("PM", "Saint Pierre and Miquelon"); //$NON-NLS-1$
   1174          sRegionNames.put("PN", "Pitcairn"); //$NON-NLS-1$
   1175          sRegionNames.put("PR", "Puerto Rico"); //$NON-NLS-1$
   1176          sRegionNames.put("PS", "Palestinian Territory, Occupied"); //$NON-NLS-1$
   1177          sRegionNames.put("PT", "Portugal"); //$NON-NLS-1$
   1178          sRegionNames.put("PW", "Palau"); //$NON-NLS-1$
   1179          sRegionNames.put("PY", "Paraguay"); //$NON-NLS-1$
   1180          sRegionNames.put("QA", "Qatar"); //$NON-NLS-1$
   1181          sRegionNames.put("RE", "R\u00e9union" /*Runion*/); //$NON-NLS-1$
   1182          sRegionNames.put("RO", "Romania"); //$NON-NLS-1$
   1183          sRegionNames.put("RS", "Serbia"); //$NON-NLS-1$
   1184          sRegionNames.put("RU", "Russian Federation"); //$NON-NLS-1$
   1185          sRegionNames.put("RW", "Rwanda"); //$NON-NLS-1$
   1186          sRegionNames.put("SA", "Saudi Arabia"); //$NON-NLS-1$
   1187          sRegionNames.put("SB", "Solomon Islands"); //$NON-NLS-1$
   1188          sRegionNames.put("SC", "Seychelles"); //$NON-NLS-1$
   1189          sRegionNames.put("SD", "Sudan"); //$NON-NLS-1$
   1190          sRegionNames.put("SE", "Sweden"); //$NON-NLS-1$
   1191          sRegionNames.put("SG", "Singapore"); //$NON-NLS-1$
   1192          sRegionNames.put("SH", "Saint Helena, Ascension and Tristan da Cunha"); //$NON-NLS-1$
   1193          sRegionNames.put("SI", "Slovenia"); //$NON-NLS-1$
   1194          sRegionNames.put("SJ", "Svalbard and Jan Mayen"); //$NON-NLS-1$
   1195          sRegionNames.put("SK", "Slovakia"); //$NON-NLS-1$
   1196          sRegionNames.put("SL", "Sierra Leone"); //$NON-NLS-1$
   1197          sRegionNames.put("SM", "San Marino"); //$NON-NLS-1$
   1198          sRegionNames.put("SN", "Senegal"); //$NON-NLS-1$
   1199          sRegionNames.put("SO", "Somalia"); //$NON-NLS-1$
   1200          sRegionNames.put("SR", "Suriname"); //$NON-NLS-1$
   1201          sRegionNames.put("SS", "South Sudan"); //$NON-NLS-1$
   1202          sRegionNames.put("ST", "Sao Tome and Principe"); //$NON-NLS-1$
   1203          sRegionNames.put("SV", "El Salvador"); //$NON-NLS-1$
   1204          sRegionNames.put("SX", "Sint Maarten (Dutch part)"); //$NON-NLS-1$
   1205          sRegionNames.put("SY", "Syrian Arab Republic"); //$NON-NLS-1$
   1206          sRegionNames.put("SZ", "Swaziland"); //$NON-NLS-1$
   1207          sRegionNames.put("TC", "Turks and Caicos Islands"); //$NON-NLS-1$
   1208          sRegionNames.put("TD", "Chad"); //$NON-NLS-1$
   1209          sRegionNames.put("TF", "French Southern Territories"); //$NON-NLS-1$
   1210          sRegionNames.put("TG", "Togo"); //$NON-NLS-1$
   1211          sRegionNames.put("TH", "Thailand"); //$NON-NLS-1$
   1212          sRegionNames.put("TJ", "Tajikistan"); //$NON-NLS-1$
   1213          sRegionNames.put("TK", "Tokelau"); //$NON-NLS-1$
   1214          sRegionNames.put("TL", "Timor-Leste"); //$NON-NLS-1$
   1215          sRegionNames.put("TM", "Turkmenistan"); //$NON-NLS-1$
   1216          sRegionNames.put("TN", "Tunisia"); //$NON-NLS-1$
   1217          sRegionNames.put("TO", "Tonga"); //$NON-NLS-1$
   1218          sRegionNames.put("TR", "Turkey"); //$NON-NLS-1$
   1219          sRegionNames.put("TT", "Trinidad and Tobago"); //$NON-NLS-1$
   1220          sRegionNames.put("TV", "Tuvalu"); //$NON-NLS-1$
   1221          sRegionNames.put("TW", "Taiwan, Province of China"); //$NON-NLS-1$
   1222          sRegionNames.put("TZ", "Tanzania, United Republic of"); //$NON-NLS-1$
   1223          sRegionNames.put("UA", "Ukraine"); //$NON-NLS-1$
   1224          sRegionNames.put("UG", "Uganda"); //$NON-NLS-1$
   1225          sRegionNames.put("UM", "United States Minor Outlying Islands"); //$NON-NLS-1$
   1226          sRegionNames.put("US", "United States"); //$NON-NLS-1$
   1227          sRegionNames.put("UY", "Uruguay"); //$NON-NLS-1$
   1228          sRegionNames.put("UZ", "Uzbekistan"); //$NON-NLS-1$
   1229          sRegionNames.put("VA", "Holy See (Vatican City State)"); //$NON-NLS-1$
   1230          sRegionNames.put("VC", "Saint Vincent and the Grenadines"); //$NON-NLS-1$
   1231          sRegionNames.put("VE", "Venezuela, Bolivarian Republic of"); //$NON-NLS-1$
   1232          sRegionNames.put("VG", "Virgin Islands, British"); //$NON-NLS-1$
   1233          sRegionNames.put("VI", "Virgin Islands, U.S."); //$NON-NLS-1$
   1234          sRegionNames.put("VN", "Viet Nam"); //$NON-NLS-1$
   1235          sRegionNames.put("VU", "Vanuatu"); //$NON-NLS-1$
   1236          sRegionNames.put("WF", "Wallis and Futuna"); //$NON-NLS-1$
   1237          sRegionNames.put("WS", "Samoa"); //$NON-NLS-1$
   1238          sRegionNames.put("YE", "Yemen"); //$NON-NLS-1$
   1239          sRegionNames.put("YT", "Mayotte"); //$NON-NLS-1$
   1240          sRegionNames.put("ZA", "South Africa"); //$NON-NLS-1$
   1241          sRegionNames.put("ZM", "Zambia"); //$NON-NLS-1$
   1242          sRegionNames.put("ZW", "Zimbabwe"); //$NON-NLS-1$
   1243 
   1244          // Aliases
   1245          // http://developer.android.com/reference/java/util/Locale.html
   1246          // Apparently we're using some old aliases for some languages
   1247          //  The Hebrew ("he") language code is rewritten as "iw", Indonesian ("id") as "in",
   1248          // and Yiddish ("yi") as "ji".
   1249          sLanguageToCountry.put("iw", sLanguageToCountry.get("he")); //$NON-NLS-1$ //$NON-NLS-2$
   1250          sLanguageToCountry.put("in", sLanguageToCountry.get("id")); //$NON-NLS-1$ //$NON-NLS-2$
   1251          sLanguageToCountry.put("ji", sLanguageToCountry.get("yi")); //$NON-NLS-1$ //$NON-NLS-2$
   1252          sLanguageNames.put("iw", sLanguageNames.get("he"));         //$NON-NLS-1$ //$NON-NLS-2$
   1253          sLanguageNames.put("in", sLanguageNames.get("id"));         //$NON-NLS-1$ //$NON-NLS-2$
   1254          sLanguageNames.put("ji", sLanguageNames.get("yi"));         //$NON-NLS-1$ //$NON-NLS-2$
   1255 
   1256         // The following miscellaneous languages have no binding to a region
   1257         // in sLanguageToCountry, since they are either extinct or constructed or
   1258         // only in literary use:
   1259         sLanguageNames.put("pi", "Pali"); //$NON-NLS-1$
   1260         sLanguageNames.put("vo", "Volap\u00fck" /*Volapk*/); //$NON-NLS-1$
   1261         sLanguageNames.put("eo", "Esperanto"); //$NON-NLS-1$
   1262         sLanguageNames.put("la", "Latin"); //$NON-NLS-1$
   1263         sLanguageNames.put("ia", "Interlingua"); //$NON-NLS-1$
   1264         sLanguageNames.put("ie", "Interlingue"); //$NON-NLS-1$
   1265         sLanguageNames.put("io", "Ido"); //$NON-NLS-1$
   1266         sLanguageNames.put("ae", "Avestan"); //$NON-NLS-1$
   1267         sLanguageNames.put("cu", "Church Slavic"); //$NON-NLS-1$
   1268 
   1269         // To check initial capacities of the maps and avoid dynamic resizing:
   1270         //System.out.println("Language count = " + sLanguageNames.size());
   1271         //System.out.println("Language Binding count = " + sLanguageToCountry.size());
   1272         //System.out.println("Region count = " + sRegionNames.size());
   1273     }
   1274 
   1275     @VisibleForTesting
   1276     static Map<String, String> getLanguageToCountryMap() {
   1277         return sLanguageToCountry;
   1278     }
   1279 
   1280     @VisibleForTesting
   1281     static Map<String, String> getLanguageNamesMap() {
   1282         return sLanguageNames;
   1283     }
   1284 
   1285     @VisibleForTesting
   1286     static Map<String, String> getRegionNamesMap() {
   1287         return sRegionNames;
   1288     }
   1289 }
   1290