diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index f44e6328bf54a9208b1c93a131d44a63a93d6d1c..8d5bc1595d6639baa98ac1d378916b1422c94e28 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -49,7 +49,6 @@ public class BinaryDictionary extends Dictionary {
 
     private static final int TYPED_LETTER_MULTIPLIER = 2;
 
-    private int mDicTypeId;
     private long mNativeDict;
     private final int[] mInputCodes = new int[MAX_WORD_LENGTH];
     private final char[] mOutputChars = new char[MAX_WORD_LENGTH * MAX_WORDS];
@@ -69,12 +68,12 @@ public class BinaryDictionary extends Dictionary {
      * @param offset the offset of the dictionary data within the file.
      * @param length the length of the binary data.
      * @param useFullEditDistance whether to use the full edit distance in suggestions
-     * @param dicTypeId the dictionary type id of the dictionary
+     * @param dictType the dictionary type, as a human-readable string
      */
     public BinaryDictionary(final Context context,
             final String filename, final long offset, final long length,
-            final boolean useFullEditDistance, final Locale locale, final int dicTypeId) {
-        mDicTypeId = dicTypeId;
+            final boolean useFullEditDistance, final Locale locale, final String dictType) {
+        super(dictType);
         mUseFullEditDistance = useFullEditDistance;
         loadDictionary(filename, offset, length);
     }
@@ -90,7 +89,7 @@ public class BinaryDictionary extends Dictionary {
     private native boolean isValidBigramNative(long dict, int[] word1, int[] word2);
     private native int getSuggestionsNative(long dict, long proximityInfo, int[] xCoordinates,
             int[] yCoordinates, int[] times, int[] pointerIds, int[] inputCodes, int codesSize,
-            int commitPoint, boolean isGesture, int dicTypeId,
+            int commitPoint, boolean isGesture,
             int[] prevWordCodePointArray, boolean useFullEditDistance, char[] outputChars,
             int[] scores, int[] outputIndices);
     private native int getBigramsNative(long dict, int[] prevWord, int prevWordLength,
@@ -202,8 +201,7 @@ public class BinaryDictionary extends Dictionary {
 
         return getSuggestionsNative(mNativeDict, proximityInfo.getNativeProximityInfo(),
             codes.getXCoordinates(), codes.getYCoordinates(), emptyArray, emptyArray, mInputCodes,
-            codesSize, 0 /* unused */, false, mDicTypeId,
-            prevWordCodePointArray, mUseFullEditDistance,
+            codesSize, 0 /* unused */, false, prevWordCodePointArray, mUseFullEditDistance,
             outputChars, scores, spaceIndices);
     }
 
diff --git a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
index 620c553af74627a792a96a27c96ce050fafbccbe..fbcaddae889ca11cec9a0e1e5030f297271c42e8 100644
--- a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
@@ -62,8 +62,8 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
      */
     private final boolean mUseFirstLastBigrams;
 
-    public ContactsBinaryDictionary(final Context context, final int dicTypeId, Locale locale) {
-        super(context, getFilenameWithLocale(NAME, locale.toString()), dicTypeId);
+    public ContactsBinaryDictionary(final Context context, Locale locale) {
+        super(context, getFilenameWithLocale(NAME, locale.toString()), Suggest.DICT_KEY_CONTACTS);
         mLocale = locale;
         mUseFirstLastBigrams = useFirstLastBigramsForLocale(locale);
         registerObserver(context);
diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java
index 00896c36427157c4348a192b459b0fd428f18615..ba129835643c098d6307029d317063d0caf316ac 100644
--- a/java/src/com/android/inputmethod/latin/Dictionary.java
+++ b/java/src/com/android/inputmethod/latin/Dictionary.java
@@ -33,6 +33,12 @@ public abstract class Dictionary {
 
     public static final int NOT_A_PROBABILITY = -1;
 
+    protected final String mDictType;
+
+    public Dictionary(final String dictType) {
+        mDictType = dictType;
+    }
+
     /**
      * Searches for words in the dictionary that match the characters in the composer. Matched
      * words are returned as an ArrayList.
diff --git a/java/src/com/android/inputmethod/latin/DictionaryCollection.java b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
index 169e70745253b622894f88b06dbe1ece8dfd9449..dcc53c59f98780d7bc3923dada8a7f0ce0f52361 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryCollection.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
@@ -33,11 +33,13 @@ public class DictionaryCollection extends Dictionary {
     private final String TAG = DictionaryCollection.class.getSimpleName();
     protected final CopyOnWriteArrayList<Dictionary> mDictionaries;
 
-    public DictionaryCollection() {
+    public DictionaryCollection(final String dictType) {
+        super(dictType);
         mDictionaries = new CopyOnWriteArrayList<Dictionary>();
     }
 
-    public DictionaryCollection(Dictionary... dictionaries) {
+    public DictionaryCollection(final String dictType, Dictionary... dictionaries) {
+        super(dictType);
         if (null == dictionaries) {
             mDictionaries = new CopyOnWriteArrayList<Dictionary>();
         } else {
@@ -46,7 +48,8 @@ public class DictionaryCollection extends Dictionary {
         }
     }
 
-    public DictionaryCollection(Collection<Dictionary> dictionaries) {
+    public DictionaryCollection(final String dictType, Collection<Dictionary> dictionaries) {
+        super(dictType);
         mDictionaries = new CopyOnWriteArrayList<Dictionary>(dictionaries);
         mDictionaries.removeAll(Collections.singleton(null));
     }
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
index 6d77c4dd2cb0d4eaf3f2d59e7b47e3202e30ca79..7ccfe05cf0c73f8d8a0ce975f5e07a5f13123f7e 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
@@ -49,7 +49,8 @@ public class DictionaryFactory {
             final Locale locale, final boolean useFullEditDistance) {
         if (null == locale) {
             Log.e(TAG, "No locale defined for dictionary");
-            return new DictionaryCollection(createBinaryDictionary(context, locale));
+            return new DictionaryCollection(Suggest.DICT_KEY_MAIN,
+                    createBinaryDictionary(context, locale));
         }
 
         final LinkedList<Dictionary> dictList = new LinkedList<Dictionary>();
@@ -59,7 +60,7 @@ public class DictionaryFactory {
             for (final AssetFileAddress f : assetFileList) {
                 final BinaryDictionary binaryDictionary =
                         new BinaryDictionary(context, f.mFilename, f.mOffset, f.mLength,
-                                useFullEditDistance, locale, Suggest.DIC_MAIN);
+                                useFullEditDistance, locale, Suggest.DICT_KEY_MAIN);
                 if (binaryDictionary.isValidDictionary()) {
                     dictList.add(binaryDictionary);
                 }
@@ -69,7 +70,7 @@ public class DictionaryFactory {
         // If the list is empty, that means we should not use any dictionary (for example, the user
         // explicitly disabled the main dictionary), so the following is okay. dictList is never
         // null, but if for some reason it is, DictionaryCollection handles it gracefully.
-        return new DictionaryCollection(dictList);
+        return new DictionaryCollection(Suggest.DICT_KEY_MAIN, dictList);
     }
 
     /**
@@ -112,7 +113,7 @@ public class DictionaryFactory {
                 return null;
             }
             return new BinaryDictionary(context, sourceDir, afd.getStartOffset(), afd.getLength(),
-                    false /* useFullEditDistance */, locale, Suggest.DIC_MAIN);
+                    false /* useFullEditDistance */, locale, Suggest.DICT_KEY_MAIN);
         } catch (android.content.res.Resources.NotFoundException e) {
             Log.e(TAG, "Could not find the resource");
             return null;
@@ -140,7 +141,7 @@ public class DictionaryFactory {
             long startOffset, long length, final boolean useFullEditDistance, Locale locale) {
         if (dictionary.isFile()) {
             return new BinaryDictionary(context, dictionary.getAbsolutePath(), startOffset, length,
-                    useFullEditDistance, locale, Suggest.DIC_MAIN);
+                    useFullEditDistance, locale, Suggest.DICT_KEY_MAIN);
         } else {
             Log.e(TAG, "Could not find the file. path=" + dictionary.getAbsolutePath());
             return null;
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index c076fa0f903f1df8d52b0f161aea2ed3c150eb6f..1cda9f25736601ed7f0b8beaa9d976f136a98664 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -76,9 +76,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
     /** The expandable fusion dictionary used to generate the binary dictionary. */
     private FusionDictionary mFusionDictionary;
 
-    /** The dictionary type id. */
-    public final int mDicTypeId;
-
     /**
      * The name of this dictionary, used as the filename for storing the binary dictionary. Multiple
      * dictionary instances with the same filename is supported, with access controlled by
@@ -124,11 +121,11 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
      * @param context The application context of the parent.
      * @param filename The filename for this binary dictionary. Multiple dictionaries with the same
      *        filename is supported.
-     * @param dictType The type of this dictionary.
+     * @param dictType the dictionary type, as a human-readable string
      */
     public ExpandableBinaryDictionary(
-            final Context context, final String filename, final int dictType) {
-        mDicTypeId = dictType;
+            final Context context, final String filename, final String dictType) {
+        super(dictType);
         mFilename = filename;
         mContext = context;
         mBinaryDictionary = null;
@@ -308,7 +305,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
         // Build the new binary dictionary
         final BinaryDictionary newBinaryDictionary =
                 new BinaryDictionary(mContext, filename, 0, length, true /* useFullEditDistance */,
-                        null, mDicTypeId);
+                        null, mDictType);
 
         if (mBinaryDictionary != null) {
             // Ensure all threads accessing the current dictionary have finished before swapping in
diff --git a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
index f19d77be2ad2268ac6d3bc3218dd28d54440ba8d..e86a657e9b19fa90554d8c20a686715bc701c284 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
@@ -38,7 +38,6 @@ public class ExpandableDictionary extends Dictionary {
 
     private Context mContext;
     private char[] mWordBuilder = new char[BinaryDictionary.MAX_WORD_LENGTH];
-    private int mDicTypeId;
     private int mMaxDepth;
     private int mInputLength;
 
@@ -152,11 +151,11 @@ public class ExpandableDictionary extends Dictionary {
 
     private int[][] mCodes;
 
-    public ExpandableDictionary(Context context, int dicTypeId) {
+    public ExpandableDictionary(final Context context, final String dictType) {
+        super(dictType);
         mContext = context;
         clearDictionary();
         mCodes = new int[BinaryDictionary.MAX_WORD_LENGTH][];
-        mDicTypeId = dicTypeId;
     }
 
     public void loadDictionary() {
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 25b8fd566265beb16f9d41b9ab57f583db6b5a72..f6ba78674e3720dc83905fe65b1917a0200bbf2a 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -499,8 +499,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
                     // If the locale has changed then recreate the contacts dictionary. This
                     // allows locale dependent rules for handling bigram name predictions.
                     oldContactsDictionary.close();
-                    dictionaryToUse = new ContactsBinaryDictionary(
-                        this, Suggest.DIC_CONTACTS, locale);
+                    dictionaryToUse = new ContactsBinaryDictionary(this, locale);
                 } else {
                     // Make sure the old contacts dictionary is opened. If it is already open,
                     // this is a no-op, so it's safe to call it anyways.
@@ -508,7 +507,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
                     dictionaryToUse = oldContactsDictionary;
                 }
             } else {
-                dictionaryToUse = new ContactsBinaryDictionary(this, Suggest.DIC_CONTACTS, locale);
+                dictionaryToUse = new ContactsBinaryDictionary(this, locale);
             }
         }
 
diff --git a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java
index 74f27e3cc5be44c606199f58c220d56f68fd91ad..9b20bd690358a9bf17b9786d9906320d83c52a6f 100644
--- a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java
@@ -28,7 +28,7 @@ public class SynchronouslyLoadedContactsBinaryDictionary extends ContactsBinaryD
     private boolean mClosed;
 
     public SynchronouslyLoadedContactsBinaryDictionary(final Context context, final Locale locale) {
-        super(context, Suggest.DIC_CONTACTS, locale);
+        super(context, locale);
     }
 
     @Override
diff --git a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
index 5bcdb57b5eb3838a3eb2641fc255c4ba0aa807ca..54c53df0cc85b9a18cf8d0a9cc9f2bedc97519b7 100644
--- a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
@@ -69,7 +69,7 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
 
     public UserBinaryDictionary(final Context context, final String locale,
             final boolean alsoUseMoreRestrictiveLocales) {
-        super(context, getFilenameWithLocale(NAME, locale), Suggest.DIC_USER);
+        super(context, getFilenameWithLocale(NAME, locale), Suggest.DICT_KEY_USER);
         if (null == locale) throw new NullPointerException(); // Catch the error earlier
         mLocale = locale;
         mAlsoUseMoreRestrictiveLocales = alsoUseMoreRestrictiveLocales;
diff --git a/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java b/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java
index 5095f65822551783335a3d310a3ae951f868ab15..d14006651846a5954e027118c80af8873c04ee73 100644
--- a/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java
@@ -128,14 +128,14 @@ public class UserHistoryDictionary extends ExpandableDictionary {
             }
         }
         final UserHistoryDictionary dict =
-                new UserHistoryDictionary(context, locale, dictTypeId, sp);
+                new UserHistoryDictionary(context, locale, sp);
         sLangDictCache.put(locale, new SoftReference<UserHistoryDictionary>(dict));
         return dict;
     }
 
-    private UserHistoryDictionary(final Context context, final String locale, final int dicTypeId,
-            SharedPreferences sp) {
-        super(context, dicTypeId);
+    private UserHistoryDictionary(final Context context, final String locale,
+            final SharedPreferences sp) {
+        super(context, Suggest.DICT_KEY_USER_HISTORY);
         mLocale = locale;
         mPrefs = sp;
         if (sOpenHelper == null) {
diff --git a/java/src/com/android/inputmethod/latin/WhitelistDictionary.java b/java/src/com/android/inputmethod/latin/WhitelistDictionary.java
index a0de2f9707746ca0b0af798c3f8f6cfd6b0b5e69..dc5706521a61857bee76e94c847e854471bbd0d8 100644
--- a/java/src/com/android/inputmethod/latin/WhitelistDictionary.java
+++ b/java/src/com/android/inputmethod/latin/WhitelistDictionary.java
@@ -37,7 +37,7 @@ public class WhitelistDictionary extends ExpandableDictionary {
 
     // TODO: Conform to the async load contact of ExpandableDictionary
     public WhitelistDictionary(final Context context, final Locale locale) {
-        super(context, Suggest.DIC_WHITELIST);
+        super(context, Suggest.DICT_KEY_WHITELIST);
         // TODO: Move whitelist dictionary into main dictionary.
         final RunInLocale<Void> job = new RunInLocale<Void>() {
             @Override
diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
index 3fa45da557b5b12480fcee0571406a538bc1addc..bee0662eebbad70efeca35e791cd36a9ebf397aa 100644
--- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
+++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
@@ -129,7 +129,7 @@ static jlong latinime_BinaryDictionary_open(JNIEnv *env, jobject object,
 static int latinime_BinaryDictionary_getSuggestions(JNIEnv *env, jobject object, jlong dict,
         jlong proximityInfo, jintArray xCoordinatesArray, jintArray yCoordinatesArray,
         jintArray timesArray, jintArray pointerIdArray, jintArray inputArray, jint arraySize,
-        jint commitPoint, jboolean isGesture, jint dicTypeId,
+        jint commitPoint, jboolean isGesture,
         jintArray prevWordForBigrams, jboolean useFullEditDistance, jcharArray outputArray,
         jintArray frequencyArray, jintArray spaceIndexArray) {
     Dictionary *dictionary = (Dictionary*) dict;
@@ -148,7 +148,7 @@ static int latinime_BinaryDictionary_getSuggestions(JNIEnv *env, jobject object,
     jsize prevWordLength = prevWordChars ? env->GetArrayLength(prevWordForBigrams) : 0;
     int count = dictionary->getSuggestions(pInfo, xCoordinates, yCoordinates, times, pointerIds,
             inputCodes, arraySize, prevWordChars, prevWordLength, commitPoint, isGesture,
-            dicTypeId, useFullEditDistance, (unsigned short*) outputChars,
+            useFullEditDistance, (unsigned short*) outputChars,
             frequencies, spaceIndices);
     if (prevWordChars) {
         env->ReleaseIntArrayElements(prevWordForBigrams, prevWordChars, JNI_ABORT);
@@ -260,7 +260,7 @@ void releaseDictBuf(void* dictBuf, const size_t length, int fd) {
 static JNINativeMethod sMethods[] = {
     {"openNative", "(Ljava/lang/String;JJIIII)J", (void*)latinime_BinaryDictionary_open},
     {"closeNative", "(J)V", (void*)latinime_BinaryDictionary_close},
-    {"getSuggestionsNative", "(JJ[I[I[I[I[IIIZI[IZ[C[I[I)I",
+    {"getSuggestionsNative", "(JJ[I[I[I[I[IIIZ[IZ[C[I[I)I",
             (void*) latinime_BinaryDictionary_getSuggestions},
     {"getFrequencyNative", "(J[II)I", (void*)latinime_BinaryDictionary_getFrequency},
     {"isValidBigramNative", "(J[I[I)Z", (void*)latinime_BinaryDictionary_isValidBigram},
diff --git a/native/jni/src/dictionary.h b/native/jni/src/dictionary.h
index 708cb090954757ece0b6187effdabdaab7bf4335..8b47694318990e92d135943f9c3528f51a265537 100644
--- a/native/jni/src/dictionary.h
+++ b/native/jni/src/dictionary.h
@@ -36,14 +36,14 @@ class Dictionary {
 
     int getSuggestions(ProximityInfo *proximityInfo, int *xcoordinates, int *ycoordinates,
             int *times, int *pointerIds, int *codes, int codesSize, int *prevWordChars,
-            int prevWordLength, int commitPoint, bool isGesture, int dicTypeId,
+            int prevWordLength, int commitPoint, bool isGesture,
             bool useFullEditDistance, unsigned short *outWords,
             int *frequencies, int *spaceIndices) {
         int result = 0;
         if (isGesture) {
             mGestureDecoder->setPrevWord(prevWordChars, prevWordLength);
             result = mGestureDecoder->getSuggestions(proximityInfo, xcoordinates, ycoordinates,
-                    times, pointerIds, codes, codesSize, commitPoint, dicTypeId == 1 /* main */,
+                    times, pointerIds, codes, codesSize, commitPoint,
                     outWords, frequencies, spaceIndices);
         } else {
             std::map<int, int> bigramMap;
diff --git a/native/jni/src/gesture/impl/gesture_decoder_impl.h b/native/jni/src/gesture/impl/gesture_decoder_impl.h
index be4e8b3c2768303a8b67ae9062911eff9a71acf1..0ca89941ca5bfe43f6118a848d3b73a34904c3e2 100644
--- a/native/jni/src/gesture/impl/gesture_decoder_impl.h
+++ b/native/jni/src/gesture/impl/gesture_decoder_impl.h
@@ -30,7 +30,7 @@ class GestureDecoderImpl : public IncrementalDecoder {
     }
 
     int getSuggestions(ProximityInfo *pInfo, int *inputXs, int *inputYs, int *times,
-            int *pointerIds, int *codes, int inputSize, int commitPoint, bool isMainDict,
+            int *pointerIds, int *codes, int inputSize, int commitPoint,
             unsigned short *outWords, int *frequencies, int *outputIndices) {
         return 0;
     }
diff --git a/native/jni/src/gesture/incremental_decoder_interface.h b/native/jni/src/gesture/incremental_decoder_interface.h
index c5404a40ca0803636242f2d16cdfe7efdb2a7233..565f89c909acde03c1aa43b72adef3554f8f82a8 100644
--- a/native/jni/src/gesture/incremental_decoder_interface.h
+++ b/native/jni/src/gesture/incremental_decoder_interface.h
@@ -28,7 +28,7 @@ class IncrementalDecoderInterface {
 
  public:
     virtual int getSuggestions(ProximityInfo *pInfo, int *inputXs, int *inputYs, int *times,
-            int *pointerIds, int *codes, int inputSize, int commitPoint, bool isMainDict,
+            int *pointerIds, int *codes, int inputSize, int commitPoint,
             unsigned short *outWords, int *frequencies, int *outputIndices) = 0;
     virtual void reset() = 0;
     virtual void setDict(const UnigramDictionary *dict, const BigramDictionary *bigram,