diff --git a/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java b/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java
index ebf2f4e608fc84716f4fb1549266f65d6379f338..86dbf1f60b32867474a44d55ee034c5115b935af 100644
--- a/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java
@@ -23,9 +23,9 @@ import android.preference.PreferenceManager;
 import android.view.InflateException;
 
 import java.lang.ref.SoftReference;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Locale;
-import java.util.Map;
 
 public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceChangeListener {
 
@@ -105,7 +105,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
     private KeyboardId mSymbolsShiftedId;
 
     private KeyboardId mCurrentId;
-    private final Map<KeyboardId, SoftReference<LatinKeyboard>> mKeyboards;
+    private final HashMap<KeyboardId, SoftReference<LatinKeyboard>> mKeyboards;
 
     private int mMode = MODE_NONE; /** One of the MODE_XXX values */
     private int mImeOptions;
@@ -194,11 +194,17 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
         public final boolean mEnableShiftLock;
         public final boolean mHasVoice;
 
+        private final int mHashCode;
+
         public KeyboardId(int xml, int mode, boolean enableShiftLock, boolean hasVoice) {
             this.mXml = xml;
             this.mKeyboardMode = mode;
             this.mEnableShiftLock = enableShiftLock;
             this.mHasVoice = hasVoice;
+
+            this.mHashCode = Arrays.hashCode(new Object[] {
+               xml, mode, enableShiftLock, hasVoice
+            });
         }
 
         public KeyboardId(int xml, boolean hasVoice) {
@@ -219,8 +225,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
 
         @Override
         public int hashCode() {
-            return (mXml + 1) * (mKeyboardMode + 1) * (mEnableShiftLock ? 2 : 1)
-                    * (mHasVoice ? 4 : 8);
+            return mHashCode;
         }
     }
 
@@ -378,7 +383,9 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
     }
 
     public void toggleShift() {
-        if (mCurrentId.equals(mSymbolsId)) {
+        if (isAlphabetMode())
+            return;
+        if (mCurrentId.equals(mSymbolsId) || !mCurrentId.equals(mSymbolsShiftedId)) {
             LatinKeyboard symbolsShiftedKeyboard = getKeyboard(mSymbolsShiftedId);
             mCurrentId = mSymbolsShiftedId;
             mInputView.setKeyboard(symbolsShiftedKeyboard);
@@ -390,7 +397,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
             symbolsShiftedKeyboard.setShiftLocked(true);
             symbolsShiftedKeyboard.setImeOptions(mInputMethodService.getResources(),
                     mMode, mImeOptions);
-        } else if (mCurrentId.equals(mSymbolsShiftedId)) {
+        } else {
             LatinKeyboard symbolsKeyboard = getKeyboard(mSymbolsId);
             mCurrentId = mSymbolsId;
             mInputView.setKeyboard(symbolsKeyboard);
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 1aa85d9cde387c1b852eb52c38fa2a14bb76e2d0..bd2459e6133c06165215c19550720cf22817d492 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -159,7 +159,7 @@ public class LatinIME extends InputMethodService
     private AlertDialog mOptionsDialog;
     private AlertDialog mVoiceWarningDialog;
 
-    KeyboardSwitcher mKeyboardSwitcher;
+    /* package */ KeyboardSwitcher mKeyboardSwitcher;
 
     private UserDictionary mUserDictionary;
     private UserBigramDictionary mUserBigramDictionary;
@@ -168,7 +168,7 @@ public class LatinIME extends InputMethodService
 
     private Hints mHints;
 
-    Resources mResources;
+    private Resources mResources;
 
     private String mInputLocale;
     private String mSystemLocale;
@@ -306,7 +306,7 @@ public class LatinIME extends InputMethodService
         }
     }
 
-    Handler mHandler = new Handler() {
+    /* package */ Handler mHandler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
@@ -338,7 +338,8 @@ public class LatinIME extends InputMethodService
         }
     };
 
-    @Override public void onCreate() {
+    @Override
+    public void onCreate() {
         LatinImeLogger.init(this);
         super.onCreate();
         //setStatusIcon(R.drawable.ime_qwerty);
@@ -395,7 +396,7 @@ public class LatinIME extends InputMethodService
      * Loads a dictionary or multiple separated dictionary
      * @return returns array of dictionary resource ids
      */
-    static int[] getDictionary(Resources res) {
+    /* package */ static int[] getDictionary(Resources res) {
         String packageName = LatinIME.class.getPackage().getName();
         XmlResourceParser xrp = res.getXml(R.xml.dictionary);
         ArrayList<Integer> dictionaries = new ArrayList<Integer>();
@@ -1013,9 +1014,6 @@ public class LatinIME extends InputMethodService
     }
 
     private void reloadKeyboards() {
-        if (mKeyboardSwitcher == null) {
-            mKeyboardSwitcher = new KeyboardSwitcher(this);
-        }
         mKeyboardSwitcher.setLanguageSwitcher(mLanguageSwitcher);
         if (mKeyboardSwitcher.getInputView() != null
                 && mKeyboardSwitcher.getKeyboardMode() != KeyboardSwitcher.MODE_NONE) {
@@ -2406,20 +2404,20 @@ public class LatinIME extends InputMethodService
         mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_START_TUTORIAL), 500);
     }
 
-    void tutorialDone() {
+    /* package */ void tutorialDone() {
         mTutorial = null;
     }
 
-    void promoteToUserDictionary(String word, int frequency) {
+    /* package */ void promoteToUserDictionary(String word, int frequency) {
         if (mUserDictionary.isValidWord(word)) return;
         mUserDictionary.addWord(word, frequency);
     }
 
-    WordComposer getCurrentWord() {
+    /* package */ WordComposer getCurrentWord() {
         return mWord;
     }
 
-    boolean getPopupOn() {
+    /* package */ boolean getPopupOn() {
         return mPopupOn;
     }
 
@@ -2624,7 +2622,8 @@ public class LatinIME extends InputMethodService
         return list;
     }
 
-    @Override protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
+    @Override
+    protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
         super.dump(fd, fout, args);
 
         final Printer p = new PrintWriterPrinter(fout);
diff --git a/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java b/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java
index d319d402001aea8ce100f45739ae182c3589ad57..b160da231de124a630d2fc97aecc68f65be07f5a 100644
--- a/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java
+++ b/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java
@@ -47,10 +47,9 @@ import android.widget.PopupWindow;
 import android.widget.TextView;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
+import java.util.WeakHashMap;
 
 /**
  * A view that renders a virtual {@link LatinKeyboard}. It handles rendering of keys and
@@ -199,7 +198,7 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx
     private PopupWindow mMiniKeyboardPopup;
     private LatinKeyboardBaseView mMiniKeyboard;
     private View mMiniKeyboardParent;
-    private Map<Key,View> mMiniKeyboardCache;
+    private final WeakHashMap<Key, View> mMiniKeyboardCache = new WeakHashMap<Key, View>();
     private int mMiniKeyboardOriginX;
     private int mMiniKeyboardOriginY;
     private long mMiniKeyboardPopupTime;
@@ -489,7 +488,6 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx
         mPaint.setAlpha(255);
 
         mPadding = new Rect(0, 0, 0, 0);
-        mMiniKeyboardCache = new HashMap<Key,View>();
         mKeyBackground.getPadding(mPadding);
 
         mSwipeThreshold = (int) (500 * res.getDisplayMetrics().density);