diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index ae9c1df38eaf537216ad0e88274dc022f6f57721..e72aa55edef61c29c29cc1a5afc1e020575c4c72 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1152,6 +1152,9 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
         if (typedWord.length() > 0) {
             commitChosenWord(typedWord, LastComposedWord.COMMIT_TYPE_USER_TYPED_WORD,
                     separatorString);
+            if (ProductionFlag.IS_EXPERIMENTAL) {
+                ResearchLogger.getInstance().onWordComplete(typedWord, Long.MAX_VALUE);
+            }
         }
     }
 
@@ -1187,8 +1190,10 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
         if (lastTwo != null && lastTwo.length() == 2
                 && lastTwo.charAt(0) == Constants.CODE_SPACE) {
             mConnection.deleteSurroundingText(2, 0);
-            mConnection.commitText(lastTwo.charAt(1) + " ", 1);
+            final String text = lastTwo.charAt(1) + " ";
+            mConnection.commitText(text, 1);
             if (ProductionFlag.IS_EXPERIMENTAL) {
+                ResearchLogger.getInstance().onWordComplete(text, Long.MAX_VALUE);
                 ResearchLogger.latinIME_swapSwapperAndSpace();
             }
             mKeyboardSwitcher.updateShiftState();
@@ -1206,7 +1211,11 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
                 && lastThree.charAt(2) == Constants.CODE_SPACE) {
             mHandler.cancelDoubleSpacePeriodTimer();
             mConnection.deleteSurroundingText(2, 0);
-            mConnection.commitText(". ", 1);
+            final String textToInsert = ". ";
+            mConnection.commitText(textToInsert, 1);
+            if (ProductionFlag.IS_EXPERIMENTAL) {
+                ResearchLogger.getInstance().onWordComplete(textToInsert, Long.MAX_VALUE);
+            }
             mKeyboardSwitcher.updateShiftState();
             return true;
         }
@@ -1455,6 +1464,9 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
             promotePhantomSpace();
         }
         mConnection.commitText(text, 1);
+        if (ProductionFlag.IS_EXPERIMENTAL) {
+            ResearchLogger.getInstance().onWordComplete(text, Long.MAX_VALUE);
+        }
         mConnection.endBatchEdit();
         // Space state must be updated before calling updateShiftState
         mSpaceState = SPACE_STATE_NONE;
