Move subtype related utility class to utils package

Change-Id: I3564796531ea85f2ebafde40cd822b806b8741df
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index d00521c..8864b76 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -25,8 +25,8 @@
 import android.view.inputmethod.InputMethodSubtype;
 
 import com.android.inputmethod.compat.EditorInfoCompatUtils;
-import com.android.inputmethod.latin.SubtypeLocale;
 import com.android.inputmethod.latin.utils.InputTypeUtils;
+import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
 
 import java.util.Arrays;
 import java.util.Locale;
@@ -76,7 +76,7 @@
 
     public KeyboardId(final int elementId, final KeyboardLayoutSet.Params params) {
         mSubtype = params.mSubtype;
-        mLocale = SubtypeLocale.getSubtypeLocale(mSubtype);
+        mLocale = SubtypeLocaleUtils.getSubtypeLocale(mSubtype);
         mOrientation = params.mOrientation;
         mWidth = params.mKeyboardWidth;
         mHeight = params.mKeyboardHeight;
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
index c4f5eb0..6a900b4 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
@@ -41,15 +41,15 @@
 import com.android.inputmethod.keyboard.internal.KeyboardBuilder;
 import com.android.inputmethod.keyboard.internal.KeyboardParams;
 import com.android.inputmethod.keyboard.internal.KeysCache;
-import com.android.inputmethod.latin.AdditionalSubtype;
 import com.android.inputmethod.latin.InputAttributes;
 import com.android.inputmethod.latin.LatinImeLogger;
 import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.SubtypeLocale;
 import com.android.inputmethod.latin.SubtypeSwitcher;
+import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils;
 import com.android.inputmethod.latin.utils.CollectionUtils;
 import com.android.inputmethod.latin.utils.InputTypeUtils;
 import com.android.inputmethod.latin.utils.ResourceUtils;
+import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
 import com.android.inputmethod.latin.utils.XmlParseUtils;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -288,7 +288,7 @@
                     : subtype;
             mParams.mSubtype = keyboardSubtype;
             mParams.mKeyboardLayoutSetName = KEYBOARD_LAYOUT_SET_RESOURCE_PREFIX
-                    + SubtypeLocale.getKeyboardLayoutSetName(keyboardSubtype);
+                    + SubtypeLocaleUtils.getKeyboardLayoutSetName(keyboardSubtype);
             return this;
         }
 
@@ -445,7 +445,7 @@
     public static KeyboardLayoutSet createKeyboardSetForSpellChecker(final Context context,
             final String locale, final String layout) {
         final InputMethodSubtype subtype =
-                AdditionalSubtype.createAdditionalSubtype(locale, layout, null);
+                AdditionalSubtypeUtils.createAdditionalSubtype(locale, layout, null);
         return createKeyboardSet(context, subtype, SPELLCHECKER_DUMMY_KEYBOARD_WIDTH,
                 SPELLCHECKER_DUMMY_KEYBOARD_HEIGHT, false /* testCasesHaveTouchCoordinates */,
                 true /* isSpellChecker */);
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index 834ff0a..a45133c 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -59,7 +59,6 @@
 import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.LatinImeLogger;
 import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.SubtypeLocale;
 import com.android.inputmethod.latin.SuggestedWords;
 import com.android.inputmethod.latin.define.ProductionFlag;
 import com.android.inputmethod.latin.settings.DebugSettings;
@@ -67,6 +66,7 @@
 import com.android.inputmethod.latin.utils.CollectionUtils;
 import com.android.inputmethod.latin.utils.CoordinateUtils;
 import com.android.inputmethod.latin.utils.StaticInnerHandlerWrapper;
+import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
 import com.android.inputmethod.latin.utils.TypefaceUtils;
 import com.android.inputmethod.latin.utils.UsabilityStudyLogUtils;
 import com.android.inputmethod.latin.utils.ViewLayoutUtils;
@@ -1342,17 +1342,17 @@
     private static String layoutLanguageOnSpacebar(final Paint paint,
             final InputMethodSubtype subtype, final int width) {
         // Choose appropriate language name to fit into the width.
-        final String fullText = SubtypeLocale.getFullDisplayName(subtype);
+        final String fullText = SubtypeLocaleUtils.getFullDisplayName(subtype);
         if (fitsTextIntoWidth(width, fullText, paint)) {
             return fullText;
         }
 
-        final String middleText = SubtypeLocale.getMiddleDisplayName(subtype);
+        final String middleText = SubtypeLocaleUtils.getMiddleDisplayName(subtype);
         if (fitsTextIntoWidth(width, middleText, paint)) {
             return middleText;
         }
 
-        final String shortText = SubtypeLocale.getShortDisplayName(subtype);
+        final String shortText = SubtypeLocaleUtils.getShortDisplayName(subtype);
         if (fitsTextIntoWidth(width, shortText, paint)) {
             return shortText;
         }
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
index 26bbd7d..e438e6d 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
@@ -30,10 +30,10 @@
 import com.android.inputmethod.keyboard.Keyboard;
 import com.android.inputmethod.keyboard.KeyboardId;
 import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.SubtypeLocale;
 import com.android.inputmethod.latin.utils.LocaleUtils.RunInLocale;
 import com.android.inputmethod.latin.utils.ResourceUtils;
 import com.android.inputmethod.latin.utils.StringUtils;
+import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
 import com.android.inputmethod.latin.utils.XmlParseUtils;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -285,7 +285,7 @@
                 }
             };
             // Null means the current system locale.
-            final Locale locale = SubtypeLocale.isNoLanguage(params.mId.mSubtype)
+            final Locale locale = SubtypeLocaleUtils.isNoLanguage(params.mId.mSubtype)
                     ? null : params.mId.mLocale;
             job.runInLocale(mResources, locale);
 
diff --git a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
index 56b1e3f..6b6bbf3 100644
--- a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
+++ b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
@@ -29,7 +29,9 @@
 
 import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
 import com.android.inputmethod.latin.settings.Settings;
+import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils;
 import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
 
 import java.util.Collections;
 import java.util.HashMap;
@@ -84,11 +86,11 @@
         mInputMethodInfoOfThisIme = getInputMethodInfoOfThisIme(context);
 
         // Initialize additional subtypes.
-        SubtypeLocale.init(context);
+        SubtypeLocaleUtils.init(context);
         final String prefAdditionalSubtypes = Settings.readPrefAdditionalSubtypes(
                 prefs, context.getResources());
         final InputMethodSubtype[] additionalSubtypes =
-                AdditionalSubtype.createAdditionalSubtypesArray(prefAdditionalSubtypes);
+                AdditionalSubtypeUtils.createAdditionalSubtypesArray(prefAdditionalSubtypes);
         setAdditionalInputMethodSubtypes(additionalSubtypes);
     }
 
@@ -134,7 +136,7 @@
         final int currentIndex = getSubtypeIndexInList(currentSubtype, enabledSubtypes);
         if (currentIndex == INDEX_NOT_FOUND) {
             Log.w(TAG, "Can't find current subtype in enabled subtypes: subtype="
-                    + SubtypeLocale.getSubtypeNameForLogging(currentSubtype));
+                    + SubtypeLocaleUtils.getSubtypeNameForLogging(currentSubtype));
             return false;
         }
         final int nextIndex = (currentIndex + 1) % enabledSubtypes.size();
