• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
get()57     public static LocaleManager get() {
58         return sInstance;
59     }
60 
61     /** Use the {@link #get()} factory method */
LocaleManager()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      */
getEmptyIcon()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      */
getGlobeIcon()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
getFlag(@ullable String language, @Nullable String region)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      */
getFlag(LanguageQualifier language, RegionQualifier region)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
getFlagForFolderName(@onNull String folder)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
getFlag(@onNull String region)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 
getIcon(@onNull String base)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
getRegionName(@onNull String regionCode)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
getLanguageName(@onNull String languageCode)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
getLanguageCodes()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
getRegionCodes()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 Bokmål*/); //$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": Yorùbá -> Nigeria, Togo, Benin
978          sLanguageToCountry.put("yo", "NG"); //$NON-NLS-1$ //$NON-NLS-2$
979          sLanguageNames.put("yo", "Yor\u00f9b\u00e1" /*Yorùbá*/); //$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 Barthélemy*/); //$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" /*Côte 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" /*Curaçao*/); //$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" /*Réunion*/); //$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" /*Volapük*/); //$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
getLanguageToCountryMap()1276     static Map<String, String> getLanguageToCountryMap() {
1277         return sLanguageToCountry;
1278     }
1279 
1280     @VisibleForTesting
getLanguageNamesMap()1281     static Map<String, String> getLanguageNamesMap() {
1282         return sLanguageNames;
1283     }
1284 
1285     @VisibleForTesting
getRegionNamesMap()1286     static Map<String, String> getRegionNamesMap() {
1287         return sRegionNames;
1288     }
1289 }
1290