@@ -1925,6 +1937,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
     }
 
     private void handleClose() {
+        // TODO: Verify that words are logged properly when IME is closed.
         commitTyped(LastComposedWord.NOT_A_SEPARATOR);
         requestHideSelf(0);
         final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
@@ -2125,7 +2138,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
         if (suggestion.length() == 1 && isShowingPunctuationList()) {
             // Word separators are suggested before the user inputs something.
             // So, LatinImeLogger logs "" as a user's input.
-            LatinImeLogger.logOnManualSuggestion("", suggestion.toString(), index, suggestedWords);
+            LatinImeLogger.logOnManualSuggestion("", suggestion, index, suggestedWords);
             // Rely on onCodeInput to do the complicated swapping/stripping logic consistently.
             final int primaryCode = suggestion.charAt(0);
             onCodeInput(primaryCode,
@@ -2165,8 +2178,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
         // We need to log before we commit, because the word composer will store away the user
         // typed word.
         final String replacedWord = mWordComposer.getTypedWord().toString();
-        LatinImeLogger.logOnManualSuggestion(replacedWord,
-                suggestion.toString(), index, suggestedWords);
+        LatinImeLogger.logOnManualSuggestion(replacedWord, suggestion, index, suggestedWords);
         mExpectingUpdateSelection = true;
         commitChosenWord(suggestion, LastComposedWord.COMMIT_TYPE_MANUAL_PICK,
                 LastComposedWord.NOT_A_SEPARATOR);
@@ -2303,8 +2315,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
         }
         mConnection.deleteSurroundingText(deleteLength, 0);
         if (!TextUtils.isEmpty(previousWord) && !TextUtils.isEmpty(committedWord)) {
-            mUserHistoryDictionary.cancelAddingUserHistory(
-                    previousWord.toString(), committedWord.toString());
+            mUserHistoryDictionary.cancelAddingUserHistory(previousWord, committedWord);
         }
         mConnection.commitText(originallyTypedWord + mLastComposedWord.mSeparatorString, 1);
         if (ProductionFlag.IS_INTERNAL) {
@@ -2312,7 +2323,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
                     Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE);
         }
         if (ProductionFlag.IS_EXPERIMENTAL) {
-            ResearchLogger.latinIME_revertCommit(originallyTypedWord);
+            ResearchLogger.latinIME_revertCommit(committedWord, originallyTypedWord);
+            ResearchLogger.getInstance().onWordComplete(originallyTypedWord, Long.MAX_VALUE);
         }
         // Don't restart suggestion yet. We'll restart if the user deletes the
         // separator.
diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java
index e9c81dab0887dbb32d25421239847a2252fc260f..fe4a257657b42027ebfd9e4cac8d418db88ac1a3 100644
--- a/java/src/com/android/inputmethod/latin/RichInputConnection.java
+++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java
@@ -178,9 +178,6 @@ public final class RichInputConnection {
         mComposingText.setLength(0);
         if (null != mIC) {
             mIC.commitText(text, i);
-            if (ProductionFlag.IS_EXPERIMENTAL) {
-                ResearchLogger.richInputConnection_commitText(text, i);
-            }
         }
     }
 
@@ -665,7 +662,11 @@ public final class RichInputConnection {
             return false;
         }
         deleteSurroundingText(2, 0);
-        commitText("  ", 1);
+        final String doubleSpace = "  ";
+        commitText(doubleSpace, 1);
+        if (ProductionFlag.IS_EXPERIMENTAL) {
+            ResearchLogger.getInstance().onWordComplete(doubleSpace, Long.MAX_VALUE);
+        }
         return true;
     }
 
@@ -686,7 +687,11 @@ public final class RichInputConnection {
             return false;
         }
         deleteSurroundingText(2, 0);
-        commitText(" " + textBeforeCursor.subSequence(0, 1), 1);
+        final String text = " " + textBeforeCursor.subSequence(0, 1);
+        commitText(text, 1);
+        if (ProductionFlag.IS_EXPERIMENTAL) {
+            ResearchLogger.getInstance().onWordComplete(text, Long.MAX_VALUE);
+        }
         return true;
     }
 
diff --git a/java/src/com/android/inputmethod/research/ResearchLogger.java b/java/src/com/android/inputmethod/research/ResearchLogger.java
index ec3d4eda460f46d80447784fa837fafaeeb3c1e9..cde100a5f92e1909fd321415c885deab75389213 100644
--- a/java/src/com/android/inputmethod/research/ResearchLogger.java
+++ b/java/src/com/android/inputmethod/research/ResearchLogger.java
@@ -741,7 +741,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
 
     private static final LogStatement LOGSTATEMENT_COMMIT_RECORD_SPLIT_WORDS =
             new LogStatement("recordSplitWords", true, false);
