diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index d02c4df7e99e4558970570e9279afec0987a89ac..4f8852b87fb266aca5e3f2fa62ba4b03d1e3ee8d 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -773,7 +773,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
         // to the user dictionary.
         if (null != mPositionalInfoForUserDictPendingAddition
                 && mPositionalInfoForUserDictPendingAddition.tryReplaceWithActualWord(
-                        mConnection, editorInfo, mLastSelectionEnd)) {
+                        mConnection, editorInfo, mLastSelectionEnd,
+                        mSubtypeSwitcher.getCurrentSubtypeLocale())) {
             mPositionalInfoForUserDictPendingAddition = null;
         }
         // If tryReplaceWithActualWord returns false, we don't know what word was
@@ -1223,11 +1224,17 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
             mPositionalInfoForUserDictPendingAddition = null;
             return;
         }
+        final String wordToEdit;
+        if (StringUtils.isAutoCapsMode(mLastComposedWord.mCapitalizedMode)) {
+            wordToEdit = word.toLowerCase(mSubtypeSwitcher.getCurrentSubtypeLocale());
+        } else {
+            wordToEdit = word;
+        }
         mPositionalInfoForUserDictPendingAddition =
                 new PositionalInfoForUserDictPendingAddition(
-                        word, mLastSelectionEnd, getCurrentInputEditorInfo(),
+                        wordToEdit, mLastSelectionEnd, getCurrentInputEditorInfo(),
                         mLastComposedWord.mCapitalizedMode);
-        mUserDictionary.addWordToUserDictionary(word, 128);
+        mUserDictionary.addWordToUserDictionary(wordToEdit);
     }
 
     public void onWordAddedToUserDictionary(final String newSpelling) {
@@ -1240,7 +1247,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
         }
         mPositionalInfoForUserDictPendingAddition.setActualWordBeingAdded(newSpelling);
         if (mPositionalInfoForUserDictPendingAddition.tryReplaceWithActualWord(
-                mConnection, getCurrentInputEditorInfo(), mLastSelectionEnd)) {
+                mConnection, getCurrentInputEditorInfo(), mLastSelectionEnd,
+                mSubtypeSwitcher.getCurrentSubtypeLocale())) {
             mPositionalInfoForUserDictPendingAddition = null;
         }
     }
diff --git a/java/src/com/android/inputmethod/latin/PositionalInfoForUserDictPendingAddition.java b/java/src/com/android/inputmethod/latin/PositionalInfoForUserDictPendingAddition.java
index a33cefcd6fb73464f9cb936451a06a3eba0be6c1..8493ef66979ed6422c7db79acd27e5409cf8dc63 100644
--- a/java/src/com/android/inputmethod/latin/PositionalInfoForUserDictPendingAddition.java
+++ b/java/src/com/android/inputmethod/latin/PositionalInfoForUserDictPendingAddition.java
@@ -18,6 +18,8 @@ package com.android.inputmethod.latin;
 
 import android.view.inputmethod.EditorInfo;
 
+import java.util.Locale;
+
 /**
  * Holder class for data about a word already committed but that may still be edited.
  *
@@ -70,10 +72,11 @@ public final class PositionalInfoForUserDictPendingAddition {
      * @param connection The RichInputConnection through which to contact the editor.
      * @param editorInfo Information pertaining to the editor we are currently in.
      * @param currentCursorPosition The current cursor position, for checking purposes.
+     * @param locale The locale for changing case, if necessary
      * @return true if the edit has been successfully made, false if we need to try again later
      */
     public boolean tryReplaceWithActualWord(final RichInputConnection connection,
-            final EditorInfo editorInfo, final int currentCursorPosition) {
+            final EditorInfo editorInfo, final int currentCursorPosition, final Locale locale) {
         // If we still don't know the actual word being added, we need to try again later.
         if (null == mActualWordBeingAdded) return false;
         // The entered text and the registered text were the same anyway : we can
@@ -92,9 +95,12 @@ public final class PositionalInfoForUserDictPendingAddition {
         // so that it won't be tried again
         if (currentCursorPosition != mCursorPos) return true;
         // We have made all the checks : do the replacement and report success
+        // If this was auto-capitalized, we need to restore the case before committing
+        final String wordWithCaseFixed = StringUtils.applyAutoCapsMode(mActualWordBeingAdded,
+                mCapitalizedMode, locale);
         connection.setComposingRegion(currentCursorPosition - mOriginalWord.length(),
                 currentCursorPosition);
-        connection.commitText(mActualWordBeingAdded, mActualWordBeingAdded.length());
+        connection.commitText(wordWithCaseFixed, wordWithCaseFixed.length());
         return true;
     }
 }
