diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 5236591f66cf336c0172ee6a307f07b1a309350e..00d4dfe937f78a70af3e04c10c541cc305753abb 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1804,14 +1804,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
 
     @Override
     public void pickSuggestionManually(final int index, final CharSequence suggestion,
-            int x, int y) {
-        mConnection.beginBatchEdit(getCurrentInputConnection());
-        pickSuggestionManuallyWhileInBatchEdit(index, suggestion, x, y);
-        mConnection.endBatchEdit();
-    }
-
-    public void pickSuggestionManuallyWhileInBatchEdit(final int index,
-        final CharSequence suggestion, final int x, final int y) {
+            final int x, final int y) {
         final SuggestedWords suggestedWords = mSuggestionsView.getSuggestions();
         // If this is a punctuation picked from the suggestion strip, pass it to onCodeInput
         if (suggestion.length() == 1 && isShowingPunctuationList()) {
@@ -1846,7 +1839,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
             mKeyboardSwitcher.updateShiftState();
             resetComposingState(true /* alsoResetLastComposedWord */);
             final CompletionInfo completionInfo = mApplicationSpecifiedCompletions[index];
+            mConnection.beginBatchEdit(getCurrentInputConnection());
             mConnection.commitCompletion(completionInfo);
+            mConnection.endBatchEdit();
             if (ProductionFlag.IS_EXPERIMENTAL) {
                 ResearchLogger.latinIME_pickApplicationSpecifiedCompletion(index,
                         completionInfo.getText(), x, y);
diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java
index 227990acc640fe6129341d399d480cd9c4154db8..0c19bed0572be4f9164344cb0a84337b5ee44384 100644
--- a/java/src/com/android/inputmethod/latin/RichInputConnection.java
+++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java
@@ -65,66 +65,70 @@ public class RichInputConnection {
         if (--mNestLevel == 0 && null != mIC) mIC.endBatchEdit();
     }
 
+    private void checkBatchEdit() {
+        if (mNestLevel != 1) {
+            // TODO: exception instead
+            Log.e(TAG, "Batch edit level incorrect : " + mNestLevel);
+            Log.e(TAG, Utils.getStackTrace(4));
+        }
+    }
+
     public void finishComposingText() {
-        if (mNestLevel <= 0) Log.e(TAG, "Batch edit not in progress!"); // TODO: exception instead
+        checkBatchEdit();
         if (null != mIC) mIC.finishComposingText();
     }
 
     public void commitText(final CharSequence text, final int i) {
-        if (mNestLevel <= 0) Log.e(TAG, "Batch edit not in progress!"); // TODO: exception instead
+        checkBatchEdit();
         if (null != mIC) mIC.commitText(text, i);
     }
 
     public int getCursorCapsMode(final int inputType) {
-        if (mNestLevel <= 0) Log.e(TAG, "Batch edit not in progress!"); // TODO: exception instead
         if (null == mIC) return Constants.TextUtils.CAP_MODE_OFF;
         return mIC.getCursorCapsMode(inputType);
     }
 
     public CharSequence getTextBeforeCursor(final int i, final int j) {
-        if (mNestLevel <= 0) Log.e(TAG, "Batch edit not in progress!"); // TODO: exception instead
         if (null != mIC) return mIC.getTextBeforeCursor(i, j);
         return null;
     }
 
     public CharSequence getTextAfterCursor(final int i, final int j) {
-        if (mNestLevel <= 0) Log.e(TAG, "Batch edit not in progress!"); // TODO: exception instead
         if (null != mIC) return mIC.getTextAfterCursor(i, j);
         return null;
     }
 
     public void deleteSurroundingText(final int i, final int j) {
-        if (mNestLevel <= 0) Log.e(TAG, "Batch edit not in progress!"); // TODO: exception instead
+        checkBatchEdit();
         if (null != mIC) mIC.deleteSurroundingText(i, j);
     }
 
     public void performEditorAction(final int actionId) {
-        if (mNestLevel <= 0) Log.e(TAG, "Batch edit not in progress!"); // TODO: exception instead
         if (null != mIC) mIC.performEditorAction(actionId);
     }
 
     public void sendKeyEvent(final KeyEvent keyEvent) {
-        if (mNestLevel <= 0) Log.e(TAG, "Batch edit not in progress!"); // TODO: exception instead
+        checkBatchEdit();
         if (null != mIC) mIC.sendKeyEvent(keyEvent);
     }
 
     public void setComposingText(final CharSequence text, final int i) {
-        if (mNestLevel <= 0) Log.e(TAG, "Batch edit not in progress!"); // TODO: exception instead
+        checkBatchEdit();
         if (null != mIC) mIC.setComposingText(text, i);
     }
 
     public void setSelection(final int from, final int to) {
-        if (mNestLevel <= 0) Log.e(TAG, "Batch edit not in progress!"); // TODO: exception instead
+        checkBatchEdit();
         if (null != mIC) mIC.setSelection(from, to);
     }
 
     public void commitCorrection(final CorrectionInfo correctionInfo) {
-        if (mNestLevel <= 0) Log.e(TAG, "Batch edit not in progress!"); // TODO: exception instead
+        checkBatchEdit();
         if (null != mIC) mIC.commitCorrection(correctionInfo);
     }
 
     public void commitCompletion(final CompletionInfo completionInfo) {
-        if (mNestLevel <= 0) Log.e(TAG, "Batch edit not in progress!"); // TODO: exception instead
+        checkBatchEdit();
         if (null != mIC) mIC.commitCompletion(completionInfo);
     }
 
@@ -316,6 +320,7 @@ public class RichInputConnection {
     }
 
     public void removeTrailingSpace() {
+        checkBatchEdit();
         final CharSequence lastOne = getTextBeforeCursor(1, 0);
         if (lastOne != null && lastOne.length() == 1
                 && lastOne.charAt(0) == Keyboard.CODE_SPACE) {
@@ -372,6 +377,7 @@ public class RichInputConnection {
     }
 
     public boolean revertDoubleSpace() {
+        checkBatchEdit();
         // Here we test whether we indeed have a period and a space before us. This should not
         // be needed, but it's there just in case something went wrong.
         final CharSequence textBeforeCursor = getTextBeforeCursor(2, 0);
@@ -395,6 +401,7 @@ public class RichInputConnection {
     }
 
     public boolean revertSwapPunctuation() {
+        checkBatchEdit();
         // Here we test whether we indeed have a space and something else before us. This should not
         // be needed, but it's there just in case something went wrong.
         final CharSequence textBeforeCursor = getTextBeforeCursor(2, 0);
diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java
index 903b5a3578b883c184da260508301a71274cb91e..f2d21ab9b19d9ccb983059581b92cf487c8833eb 100644
--- a/java/src/com/android/inputmethod/latin/Utils.java
+++ b/java/src/com/android/inputmethod/latin/Utils.java
@@ -204,18 +204,24 @@ public class Utils {
     }
 
     // Get the current stack trace
-    public static String getStackTrace() {
+    public static String getStackTrace(final int limit) {
         StringBuilder sb = new StringBuilder();
         try {
             throw new RuntimeException();
         } catch (RuntimeException e) {
             StackTraceElement[] frames = e.getStackTrace();
             // Start at 1 because the first frame is here and we don't care about it
-            for (int j = 1; j < frames.length; ++j) sb.append(frames[j].toString() + "\n");
+            for (int j = 1; j < frames.length && j < limit + 1; ++j) {
+                sb.append(frames[j].toString() + "\n");
+            }
         }
         return sb.toString();
     }
 
+    public static String getStackTrace() {
+        return getStackTrace(Integer.MAX_VALUE);
+    }
+
     public static class UsabilityStudyLogUtils {
         // TODO: remove code duplication with ResearchLog class
         private static final String USABILITY_TAG = UsabilityStudyLogUtils.class.getSimpleName();