@@ -342,7 +344,7 @@
         final int count = myImi.getSubtypeCount();
         for (int i = 0; i < count; i++) {
             final InputMethodSubtype subtype = myImi.getSubtypeAt(i);
-            final String layoutName = SubtypeLocale.getKeyboardLayoutSetName(subtype);
+            final String layoutName = SubtypeLocaleUtils.getKeyboardLayoutSetName(subtype);
             if (localeString.equals(subtype.getLocale())
                     && keyboardLayoutSetName.equals(layoutName)) {
                 return subtype;
diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
index dfa4a86..be03d4a 100644
--- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
@@ -33,6 +33,7 @@
 
 import com.android.inputmethod.annotations.UsedForTesting;
 import com.android.inputmethod.keyboard.KeyboardSwitcher;
+import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
 
 import java.util.List;
 import java.util.Locale;
@@ -82,7 +83,7 @@
     }
 
     public static void init(final Context context) {
-        SubtypeLocale.init(context);
+        SubtypeLocaleUtils.init(context);
         RichInputMethodManager.init(context);
         sInstance.initialize(context);
     }
@@ -153,10 +154,11 @@
     // Update the current subtype. LatinIME.onCurrentInputMethodSubtypeChanged calls this function.
     public void onSubtypeChanged(final InputMethodSubtype newSubtype) {
         if (DBG) {
-            Log.w(TAG, "onSubtypeChanged: " + SubtypeLocale.getSubtypeNameForLogging(newSubtype));
+            Log.w(TAG, "onSubtypeChanged: "
+                    + SubtypeLocaleUtils.getSubtypeNameForLogging(newSubtype));
         }
 
-        final Locale newLocale = SubtypeLocale.getSubtypeLocale(newSubtype);
+        final Locale newLocale = SubtypeLocaleUtils.getSubtypeLocale(newSubtype);
         final Locale systemLocale = mResources.getConfiguration().locale;
         final boolean sameLocale = systemLocale.equals(newLocale);
         final boolean sameLanguage = systemLocale.getLanguage().equals(newLocale.getLanguage());
@@ -232,7 +234,7 @@
     //////////////////////////////////
 
     public boolean needsToDisplayLanguage(final Locale keyboardLocale) {
-        if (keyboardLocale.toString().equals(SubtypeLocale.NO_LANGUAGE)) {
+        if (keyboardLocale.toString().equals(SubtypeLocaleUtils.NO_LANGUAGE)) {
             return true;
         }
         if (!keyboardLocale.equals(getCurrentSubtypeLocale())) {
@@ -249,7 +251,7 @@
 
     public Locale getCurrentSubtypeLocale() {
         if (null != sForcedLocaleForTesting) return sForcedLocaleForTesting;
-        return SubtypeLocale.getSubtypeLocale(getCurrentSubtype());
+        return SubtypeLocaleUtils.getSubtypeLocale(getCurrentSubtype());
     }
 
     public InputMethodSubtype getCurrentSubtype() {
@@ -259,7 +261,7 @@
     public InputMethodSubtype getNoLanguageSubtype() {
         if (mNoLanguageSubtype == null) {
             mNoLanguageSubtype = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
-                    SubtypeLocale.NO_LANGUAGE, SubtypeLocale.QWERTY);
+                    SubtypeLocaleUtils.NO_LANGUAGE, SubtypeLocaleUtils.QWERTY);
         }
         if (mNoLanguageSubtype != null) {
             return mNoLanguageSubtype;
diff --git a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
index ab8f348..ed6fefa 100644
--- a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
@@ -29,6 +29,7 @@
 
 import com.android.inputmethod.compat.UserDictionaryCompatUtils;
 import com.android.inputmethod.latin.utils.LocaleUtils;
+import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
 
 import java.util.Arrays;
 import java.util.Locale;
@@ -76,7 +77,7 @@
             final boolean alsoUseMoreRestrictiveLocales) {
         super(context, getFilenameWithLocale(NAME, locale), Dictionary.TYPE_USER);
         if (null == locale) throw new NullPointerException(); // Catch the error earlier
-        if (SubtypeLocale.NO_LANGUAGE.equals(locale)) {
+        if (SubtypeLocaleUtils.NO_LANGUAGE.equals(locale)) {
             // If we don't have a locale, insert into the "all locales" user dictionary.
             mLocale = USER_DICTIONARY_ALL_LANGUAGES;
         } else {
diff --git a/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java b/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java
index 2ef555e..4bf524c 100644
--- a/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java
+++ b/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java
@@ -44,12 +44,12 @@
 import android.widget.SpinnerAdapter;
 import android.widget.Toast;
 
-import com.android.inputmethod.latin.AdditionalSubtype;
 import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.RichInputMethodManager;
-import com.android.inputmethod.latin.SubtypeLocale;
+import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils;
 import com.android.inputmethod.latin.utils.CollectionUtils;
 import com.android.inputmethod.latin.utils.IntentUtils;
+import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
 
 import java.util.ArrayList;
 import java.util.TreeSet;
@@ -78,7 +78,7 @@
 
         public SubtypeLocaleItem(final String localeString) {
             this(localeString,
-                    SubtypeLocale.getSubtypeLocaleDisplayNameInSystemLocale(localeString));
+                    SubtypeLocaleUtils.getSubtypeLocaleDisplayNameInSystemLocale(localeString));
         }
 
         @Override
@@ -109,7 +109,7 @@
                 if (DEBUG_SUBTYPE_ID) {
                     android.util.Log.d(TAG, String.format("%-6s 0x%08x %11d %s",
                             subtype.getLocale(), subtype.hashCode(), subtype.hashCode(),
-                            SubtypeLocale.getSubtypeDisplayNameInSystemLocale(subtype)));
+                            SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(subtype)));
                 }
                 if (subtype.containsExtraValueKey(ASCII_CAPABLE)) {
                     items.add(createItem(context, subtype.getLocale()));
@@ -121,7 +121,7 @@
 
         public static SubtypeLocaleItem createItem(final Context context,
                 final String localeString) {
-            if (localeString.equals(SubtypeLocale.NO_LANGUAGE)) {
+            if (localeString.equals(SubtypeLocaleUtils.NO_LANGUAGE)) {
                 final String displayName = context.getString(R.string.subtype_no_language);
                 return new SubtypeLocaleItem(localeString, displayName);
             } else {
@@ -132,8 +132,8 @@
 
     static final class KeyboardLayoutSetItem extends Pair<String, String> {
         public KeyboardLayoutSetItem(final InputMethodSubtype subtype) {
-            super(SubtypeLocale.getKeyboardLayoutSetName(subtype),
-                    SubtypeLocale.getKeyboardLayoutSetDisplayName(subtype));
+            super(SubtypeLocaleUtils.getKeyboardLayoutSetName(subtype),
+                    SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(subtype));
         }
 
         @Override
@@ -148,10 +148,10 @@
             setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
 
             // TODO: Should filter out already existing combinations of locale and layout.
-            for (final String layout : SubtypeLocale.getPredefinedKeyboardLayoutSet()) {
+            for (final String layout : SubtypeLocaleUtils.getPredefinedKeyboardLayoutSet()) {
                 // This is a dummy subtype with NO_LANGUAGE, only for display.
-                final InputMethodSubtype subtype = AdditionalSubtype.createAdditionalSubtype(
-                        SubtypeLocale.NO_LANGUAGE, layout, null);
+                final InputMethodSubtype subtype = AdditionalSubtypeUtils.createAdditionalSubtype(
+                        SubtypeLocaleUtils.NO_LANGUAGE, layout, null);
                 add(new KeyboardLayoutSetItem(subtype));
             }
         }
@@ -212,11 +212,11 @@
                 setKey(KEY_NEW_SUBTYPE);
             } else {
                 final String displayName =
-                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(subtype);
+                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(subtype);
                 setTitle(displayName);
                 setDialogTitle(displayName);
                 setKey(KEY_PREFIX + subtype.getLocale() + "_"
-                        + SubtypeLocale.getKeyboardLayoutSetName(subtype));
+                        + SubtypeLocaleUtils.getKeyboardLayoutSetName(subtype));
             }
         }
 
@@ -286,7 +286,7 @@
                         (SubtypeLocaleItem) mSubtypeLocaleSpinner.getSelectedItem();
                 final KeyboardLayoutSetItem layout =
                         (KeyboardLayoutSetItem) mKeyboardLayoutSetSpinner.getSelectedItem();
-                final InputMethodSubtype subtype = AdditionalSubtype.createAdditionalSubtype(
+                final InputMethodSubtype subtype = AdditionalSubtypeUtils.createAdditionalSubtype(
                         locale.first, layout.first, ASCII_CAPABLE);
                 setSubtype(subtype);
                 notifyChanged();
@@ -504,13 +504,13 @@
         final Context context = getActivity();
         final Resources res = context.getResources();
         final String message = res.getString(R.string.custom_input_style_already_exists,
-                SubtypeLocale.getSubtypeDisplayNameInSystemLocale(subtype));
+                SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(subtype));
         Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
     }
 
     private InputMethodSubtype findDuplicatedSubtype(final InputMethodSubtype subtype) {
         final String localeString = subtype.getLocale();
-        final String keyboardLayoutSetName = SubtypeLocale.getKeyboardLayoutSetName(subtype);
+        final String keyboardLayoutSetName = SubtypeLocaleUtils.getKeyboardLayoutSetName(subtype);
         return mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
                 localeString, keyboardLayoutSetName);
     }
@@ -543,7 +543,7 @@
         final PreferenceGroup group = getPreferenceScreen();
         group.removeAll();
         final InputMethodSubtype[] subtypesArray =
-                AdditionalSubtype.createAdditionalSubtypesArray(prefSubtypes);
+                AdditionalSubtypeUtils.createAdditionalSubtypesArray(prefSubtypes);
         for (final InputMethodSubtype subtype : subtypesArray) {
             final SubtypePreference pref = new SubtypePreference(
                     context, subtype, mSubtypeProxy);
@@ -572,7 +572,7 @@
         super.onPause();
         final String oldSubtypes = Settings.readPrefAdditionalSubtypes(mPrefs, getResources());
         final InputMethodSubtype[] subtypes = getSubtypes();
-        final String prefSubtypes = AdditionalSubtype.createPrefSubtypes(subtypes);
+        final String prefSubtypes = AdditionalSubtypeUtils.createPrefSubtypes(subtypes);
         if (prefSubtypes.equals(oldSubtypes)) {
             return;
         }
diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java
index 674263d..bfaf2ca 100644
--- a/java/src/com/android/inputmethod/latin/settings/Settings.java
+++ b/java/src/com/android/inputmethod/latin/settings/Settings.java
@@ -24,9 +24,9 @@
 import android.util.Log;
 
 import com.android.inputmethod.latin.AudioAndHapticFeedbackManager;
-import com.android.inputmethod.latin.AdditionalSubtype;
 import com.android.inputmethod.latin.InputAttributes;
 import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils;
 import com.android.inputmethod.latin.utils.LocaleUtils;
 import com.android.inputmethod.latin.utils.LocaleUtils.RunInLocale;
 import com.android.inputmethod.latin.utils.ResourceUtils;
@@ -241,7 +241,7 @@
 
     public static String readPrefAdditionalSubtypes(final SharedPreferences prefs,
             final Resources res) {
-        final String predefinedPrefSubtypes = AdditionalSubtype.createPrefSubtypes(
+        final String predefinedPrefSubtypes = AdditionalSubtypeUtils.createPrefSubtypes(
                 res.getStringArray(R.array.predefined_subtypes));
         return prefs.getString(PREF_CUSTOM_INPUT_STYLES, predefinedPrefSubtypes);
     }
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
index 4b62a53..4467777 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
@@ -37,17 +37,17 @@
 import android.view.inputmethod.InputMethodSubtype;
 
 import com.android.inputmethod.dictionarypack.DictionarySettingsActivity;
-import com.android.inputmethod.latin.AdditionalSubtype;
 import com.android.inputmethod.latin.AudioAndHapticFeedbackManager;
 import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.SubtypeLocale;
 import com.android.inputmethod.latin.SubtypeSwitcher;
 import com.android.inputmethod.latin.define.ProductionFlag;
 import com.android.inputmethod.latin.setup.LauncherIconVisibilityManager;
 import com.android.inputmethod.latin.userdictionary.UserDictionaryList;
 import com.android.inputmethod.latin.userdictionary.UserDictionarySettings;
+import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils;
 import com.android.inputmethod.latin.utils.ApplicationUtils;
 import com.android.inputmethod.latin.utils.FeedbackUtils;
+import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
 import com.android.inputmethod.research.ResearchLogger;
 import com.android.inputmethodcommon.InputMethodSettingsFragment;
 
@@ -104,7 +104,7 @@
         // singleton and utility classes may not have been initialized.  We have to call
         // initialization method of these classes here. See {@link LatinIME#onCreate()}.
         SubtypeSwitcher.init(context);
-        SubtypeLocale.init(context);
+        SubtypeLocaleUtils.init(context);
         AudioAndHapticFeedbackManager.init(context);
 
         mVoicePreference = (ListPreference) findPreference(Settings.PREF_VOICE_MODE);
@@ -314,11 +314,11 @@
         final Resources res = getResources();
         final String prefSubtype = Settings.readPrefAdditionalSubtypes(prefs, res);
         final InputMethodSubtype[] subtypes =
-                AdditionalSubtype.createAdditionalSubtypesArray(prefSubtype);
+                AdditionalSubtypeUtils.createAdditionalSubtypesArray(prefSubtype);
         final StringBuilder styles = new StringBuilder();
         for (final InputMethodSubtype subtype : subtypes) {
             if (styles.length() > 0) styles.append(", ");
-            styles.append(SubtypeLocale.getSubtypeDisplayNameInSystemLocale(subtype));
+            styles.append(SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(subtype));
         }
         customInputStyles.setSummary(styles);
     }
diff --git a/java/src/com/android/inputmethod/latin/AdditionalSubtype.java b/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java
similarity index 89%
rename from java/src/com/android/inputmethod/latin/AdditionalSubtype.java
rename to java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java
index 0bddeb5..215faa0 100644
--- a/java/src/com/android/inputmethod/latin/AdditionalSubtype.java
+++ b/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import static com.android.inputmethod.latin.Constants.Subtype.KEYBOARD_MODE;
 import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.IS_ADDITIONAL_SUBTYPE;
@@ -25,15 +25,14 @@
 import android.text.TextUtils;
 import android.view.inputmethod.InputMethodSubtype;
 
-import com.android.inputmethod.latin.utils.CollectionUtils;
-import com.android.inputmethod.latin.utils.StringUtils;
+import com.android.inputmethod.latin.R;
 
 import java.util.ArrayList;
 
-public final class AdditionalSubtype {
+public final class AdditionalSubtypeUtils {
     private static final InputMethodSubtype[] EMPTY_SUBTYPE_ARRAY = new InputMethodSubtype[0];
 
-    private AdditionalSubtype() {
+    private AdditionalSubtypeUtils() {
         // This utility class is not publicly instantiable.
     }
 
@@ -49,8 +48,8 @@
         final String layoutExtraValue = KEYBOARD_LAYOUT_SET + "=" + keyboardLayoutSetName;
         final String layoutDisplayNameExtraValue;
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN
-                && SubtypeLocale.isExceptionalLocale(localeString)) {
-            final String layoutDisplayName = SubtypeLocale.getKeyboardLayoutSetDisplayName(
+                && SubtypeLocaleUtils.isExceptionalLocale(localeString)) {
+            final String layoutDisplayName = SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(
                     keyboardLayoutSetName);
             layoutDisplayNameExtraValue = StringUtils.appendToCommaSplittableTextIfNotExists(
                     UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME + "=" + layoutDisplayName, extraValue);
@@ -60,7 +59,7 @@
         final String additionalSubtypeExtraValue =
                 StringUtils.appendToCommaSplittableTextIfNotExists(
                         IS_ADDITIONAL_SUBTYPE, layoutDisplayNameExtraValue);
-        final int nameId = SubtypeLocale.getSubtypeNameId(localeString, keyboardLayoutSetName);
+        final int nameId = SubtypeLocaleUtils.getSubtypeNameId(localeString, keyboardLayoutSetName);
         return new InputMethodSubtype(nameId, R.drawable.ic_subtype_keyboard,
                 localeString, KEYBOARD_MODE,
                 layoutExtraValue + "," + additionalSubtypeExtraValue, false, false);
@@ -68,7 +67,7 @@
 
     public static String getPrefSubtype(final InputMethodSubtype subtype) {
         final String localeString = subtype.getLocale();
-        final String keyboardLayoutSetName = SubtypeLocale.getKeyboardLayoutSetName(subtype);
+        final String keyboardLayoutSetName = SubtypeLocaleUtils.getKeyboardLayoutSetName(subtype);
         final String layoutExtraValue = KEYBOARD_LAYOUT_SET + "=" + keyboardLayoutSetName;
         final String extraValue = StringUtils.removeFromCommaSplittableTextIfExists(
                 layoutExtraValue, StringUtils.removeFromCommaSplittableTextIfExists(
@@ -99,7 +98,7 @@
                 CollectionUtils.newArrayList(prefSubtypeArray.length);
         for (final String prefSubtype : prefSubtypeArray) {
             final InputMethodSubtype subtype = createAdditionalSubtype(prefSubtype);
-            if (subtype.getNameResId() == SubtypeLocale.UNKNOWN_KEYBOARD_LAYOUT) {
+            if (subtype.getNameResId() == SubtypeLocaleUtils.UNKNOWN_KEYBOARD_LAYOUT) {
                 // Skip unknown keyboard layout subtype. This may happen when predefined keyboard
                 // layout has been removed.
                 continue;
diff --git a/java/src/com/android/inputmethod/latin/SubtypeLocale.java b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
similarity index 96%
rename from java/src/com/android/inputmethod/latin/SubtypeLocale.java
rename to java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
index 683211c..4cfa289 100644
--- a/java/src/com/android/inputmethod/latin/SubtypeLocale.java
+++ b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
 
 import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.KEYBOARD_LAYOUT_SET;
 import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME;
@@ -25,17 +25,15 @@
 import android.util.Log;
 import android.view.inputmethod.InputMethodSubtype;
 
-import com.android.inputmethod.latin.utils.CollectionUtils;
-import com.android.inputmethod.latin.utils.DebugLogUtils;
-import com.android.inputmethod.latin.utils.LocaleUtils;
+import com.android.inputmethod.latin.DictionaryFactory;
+import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.utils.LocaleUtils.RunInLocale;
-import com.android.inputmethod.latin.utils.StringUtils;
 
 import java.util.HashMap;
 import java.util.Locale;
 
-public final class SubtypeLocale {
-    static final String TAG = SubtypeLocale.class.getSimpleName();
+public final class SubtypeLocaleUtils {
+    static final String TAG = SubtypeLocaleUtils.class.getSimpleName();
     // This class must be located in the same package as LatinIME.java.
     private static final String RESOURCE_PACKAGE_NAME =
             DictionaryFactory.class.getPackage().getName();
@@ -73,7 +71,7 @@
     private static final HashMap<String, String> sLocaleAndExtraValueToKeyboardLayoutSetMap =
             CollectionUtils.newHashMap();
 
-    private SubtypeLocale() {
+    private SubtypeLocaleUtils() {
         // Intentional empty constructor for utility class.
     }
 
diff --git a/tests/src/com/android/inputmethod/latin/SubtypeLocaleTests.java b/tests/src/com/android/inputmethod/latin/SubtypeLocaleTests.java
deleted file mode 100644
index 0548720..0000000
--- a/tests/src/com/android/inputmethod/latin/SubtypeLocaleTests.java
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.latin;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.view.inputmethod.InputMethodSubtype;
-
-import com.android.inputmethod.latin.utils.CollectionUtils;
-import com.android.inputmethod.latin.utils.LocaleUtils.RunInLocale;
-import com.android.inputmethod.latin.utils.StringUtils;
-
-import java.util.ArrayList;
-import java.util.Locale;
-
-@SmallTest
-public class SubtypeLocaleTests extends AndroidTestCase {
-    // Locale to subtypes list.
-    private final ArrayList<InputMethodSubtype> mSubtypesList = CollectionUtils.newArrayList();
-
-    private RichInputMethodManager mRichImm;
-    private Resources mRes;
-
-    InputMethodSubtype EN_US;
-    InputMethodSubtype EN_GB;
-    InputMethodSubtype ES_US;
-    InputMethodSubtype FR;
-    InputMethodSubtype FR_CA;
-    InputMethodSubtype DE;
-    InputMethodSubtype ZZ;
-    InputMethodSubtype DE_QWERTY;
-    InputMethodSubtype FR_QWERTZ;
-    InputMethodSubtype EN_US_AZERTY;
-    InputMethodSubtype EN_UK_DVORAK;
-    InputMethodSubtype ES_US_COLEMAK;
-    InputMethodSubtype ZZ_AZERTY;
-    InputMethodSubtype ZZ_PC;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        final Context context = getContext();
-        RichInputMethodManager.init(context);
-        mRichImm = RichInputMethodManager.getInstance();
-        mRes = context.getResources();
-        SubtypeLocale.init(context);
-
-        EN_US = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
-                Locale.US.toString(), "qwerty");
-        EN_GB = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
-                Locale.UK.toString(), "qwerty");
-        ES_US = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
-                "es_US", "spanish");
-        FR = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
-                Locale.FRENCH.toString(), "azerty");
-        FR_CA = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
-                Locale.CANADA_FRENCH.toString(), "qwerty");
-        DE = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
-                Locale.GERMAN.toString(), "qwertz");
-        ZZ = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
-                SubtypeLocale.NO_LANGUAGE, "qwerty");
-        DE_QWERTY = AdditionalSubtype.createAdditionalSubtype(
-                Locale.GERMAN.toString(), "qwerty", null);
-        FR_QWERTZ = AdditionalSubtype.createAdditionalSubtype(
-                Locale.FRENCH.toString(), "qwertz", null);
-        EN_US_AZERTY = AdditionalSubtype.createAdditionalSubtype(
-                Locale.US.toString(), "azerty", null);
-        EN_UK_DVORAK = AdditionalSubtype.createAdditionalSubtype(
-                Locale.UK.toString(), "dvorak", null);
-        ES_US_COLEMAK = AdditionalSubtype.createAdditionalSubtype(
-                "es_US", "colemak", null);
-        ZZ_AZERTY = AdditionalSubtype.createAdditionalSubtype(
-                SubtypeLocale.NO_LANGUAGE, "azerty", null);
-        ZZ_PC = AdditionalSubtype.createAdditionalSubtype(
-                SubtypeLocale.NO_LANGUAGE, "pcqwerty", null);
-
-    }
-
-    public void testAllFullDisplayName() {
-        for (final InputMethodSubtype subtype : mSubtypesList) {
-            final String subtypeName = SubtypeLocale.getSubtypeDisplayNameInSystemLocale(subtype);
-            if (SubtypeLocale.isNoLanguage(subtype)) {
-                final String noLanguage = mRes.getString(R.string.subtype_no_language);
-                assertTrue(subtypeName, subtypeName.contains(noLanguage));
-            } else {
-                final String languageName =
-                        SubtypeLocale.getSubtypeLocaleDisplayName(subtype.getLocale());
-                assertTrue(subtypeName, subtypeName.contains(languageName));
-            }
-        }
-    }
-
-    public void testKeyboardLayoutSetName() {
-        assertEquals("en_US", "qwerty", SubtypeLocale.getKeyboardLayoutSetName(EN_US));
-        assertEquals("en_GB", "qwerty", SubtypeLocale.getKeyboardLayoutSetName(EN_GB));
-        assertEquals("es_US", "spanish", SubtypeLocale.getKeyboardLayoutSetName(ES_US));
-        assertEquals("fr   ", "azerty", SubtypeLocale.getKeyboardLayoutSetName(FR));
-        assertEquals("fr_CA", "qwerty", SubtypeLocale.getKeyboardLayoutSetName(FR_CA));
-        assertEquals("de   ", "qwertz", SubtypeLocale.getKeyboardLayoutSetName(DE));
-        assertEquals("zz   ", "qwerty", SubtypeLocale.getKeyboardLayoutSetName(ZZ));
-    }
-
-    // InputMethodSubtype's display name in system locale (en_US).
-    //        isAdditionalSubtype (T=true, F=false)
-    // locale layout  |  display name
-    // ------ ------- - ----------------------
-    //  en_US qwerty  F  English (US)            exception
-    //  en_GB qwerty  F  English (UK)            exception
-    //  es_US spanish F  Spanish (US)            exception
-    //  fr    azerty  F  French
-    //  fr_CA qwerty  F  French (Canada)
-    //  de    qwertz  F  German
-    //  zz    qwerty  F  No language (QWERTY)
-    //  fr    qwertz  T  French (QWERTZ)
-    //  de    qwerty  T  German (QWERTY)
-    //  en_US azerty  T  English (US) (AZERTY)   exception
-    //  en_UK dvorak  T  English (UK) (Dvorak)   exception
-    //  es_US colemak T  Spanish (US) (Colemak)  exception
-    //  zz    pc      T  No language (PC)
-
-    public void testPredefinedSubtypesInEnglishSystemLocale() {
-        final RunInLocale<Void> tests = new RunInLocale<Void>() {
-            @Override
-            protected Void job(Resources res) {
-                assertEquals("en_US", "English (US)",
-                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(EN_US));
-                assertEquals("en_GB", "English (UK)",
-                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(EN_GB));
-                assertEquals("es_US", "Spanish (US)",
-                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(ES_US));
-                assertEquals("fr   ", "French",
-                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(FR));
-                assertEquals("fr_CA", "French (Canada)",
-                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(FR_CA));
-                assertEquals("de   ", "German",
-                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(DE));
-                assertEquals("zz   ", "No language (QWERTY)",
-                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(ZZ));
-                return null;
-            }
-        };
-        tests.runInLocale(mRes, Locale.ENGLISH);
-    }
-
-    public void testAdditionalSubtypesInEnglishSystemLocale() {
-        final RunInLocale<Void> tests = new RunInLocale<Void>() {
-            @Override
-            protected Void job(Resources res) {
-                assertEquals("fr qwertz",    "French (QWERTZ)",
-                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(FR_QWERTZ));
-                assertEquals("de qwerty",    "German (QWERTY)",
-                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(DE_QWERTY));
-                assertEquals("en_US azerty", "English (US) (AZERTY)",
-                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(EN_US_AZERTY));
-                assertEquals("en_UK dvorak", "English (UK) (Dvorak)",
-                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(EN_UK_DVORAK));
-                assertEquals("es_US colemak","Spanish (US) (Colemak)",
-                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(ES_US_COLEMAK));
-                assertEquals("zz azerty",    "No language (PC)",
-                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(ZZ_PC));
-                return null;
-            }
-        };
-        tests.runInLocale(mRes, Locale.ENGLISH);
-    }
-
-    // InputMethodSubtype's display name in system locale (fr).
-    //        isAdditionalSubtype (T=true, F=false)
-    // locale layout  |  display name
-    // ------ ------- - ----------------------
-    //  en_US qwerty  F  Anglais (États-Unis)            exception
-    //  en_GB qwerty  F  Anglais (Royaume-Uni)            exception
-    //  es_US spanish F  Espagnol (États-Unis)            exception
-    //  fr    azerty  F  Français
-    //  fr_CA qwerty  F  Français (Canada)
-    //  de    qwertz  F  Allemand
-    //  zz    qwerty  F  Aucune langue (QWERTY)
-    //  fr    qwertz  T  Français (QWERTZ)
-    //  de    qwerty  T  Allemand (QWERTY)
-    //  en_US azerty  T  Anglais (États-Unis) (AZERTY)   exception
-    //  en_UK dvorak  T  Anglais (Royaume-Uni) (Dvorak)   exception
-    //  es_US colemak T  Espagnol (États-Unis) (Colemak)  exception
-    //  zz    pc      T  Aucune langue (PC)
-
-    public void testPredefinedSubtypesInFrenchSystemLocale() {
-        final RunInLocale<Void> tests = new RunInLocale<Void>() {
-            @Override
-            protected Void job(Resources res) {
-                assertEquals("en_US", "Anglais (États-Unis)",
-                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(EN_US));
-                assertEquals("en_GB", "Anglais (Royaume-Uni)",
-                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(EN_GB));
-                assertEquals("es_US", "Espagnol (États-Unis)",
-                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(ES_US));
-                assertEquals("fr   ", "Français",
-                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(FR));
-                assertEquals("fr_CA", "Français (Canada)",
-                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(FR_CA));
-                assertEquals("de   ", "Allemand",
-                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(DE));
-                assertEquals("zz   ", "Aucune langue (QWERTY)",
-                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(ZZ));
-                return null;
-            }
-        };
-        tests.runInLocale(mRes, Locale.FRENCH);
-    }
-
-    public void testAdditionalSubtypesInFrenchSystemLocale() {
-        final RunInLocale<Void> tests = new RunInLocale<Void>() {
-            @Override
-            protected Void job(Resources res) {
-                assertEquals("fr qwertz",    "Français (QWERTZ)",
-                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(FR_QWERTZ));
-                assertEquals("de qwerty",    "Allemand (QWERTY)",
-                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(DE_QWERTY));
-                assertEquals("en_US azerty", "Anglais (États-Unis) (AZERTY)",
-                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(EN_US_AZERTY));
-                assertEquals("en_UK dvorak", "Anglais (Royaume-Uni) (Dvorak)",
-                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(EN_UK_DVORAK));
-                assertEquals("es_US colemak","Espagnol (États-Unis) (Colemak)",
-                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(ES_US_COLEMAK));
-                assertEquals("zz azerty",    "Aucune langue (PC)",
-                        SubtypeLocale.getSubtypeDisplayNameInSystemLocale(ZZ_PC));
-                return null;
-            }
-        };
-        tests.runInLocale(mRes, Locale.FRENCH);
-    }
-
-    public void testAllFullDisplayNameForSpacebar() {
-        for (final InputMethodSubtype subtype : mSubtypesList) {
-            final String subtypeName = SubtypeLocale.getSubtypeDisplayNameInSystemLocale(subtype);
-            final String spacebarText = SubtypeLocale.getFullDisplayName(subtype);
-            final String languageName =
-                    SubtypeLocale.getSubtypeLocaleDisplayName(subtype.getLocale());
-            if (SubtypeLocale.isNoLanguage(subtype)) {
-                assertFalse(subtypeName, spacebarText.contains(languageName));
-            } else {
-                assertTrue(subtypeName, spacebarText.contains(languageName));
-            }
-        }
-    }
-
-   public void testAllMiddleDisplayNameForSpacebar() {
-        for (final InputMethodSubtype subtype : mSubtypesList) {
-            final String subtypeName = SubtypeLocale.getSubtypeDisplayNameInSystemLocale(subtype);
-            final String spacebarText = SubtypeLocale.getMiddleDisplayName(subtype);
-            if (SubtypeLocale.isNoLanguage(subtype)) {
-                assertEquals(subtypeName,
-                        SubtypeLocale.getKeyboardLayoutSetName(subtype), spacebarText);
-            } else {
-                assertEquals(subtypeName,
-                        SubtypeLocale.getSubtypeLocaleDisplayName(subtype.getLocale()),
-                        spacebarText);
-            }
-        }
-    }
-
-    public void testAllShortDisplayNameForSpacebar() {
-        for (final InputMethodSubtype subtype : mSubtypesList) {
-            final String subtypeName = SubtypeLocale.getSubtypeDisplayNameInSystemLocale(subtype);
-            final Locale locale = SubtypeLocale.getSubtypeLocale(subtype);
-            final String spacebarText = SubtypeLocale.getShortDisplayName(subtype);
-            final String languageCode = StringUtils.capitalizeFirstCodePoint(
-                    locale.getLanguage(), locale);
-            if (SubtypeLocale.isNoLanguage(subtype)) {
-                assertEquals(subtypeName, "", spacebarText);
-            } else {
-                assertEquals(subtypeName, languageCode, spacebarText);
-            }
-        }
-    }
-
-    // InputMethodSubtype's display name for spacebar text in its locale.
-    //        isAdditionalSubtype (T=true, F=false)
-    // locale layout  | Short  Middle      Full
-    // ------ ------- - ---- --------- ----------------------
-    //  en_US qwerty  F  En  English   English (US)           exception
-    //  en_GB qwerty  F  En  English   English (UK)           exception
-    //  es_US spanish F  Es  Español   Español (EE.UU.)       exception
-    //  fr    azerty  F  Fr  Français  Français
-    //  fr_CA qwerty  F  Fr  Français  Français (Canada)
-    //  de    qwertz  F  De  Deutsch   Deutsch
-    //  zz    qwerty  F      QWERTY    QWERTY
-    //  fr    qwertz  T  Fr  Français  Français
-    //  de    qwerty  T  De  Deutsch   Deutsch
-    //  en_US azerty  T  En  English   English (US)
-    //  zz    azerty  T      AZERTY    AZERTY
-
-    private final RunInLocale<Void> testsPredefinedSubtypesForSpacebar = new RunInLocale<Void>() {
-        @Override
-        protected Void job(Resources res) {
-            assertEquals("en_US", "English (US)",      SubtypeLocale.getFullDisplayName(EN_US));
-            assertEquals("en_GB", "English (UK)",      SubtypeLocale.getFullDisplayName(EN_GB));
-            assertEquals("es_US", "Español (EE.UU.)",  SubtypeLocale.getFullDisplayName(ES_US));
-            assertEquals("fr   ", "Français",          SubtypeLocale.getFullDisplayName(FR));
-            assertEquals("fr_CA", "Français (Canada)", SubtypeLocale.getFullDisplayName(FR_CA));
-            assertEquals("de   ", "Deutsch",           SubtypeLocale.getFullDisplayName(DE));
-            assertEquals("zz   ", "QWERTY",            SubtypeLocale.getFullDisplayName(ZZ));
-
-            assertEquals("en_US", "English",  SubtypeLocale.getMiddleDisplayName(EN_US));
-            assertEquals("en_GB", "English",  SubtypeLocale.getMiddleDisplayName(EN_GB));
-            assertEquals("es_US", "Español",  SubtypeLocale.getMiddleDisplayName(ES_US));
-            assertEquals("fr   ", "Français", SubtypeLocale.getMiddleDisplayName(FR));
-            assertEquals("fr_CA", "Français", SubtypeLocale.getMiddleDisplayName(FR_CA));
-            assertEquals("de   ", "Deutsch",  SubtypeLocale.getMiddleDisplayName(DE));
-            assertEquals("zz   ", "QWERTY",   SubtypeLocale.getMiddleDisplayName(ZZ));
-
-            assertEquals("en_US", "En", SubtypeLocale.getShortDisplayName(EN_US));
-            assertEquals("en_GB", "En", SubtypeLocale.getShortDisplayName(EN_GB));
-            assertEquals("es_US", "Es", SubtypeLocale.getShortDisplayName(ES_US));
-            assertEquals("fr   ", "Fr", SubtypeLocale.getShortDisplayName(FR));
-            assertEquals("fr_CA", "Fr", SubtypeLocale.getShortDisplayName(FR_CA));
-            assertEquals("de   ", "De", SubtypeLocale.getShortDisplayName(DE));
-            assertEquals("zz   ", "",   SubtypeLocale.getShortDisplayName(ZZ));
-            return null;
-        }
-    };
-
-    private final RunInLocale<Void> testsAdditionalSubtypesForSpacebar = new RunInLocale<Void>() {
-        @Override
-        protected Void job(Resources res) {
-            assertEquals("fr qwertz",    "Français",
-                    SubtypeLocale.getFullDisplayName(FR_QWERTZ));
-            assertEquals("de qwerty",    "Deutsch",
-                    SubtypeLocale.getFullDisplayName(DE_QWERTY));
-            assertEquals("en_US azerty", "English (US)",
-                    SubtypeLocale.getFullDisplayName(EN_US_AZERTY));
-            assertEquals("zz azerty",    "AZERTY",
-                    SubtypeLocale.getFullDisplayName(ZZ_AZERTY));
-
-            assertEquals("fr qwertz",    "Français",
-                    SubtypeLocale.getMiddleDisplayName(FR_QWERTZ));
-            assertEquals("de qwerty",    "Deutsch",
-                    SubtypeLocale.getMiddleDisplayName(DE_QWERTY));
-            assertEquals("en_US azerty", "English",
-                    SubtypeLocale.getMiddleDisplayName(EN_US_AZERTY));
-            assertEquals("zz azerty",    "AZERTY",
-                    SubtypeLocale.getMiddleDisplayName(ZZ_AZERTY));
-
-            assertEquals("fr qwertz",    "Fr", SubtypeLocale.getShortDisplayName(FR_QWERTZ));
-            assertEquals("de qwerty",    "De", SubtypeLocale.getShortDisplayName(DE_QWERTY));
-            assertEquals("en_US azerty", "En", SubtypeLocale.getShortDisplayName(EN_US_AZERTY));
-            assertEquals("zz azerty",    "",   SubtypeLocale.getShortDisplayName(ZZ_AZERTY));
-            return null;
-        }
-    };
-
-    public void testPredefinedSubtypesForSpacebarInEnglish() {
-        testsPredefinedSubtypesForSpacebar.runInLocale(mRes, Locale.ENGLISH);
-    }
-
-    public void testAdditionalSubtypeForSpacebarInEnglish() {
-        testsAdditionalSubtypesForSpacebar.runInLocale(mRes, Locale.ENGLISH);
-    }
-
-    public void testPredefinedSubtypesForSpacebarInFrench() {
-        testsPredefinedSubtypesForSpacebar.runInLocale(mRes, Locale.FRENCH);
-    }
-
-    public void testAdditionalSubtypeForSpacebarInFrench() {
-        testsAdditionalSubtypesForSpacebar.runInLocale(mRes, Locale.FRENCH);
-    }
-}
diff --git a/tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java
new file mode 100644
index 0000000..963a5b3
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.utils;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.inputmethod.InputMethodSubtype;
+
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.RichInputMethodManager;
+import com.android.inputmethod.latin.utils.LocaleUtils.RunInLocale;
+
+import java.util.ArrayList;
+import java.util.Locale;
+
+@SmallTest
+public class SubtypeLocaleUtilsTests extends AndroidTestCase {
+    // Locale to subtypes list.
+    private final ArrayList<InputMethodSubtype> mSubtypesList = CollectionUtils.newArrayList();
+
+    private RichInputMethodManager mRichImm;
+    private Resources mRes;
+
+    InputMethodSubtype EN_US;
+    InputMethodSubtype EN_GB;
+    InputMethodSubtype ES_US;
+    InputMethodSubtype FR;
+    InputMethodSubtype FR_CA;
+    InputMethodSubtype DE;
+    InputMethodSubtype ZZ;
+    InputMethodSubtype DE_QWERTY;
+    InputMethodSubtype FR_QWERTZ;
+    InputMethodSubtype EN_US_AZERTY;
+    InputMethodSubtype EN_UK_DVORAK;
+    InputMethodSubtype ES_US_COLEMAK;
+    InputMethodSubtype ZZ_AZERTY;
+    InputMethodSubtype ZZ_PC;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        final Context context = getContext();
+        RichInputMethodManager.init(context);
+        mRichImm = RichInputMethodManager.getInstance();
+        mRes = context.getResources();
+        SubtypeLocaleUtils.init(context);
+
+        EN_US = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
+                Locale.US.toString(), "qwerty");
+        EN_GB = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
+                Locale.UK.toString(), "qwerty");
+        ES_US = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
+                "es_US", "spanish");
+        FR = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
+                Locale.FRENCH.toString(), "azerty");
+        FR_CA = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
+                Locale.CANADA_FRENCH.toString(), "qwerty");
+        DE = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
+                Locale.GERMAN.toString(), "qwertz");
+        ZZ = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
+                SubtypeLocaleUtils.NO_LANGUAGE, "qwerty");
+        DE_QWERTY = AdditionalSubtypeUtils.createAdditionalSubtype(
+                Locale.GERMAN.toString(), "qwerty", null);
+        FR_QWERTZ = AdditionalSubtypeUtils.createAdditionalSubtype(
+                Locale.FRENCH.toString(), "qwertz", null);
+        EN_US_AZERTY = AdditionalSubtypeUtils.createAdditionalSubtype(
+                Locale.US.toString(), "azerty", null);
+        EN_UK_DVORAK = AdditionalSubtypeUtils.createAdditionalSubtype(
+                Locale.UK.toString(), "dvorak", null);
+        ES_US_COLEMAK = AdditionalSubtypeUtils.createAdditionalSubtype(
+                "es_US", "colemak", null);
+        ZZ_AZERTY = AdditionalSubtypeUtils.createAdditionalSubtype(
+                SubtypeLocaleUtils.NO_LANGUAGE, "azerty", null);
+        ZZ_PC = AdditionalSubtypeUtils.createAdditionalSubtype(
+                SubtypeLocaleUtils.NO_LANGUAGE, "pcqwerty", null);
+
+    }
+
+    public void testAllFullDisplayName() {
+        for (final InputMethodSubtype subtype : mSubtypesList) {
+            final String subtypeName =
+                    SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(subtype);
+            if (SubtypeLocaleUtils.isNoLanguage(subtype)) {
+                final String noLanguage = mRes.getString(R.string.subtype_no_language);
+                assertTrue(subtypeName, subtypeName.contains(noLanguage));
+            } else {
+                final String languageName =
+                        SubtypeLocaleUtils.getSubtypeLocaleDisplayName(subtype.getLocale());
+                assertTrue(subtypeName, subtypeName.contains(languageName));
+            }
+        }
+    }
+
+    public void testKeyboardLayoutSetName() {
+        assertEquals("en_US", "qwerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(EN_US));
+        assertEquals("en_GB", "qwerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(EN_GB));
+        assertEquals("es_US", "spanish", SubtypeLocaleUtils.getKeyboardLayoutSetName(ES_US));
+        assertEquals("fr   ", "azerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(FR));
+        assertEquals("fr_CA", "qwerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(FR_CA));
+        assertEquals("de   ", "qwertz", SubtypeLocaleUtils.getKeyboardLayoutSetName(DE));
+        assertEquals("zz   ", "qwerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(ZZ));
+    }
+
+    // InputMethodSubtype's display name in system locale (en_US).
+    //        isAdditionalSubtype (T=true, F=false)
+    // locale layout  |  display name
+    // ------ ------- - ----------------------
+    //  en_US qwerty  F  English (US)            exception
+    //  en_GB qwerty  F  English (UK)            exception
+    //  es_US spanish F  Spanish (US)            exception
+    //  fr    azerty  F  French
+    //  fr_CA qwerty  F  French (Canada)
+    //  de    qwertz  F  German
+    //  zz    qwerty  F  No language (QWERTY)
+    //  fr    qwertz  T  French (QWERTZ)
+    //  de    qwerty  T  German (QWERTY)
+    //  en_US azerty  T  English (US) (AZERTY)   exception
+    //  en_UK dvorak  T  English (UK) (Dvorak)   exception
+    //  es_US colemak T  Spanish (US) (Colemak)  exception
+    //  zz    pc      T  No language (PC)
+
+    public void testPredefinedSubtypesInEnglishSystemLocale() {
+        final RunInLocale<Void> tests = new RunInLocale<Void>() {
+            @Override
+            protected Void job(Resources res) {
+                assertEquals("en_US", "English (US)",
+                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(EN_US));
+                assertEquals("en_GB", "English (UK)",
+                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(EN_GB));
+                assertEquals("es_US", "Spanish (US)",
+                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ES_US));
+                assertEquals("fr   ", "French",
+                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR));
+                assertEquals("fr_CA", "French (Canada)",
+                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR_CA));
+                assertEquals("de   ", "German",
+                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE));
+                assertEquals("zz   ", "No language (QWERTY)",
+                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ));
+                return null;
+            }
+        };
+        tests.runInLocale(mRes, Locale.ENGLISH);
+    }
+
+    public void testAdditionalSubtypesInEnglishSystemLocale() {
+        final RunInLocale<Void> tests = new RunInLocale<Void>() {
+            @Override
+            protected Void job(Resources res) {
+                assertEquals("fr qwertz",    "French (QWERTZ)",
+                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR_QWERTZ));
+                assertEquals("de qwerty",    "German (QWERTY)",
+                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE_QWERTY));
+                assertEquals("en_US azerty", "English (US) (AZERTY)",
+                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(EN_US_AZERTY));
+                assertEquals("en_UK dvorak", "English (UK) (Dvorak)",
+                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(EN_UK_DVORAK));
+                assertEquals("es_US colemak","Spanish (US) (Colemak)",
+                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ES_US_COLEMAK));
+                assertEquals("zz azerty",    "No language (PC)",
+                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ_PC));
+                return null;
+            }
+        };
+        tests.runInLocale(mRes, Locale.ENGLISH);
+    }
+
+    // InputMethodSubtype's display name in system locale (fr).
+    //        isAdditionalSubtype (T=true, F=false)
+    // locale layout  |  display name
+    // ------ ------- - ----------------------
+    //  en_US qwerty  F  Anglais (États-Unis)            exception
+    //  en_GB qwerty  F  Anglais (Royaume-Uni)            exception
+    //  es_US spanish F  Espagnol (États-Unis)            exception
+    //  fr    azerty  F  Français
+    //  fr_CA qwerty  F  Français (Canada)
+    //  de    qwertz  F  Allemand
+    //  zz    qwerty  F  Aucune langue (QWERTY)
+    //  fr    qwertz  T  Français (QWERTZ)
+    //  de    qwerty  T  Allemand (QWERTY)
+    //  en_US azerty  T  Anglais (États-Unis) (AZERTY)   exception
+    //  en_UK dvorak  T  Anglais (Royaume-Uni) (Dvorak)   exception
+    //  es_US colemak T  Espagnol (États-Unis) (Colemak)  exception
+    //  zz    pc      T  Aucune langue (PC)
+
+    public void testPredefinedSubtypesInFrenchSystemLocale() {
+        final RunInLocale<Void> tests = new RunInLocale<Void>() {
+            @Override
+            protected Void job(Resources res) {
+                assertEquals("en_US", "Anglais (États-Unis)",
+                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(EN_US));
+                assertEquals("en_GB", "Anglais (Royaume-Uni)",
+                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(EN_GB));
+                assertEquals("es_US", "Espagnol (États-Unis)",
+                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ES_US));
+                assertEquals("fr   ", "Français",
+                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR));
+                assertEquals("fr_CA", "Français (Canada)",
+                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR_CA));
+                assertEquals("de   ", "Allemand",
+                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE));
+                assertEquals("zz   ", "Aucune langue (QWERTY)",
+                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ));
+                return null;
+            }
+        };
+        tests.runInLocale(mRes, Locale.FRENCH);
+    }
+
+    public void testAdditionalSubtypesInFrenchSystemLocale() {
+        final RunInLocale<Void> tests = new RunInLocale<Void>() {
+            @Override
+            protected Void job(Resources res) {
+                assertEquals("fr qwertz",    "Français (QWERTZ)",
+                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR_QWERTZ));
+                assertEquals("de qwerty",    "Allemand (QWERTY)",
+                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE_QWERTY));
+                assertEquals("en_US azerty", "Anglais (États-Unis) (AZERTY)",
+                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(EN_US_AZERTY));
+                assertEquals("en_UK dvorak", "Anglais (Royaume-Uni) (Dvorak)",
+                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(EN_UK_DVORAK));
+                assertEquals("es_US colemak","Espagnol (États-Unis) (Colemak)",
+                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ES_US_COLEMAK));
+                assertEquals("zz azerty",    "Aucune langue (PC)",
+                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ_PC));
+                return null;
+            }
+        };
+        tests.runInLocale(mRes, Locale.FRENCH);
+    }
+
+    public void testAllFullDisplayNameForSpacebar() {
+        for (final InputMethodSubtype subtype : mSubtypesList) {
+            final String subtypeName =
+                    SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(subtype);
+            final String spacebarText = SubtypeLocaleUtils.getFullDisplayName(subtype);
+            final String languageName =
+                    SubtypeLocaleUtils.getSubtypeLocaleDisplayName(subtype.getLocale());
+            if (SubtypeLocaleUtils.isNoLanguage(subtype)) {
+                assertFalse(subtypeName, spacebarText.contains(languageName));
+            } else {
+                assertTrue(subtypeName, spacebarText.contains(languageName));
+            }
+        }
+    }
+
+   public void testAllMiddleDisplayNameForSpacebar() {
+        for (final InputMethodSubtype subtype : mSubtypesList) {
+            final String subtypeName =
+                    SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(subtype);
+            final String spacebarText = SubtypeLocaleUtils.getMiddleDisplayName(subtype);
+            if (SubtypeLocaleUtils.isNoLanguage(subtype)) {
+                assertEquals(subtypeName,
+                        SubtypeLocaleUtils.getKeyboardLayoutSetName(subtype), spacebarText);
+            } else {
+                assertEquals(subtypeName,
+                        SubtypeLocaleUtils.getSubtypeLocaleDisplayName(subtype.getLocale()),
+                        spacebarText);
+            }
+        }
+    }
+
+    public void testAllShortDisplayNameForSpacebar() {
+        for (final InputMethodSubtype subtype : mSubtypesList) {
+            final String subtypeName =
+                    SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(subtype);
+            final Locale locale = SubtypeLocaleUtils.getSubtypeLocale(subtype);
+            final String spacebarText = SubtypeLocaleUtils.getShortDisplayName(subtype);
+            final String languageCode = StringUtils.capitalizeFirstCodePoint(
+                    locale.getLanguage(), locale);
+            if (SubtypeLocaleUtils.isNoLanguage(subtype)) {
+                assertEquals(subtypeName, "", spacebarText);
+            } else {
+                assertEquals(subtypeName, languageCode, spacebarText);
+            }
+        }
+    }
+
+    // InputMethodSubtype's display name for spacebar text in its locale.
+    //        isAdditionalSubtype (T=true, F=false)
+    // locale layout  | Short  Middle      Full
+    // ------ ------- - ---- --------- ----------------------
+    //  en_US qwerty  F  En  English   English (US)           exception
+    //  en_GB qwerty  F  En  English   English (UK)           exception
+    //  es_US spanish F  Es  Español   Español (EE.UU.)       exception
+    //  fr    azerty  F  Fr  Français  Français
+    //  fr_CA qwerty  F  Fr  Français  Français (Canada)
+    //  de    qwertz  F  De  Deutsch   Deutsch
+    //  zz    qwerty  F      QWERTY    QWERTY
+    //  fr    qwertz  T  Fr  Français  Français
+    //  de    qwerty  T  De  Deutsch   Deutsch
+    //  en_US azerty  T  En  English   English (US)
+    //  zz    azerty  T      AZERTY    AZERTY
+
+    private final RunInLocale<Void> testsPredefinedSubtypesForSpacebar = new RunInLocale<Void>() {
+        @Override
+        protected Void job(Resources res) {
+            assertEquals("en_US", "English (US)", SubtypeLocaleUtils.getFullDisplayName(EN_US));
+            assertEquals("en_GB", "English (UK)", SubtypeLocaleUtils.getFullDisplayName(EN_GB));
+            assertEquals("es_US", "Español (EE.UU.)",
+                    SubtypeLocaleUtils.getFullDisplayName(ES_US));
+            assertEquals("fr   ", "Français",     SubtypeLocaleUtils.getFullDisplayName(FR));
+            assertEquals("fr_CA", "Français (Canada)",
+                    SubtypeLocaleUtils.getFullDisplayName(FR_CA));
+            assertEquals("de   ", "Deutsch",      SubtypeLocaleUtils.getFullDisplayName(DE));
+            assertEquals("zz   ", "QWERTY",       SubtypeLocaleUtils.getFullDisplayName(ZZ));
+
+            assertEquals("en_US", "English",  SubtypeLocaleUtils.getMiddleDisplayName(EN_US));
+            assertEquals("en_GB", "English",  SubtypeLocaleUtils.getMiddleDisplayName(EN_GB));
+            assertEquals("es_US", "Español",  SubtypeLocaleUtils.getMiddleDisplayName(ES_US));
+            assertEquals("fr   ", "Français", SubtypeLocaleUtils.getMiddleDisplayName(FR));
+            assertEquals("fr_CA", "Français", SubtypeLocaleUtils.getMiddleDisplayName(FR_CA));
+            assertEquals("de   ", "Deutsch",  SubtypeLocaleUtils.getMiddleDisplayName(DE));
+            assertEquals("zz   ", "QWERTY",   SubtypeLocaleUtils.getMiddleDisplayName(ZZ));
+
+            assertEquals("en_US", "En", SubtypeLocaleUtils.getShortDisplayName(EN_US));
+            assertEquals("en_GB", "En", SubtypeLocaleUtils.getShortDisplayName(EN_GB));
+            assertEquals("es_US", "Es", SubtypeLocaleUtils.getShortDisplayName(ES_US));
+            assertEquals("fr   ", "Fr", SubtypeLocaleUtils.getShortDisplayName(FR));
+            assertEquals("fr_CA", "Fr", SubtypeLocaleUtils.getShortDisplayName(FR_CA));
+            assertEquals("de   ", "De", SubtypeLocaleUtils.getShortDisplayName(DE));
+            assertEquals("zz   ", "",   SubtypeLocaleUtils.getShortDisplayName(ZZ));
+            return null;
+        }
+    };
+
+    private final RunInLocale<Void> testsAdditionalSubtypesForSpacebar = new RunInLocale<Void>() {
+        @Override
+        protected Void job(Resources res) {
+            assertEquals("fr qwertz",    "Français",
+                    SubtypeLocaleUtils.getFullDisplayName(FR_QWERTZ));
+            assertEquals("de qwerty",    "Deutsch",
+                    SubtypeLocaleUtils.getFullDisplayName(DE_QWERTY));
+            assertEquals("en_US azerty", "English (US)",
+                    SubtypeLocaleUtils.getFullDisplayName(EN_US_AZERTY));
+            assertEquals("zz azerty",    "AZERTY",
+                    SubtypeLocaleUtils.getFullDisplayName(ZZ_AZERTY));
+
+            assertEquals("fr qwertz",    "Français",
+                    SubtypeLocaleUtils.getMiddleDisplayName(FR_QWERTZ));
+            assertEquals("de qwerty",    "Deutsch",
+                    SubtypeLocaleUtils.getMiddleDisplayName(DE_QWERTY));
+            assertEquals("en_US azerty", "English",
+                    SubtypeLocaleUtils.getMiddleDisplayName(EN_US_AZERTY));
+            assertEquals("zz azerty",    "AZERTY",
+                    SubtypeLocaleUtils.getMiddleDisplayName(ZZ_AZERTY));
+
+            assertEquals("fr qwertz",    "Fr", SubtypeLocaleUtils.getShortDisplayName(FR_QWERTZ));
+            assertEquals("de qwerty",    "De", SubtypeLocaleUtils.getShortDisplayName(DE_QWERTY));
+            assertEquals("en_US azerty", "En",
+                    SubtypeLocaleUtils.getShortDisplayName(EN_US_AZERTY));
+            assertEquals("zz azerty",    "",   SubtypeLocaleUtils.getShortDisplayName(ZZ_AZERTY));
+            return null;
+        }
+    };
+
+    public void testPredefinedSubtypesForSpacebarInEnglish() {
+        testsPredefinedSubtypesForSpacebar.runInLocale(mRes, Locale.ENGLISH);
+    }
+
+    public void testAdditionalSubtypeForSpacebarInEnglish() {
+        testsAdditionalSubtypesForSpacebar.runInLocale(mRes, Locale.ENGLISH);
+    }
+
+    public void testPredefinedSubtypesForSpacebarInFrench() {
+        testsPredefinedSubtypesForSpacebar.runInLocale(mRes, Locale.FRENCH);
+    }
+
+    public void testAdditionalSubtypeForSpacebarInFrench() {
+        testsAdditionalSubtypesForSpacebar.runInLocale(mRes, Locale.FRENCH);
+    }
+}