Merge "Create "src/utils" directory"
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index c9a42a3..70f8d0d 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1797,8 +1797,6 @@
                     if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
                         final String word = mWordComposer.getTypedWord();
                         ResearchLogger.latinIME_handleBackspace_batch(word, 1);
-                        ResearchLogger.getInstance().uncommitCurrentLogUnit(
-                                word, false /* dumpCurrentLogUnit */);
                     }
                     final String rejectedSuggestion = mWordComposer.getTypedWord();
                     mWordComposer.reset();
@@ -1825,6 +1823,9 @@
                 // like the smiley key or the .com key.
                 final int length = mEnteredText.length();
                 mConnection.deleteSurroundingText(length, 0);
+                if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
+                    ResearchLogger.latinIME_handleBackspace_cancelTextInput(mEnteredText);
+                }
                 mEnteredText = null;
                 // If we have mEnteredText, then we know that mHasUncommittedTypedChars == false.
                 // In addition we know that spaceState is false, and that we should not be
@@ -1858,7 +1859,8 @@
                 mLastSelectionEnd = mLastSelectionStart;
                 mConnection.deleteSurroundingText(numCharsDeleted, 0);
                 if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
-                    ResearchLogger.latinIME_handleBackspace(numCharsDeleted);
+                    ResearchLogger.latinIME_handleBackspace(numCharsDeleted,
+                            false /* shouldUncommitLogUnit */);
                 }
             } else {
                 // There is no selection, just delete one character.
@@ -1876,12 +1878,13 @@
                     mConnection.deleteSurroundingText(1, 0);
                 }
                 if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
-                    ResearchLogger.latinIME_handleBackspace(1);
+                    ResearchLogger.latinIME_handleBackspace(1, true /* shouldUncommitLogUnit */);
                 }
                 if (mDeleteCount > DELETE_ACCELERATE_AT) {
                     mConnection.deleteSurroundingText(1, 0);
                     if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
-                        ResearchLogger.latinIME_handleBackspace(1);
+                        ResearchLogger.latinIME_handleBackspace(1,
+                                true /* shouldUncommitLogUnit */);
                     }
                 }
             }
diff --git a/java/src/com/android/inputmethod/research/ResearchLogger.java b/java/src/com/android/inputmethod/research/ResearchLogger.java
index 56ab90c..39236da 100644
--- a/java/src/com/android/inputmethod/research/ResearchLogger.java
+++ b/java/src/com/android/inputmethod/research/ResearchLogger.java
@@ -863,7 +863,10 @@
         // Check that expected word matches.
         if (oldLogUnit != null) {
             final String oldLogUnitWords = oldLogUnit.getWordsAsString();
-            if (oldLogUnitWords != null && !oldLogUnitWords.equals(expectedWord)) {
+            // Because the word is stored in the LogUnit with digits scrubbed, the comparison must
+            // be made on a scrubbed version of the expectedWord as well.
+            if (oldLogUnitWords != null && !oldLogUnitWords.equals(
+                    scrubDigitsFromString(expectedWord))) {
                 return;
             }
         }
@@ -1274,6 +1277,16 @@
     }
 
     /**
+     * Log a revert of onTextInput() (known in the IME as "EnteredText").
+     *
+     * SystemResponse: Remove the LogUnit recording the textInput
+     */
+    public static void latinIME_handleBackspace_cancelTextInput(final String text) {
+        final ResearchLogger researchLogger = getInstance();
+        researchLogger.uncommitCurrentLogUnit(text, true /* dumpCurrentLogUnit */);
+    }
+
+    /**
      * Log a call to LatinIME.pickSuggestionManually().
      *
      * UserAction: The user has chosen a specific word from the suggestion strip.
@@ -1806,17 +1819,26 @@
                 SystemClock.uptimeMillis());
     }
 
+    private static final LogStatement LOGSTATEMENT_LATINIME_HANDLEBACKSPACE =
+            new LogStatement("LatinIMEHandleBackspace", true, false, "numCharacters");
     /**
      * Log a call to LatinIME.handleBackspace() that is not a batch delete.
      *
      * UserInput: The user is deleting one or more characters by hitting the backspace key once.
      * The covers single character deletes as well as deleting selections.
+     *
+     * @param numCharacters how many characters the backspace operation deleted
+     * @param shouldUncommitLogUnit whether to uncommit the last {@code LogUnit} in the
+     * {@code LogBuffer}
      */
-    private static final LogStatement LOGSTATEMENT_LATINIME_HANDLEBACKSPACE =
-            new LogStatement("LatinIMEHandleBackspace", true, false, "numCharacters");
-    public static void latinIME_handleBackspace(final int numCharacters) {
+    public static void latinIME_handleBackspace(final int numCharacters,
+            final boolean shouldUncommitLogUnit) {
         final ResearchLogger researchLogger = getInstance();
         researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_HANDLEBACKSPACE, numCharacters);
+        if (shouldUncommitLogUnit) {
+            ResearchLogger.getInstance().uncommitCurrentLogUnit(
+                    null, true /* dumpCurrentLogUnit */);
+        }
     }
 
     /**
@@ -1834,6 +1856,8 @@
                 numCharacters);
         researchLogger.mStatistics.recordGestureDelete(deletedText.length(),
                 SystemClock.uptimeMillis());
+        researchLogger.uncommitCurrentLogUnit(deletedText.toString(),
+                false /* dumpCurrentLogUnit */);
     }
 
     /**