-    private void onWordComplete(final String word, final long maxTime, final boolean isSplitWords) {
+    public void onWordComplete(final String word, final long maxTime) {
         final Dictionary dictionary = getDictionary();
         if (word != null && word.length() > 0 && hasLetters(word)) {
             mCurrentLogUnit.setWord(word);
@@ -751,11 +751,6 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
         }
         final LogUnit newLogUnit = mCurrentLogUnit.splitByTime(maxTime);
         enqueueCommitText(word);
-        if (isSplitWords) {
-            enqueueEvent(LOGSTATEMENT_COMMIT_RECORD_SPLIT_WORDS);
-            enqueueCommitText(" ");
-            mStatistics.recordSplitWords();
-        }
         commitCurrentLogUnit();
         mCurrentLogUnit = newLogUnit;
     }
@@ -1049,12 +1044,15 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
             new LogStatement("LatinIMEPickSuggestionManually", true, false, "replacedWord", "index",
                     "suggestion", "x", "y");
     public static void latinIME_pickSuggestionManually(final String replacedWord,
-            final int index, CharSequence suggestion) {
+            final int index, final String suggestion) {
+        final String scrubbedWord = scrubDigitsFromString(suggestion);
         final ResearchLogger researchLogger = getInstance();
         researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_PICKSUGGESTIONMANUALLY,
                 scrubDigitsFromString(replacedWord), index,
-                suggestion == null ? null : scrubDigitsFromString(suggestion.toString()),
-                Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE);
+                suggestion == null ? null : scrubbedWord, Constants.SUGGESTION_STRIP_COORDINATE,
+                Constants.SUGGESTION_STRIP_COORDINATE);
+        researchLogger.onWordComplete(scrubbedWord, Long.MAX_VALUE);
+        researchLogger.mStatistics.recordManualSuggestion();
     }
 
     /**
@@ -1065,10 +1063,11 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
     private static final LogStatement LOGSTATEMENT_LATINIME_PUNCTUATIONSUGGESTION =
             new LogStatement("LatinIMEPunctuationSuggestion", false, false, "index", "suggestion",
                     "x", "y");
-    public static void latinIME_punctuationSuggestion(final int index,
-            final CharSequence suggestion) {
-        getInstance().enqueueEvent(LOGSTATEMENT_LATINIME_PUNCTUATIONSUGGESTION, index, suggestion,
+    public static void latinIME_punctuationSuggestion(final int index, final String suggestion) {
+        final ResearchLogger researchLogger = getInstance();
+        researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_PUNCTUATIONSUGGESTION, index, suggestion,
                 Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE);
+        researchLogger.onWordComplete(suggestion, Long.MAX_VALUE);
     }
 
     /**
@@ -1147,9 +1146,14 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
      * backspace.
      */
     private static final LogStatement LOGSTATEMENT_LATINIME_REVERTCOMMIT =
-            new LogStatement("LatinIMERevertCommit", true, false, "originallyTypedWord");
-    public static void latinIME_revertCommit(final String originallyTypedWord) {
-        getInstance().enqueueEvent(LOGSTATEMENT_LATINIME_REVERTCOMMIT, originallyTypedWord);
+            new LogStatement("LatinIMERevertCommit", true, false, "committedWord",
+                    "originallyTypedWord");
+    public static void latinIME_revertCommit(final String committedWord,
+            final String originallyTypedWord) {
+        final ResearchLogger researchLogger = getInstance();
+        researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_REVERTCOMMIT, committedWord,
+                originallyTypedWord);
+        researchLogger.mStatistics.recordRevertCommit();
     }
 
     /**
@@ -1259,17 +1263,27 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
         final ResearchLogger researchLogger = getInstance();
         researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_COMMITCURRENTAUTOCORRECTION,
                 scrubbedTypedWord, scrubbedAutoCorrection, separatorString);
-        researchLogger.onWordComplete(scrubbedAutoCorrection, Long.MAX_VALUE,
-                false /* isPartial */);
+        researchLogger.onWordComplete(scrubbedAutoCorrection, Long.MAX_VALUE);
     }
 
     private boolean isExpectingCommitText = false;