diff --git a/java/src/com/android/inputmethod/latin/StringUtils.java b/java/src/com/android/inputmethod/latin/StringUtils.java
index ddaa5ff5b5e57fa4362face30c4b34be9f882d5c..d00edbe92b60885727afa3ef02af4614b661b483 100644
--- a/java/src/com/android/inputmethod/latin/StringUtils.java
+++ b/java/src/com/android/inputmethod/latin/StringUtils.java
@@ -103,6 +103,37 @@ public final class StringUtils {
         }
     }
 
+    /**
+     * Apply an auto-caps mode to a string.
+     *
+     * This intentionally does NOT apply manual caps mode. It only changes the capitalization if
+     * the mode is one of the auto-caps modes.
+     * @param s The string to capitalize.
+     * @param capitalizeMode The mode in which to capitalize.
+     * @param locale The locale for capitalizing.
+     * @return The capitalized string.
+     */
+    public static String applyAutoCapsMode(final String s, final int capitalizeMode,
+            final Locale locale) {
+        if (WordComposer.CAPS_MODE_AUTO_SHIFT_LOCKED == capitalizeMode) {
+            return s.toUpperCase(locale);
+        } else if (WordComposer.CAPS_MODE_AUTO_SHIFTED == capitalizeMode) {
+            return toTitleCase(s, locale);
+        } else {
+            return s;
+        }
+    }
+
+    /**
+     * Return whether a constant represents an auto-caps mode (either auto-shift or auto-shift-lock)
+     * @param mode The mode to test for
+     * @return true if this represents an auto-caps mode, false otherwise
+     */
+    public static boolean isAutoCapsMode(final int mode) {
+        return WordComposer.CAPS_MODE_AUTO_SHIFTED == mode
+                || WordComposer.CAPS_MODE_AUTO_SHIFT_LOCKED == mode;
+    }
+
     public static String toTitleCase(final String s, final Locale locale) {
         if (s.length() <= 1) {
             // TODO: is this really correct? Shouldn't this be s.toUpperCase()?
diff --git a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
index a167849853a02225e72d4ed48b15e56b5e4e8b3c..0d5bde6233e44ae2f094e129f95cec57d7a15cd7 100644
--- a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
@@ -216,17 +216,13 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
      *
      * @param word the word to add. If the word is capitalized, then the dictionary will
      * recognize it as a capitalized word when searched.
-     * @param frequency the frequency of occurrence of the word. A frequency of 255 is considered
-     * the highest.
-     * @TODO use a higher or float range for frequency
      */
-    public synchronized void addWordToUserDictionary(final String word, final int frequency) {
+    public synchronized void addWordToUserDictionary(final String word) {
         // TODO: do something for the UI. With the following, any sufficiently long word will
         // look like it will go to the user dictionary but it won't.
         // Safeguard against adding long words. Can cause stack overflow.
         if (word.length() >= MAX_WORD_LENGTH) return;
 
-        // TODO: Add an argument to the intent to specify the frequency.
         Intent intent = new Intent(ACTION_USER_DICTIONARY_INSERT);
         intent.putExtra(Words.WORD, word);
         intent.putExtra(Words.LOCALE, mLocale);