diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index fd34b98f4af8786aa7ce1a6f974a77ab4977fb58..23f8a249a5201a3910967d518e8e976a239f96f9 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -318,16 +318,16 @@ public final class BinaryDictionary extends Dictionary {
                 ++len;
             }
             if (len > 0) {
-                final int flags = mOutputTypes[j] & SuggestedWordInfo.KIND_MASK_FLAGS;
+                final int kindAndFlags = mOutputTypes[j];
                 if (blockOffensiveWords
-                        && 0 != (flags & SuggestedWordInfo.KIND_FLAG_POSSIBLY_OFFENSIVE)
-                        && 0 == (flags & SuggestedWordInfo.KIND_FLAG_EXACT_MATCH)) {
+                        && 0 != (kindAndFlags & SuggestedWordInfo.KIND_FLAG_POSSIBLY_OFFENSIVE)
+                        && 0 == (kindAndFlags & SuggestedWordInfo.KIND_FLAG_EXACT_MATCH)) {
                     // If we block potentially offensive words, and if the word is possibly
                     // offensive, then we don't output it unless it's also an exact match.
                     continue;
                 }
                 suggestions.add(new SuggestedWordInfo(new String(mOutputCodePoints, start, len),
-                        mOutputScores[j], mOutputTypes[j], this /* sourceDict */,
+                        mOutputScores[j], kindAndFlags, this /* sourceDict */,
                         mSpaceIndices[j] /* indexOfTouchPointOfSecondWord */,
                         mOutputAutoCommitFirstWordConfidence[0]));
             }
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 63928e31f599cfa367b273cbb7bc7bd6a5cfdbaa..9ec697b5ec406beca204b078bb3f7a95bc28bd62 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -322,7 +322,7 @@ public final class Suggest {
         for (int i = quotesToAppend - 1; i >= 0; --i) {
             sb.appendCodePoint(Constants.CODE_SINGLE_QUOTE);
         }
-        return new SuggestedWordInfo(sb.toString(), wordInfo.mScore, wordInfo.mKind,
+        return new SuggestedWordInfo(sb.toString(), wordInfo.mScore, wordInfo.mKindAndFlags,
                 wordInfo.mSourceDict, wordInfo.mIndexOfTouchPointOfSecondWord,
                 wordInfo.mAutoCommitFirstWordConfidence);
     }
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index 62da0f99256845067e337ad59ac584843bc76d71..09c6727180deb04d6babdfca7a63ad39e205a0d7 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -208,8 +208,7 @@ public class SuggestedWords {
         public static final int NOT_A_CONFIDENCE = -1;
         public static final int MAX_SCORE = Integer.MAX_VALUE;
 
-        // TODO: Make KIND_MASK_KIND private.
-        public static final int KIND_MASK_KIND = 0xFF; // Mask to get only the kind
+        private static final int KIND_MASK_KIND = 0xFF; // Mask to get only the kind
         public static final int KIND_TYPED = 0; // What user typed
         public static final int KIND_CORRECTION = 1; // Simple correction/suggestion
         public static final int KIND_COMPLETION = 2; // Completion (suggestion with appended chars)
@@ -224,8 +223,6 @@ public class SuggestedWords {
         public static final int KIND_RESUMED = 9;
         public static final int KIND_OOV_CORRECTION = 10; // Most probable string correction
 
-        // TODO: Make KIND_MASK_FLAGS private.
-        public static final int KIND_MASK_FLAGS = 0xFFFFFF00; // Mask to get the flags
         public static final int KIND_FLAG_POSSIBLY_OFFENSIVE = 0x80000000;
         public static final int KIND_FLAG_EXACT_MATCH = 0x40000000;
         public static final int KIND_FLAG_EXACT_MATCH_WITH_INTENTIONAL_OMISSION = 0x20000000;
@@ -235,8 +232,7 @@ public class SuggestedWords {
         // the application (including keyboard-computed ones, so this is almost always null)
         public final CompletionInfo mApplicationSpecifiedCompletionInfo;
         public final int mScore;
-        // TODO: Rename to mKindAndFlags and make this private.
-        public final int mKind; // kind and kind flags
+        public final int mKindAndFlags;
         public final int mCodePointCount;
         public final Dictionary mSourceDict;
         // For auto-commit. This keeps track of the index inside the touch coordinates array
@@ -252,18 +248,19 @@ public class SuggestedWords {
          * Create a new suggested word info.
          * @param word The string to suggest.
          * @param score A measure of how likely this suggestion is.
-         * @param kind The kind of suggestion, as one of the above KIND_* constants with flags.
+         * @param kindAndFlags The kind of suggestion, as one of the above KIND_* constants with
+         * flags.
          * @param sourceDict What instance of Dictionary produced this suggestion.
          * @param indexOfTouchPointOfSecondWord See mIndexOfTouchPointOfSecondWord.
          * @param autoCommitFirstWordConfidence See mAutoCommitFirstWordConfidence.
          */
-        public SuggestedWordInfo(final String word, final int score, final int kind,
+        public SuggestedWordInfo(final String word, final int score, final int kindAndFlags,
                 final Dictionary sourceDict, final int indexOfTouchPointOfSecondWord,
                 final int autoCommitFirstWordConfidence) {
             mWord = word;
             mApplicationSpecifiedCompletionInfo = null;
             mScore = score;
-            mKind = kind;
+            mKindAndFlags = kindAndFlags;
             mSourceDict = sourceDict;
             mCodePointCount = StringUtils.codePointCount(mWord);
             mIndexOfTouchPointOfSecondWord = indexOfTouchPointOfSecondWord;
@@ -279,7 +276,7 @@ public class SuggestedWords {
             mWord = applicationSpecifiedCompletion.getText().toString();
             mApplicationSpecifiedCompletionInfo = applicationSpecifiedCompletion;
             mScore = SuggestedWordInfo.MAX_SCORE;
-            mKind = SuggestedWordInfo.KIND_APP_DEFINED;
+            mKindAndFlags = SuggestedWordInfo.KIND_APP_DEFINED;
             mSourceDict = Dictionary.DICTIONARY_APPLICATION_DEFINED;
             mCodePointCount = StringUtils.codePointCount(mWord);
             mIndexOfTouchPointOfSecondWord = SuggestedWordInfo.NOT_AN_INDEX;
@@ -290,11 +287,26 @@ public class SuggestedWords {
             return (isKindOf(KIND_CORRECTION) && NOT_AN_INDEX != mIndexOfTouchPointOfSecondWord);
         }
 
+        public int getKind() {
+            return (mKindAndFlags & KIND_MASK_KIND);
+        }
+
         public boolean isKindOf(final int kind) {
-            return (mKind & KIND_MASK_KIND) == kind;
+            return getKind() == kind;
+        }
+
+        public boolean isPossiblyOffensive() {
+            return (mKindAndFlags & SuggestedWordInfo.KIND_FLAG_POSSIBLY_OFFENSIVE) != 0;
         }
 
-        // TODO: Add predicate methods for each flag.
+        public boolean isExactMatch() {
+            return (mKindAndFlags & SuggestedWordInfo.KIND_FLAG_EXACT_MATCH) != 0;
+        }
+
+        public boolean isExactMatchWithIntentionalOmission() {
+            return (mKindAndFlags
+                    & SuggestedWordInfo.KIND_FLAG_EXACT_MATCH_WITH_INTENTIONAL_OMISSION) != 0;
+        }
 
         public void setDebugString(final String str) {
             if (null == str) throw new NullPointerException("Debug info is null");
@@ -375,7 +387,7 @@ public class SuggestedWords {
             final SuggestedWordInfo info = mSuggestedWordInfoList.get(i);
             final int indexOfLastSpace = info.mWord.lastIndexOf(Constants.CODE_SPACE) + 1;
             final String lastWord = info.mWord.substring(indexOfLastSpace);
-            newSuggestions.add(new SuggestedWordInfo(lastWord, info.mScore, info.mKind,
+            newSuggestions.add(new SuggestedWordInfo(lastWord, info.mScore, info.mKindAndFlags,
                     info.mSourceDict, SuggestedWordInfo.NOT_AN_INDEX,
                     SuggestedWordInfo.NOT_A_CONFIDENCE));
         }
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index 2318dae2dfb94737a8ff6e59e9ca7261f5b9a9ae..2b7024ad6e13b743ca1304804861d728295b08aa 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -289,7 +289,7 @@ public final class InputLogic {
         if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
             ResearchLogger.latinIME_pickSuggestionManually(replacedWord, index, suggestion,
                     mWordComposer.isBatchMode(), suggestionInfo.mScore,
-                    suggestionInfo.mKind, suggestionInfo.mSourceDict.mDictType);
+                    suggestionInfo.mKindAndFlags, suggestionInfo.mSourceDict.mDictType);
         }
         mConnection.endBatchEdit();
         // Don't allow cancellation of manual pick
@@ -301,8 +301,8 @@ public final class InputLogic {
         // We should show the "Touch again to save" hint if the user pressed the first entry
         // AND it's in none of our current dictionaries (main, user or otherwise).
         final boolean showingAddToDictionaryHint =
-                (SuggestedWordInfo.KIND_TYPED == suggestionInfo.mKind
-                        || SuggestedWordInfo.KIND_OOV_CORRECTION == suggestionInfo.mKind)
+                (suggestionInfo.isKindOf(SuggestedWordInfo.KIND_TYPED)
+                        || suggestionInfo.isKindOf(SuggestedWordInfo.KIND_OOV_CORRECTION))
                         && !mDictionaryFacilitator.isValidWord(suggestion, true /* ignoreCase */);
 
         if (settingsValues.mIsInternal) {
diff --git a/java/src/com/android/inputmethod/latin/utils/AutoCorrectionUtils.java b/java/src/com/android/inputmethod/latin/utils/AutoCorrectionUtils.java
index 857d0b0da7714b806f9a05ad611472e615ea97f7..34ee2152a7707a511f5c4df27dc17c936dbdf385 100644
--- a/java/src/com/android/inputmethod/latin/utils/AutoCorrectionUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/AutoCorrectionUtils.java
@@ -35,7 +35,9 @@ public final class AutoCorrectionUtils {
             final float autoCorrectionThreshold) {
         if (null != suggestion) {
             // Shortlist a whitelisted word
-            if (suggestion.mKind == SuggestedWordInfo.KIND_WHITELIST) return true;
+            if (suggestion.isKindOf(SuggestedWordInfo.KIND_WHITELIST)) {
+                return true;
+            }
             final int autoCorrectionSuggestionScore = suggestion.mScore;
             // TODO: when the normalized score of the first suggestion is nearly equals to
             //       the normalized score of the second suggestion, behave less aggressive.
diff --git a/java/src/com/android/inputmethod/latin/utils/DistracterFilterUsingSuggestion.java b/java/src/com/android/inputmethod/latin/utils/DistracterFilterUsingSuggestion.java
index ac0ab28bfc4adc4355209d6ee436903eca51fae2..b9c7f56710e174a6e5e065052d26ca27ca6f6b6d 100644
--- a/java/src/com/android/inputmethod/latin/utils/DistracterFilterUsingSuggestion.java
+++ b/java/src/com/android/inputmethod/latin/utils/DistracterFilterUsingSuggestion.java
@@ -108,10 +108,9 @@ public class DistracterFilterUsingSuggestion implements DistracterFilter {
                 continue;
             }
             // Exact match can include case errors, accent errors, digraph conversions.
-            final boolean isExactMatch =
-                    (suggestedWordInfo.mKind & SuggestedWordInfo.KIND_FLAG_EXACT_MATCH) != 0;
-            final boolean isExactMatchWithIntentionalOmission = (suggestedWordInfo.mKind
-                    & SuggestedWordInfo.KIND_FLAG_EXACT_MATCH_WITH_INTENTIONAL_OMISSION) != 0;
+            final boolean isExactMatch = suggestedWordInfo.isExactMatch();
+            final boolean isExactMatchWithIntentionalOmission =
+                    suggestedWordInfo.isExactMatchWithIntentionalOmission();
 
             if (DEBUG) {
                 final float normalizedScore = BinaryDictionaryUtils.calcNormalizedScore(
diff --git a/java/src/com/android/inputmethod/research/JsonUtils.java b/java/src/com/android/inputmethod/research/JsonUtils.java
index 6170b4339aa363ddfab912b4ee279b77cefdc969..63c08e8bb366ae695dd9d8f79191ea0d25310d89 100644
--- a/java/src/com/android/inputmethod/research/JsonUtils.java
+++ b/java/src/com/android/inputmethod/research/JsonUtils.java
@@ -102,7 +102,7 @@ import java.util.Map;
             jsonWriter.beginObject();
             jsonWriter.name("word").value(wordInfo.toString());
             jsonWriter.name("score").value(wordInfo.mScore);
-            jsonWriter.name("kind").value(wordInfo.mKind);
+            jsonWriter.name("kind").value(wordInfo.getKind());
             jsonWriter.name("sourceDict").value(wordInfo.mSourceDict.mDictType);
             jsonWriter.endObject();
         }
diff --git a/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java b/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java
index 330bedd6b87cadd6c5fa45de04f3175f0e885c48..66b4a9c71d111b5701fd9ebe414d7bda7a2cad7b 100644
--- a/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java
+++ b/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java
@@ -51,16 +51,16 @@ public class SuggestedWordsTests extends AndroidTestCase {
                 false /* isPrediction*/);
         assertEquals(NUMBER_OF_ADDED_SUGGESTIONS + 1, words.size());
         assertEquals("typed", words.getWord(0));
-        assertEquals(SuggestedWordInfo.KIND_TYPED, words.getInfo(0).mKind);
+        assertTrue(words.getInfo(0).isKindOf(SuggestedWordInfo.KIND_TYPED));
         assertEquals("0", words.getWord(1));
-        assertEquals(SuggestedWordInfo.KIND_CORRECTION, words.getInfo(1).mKind);
+        assertTrue(words.getInfo(1).isKindOf(SuggestedWordInfo.KIND_CORRECTION));
         assertEquals("4", words.getWord(5));
-        assertEquals(SuggestedWordInfo.KIND_CORRECTION, words.getInfo(5).mKind);
+        assertTrue(words.getInfo(5).isKindOf(SuggestedWordInfo.KIND_CORRECTION));
 
         final SuggestedWords wordsWithoutTyped = words.getSuggestedWordsExcludingTypedWord();
         assertEquals(words.size() - 1, wordsWithoutTyped.size());
         assertEquals("0", wordsWithoutTyped.getWord(0));
-        assertEquals(SuggestedWordInfo.KIND_CORRECTION, wordsWithoutTyped.getInfo(0).mKind);
+        assertTrue(wordsWithoutTyped.getInfo(0).isKindOf(SuggestedWordInfo.KIND_CORRECTION));
     }
 
     // Helper for testGetTransformedWordInfo