+    /**
+     * Log a call to RichInputConnection.commitPartialText
+     *
+     * SystemResponse: The IME is committing part of a word.  This happens if a space is
+     * automatically inserted to split a single typed string into two or more words.
+     */
+    // TODO: This method is currently unused.  Find where it should be called from in the IME and
+    // add invocations.
+    private static final LogStatement LOGSTATEMENT_LATINIME_COMMIT_PARTIAL_TEXT =
+            new LogStatement("LatinIMECommitPartialText", true, false, "newCursorPosition");
     public static void latinIME_commitPartialText(final CharSequence committedWord,
             final long lastTimestampOfWordData) {
         final ResearchLogger researchLogger = getInstance();
         final String scrubbedWord = scrubDigitsFromString(committedWord.toString());
-        researchLogger.onWordComplete(scrubbedWord, lastTimestampOfWordData, true /* isPartial */);
-        researchLogger.isExpectingCommitText = true;
+        researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_COMMIT_PARTIAL_TEXT);
+        researchLogger.onWordComplete(scrubbedWord, lastTimestampOfWordData);
+        researchLogger.mStatistics.recordSplitWords();
     }
 
     /**
@@ -1287,7 +1301,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
         if (!researchLogger.isExpectingCommitText) {
             researchLogger.enqueueEvent(LOGSTATEMENT_RICHINPUTCONNECTIONCOMMITTEXT,
                     newCursorPosition);
-            researchLogger.onWordComplete(scrubbedWord, Long.MAX_VALUE, false /* isPartial */);
+            researchLogger.onWordComplete(scrubbedWord, Long.MAX_VALUE);
         }
         researchLogger.isExpectingCommitText = false;
     }
@@ -1465,7 +1479,8 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
                     "isEmptinessStateKnown", "averageTimeBetweenKeys", "averageTimeBeforeDelete",
                     "averageTimeDuringRepeatedDelete", "averageTimeAfterDelete",
                     "dictionaryWordCount", "splitWordsCount", "gestureInputCount",
-                    "gestureCharsCount", "gesturesDeletedCount");
+                    "gestureCharsCount", "gesturesDeletedCount", "manualSuggestionsCount",
+                    "revertCommitsCount");
     private static void logStatistics() {
         final ResearchLogger researchLogger = getInstance();
         final Statistics statistics = researchLogger.mStatistics;
@@ -1477,8 +1492,8 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
                 statistics.mDuringRepeatedDeleteKeysCounter.getAverageTime(),
                 statistics.mAfterDeleteKeyCounter.getAverageTime(),
                 statistics.mDictionaryWordCount, statistics.mSplitWordsCount,
-                statistics.mGesturesInputCount,
-                statistics.mGesturesCharsCount,
-                statistics.mGesturesDeletedCount);
+                statistics.mGesturesInputCount, statistics.mGesturesCharsCount,
+                statistics.mGesturesDeletedCount, statistics.mManualSuggestionsCount,
+                statistics.mRevertCommitsCount);
     }
 }
diff --git a/java/src/com/android/inputmethod/research/Statistics.java b/java/src/com/android/inputmethod/research/Statistics.java
index a02aabf3cdbe6601c709a49bf36df225c0dc4b2b..e9c02c919ff0f944dc820a8ecc0346cf88c563a0 100644
--- a/java/src/com/android/inputmethod/research/Statistics.java
+++ b/java/src/com/android/inputmethod/research/Statistics.java
@@ -47,6 +47,10 @@ public class Statistics {
     int mGesturesDeletedCount;
     // Total number of characters in words entered by gesture.
     int mGesturesCharsCount;
+    // Number of manual suggestions chosen.
+    int mManualSuggestionsCount;
+    // Number of times a commit was reverted in this session.
+    int mRevertCommitsCount;
     // Whether the text field was empty upon editing
     boolean mIsEmptyUponStarting;
     boolean mIsEmptinessStateKnown;
@@ -111,6 +115,8 @@ public class Statistics {
         mSplitWordsCount = 0;
         mGesturesInputCount = 0;
         mGesturesDeletedCount = 0;
+        mManualSuggestionsCount = 0;
+        mRevertCommitsCount = 0;
         mIsEmptyUponStarting = true;
         mIsEmptinessStateKnown = false;
         mKeyCounter.reset();
@@ -184,4 +190,11 @@ public class Statistics {
     public void recordGestureDelete() {
         mGesturesDeletedCount++;
     }
+    public void recordManualSuggestion() {
+        mManualSuggestionsCount++;
+    }
+
+    public void recordRevertCommit() {
+        mRevertCommitsCount++;
+    }
 }