diff --git a/java/res/values/predefined-subtypes.xml b/java/res/values/predefined-subtypes.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e67fee53f2661208f4a018f4587d62973171d0ef
--- /dev/null
+++ b/java/res/values/predefined-subtypes.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2012, 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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Predefined subtypes (language:layout) in CSV format -->
+    <string name="predefined_subtypes" translatable="false">de:qwerty,fr:qwertz</string>
+</resources>
diff --git a/java/src/com/android/inputmethod/latin/AdditionalSubtype.java b/java/src/com/android/inputmethod/latin/AdditionalSubtype.java
index 5e42ad6c5d74f80c4b59dcb4736012dbed353ca3..b24f064720cc950c6064559e8917ea0c2467a626 100644
--- a/java/src/com/android/inputmethod/latin/AdditionalSubtype.java
+++ b/java/src/com/android/inputmethod/latin/AdditionalSubtype.java
@@ -52,4 +52,20 @@ public class AdditionalSubtype {
         return new InputMethodSubtype(nameId, R.drawable.ic_subtype_keyboard,
                 localeString, SUBTYPE_MODE_KEYBOARD, extraValue, false, false);
     }
+
+    private static final String LOCALE_AND_LAYOUT_SEPARATOR = ":";
+    private static final String SUBTYPE_SEPARATOR = ",";
+
+    public static InputMethodSubtype[] createAdditionalSubtypesArray(String csvSubtypes) {
+        final String[] subtypeSpecs = csvSubtypes.split(SUBTYPE_SEPARATOR);
+        final InputMethodSubtype[] subtypesArray = new InputMethodSubtype[subtypeSpecs.length];
+        for (int i = 0; i < subtypeSpecs.length; i++) {
+            final String elems[] = subtypeSpecs[i].split(LOCALE_AND_LAYOUT_SEPARATOR);
+            final String localeString = elems[0];
+            final String keyboardLayoutSetName = elems[1];
+            subtypesArray[i] = AdditionalSubtype.createAdditionalSubtype(
+                    localeString, keyboardLayoutSetName);
+        }
+        return subtypesArray;
+    }
 }
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index aea6add56a23a054fe3816bb97b10422bae5030c..682901cbc8f65c1f09da918496f058e61a514617 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -441,8 +441,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
 
         loadSettings();
 
-        ImfUtils.setAdditionalInputMethodSubtypes(
-                this, mSettingsValues.getPrefefinedAdditionalSubtypes());
+        ImfUtils.setAdditionalInputMethodSubtypes(this, mSettingsValues.getAdditionalSubtypes());
 
         // TODO: remove the following when it's not needed by updateCorrectionMode() any more
         mInputAttributes = new InputAttributes(null, false /* isFullscreenMode */);
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index 43e7e278f5d7d27ccaca0214cab36d7dcee4013a..29825df7dee7a0afc5eff139f4774c2645990f8a 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -62,6 +62,7 @@ public class Settings extends InputMethodSettingsFragment
             "pref_suppress_language_switch_key";
     public static final String PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST =
             "pref_include_other_imes_in_language_switch_list";
+    public static final String PREF_CUSTOM_INPUT_STYLES = "custom_input_styles";
     public static final String PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY =
             "pref_key_preview_popup_dismiss_delay";
     public static final String PREF_KEY_USE_CONTACTS_DICT = "pref_key_use_contacts_dict";
diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java
index 539ac59638c986e43eff88487c322ea3562eec39..c160555f08fac0b2a46e87289246f8a78e1b187c 100644
--- a/java/src/com/android/inputmethod/latin/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/SettingsValues.java
@@ -71,7 +71,7 @@ public class SettingsValues {
     private final int mVibrationDurationSettingsRawValue;
     @SuppressWarnings("unused") // TODO: Use this
     private final float mKeypressSoundVolumeRawValue;
-    private final InputMethodSubtype[] mPredefinedAdditionalSubtypes;
+    private final InputMethodSubtype[] mAdditionalSubtypes;
 
     // Deduced settings
     public final int mKeypressVibrationDuration;
@@ -149,15 +149,8 @@ public class SettingsValues {
         mVoiceKeyEnabled = mVoiceMode != null && !mVoiceMode.equals(voiceModeOff);
         mVoiceKeyOnMain = mVoiceMode != null && mVoiceMode.equals(voiceModeMain);
 
-        // Predefined additional subtypes
-        final InputMethodSubtype DE_QWERTY = AdditionalSubtype.createAdditionalSubtype(
-                Locale.GERMAN.toString(), AdditionalSubtype.QWERTY);
-        final InputMethodSubtype FR_QWERTZ = AdditionalSubtype.createAdditionalSubtype(
-                Locale.FRENCH.toString(), AdditionalSubtype.QWERTZ);
-        mPredefinedAdditionalSubtypes = new InputMethodSubtype[] {
-                DE_QWERTY,
-                FR_QWERTZ,
-        };
+        mAdditionalSubtypes = AdditionalSubtype.createAdditionalSubtypesArray(
+                getCsvAdditionalSubtypes(prefs, res));
     }
 
     // Helper functions to create member values.
@@ -318,9 +311,14 @@ public class SettingsValues {
         return res.getBoolean(R.bool.config_use_fullscreen_mode);
     }
 
-    // TODO: Should be able to add/remove/edit.
-    public InputMethodSubtype[] getPrefefinedAdditionalSubtypes() {
-        return mPredefinedAdditionalSubtypes;
+    public InputMethodSubtype[] getAdditionalSubtypes() {
+        return mAdditionalSubtypes;
+    }
+
+    public static String getCsvAdditionalSubtypes(final SharedPreferences prefs,
+            final Resources res) {
+        final String csvPredefinedSubtypes = res.getString(R.string.predefined_subtypes, "");
+        return prefs.getString(Settings.PREF_CUSTOM_INPUT_STYLES, csvPredefinedSubtypes);
     }
 
     // Accessed from the settings interface, hence public